// InstallWithAptGetIfNeeded ... func InstallWithAptGetIfNeeded(tool string, isCIMode bool) error { if out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("which", tool); err != nil { if err.Error() == "exit status 1" && out == "" { // Tool isn't installed -- install it... if !isCIMode { log.Infof("This step requires %s, which is not installed", tool) allow, err := goinp.AskForBool("Would you like to install (" + tool + ") with brew ? [yes/no]") if err != nil { return err } if !allow { return errors.New("(" + tool + ") is required for step") } } log.Infof("(%s) isn't installed, installing...", tool) if out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("sudo", "apt-get", "-y", "install", tool); err != nil { log.Errorf("sudo apt-get -y install %s failed -- out: (%s) err: (%s)", tool, out, err) return err } log.Infof(" * "+colorstring.Green("[OK]")+" %s installed", tool) } else { // which failed log.Errorf("which (%s) failed -- out: (%s) err: (%s)", tool, out, err) return err } } else if out != "" { // already installed } else { log.Warnf("which (%s) -- out (%s)", tool, out) } return nil }
// InstallWithAptGetIfNeeded ... func InstallWithAptGetIfNeeded(aptGetDep stepmanModels.AptGetDepModel, isCIMode bool) error { isDepInstalled := false // First do a "which", to see if the binary is available. // Can be available from another source, not just from brew, // e.g. it's common to use NVM or similar to install and manage the Node.js version. { if out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("which", aptGetDep.GetBinaryName()); err != nil { if err.Error() == "exit status 1" && out == "" { isDepInstalled = false } else { // unexpected `which` error return fmt.Errorf("which (%s) failed -- out: (%s) err: (%s)", aptGetDep.Name, out, err) } } else if out != "" { isDepInstalled = true } else { // no error but which's output was empty return fmt.Errorf("which (%s) failed -- no error (exit code 0) but output was empty", aptGetDep.Name) } } // then do a package manager specific lookup { if !isDepInstalled { // which did not find the binary, also check in brew, // whether the package is installed isDepInstalled = checkIfAptPackageInstalled(aptGetDep.Name) } } if !isDepInstalled { // Tool isn't installed -- install it... if !isCIMode { log.Infof(`This step requires "%s" to be available, but it is not installed.`, aptGetDep.GetBinaryName()) allow, err := goinp.AskForBoolWithDefault(`Would you like to install the "`+aptGetDep.Name+`" package with apt-get?`, true) if err != nil { return err } if !allow { return errors.New("(" + aptGetDep.Name + ") is required for step") } } log.Infof("(%s) isn't installed, installing...", aptGetDep.Name) if cmdOut, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("sudo", "apt-get", "-y", "install", aptGetDep.Name); err != nil { log.Errorf("sudo apt-get -y install %s failed -- out: (%s) err: (%s)", aptGetDep.Name, cmdOut, err) return err } log.Infof(" * "+colorstring.Green("[OK]")+" %s installed", aptGetDep.Name) } return nil }
func cmdExist(cmdSlice []string) bool { if len(cmdSlice) == 0 { return false } if len(cmdSlice) == 1 { _, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr(cmdSlice[0]) return (err == nil) } _, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr(cmdSlice[0], cmdSlice[1:]...) return (err == nil) }
func getOsAndArch() (string, string, error) { osOut, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("uname", "-s") if err != nil { return "", "", err } archOut, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("uname", "-m") if err != nil { return "", "", err } return osOut, archOut, nil }
// InstallWithBrewIfNeeded ... func InstallWithBrewIfNeeded(brewDep stepmanModels.BrewDepModel, isCIMode bool) error { isDepInstalled := false // First do a "which", to see if the binary is available. // Can be available from another source, not just from brew, // e.g. it's common to use NVM or similar to install and manage the Node.js version. if out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("which", brewDep.GetBinaryName()); err != nil { if err.Error() == "exit status 1" && out == "" { isDepInstalled = false } else { // unexpected `which` error return fmt.Errorf("which (%s) failed -- out: (%s) err: (%s)", brewDep.Name, out, err) } } else if out != "" { isDepInstalled = true } else { // no error but which's output was empty return fmt.Errorf("which (%s) failed -- no error (exit code 0) but output was empty", brewDep.Name) } if !isDepInstalled { // which did not find the binary, also check in brew, // whether the package is installed isDepInstalled = checkIfBrewPackageInstalled(brewDep.Name) } if !isDepInstalled { // Tool isn't installed -- install it... if !isCIMode { log.Infof("This step requires %s, which is not installed", brewDep.Name) allow, err := goinp.AskForBool("Would you like to install (" + brewDep.Name + ") with brew?") if err != nil { return err } if !allow { return errors.New("(" + brewDep.Name + ") is required for step") } } log.Infof("(%s) isn't installed, installing...", brewDep.Name) if out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("brew", "install", brewDep.Name); err != nil { log.Errorf("brew install %s failed -- out: (%s) err: (%s)", brewDep.Name, out, err) return err } log.Infof(" * "+colorstring.Green("[OK]")+" %s installed", brewDep.Name) } return nil }
func Test_InvalidCommand(t *testing.T) { t.Log("Invalid command") { _, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr(binPath(), "invalidcmd") require.EqualError(t, err, "exit status 1") } }
func systemOsName() (string, error) { osOut, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("uname", "-s") if err != nil { return "", err } return strip(osOut), nil }
// StepmanPrintRawStepList ... func StepmanPrintRawStepList(collection string) error { logLevel := log.GetLevel().String() args := []string{"--debug", "--loglevel", logLevel, "step-list", "--collection", collection, "--format", "raw"} out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("stepman", args...) if err != nil { return err } fmt.Println(out) return nil }
// Run ... func (command PrintableCommand) Run() (string, error) { log.Debugf("=> (%#v)", command) out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr(command.Name, command.Args...) if err != nil { log.Fatalf("Failed to execute:\ncommand:(%s),\noutput:(%s),\nerror:(%#v)", command.RawCommand, out, err) } log.Debugf("output:\n(%s)", out) return out, err }
// StepmanPrintRawLocalStepInfo ... func StepmanPrintRawLocalStepInfo(pth string) error { logLevel := log.GetLevel().String() args := []string{"--debug", "--loglevel", logLevel, "step-info", "--step-yml", pth, "--format", "raw"} out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("stepman", args...) if err != nil { return err } fmt.Println(out) return nil }
func Test_VersionOutput(t *testing.T) { t.Log("Version") { out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr(binPath(), "version") require.NoError(t, err) require.Equal(t, "1.5.0", out) } t.Log("Version --full") { out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr(binPath(), "version", "--full") require.NoError(t, err) expectedOSVersion := fmt.Sprintf("%s (%s)", runtime.GOOS, runtime.GOARCH) expectedVersionOut := fmt.Sprintf(`version: 1.5.0 format version: 1.4.0 os: %s go: %s build number: commit:`, expectedOSVersion, runtime.Version()) require.Equal(t, expectedVersionOut, out) } }
// RunXcodebuildCommand ... func (xccmd CommandModel) RunXcodebuildCommand(xcodebuildActionArgs ...string) (string, error) { xcodeCmdParamsToRun, err := xccmd.transformToXcodebuildParams(xcodebuildActionArgs...) if err != nil { return "", err } log.Infof("$ xcodebuild %s", cmdex.PrintableCommandArgs(true, xcodeCmdParamsToRun)) fmt.Print("Running and analyzing log ...") xcoutput, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("xcodebuild", xcodeCmdParamsToRun...) if err != nil { return xcoutput, fmt.Errorf("Failed to run xcodebuild command, error: %s", err) } log.Debugf("xcoutput: %s", xcoutput) return xcoutput, nil }
// StepmanStepInfo ... func StepmanStepInfo(collection, stepID, stepVersion string) (models.StepInfoModel, error) { logLevel := log.GetLevel().String() args := []string{"--debug", "--loglevel", logLevel, "step-info", "--collection", collection, "--id", stepID, "--version", stepVersion} out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("stepman", args...) if err != nil { return models.StepInfoModel{}, fmt.Errorf("Failed to run stepman step-info, err: %s", err) } stepInfo := models.StepInfoModel{} if err := json.Unmarshal([]byte(out), &stepInfo); err != nil { return models.StepInfoModel{}, err } return stepInfo, nil }
// EnvmanVersion ... func EnvmanVersion() (version.Version, error) { logLevel := log.GetLevel().String() args := []string{"--loglevel", logLevel, "--version"} versionOut, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("envman", args...) if err != nil { return version.Version{}, err } versionPtr, err := version.NewVersion(versionOut) if err != nil { return version.Version{}, err } if versionPtr == nil { return version.Version{}, fmt.Errorf("Failed to parse version (%s)", versionOut) } return *versionPtr, nil }
// NewRubyCommandModel ... func NewRubyCommandModel() (RubyCommandModel, error) { whichRuby, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("which", "ruby") if err != nil { return RubyCommandModel{}, err } command := RubyCommandModel{} if whichRuby == systemRubyPth { command.rubyInstallType = SystemRuby } else if whichRuby == brewRubyPth { command.rubyInstallType = BrewRuby } else if cmdExist([]string{"rvm", "-v"}) { command.rubyInstallType = RVMRuby } else if cmdExist([]string{"rbenv", "-v"}) { command.rubyInstallType = RbenvRuby } else { return RubyCommandModel{}, errors.New("unkown ruby installation type") } return command, nil }
// PrintInstalledXcodeInfos ... func PrintInstalledXcodeInfos() error { xcodeSelectPth, err := cmdex.RunCommandAndReturnStdout("xcode-select", "--print-path") if err != nil { xcodeSelectPth = "xcode-select --print-path failed to detect the location of activate Xcode Command Line Tools path" } progInstallPth, err := utils.CheckProgramInstalledPath("xcodebuild") if err != nil { return errors.New("xcodebuild is not installed") } isFullXcodeAvailable := false verStr, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("xcodebuild", "-version") if err != nil { // No full Xcode available, only the Command Line Tools // verStr is something like "xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance" isFullXcodeAvailable = false } else { // version OK - full Xcode available // we'll just format it a bit to fit into one line isFullXcodeAvailable = true verStr = strings.Join(strings.Split(verStr, "\n"), " | ") } log.Infoln(" * "+colorstring.Green("[OK]")+" xcodebuild path :", progInstallPth) if !isFullXcodeAvailable { log.Infoln(" version (xcodebuild) :", colorstring.Yellowf("%s", verStr)) } else { log.Infoln(" version (xcodebuild) :", verStr) } log.Infoln(" active Xcode (Command Line Tools) path (xcode-select --print-path) :", xcodeSelectPth) if !isFullXcodeAvailable { log.Warn(colorstring.Yellowf("%s", "No Xcode found, only the Xcode Command Line Tools are available!")) log.Warn(colorstring.Yellowf("%s", "Full Xcode is required to build, test and archive iOS apps!")) } return nil }
// InstallWithBrewIfNeeded ... func InstallWithBrewIfNeeded(tool string, isCIMode bool) error { if err := checkWithBrewProgramInstalled(tool); err != nil { if !isCIMode { log.Infof("This step requires %s, which is not installed", tool) allow, err := goinp.AskForBool("Would you like to install (" + tool + ") with brew ? [yes/no]") if err != nil { return err } if !allow { return errors.New("(" + tool + ") is required for step") } } log.Infof("(%s) isn't installed, installing...", tool) if out, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("brew", "install", tool); err != nil { log.Errorf("brew install %s failed -- out: (%s) err: (%s)", tool, out, err) return err } log.Infof(" * "+colorstring.Green("[OK]")+" %s installed", tool) return nil } return nil }
// CheckIsHomebrewInstalled ... func CheckIsHomebrewInstalled(isFullSetupMode bool) error { brewRubyInstallCmdString := `$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"` officialSiteURL := "http://brew.sh/" progInstallPth, err := utils.CheckProgramInstalledPath("brew") if err != nil { fmt.Println() log.Warn("It seems that Homebrew is not installed on your system.") log.Infoln("Homebrew (short: brew) is required in order to be able to auto-install all the bitrise dependencies.") log.Infoln("You should be able to install brew by copying this command and running it in your Terminal:") log.Infoln(brewRubyInstallCmdString) log.Infoln("You can find more information about Homebrew on its official site at:", officialSiteURL) log.Warn("Once the installation of brew is finished you should call the bitrise setup again.") return err } verStr, err := cmdex.RunCommandAndReturnStdout("brew", "--version") if err != nil { log.Infoln("") return errors.New("Failed to get version") } if isFullSetupMode { // brew doctor doctorOutput, err := cmdex.RunCommandAndReturnCombinedStdoutAndStderr("brew", "doctor") if err != nil { fmt.Println("") log.Warn("brew doctor returned an error:") log.Warnf("%s", doctorOutput) return errors.New("Failed to: brew doctor") } } log.Infoln(" * "+colorstring.Green("[OK]")+" Homebrew :", progInstallPth) log.Infoln(" version :", verStr) return nil }
// StepmanVersion ... func StepmanVersion() (string, error) { logLevel := log.GetLevel().String() args := []string{"--debug", "--loglevel", logLevel, "--version"} return cmdex.RunCommandAndReturnCombinedStdoutAndStderr("stepman", args...) }
// StepmanRawLocalStepInfo ... func StepmanRawLocalStepInfo(pth string) (string, error) { logLevel := log.GetLevel().String() args := []string{"--debug", "--loglevel", logLevel, "step-info", "--step-yml", pth, "--format", "raw"} return cmdex.RunCommandAndReturnCombinedStdoutAndStderr("stepman", args...) }
// StepmanRawStepList ... func StepmanRawStepList(collection string) (string, error) { logLevel := log.GetLevel().String() args := []string{"--debug", "--loglevel", logLevel, "step-list", "--collection", collection, "--format", "raw"} return cmdex.RunCommandAndReturnCombinedStdoutAndStderr("stepman", args...) }