// run all given tasks func RunTasks(workingDirectory string, destPlatforms []platforms.Platform, settings *config.Settings, maxProcessors int) error { if settings.IsVerbose() { log.Printf("Using Go root: %s", settings.GoRoot) log.Printf("looping through each platform") } appName := core.GetAppName(settings.AppName, workingDirectory) outDestRoot, err := core.GetOutDestRoot(appName, workingDirectory, settings.ArtifactsDest) if err != nil { return err } defer log.SetPrefix("[goxc] ") exclusions := ResolveAliases(settings.TasksExclude) appends := ResolveAliases(settings.TasksAppend) mains := ResolveAliases(settings.Tasks) all := ResolveAliases(settings.TasksPrepend) //log.Printf("prepending %v", all) all = append(all, mains...) all = append(all, appends...) //exclude by resolved task names (not by aliases) tasksToRun := []string{} for _, taskName := range all { if !core.ContainsString(exclusions, taskName) { tasksToRun = append(tasksToRun, taskName) } } //0.6 check all tasks are valid before continuing for _, taskName := range tasksToRun { if _, keyExists := allTasks[taskName]; !keyExists { if strings.HasPrefix(taskName, ".") { log.Printf("'%s' looks like a directory, not a task - specify 'working directory' with -wd option", taskName) } if e, _ := core.FileExists(taskName); e { log.Printf("'%s' looks like a directory, not a task - specify 'working directory' with -wd option", taskName) } if settings.IsVerbose() { log.Printf("Task '%s' does NOT exist!", taskName) } return errors.New("Task '" + taskName + "' does not exist") } } mainDirs := []string{} allPackages := []string{} if len(tasksToRun) == 1 && tasksToRun[0] == "toolchain" { log.Printf("Toolchain task only - not searching for main dirs") //mainDirs = []string{workingDirectory} } else { var err error excludes := core.ParseCommaGlobs(settings.MainDirsExclude) excludesSource := core.ParseCommaGlobs(settings.SourceDirsExclude) excludesSource = append(excludesSource, excludes...) allPackages, err = source.FindSourceDirs(workingDirectory, "", excludesSource, settings.IsVerbose()) if err != nil || len(allPackages) == 0 { log.Printf("Warning: could not establish list of source packages. Using working directory") allPackages = []string{workingDirectory} } mainDirs, err = source.FindMainDirs(workingDirectory, excludes, settings.IsVerbose()) if err != nil || len(mainDirs) == 0 { log.Printf("Warning: could not find any main dirs: %v", err) } else { if settings.IsVerbose() { log.Printf("Found 'main package' dirs (len %d): %v", len(mainDirs), mainDirs) } } } if settings.IsVerbose() { log.Printf("Running tasks: %v", tasksToRun) log.Printf("All packages: %v", allPackages) } for _, taskName := range tasksToRun { log.SetPrefix("[goxc:" + taskName + "] ") if settings.IsVerbose() { log.Printf("Running task %s with settings: %v", taskName, settings.TaskSettings[taskName]) } err := runTask(taskName, destPlatforms, allPackages, mainDirs, appName, workingDirectory, outDestRoot, settings, maxProcessors) if err != nil { // TODO: implement 'force' option. log.Printf("Stopping after '%s' failed with error '%v'", taskName, err) return err } else { if !settings.IsQuiet() { log.Printf("Task %s succeeded", taskName) } } } return nil }
// invoke the go command via the os/exec package // 0.3.1 // v0.9 changed signature func InvokeGo(workingDirectory string, subCmd string, subCmdArgs []string, env []string, settings *config.Settings) error { fullVersionName := settings.GetFullVersionName() //var buildSettings config.BuildSettings buildSettings := settings.BuildSettings goRoot := settings.GoRoot if settings.IsVerbose() { log.Printf("build settings: %s", goRoot) } cmdPath := filepath.Join(goRoot, "bin", "go") args := []string{subCmd} //these features only apply to `go build` & `go install` if isBuildCommand(subCmd) { if buildSettings.Processors != nil { args = append(args, "-p", strconv.Itoa(*buildSettings.Processors)) } if buildSettings.Race != nil && *buildSettings.Race { args = append(args, "-race") } if buildSettings.Verbose != nil && *buildSettings.Verbose { args = append(args, "-v") } if buildSettings.PrintCommands != nil && *buildSettings.PrintCommands { args = append(args, "-x") } if buildSettings.CcFlags != nil && *buildSettings.CcFlags != "" { args = append(args, "-ccflags", *buildSettings.CcFlags) } if buildSettings.Compiler != nil && *buildSettings.Compiler != "" { args = append(args, "-compiler", *buildSettings.Compiler) } if buildSettings.GccGoFlags != nil && *buildSettings.GccGoFlags != "" { args = append(args, "-gccgoflags", *buildSettings.GccGoFlags) } if buildSettings.GcFlags != nil && *buildSettings.GcFlags != "" { args = append(args, "-gcflags", *buildSettings.GcFlags) } if buildSettings.InstallSuffix != nil && *buildSettings.InstallSuffix != "" { args = append(args, "-installsuffix", *buildSettings.InstallSuffix) } ldflags := "" if buildSettings.LdFlags != nil { ldflags = *buildSettings.LdFlags } if buildSettings.LdFlagsXVars != nil { //TODO! ldflags = ldflags + " " + buildFlags(buildInterpolationVars(*buildSettings.LdFlagsXVars, fullVersionName), "-X") } else { log.Printf("WARNING: LdFlagsXVars is nil. Not passing package version into compiler") } if ldflags != "" { args = append(args, "-ldflags", ldflags) } if buildSettings.Tags != nil && *buildSettings.Tags != "" { args = append(args, "-tags", *buildSettings.Tags) } if len(buildSettings.ExtraArgs) > 0 { args = append(args, buildSettings.ExtraArgs...) } } if settings.IsVerbose() { log.Printf("Env: %v", settings.Env) } if len(settings.Env) > 0 { vars := struct { PS string PLS string Env map[string]string }{ string(os.PathSeparator), string(os.PathListSeparator), map[string]string{}, } for _, val := range os.Environ() { k, v, err := splitEnvVar(val) if err != nil { //ignore invalid env vars from environment } else { vars.Env[k] = v } } for _, envTpl := range settings.Env { if settings.IsVerbose() { log.Printf("Processing env var %s", envTpl) } tpl, err := template.New("envItem").Parse(envTpl) if err != nil { return err } var dest bytes.Buffer err = tpl.Execute(&dest, vars) if err != nil { return err } executed := dest.String() if settings.IsVerbose() { if envTpl != executed { log.Printf("Setting env var (converted from %s to %s)", envTpl, executed) } else { log.Printf("Setting env var from config: %s", executed) } } env = append(env, dest.String()) //new address if necessary k, v, err := splitEnvVar(dest.String()) if err != nil { //fail on badly specified ENV vars return errors.New("Invalid env var defined by settings") } else { vars.Env[k] = v } } } args = append(args, subCmdArgs...) cmd, err := NewCmd(cmdPath, workingDirectory, args, env, settings.IsVerbose(), !settings.IsQuiet()) if err != nil { return err } if settings.IsVerbose() { log.Printf("invoking '%s %v' from '%s'", cmdPath, PrintableArgs(args), workingDirectory) } err = StartAndWait(cmd) if err != nil { log.Printf("'go' returned error: %s", err) return err } if settings.IsVerbose() { log.Printf("'go' completed successfully") } return nil }