github.com/snyk/vervet/v5@v5.11.1-0.20240202085829-ad4dd7fb6101/generate/generate.go (about) 1 package generate 2 3 import ( 4 "fmt" 5 "io/fs" 6 "os" 7 "path/filepath" 8 "strings" 9 "text/template" 10 11 "github.com/snyk/vervet/v5/config" 12 "github.com/snyk/vervet/v5/internal/generator" 13 ) 14 15 // GeneratorParams contains the metadata needed to execute code generators. 16 type GeneratorParams struct { 17 ProjectDir string 18 ConfigFile string 19 Generators []string 20 GeneratorsFile string 21 Force bool 22 Debug bool 23 DryRun bool 24 FS fs.FS 25 Functions template.FuncMap 26 } 27 28 // Generate executes code generators against OpenAPI specs. 29 func Generate(params GeneratorParams) error { 30 f, err := os.Open(params.ConfigFile) 31 if err != nil { 32 return err 33 } 34 defer f.Close() 35 proj, err := config.Load(f) 36 if err != nil { 37 return err 38 } 39 40 selectedGenerators := map[string]struct{}{} 41 for _, generator := range params.Generators { 42 selectedGenerators[generator] = struct{}{} 43 } 44 45 // Ensure a default FS if one isn't provided. 46 basePath := "" 47 if params.FS == nil { 48 basePath = "/" 49 params.FS = os.DirFS(basePath) 50 } 51 52 // Option to load generators and overlay onto project config 53 generatorsHere := map[string]string{} 54 if params.GeneratorsFile != "" { 55 genFile := strings.TrimPrefix(params.GeneratorsFile, "/") 56 f, err := params.FS.Open(genFile) 57 if err != nil { 58 return err 59 } 60 defer f.Close() 61 generators, err := config.LoadGenerators(f) 62 if err != nil { 63 return err 64 } 65 for k, v := range generators { 66 proj.Generators[k] = v 67 generatorsHere[k] = filepath.Dir(filepath.Join(basePath, genFile)) 68 } 69 } 70 // If a list of specific generators were specified, only instantiate those. 71 if len(selectedGenerators) > 0 { 72 for k := range proj.Generators { 73 if _, ok := selectedGenerators[k]; !ok { 74 delete(proj.Generators, k) 75 } 76 } 77 } 78 79 options := []generator.Option{generator.Force(true)} 80 if params.Debug { 81 options = append(options, generator.Debug(true)) 82 } 83 if params.DryRun { 84 options = append(options, generator.DryRun(true)) 85 } 86 if params.FS != nil { 87 options = append(options, generator.Filesystem(params.FS)) 88 } 89 if len(params.Functions) > 0 { 90 options = append(options, generator.Functions(params.Functions)) 91 } 92 generators := map[string]*generator.Generator{} 93 for k, genConf := range proj.Generators { 94 genHere, ok := generatorsHere[k] 95 if !ok { 96 genHere = params.ProjectDir 97 } 98 genHere, err = filepath.Abs(genHere) 99 if err != nil { 100 return err 101 } 102 gen, err := generator.New(genConf, append(options, generator.Here(genHere))...) 103 if err != nil { 104 return err 105 } 106 generators[k] = gen 107 } 108 109 err = os.Chdir(params.ProjectDir) 110 if err != nil { 111 return err 112 } 113 114 resources, err := generator.MapResources(proj) 115 if err != nil { 116 return err 117 } 118 119 var allGeneratedFiles []string 120 for _, gen := range generators { 121 generatedFiles, err := gen.Execute(resources) 122 if err != nil { 123 return err 124 } 125 allGeneratedFiles = append(allGeneratedFiles, generatedFiles...) 126 } 127 128 for _, generatedFile := range allGeneratedFiles { 129 fmt.Println(generatedFile) 130 } 131 132 return nil 133 }