github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/cmd/verify/cmd.go (about)

     1  // Copyright 2016 Palantir Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package verify
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/nmiyake/pkg/dirs"
    22  	"github.com/palantir/amalgomate/amalgomated"
    23  	"github.com/palantir/pkg/cli"
    24  	"github.com/palantir/pkg/cli/flag"
    25  	"github.com/pkg/errors"
    26  
    27  	"github.com/palantir/godel/cmd"
    28  )
    29  
    30  const (
    31  	cmdName         = "verify"
    32  	apply           = "apply"
    33  	skipFormat      = "skip-format"
    34  	skipImports     = "skip-imports"
    35  	skipLicense     = "skip-license"
    36  	skipCheck       = "skip-check"
    37  	skipTest        = "skip-test"
    38  	junitOutputPath = "junit-output"
    39  )
    40  
    41  func Command(gödelPath string) cli.Command {
    42  	return cli.Command{
    43  		Name:  cmdName,
    44  		Usage: "Run format, check and test tasks",
    45  		Flags: []flag.Flag{
    46  			flag.BoolFlag{Name: apply, Usage: "Apply changes when possible", Value: true},
    47  			flag.BoolFlag{Name: skipFormat, Usage: "Skip 'format' task"},
    48  			flag.BoolFlag{Name: skipImports, Usage: "Skip 'imports' task"},
    49  			flag.BoolFlag{Name: skipLicense, Usage: "Skip 'license' task"},
    50  			flag.BoolFlag{Name: skipCheck, Usage: "Skip 'check' task"},
    51  			flag.BoolFlag{Name: skipTest, Usage: "Skip 'test' task"},
    52  			flag.StringFlag{Name: junitOutputPath, Usage: "Path to JUnit XML output (only used if 'test' task is run)"},
    53  		},
    54  		Action: func(ctx cli.Context) error {
    55  			wd, err := dirs.GetwdEvalSymLinks()
    56  			if err != nil {
    57  				return err
    58  			}
    59  
    60  			globalFlags, err := globalFlags(ctx)
    61  			if err != nil {
    62  				return err
    63  			}
    64  			cmder := amalgomated.PathCmder(gödelPath, globalFlags...)
    65  
    66  			var failedChecks []string
    67  
    68  			if !ctx.Bool(skipFormat) {
    69  				args := []string{"format", "-v"}
    70  				if !ctx.Bool(apply) {
    71  					args = append(args, "-l")
    72  				}
    73  				if err := runCmd(cmder, args, wd, ctx); err != nil {
    74  					failedChecks = append(failedChecks, strings.Join(args, " "))
    75  				}
    76  			}
    77  
    78  			if !ctx.Bool(skipImports) {
    79  				args := []string{"imports"}
    80  				if !ctx.Bool(apply) {
    81  					args = append(args, "--verify")
    82  				}
    83  				ctx.Println("Running gocd...")
    84  				if err := runCmd(cmder, args, wd, ctx); err != nil {
    85  					failedChecks = append(failedChecks, strings.Join(args, " "))
    86  				}
    87  			}
    88  
    89  			if !ctx.Bool(skipLicense) {
    90  				args := []string{"license"}
    91  				if !ctx.Bool(apply) {
    92  					args = append(args, "--verify")
    93  				}
    94  				ctx.Println("Running golicense...")
    95  				if err := runCmd(cmder, args, wd, ctx); err != nil {
    96  					failedChecks = append(failedChecks, strings.Join(args, " "))
    97  				}
    98  			}
    99  
   100  			if !ctx.Bool(skipCheck) {
   101  				if err := runCmd(cmder, []string{"check"}, wd, ctx); err != nil {
   102  					failedChecks = append(failedChecks, "check")
   103  				}
   104  			}
   105  
   106  			if !ctx.Bool(skipTest) {
   107  				args := []string{"test"}
   108  				if ctx.Has(junitOutputPath) {
   109  					args = append(args, "--"+junitOutputPath, ctx.String(junitOutputPath))
   110  				}
   111  				if err := runCmd(cmder, args, wd, ctx); err != nil {
   112  					failedChecks = append(failedChecks, "test")
   113  				}
   114  			}
   115  
   116  			if len(failedChecks) != 0 {
   117  				msgParts := []string{"Failed tasks:"}
   118  				for _, check := range failedChecks {
   119  					msgParts = append(msgParts, "\t"+check)
   120  				}
   121  				return fmt.Errorf(strings.Join(msgParts, "\n"))
   122  			}
   123  
   124  			return nil
   125  		},
   126  	}
   127  }
   128  
   129  func globalFlags(ctx cli.Context) ([]string, error) {
   130  	var globalArgs []string
   131  	for _, f := range cmd.GlobalCLIFlags() {
   132  		if ctx.Has(f.MainName()) {
   133  			var flagValue string
   134  			switch f.(type) {
   135  			case flag.BoolFlag:
   136  				flagValue = fmt.Sprintf("%v", ctx.Bool(f.MainName()))
   137  			case flag.StringFlag:
   138  				flagValue = ctx.String(f.MainName())
   139  			default:
   140  				return nil, errors.Errorf("Unhandled flag type %T for flag %v", f, f)
   141  			}
   142  			globalArgs = append(globalArgs, "--"+f.MainName(), flagValue)
   143  		}
   144  	}
   145  	return globalArgs, nil
   146  }
   147  
   148  func runCmd(cmder amalgomated.Cmder, args []string, wd string, ctx cli.Context) error {
   149  	cmd := cmder.Cmd(args, wd)
   150  	cmd.Stdout = ctx.App.Stdout
   151  	cmd.Stderr = ctx.App.Stderr
   152  	return cmd.Run()
   153  }