github.com/mattdotmatt/gauge@v0.3.2-0.20160421115137-425a4cdccb62/gauge.go (about) 1 // Copyright 2015 ThoughtWorks, Inc. 2 3 // This file is part of Gauge. 4 5 // Gauge is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 10 // Gauge is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 15 // You should have received a copy of the GNU General Public License 16 // along with Gauge. If not, see <http://www.gnu.org/licenses/>. 17 18 package main 19 20 import ( 21 "encoding/json" 22 "fmt" 23 "os" 24 "path/filepath" 25 "time" 26 27 "github.com/getgauge/common" 28 "github.com/getgauge/gauge/api" 29 "github.com/getgauge/gauge/config" 30 "github.com/getgauge/gauge/env" 31 "github.com/getgauge/gauge/execution" 32 "github.com/getgauge/gauge/filter" 33 "github.com/getgauge/gauge/formatter" 34 "github.com/getgauge/gauge/logger" 35 "github.com/getgauge/gauge/plugin" 36 "github.com/getgauge/gauge/refactor" 37 "github.com/getgauge/gauge/reporter" 38 "github.com/getgauge/gauge/validation" 39 "github.com/getgauge/gauge/version" 40 41 "github.com/getgauge/gauge/plugin/install" 42 "github.com/getgauge/gauge/projectInit" 43 "github.com/getgauge/gauge/util" 44 flag "github.com/getgauge/mflag" 45 ) 46 47 // Command line flags 48 var daemonize = flag.Bool([]string{"-daemonize"}, false, "Run as a daemon") 49 var gaugeVersion = flag.Bool([]string{"v", "-version", "version"}, false, "Print the current version and exit. Eg: gauge --version") 50 var verbosity = flag.Bool([]string{"-verbose"}, false, "Enable step level reporting on console, default being scenario level. Eg: gauge --verbose specs") 51 var logLevel = flag.String([]string{"-log-level"}, "", "Set level of logging to debug, info, warning, error or critical") 52 var simpleConsoleOutput = flag.Bool([]string{"-simple-console"}, false, "Removes colouring and simplifies from the console output") 53 var initialize = flag.String([]string{"-init"}, "", "Initializes project structure in the current directory. Eg: gauge --init java") 54 var installPlugin = flag.String([]string{"-install"}, "", "Downloads and installs a plugin. Eg: gauge --install java") 55 var uninstallPlugin = flag.String([]string{"-uninstall"}, "", "Uninstalls a plugin. Eg: gauge --uninstall java") 56 var installAll = flag.Bool([]string{"-install-all"}, false, "Installs all the plugins specified in project manifest, if not installed. Eg: gauge --install-all") 57 var update = flag.String([]string{"-update"}, "", "Updates a plugin. Eg: gauge --update java") 58 var pluginVersion = flag.String([]string{"-plugin-version"}, "", "Version of plugin to be installed. This is used with --install") 59 var installZip = flag.String([]string{"-file", "f"}, "", "Installs the plugin from zip file. This is used with --install. Eg: gauge --install java -f ZIP_FILE") 60 var currentEnv = flag.String([]string{"-env"}, "default", "Specifies the environment. If not specified, default will be used") 61 var addPlugin = flag.String([]string{"-add-plugin"}, "", "Adds the specified non-language plugin to the current project") 62 var pluginArgs = flag.String([]string{"-plugin-args"}, "", "Specified additional arguments to the plugin. This is used together with --add-plugin") 63 var specFilesToFormat = flag.String([]string{"-format"}, "", "Formats the specified spec files") 64 var executeTags = flag.String([]string{"-tags"}, "", "Executes the specs and scenarios tagged with given tags. Eg: gauge --tags tag1,tag2 specs") 65 var tableRows = flag.String([]string{"-table-rows"}, "", "Executes the specs and scenarios only for the selected rows. Eg: gauge --table-rows \"1-3\" specs/hello.spec") 66 var apiPort = flag.String([]string{"-api-port"}, "", "Specifies the api port to be used. Eg: gauge --daemonize --api-port 7777") 67 var refactorSteps = flag.String([]string{"-refactor"}, "", "Refactor steps. Eg: gauge --refactor <old step> <new step> [[spec directories]]") 68 var parallel = flag.Bool([]string{"-parallel", "p"}, false, "Execute specs in parallel") 69 var numberOfExecutionStreams = flag.Int([]string{"n"}, util.NumberOfCores(), "Specify number of parallel execution streams") 70 var distribute = flag.Int([]string{"g", "-group"}, -1, "Specify which group of specification to execute based on -n flag") 71 var workingDir = flag.String([]string{"-dir"}, ".", "Set the working directory for the current command, accepts a path relative to current directory.") 72 var strategy = flag.String([]string{"-strategy"}, "lazy", "Set the parallelization strategy for execution. Possible options are: `eager`, `lazy`. Ex: gauge -p --strategy=\"eager\"") 73 var doNotRandomize = flag.Bool([]string{"-sort", "s"}, false, "Run specs in Alphabetical Order. Eg: gauge -s specs") 74 var validate = flag.Bool([]string{"-validate", "#-check"}, false, "Check for validation and parse errors. Eg: gauge --validate specs") 75 var updateAll = flag.Bool([]string{"-update-all"}, false, "Updates all the installed Gauge plugins. Eg: gauge --update-all") 76 var checkUpdates = flag.Bool([]string{"-check-updates"}, false, "Checks for Gauge and plugins updates. Eg: gauge --check-updates") 77 var listTemplates = flag.Bool([]string{"-list-templates"}, false, "Lists all the Gauge templates available. Eg: gauge --list-templates") 78 var machineReadable = flag.Bool([]string{"-machine-readable"}, false, "Used with `--version` to produce JSON output of currently installed Gauge and plugin versions. e.g: gauge --version --machine-readable") 79 80 func main() { 81 flag.Parse() 82 util.SetWorkingDir(*workingDir) 83 initPackageFlags() 84 validGaugeProject := true 85 err := config.SetProjectRoot(flag.Args()) 86 if err != nil { 87 validGaugeProject = false 88 } 89 env.LoadEnv(*currentEnv) 90 logger.Initialize(*logLevel) 91 if *gaugeVersion && *machineReadable { 92 printJSONVersion() 93 } else if *machineReadable { 94 fmt.Printf("flag '--machine-readable' can only be used with '--version' or '-v'\n\n") 95 fmt.Printf("Usage:\n\n") 96 flag.PrintDefaults() 97 os.Exit(1) 98 } else if *gaugeVersion { 99 printVersion() 100 } else if *initialize != "" { 101 projectInit.InitializeProject(*initialize) 102 } else if *installZip != "" && *installPlugin != "" { 103 install.HandleInstallResult(install.InstallPluginFromZipFile(*installZip, *installPlugin), *installPlugin, true) 104 } else if *installPlugin != "" { 105 install.HandleInstallResult(install.InstallPlugin(*installPlugin, *pluginVersion), *installPlugin, true) 106 } else if *uninstallPlugin != "" { 107 install.UninstallPlugin(*uninstallPlugin, *pluginVersion) 108 } else if *installAll { 109 install.InstallAllPlugins() 110 } else if *update != "" { 111 install.HandleUpdateResult(install.InstallPlugin(*update, *pluginVersion), *update, true) 112 } else if *updateAll { 113 install.UpdatePlugins() 114 } else if *checkUpdates { 115 install.PrintUpdateInfoWithDetails() 116 } else if *addPlugin != "" { 117 install.AddPluginToProject(*addPlugin, *pluginArgs) 118 } else if *listTemplates { 119 projectInit.ListTemplates() 120 } else if flag.NFlag() == 0 && len(flag.Args()) == 0 { 121 printUsage() 122 os.Exit(0) 123 } else if validGaugeProject { 124 var specDirs = []string{common.SpecsDirectoryName} 125 if len(flag.Args()) > 0 { 126 specDirs = flag.Args() 127 } 128 if *refactorSteps != "" { 129 refactorInit(flag.Args()) 130 } else if *daemonize { 131 api.RunInBackground(*apiPort, specDirs) 132 } else if *specFilesToFormat != "" { 133 formatter.FormatSpecFilesIn(*specFilesToFormat) 134 } else if *validate { 135 validation.Validate(flag.Args()) 136 } else { 137 exitCode := execution.ExecuteSpecs(specDirs) 138 os.Exit(exitCode) 139 } 140 } else { 141 logger.Fatalf(err.Error()) 142 } 143 } 144 145 func refactorInit(args []string) { 146 if len(args) < 1 { 147 logger.Fatalf("Flag needs at least two arguments: --refactor\nUsage : gauge --refactor <old step> <new step> [[spec directories]]") 148 } 149 var specDirs = []string{common.SpecsDirectoryName} 150 if len(args) > 1 { 151 specDirs = args[1:] 152 } 153 startChan := api.StartAPI() 154 refactor.RefactorSteps(*refactorSteps, args[0], startChan, specDirs) 155 } 156 157 func printJSONVersion() { 158 type pluginJSON struct { 159 Name string `json:"name"` 160 Version string `json:"version"` 161 } 162 type versionJSON struct { 163 Version string `json:"version"` 164 Plugins []*pluginJSON `json:"plugins"` 165 } 166 gaugeVersion := versionJSON{version.FullVersion(), make([]*pluginJSON, 0)} 167 allPluginsWithVersion, err := plugin.GetAllInstalledPluginsWithVersion() 168 for _, pluginInfo := range allPluginsWithVersion { 169 gaugeVersion.Plugins = append(gaugeVersion.Plugins, &pluginJSON{pluginInfo.Name, filepath.Base(pluginInfo.Path)}) 170 } 171 b, err := json.MarshalIndent(gaugeVersion, "", " ") 172 if err != nil { 173 fmt.Println("error:", err) 174 } 175 fmt.Println(fmt.Sprintf("%s\n", string(b))) 176 } 177 178 func printVersion() { 179 fmt.Printf("Gauge version: %s\n\n", version.FullVersion()) 180 fmt.Println("Plugins\n-------") 181 allPluginsWithVersion, err := plugin.GetAllInstalledPluginsWithVersion() 182 if err != nil { 183 fmt.Println("No plugins found") 184 fmt.Println("Plugins can be installed with `gauge --install {plugin-name}`") 185 os.Exit(0) 186 } 187 for _, pluginInfo := range allPluginsWithVersion { 188 fmt.Printf("%s (%s)\n", pluginInfo.Name, filepath.Base(pluginInfo.Path)) 189 } 190 } 191 192 func printUsage() { 193 fmt.Printf("gauge -version %s\n", version.FullVersion()) 194 fmt.Printf("Copyright %d ThoughtWorks, Inc.\n\n", time.Now().Year()) 195 fmt.Println("Usage:") 196 fmt.Println("\tgauge specs/") 197 fmt.Println("\tgauge specs/spec_name.spec") 198 fmt.Println("\nOptions:") 199 flag.PrintDefaults() 200 } 201 202 func initPackageFlags() { 203 if *parallel { 204 *simpleConsoleOutput = true 205 } 206 reporter.SimpleConsoleOutput = *simpleConsoleOutput 207 reporter.Verbose = *verbosity 208 execution.ExecuteTags = *executeTags 209 execution.TableRows = *tableRows 210 execution.NumberOfExecutionStreams = *numberOfExecutionStreams 211 execution.InParallel = *parallel 212 filter.ExecuteTags = *executeTags 213 filter.DoNotRandomize = *doNotRandomize 214 filter.Distribute = *distribute 215 filter.NumberOfExecutionStreams = *numberOfExecutionStreams 216 execution.Strategy = *strategy 217 if *distribute != -1 { 218 execution.Strategy = execution.Eager 219 } 220 }