diff --git a/cmd/root.go b/cmd/root.go index e113ca5..33b3f9d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,6 +7,7 @@ import ( "fmt" "io/fs" "io/ioutil" + "log" "os" "path" "path/filepath" @@ -22,12 +23,15 @@ import ( ) var targetDirectory string +var localManifest string var scaffold string var noInteraction bool +var inputFile string func getScaffoldsKeys() []string { + scaffolds, _ := internal.GetScaffolds(localManifest) var ret []string - for k := range internal.GetScaffolds() { + for k := range scaffolds { ret = append(ret, k) } sort.Strings(ret) @@ -35,11 +39,15 @@ func getScaffoldsKeys() []string { } func selectScaffold(scaffold *string) error { + scaffolds, err := internal.GetScaffolds(localManifest) + if err != nil { + return err + } prompt := survey.Select{ Message: "Select a scaffold to run", Options: getScaffoldsKeys(), Description: func(value string, index int) string { - return internal.GetScaffolds()[value].ShortDescription + return scaffolds[value].ShortDescription }, } @@ -53,7 +61,12 @@ var RootCmd = &cobra.Command{ Long: `Lagoon scaffold will pull a new site and fill in the details`, RunE: func(cmd *cobra.Command, args []string) error { - scaffolds := internal.GetScaffolds() + scaffolds, err := internal.GetScaffolds(localManifest) + + if err != nil { + fmt.Println(err) + os.Exit(1) + } if scaffold == "" && noInteraction { return errors.New("Please select a scaffold") @@ -107,7 +120,23 @@ var RootCmd = &cobra.Command{ return err } - values, err := internal.RunFromSurveyQuestions(questions, !noInteraction) + var values interface{} + + if inputFile == "" { + values, err = internal.RunFromSurveyQuestions(questions, !noInteraction) + if err != nil { + log.Fatalf("Error running survey: %v", err) + } + } else { // we're going to attempt to load these values from the file + yamlFile, err := ioutil.ReadFile(inputFile) + if err != nil { + log.Fatalf("Error reading YAML file: %v", err) + } + err = yaml.Unmarshal(yamlFile, &values) + if err != nil { + log.Fatalf("Error parsing YAML file: %v", err) + } + } if err = processTemplates(values, tDir); err != nil { return err @@ -225,8 +254,9 @@ var listCmd = &cobra.Command{ Long: "Lists all currently supported Lagoon scaffolds", Example: "lagoon-init-prot list", Run: func(cmd *cobra.Command, args []string) { + scaffolds, _ := internal.GetScaffolds(localManifest) fmt.Println("We currently support the following:") - for pagage := range internal.GetScaffolds() { + for pagage := range scaffolds { fmt.Println(pagage) } }, @@ -237,6 +267,8 @@ func init() { RootCmd.PersistentFlags().StringVar(&scaffold, "scaffold", "", "Which scaffold to pull into directory") RootCmd.Flags().BoolVar(&noInteraction, "no-interaction", false, "Don't interactively fill in any values for the scaffold - use defaults") RootCmd.Flags().StringVar(&targetDirectory, "targetdir", "./", "Directory to check out project into - defaults to current directory") + RootCmd.Flags().StringVar(&localManifest, "manifest", "", "Custom local manifest file for scaffold list - defaults to an empty string") + RootCmd.Flags().StringVar(&inputFile, "values", "", "A Yaml file that provides defaults/answers for a scaffold - can be used in automation") } func Execute() { diff --git a/internal/manifest.go b/internal/manifest.go index 450f5ed..2b26e8e 100644 --- a/internal/manifest.go +++ b/internal/manifest.go @@ -5,6 +5,7 @@ import ( "gopkg.in/yaml.v2" "io/ioutil" "net/http" + "os" ) const manifestUrl = "https://raw.githubusercontent.com/uselagoon/lagoon-scaffold/main/internal/assets/scaffolds.yml" @@ -76,8 +77,25 @@ func remapScaffoldLoader(loader *ScaffoldLoader) map[string]ScaffoldRepo { return remapped } -func GetScaffolds() map[string]ScaffoldRepo { - return resolveScaffolds(manifestUrl) +func GetScaffolds(localmanifest string) (map[string]ScaffoldRepo, error) { + + if localmanifest != "" { // we try load up a manifest given locally + // try open and read the file + + loader := &ScaffoldLoader{ + Scaffolds: make([]ScaffoldRepo, 0), + } + dat, err := os.ReadFile(localmanifest) + err = yaml.Unmarshal(dat, loader) + if err != nil { + return map[string]ScaffoldRepo{}, err + } + + return remapScaffoldLoader(loader), nil + + } + + return resolveScaffolds(manifestUrl), nil } type ScaffoldRepo struct { diff --git a/internal/manifest_test.go b/internal/manifest_test.go index c62a6b5..72e01da 100644 --- a/internal/manifest_test.go +++ b/internal/manifest_test.go @@ -44,3 +44,43 @@ func Test_resolveScaffolds(t *testing.T) { }) } } + +func TestGetScaffolds(t *testing.T) { + type args struct { + localmanifest string + } + tests := []struct { + name string + args args + want map[string]ScaffoldRepo + wantErr bool + }{ + { + name: "Test 1 - Passing manifest file manually", + args: args{ + localmanifest: "./testassets/manifest_test_1.yml", + }, + want: map[string]ScaffoldRepo{ + "test1": { + Name: "test1", + GitRepo: "https://github.com/lagoon-examples/test1.git", + Branch: "test1_branch", + Description: "test1_description", + ShortDescription: "test1_shortDescription", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetScaffolds(tt.args.localmanifest) + if (err != nil) != tt.wantErr { + t.Errorf("GetScaffolds() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetScaffolds() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/testassets/manifest_test_1.yml b/internal/testassets/manifest_test_1.yml new file mode 100644 index 0000000..b86c26b --- /dev/null +++ b/internal/testassets/manifest_test_1.yml @@ -0,0 +1,6 @@ +scaffolds: + - name: test1 + git_repo: https://github.com/lagoon-examples/test1.git + branch: test1_branch + description: test1_description + shortDescription: test1_shortDescription