github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/experiment/bootstrap/args.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  
    22  	flag "github.com/spf13/pflag"
    23  )
    24  
    25  // Args contains all of the (parsed) command line arguments for bootstrap
    26  // NOTE: Repo should be further parsed by ParseRepos
    27  type Args struct {
    28  	Root           string
    29  	Timeout        int32
    30  	Repo           []string
    31  	Bare           bool
    32  	Job            string
    33  	Upload         string
    34  	ServiceAccount string
    35  	SSH            string
    36  	GitCache       string
    37  	Clean          bool
    38  	// Note: these are the args after `--` terminates the other args
    39  	// IE `bootstrap --job=foo -- --bar=baz` -> JobArgs == []string{"--bar=baz"}
    40  	JobArgs []string
    41  }
    42  
    43  // ParseArgs parses the command line to an Args instance
    44  // arguments should be generally be os.Args[1:]
    45  func ParseArgs(arguments []string) (*Args, error) {
    46  	args := &Args{}
    47  	flags := flag.NewFlagSet("bootstrap", flag.ContinueOnError)
    48  	// used to mimic required=true
    49  	requiredFlags := []string{"job"}
    50  
    51  	// add all of the args from parse_args in jenkins/bootstrap.py
    52  	flags.StringVar(&args.Root, "root", ".", "Root dir to work with")
    53  
    54  	// NOTE: jenkins/bootstrap.py technically used a float for this arg
    55  	// when parsing but only ever used the arg as an integer number
    56  	// of timeout minutes.
    57  	// int32 makes more sense and will let use time.Minute * timeout
    58  	flags.Int32Var(&args.Timeout, "timeout", 0, "Timeout in minutes if set")
    59  
    60  	flags.StringArrayVar(&args.Repo, "repo", []string{},
    61  		"Fetch the specified repositories, with the first one considered primary")
    62  
    63  	flags.BoolVar(&args.Bare, "bare", false, "Do not check out a repository")
    64  	flags.Lookup("bare").NoOptDefVal = "true" // allows using --bare
    65  
    66  	// NOTE: this arg is required (set above)
    67  	flags.StringVar(&args.Job, "job", "", "Name of the job to run")
    68  
    69  	flags.StringVar(&args.Upload, "upload", "",
    70  		"Upload results here if set, requires --service-account")
    71  	flags.StringVar(&args.ServiceAccount, "service-account", "",
    72  		"Activate and use path/to/service-account.json if set.")
    73  	flags.StringVar(&args.SSH, "ssh", "",
    74  		"Use the ssh key to fetch the repository instead of https if set.")
    75  	flags.StringVar(&args.GitCache, "git-cache", "", "Location of the git cache.")
    76  
    77  	flags.BoolVar(&args.Clean, "clean", false, "Clean the git repo before running tests.")
    78  	flags.Lookup("clean").NoOptDefVal = "true" // allows using --clean
    79  
    80  	// parse flags
    81  	// NOTE: this stops parsing at `--`, after which we grab arguments as
    82  	// JobArgs below.
    83  	err := flags.Parse(arguments)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	for i, arg := range arguments {
    88  		if arg == "--" {
    89  			args.JobArgs = arguments[i+1:]
    90  			break
    91  		}
    92  	}
    93  
    94  	// check that required args were set
    95  	for _, arg := range requiredFlags {
    96  		if flag := flags.Lookup(arg); !flag.Changed {
    97  			err = fmt.Errorf("flag '--%s' is required but was not set", flag.Name)
    98  			return nil, err
    99  		}
   100  	}
   101  
   102  	// validate args
   103  	if args.Bare == (len(args.Repo) != 0) {
   104  		err = fmt.Errorf("expected --repo xor --bare, Got: --repo=%v, --bare=%v", args.Repo, args.Bare)
   105  		return nil, err
   106  	}
   107  	if args.Job == "" {
   108  		return nil, fmt.Errorf("--job=\"\" is not valid, please supply a job name")
   109  	}
   110  
   111  	return args, nil
   112  }