github.com/snyk/vervet/v4@v4.27.2/internal/cmd/compiler.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/urfave/cli/v2"
     8  
     9  	"github.com/snyk/vervet/v4/config"
    10  	"github.com/snyk/vervet/v4/internal/compiler"
    11  )
    12  
    13  // BuildCommand is the `vervet build` subcommand.
    14  var BuildCommand = cli.Command{
    15  	Name:      "build",
    16  	Usage:     "Build versioned resources into versioned OpenAPI specs",
    17  	ArgsUsage: "[input resources root] [output api root]",
    18  	Flags: []cli.Flag{
    19  		&cli.StringFlag{
    20  			Name:    "config",
    21  			Aliases: []string{"c", "conf"},
    22  			Usage:   "Project configuration file",
    23  		},
    24  		&cli.BoolFlag{
    25  			Name:  "lint",
    26  			Usage: "Enable linting during build",
    27  			Value: true,
    28  		},
    29  		&cli.StringFlag{
    30  			Name:    "include",
    31  			Aliases: []string{"I"},
    32  			Usage:   "OpenAPI specification to include in build output",
    33  		},
    34  	},
    35  	Action: Build,
    36  }
    37  
    38  // Build compiles versioned resources into versioned API specs.
    39  func Build(ctx *cli.Context) error {
    40  	project, err := projectFromContext(ctx)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	return runCompiler(ctx, project, ctx.Bool("lint"), true)
    45  }
    46  
    47  // LintCommand is the `vervet lint` subcommand.
    48  var LintCommand = cli.Command{
    49  	Name:      "lint",
    50  	Usage:     "Lint  versioned resources",
    51  	ArgsUsage: "[input resources root] [output api root]",
    52  	Flags: []cli.Flag{
    53  		&cli.StringFlag{
    54  			Name:    "config",
    55  			Aliases: []string{"c", "conf"},
    56  			Usage:   "Project configuration file",
    57  		},
    58  	},
    59  	Action: Lint,
    60  }
    61  
    62  // Lint checks versioned resources against linting rules.
    63  func Lint(ctx *cli.Context) error {
    64  	project, err := projectFromContext(ctx)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	return runCompiler(ctx, project, true, false)
    69  }
    70  
    71  func projectFromContext(ctx *cli.Context) (*config.Project, error) {
    72  	var project *config.Project
    73  	if ctx.Args().Len() == 0 {
    74  		var configPath string
    75  		if s := ctx.String("config"); s != "" {
    76  			configPath = s
    77  		} else {
    78  			configPath = ".vervet.yaml"
    79  		}
    80  		f, err := os.Open(configPath)
    81  		if err != nil {
    82  			return nil, fmt.Errorf("failed to open %q: %w", configPath, err)
    83  		}
    84  		defer f.Close()
    85  		project, err = config.Load(f)
    86  		if err != nil {
    87  			return nil, err
    88  		}
    89  	} else {
    90  		api := &config.API{
    91  			Resources: []*config.ResourceSet{{
    92  				Path: ctx.Args().Get(0),
    93  			}},
    94  			Output: &config.Output{
    95  				Path: ctx.Args().Get(1),
    96  			},
    97  		}
    98  		if includePath := ctx.String("include"); includePath != "" {
    99  			api.Overlays = append(api.Overlays, &config.Overlay{
   100  				Include: includePath,
   101  			})
   102  		}
   103  		project = &config.Project{
   104  			APIs: map[string]*config.API{
   105  				"": api,
   106  			},
   107  		}
   108  	}
   109  	return project, nil
   110  }
   111  
   112  func runCompiler(ctx *cli.Context, project *config.Project, lint, build bool) error {
   113  	comp, err := compiler.New(ctx.Context, project)
   114  	if err != nil {
   115  		return err
   116  	}
   117  	if lint {
   118  		err = comp.LintResourcesAll(ctx.Context)
   119  		if err != nil {
   120  			return err
   121  		}
   122  	}
   123  	if build {
   124  		err = comp.BuildAll(ctx.Context)
   125  		if err != nil {
   126  			return err
   127  		}
   128  	}
   129  	if lint {
   130  		err = comp.LintOutputAll(ctx.Context)
   131  		if err != nil {
   132  			return err
   133  		}
   134  	}
   135  	return nil
   136  }