예제 #1
0
func runGradleTask(gradleTool, buildFile, tasks, options string) error {
	optionSlice, err := shellquote.Split(options)
	if err != nil {
		return err
	}

	taskSlice, err := shellquote.Split(tasks)
	if err != nil {
		return err
	}

	cmdSlice := []string{gradleTool, "--build-file", buildFile}
	cmdSlice = append(cmdSlice, taskSlice...)
	cmdSlice = append(cmdSlice, optionSlice...)

	log.Done("$ %s", cmdex.PrintableCommandArgs(false, cmdSlice))
	fmt.Println()

	cmd, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return fmt.Errorf("failed to create command, error: %s", err)
	}

	cmd.SetStdout(os.Stdout)
	cmd.SetStderr(os.Stderr)

	return cmd.Run()
}
예제 #2
0
// PrintableCmd ...
func (c CommandModel) PrintableCmd() string {
	prettyCmdSlice := c.cmdSlice()
	prettyCmdStr := cmdex.PrintableCommandArgs(false, prettyCmdSlice)

	cmdStr := c.xcodebuildCommand.PrintableCmd()

	return fmt.Sprintf("set -o pipefail && %s | %s", cmdStr, prettyCmdStr)
}
예제 #3
0
// 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
}
예제 #4
0
// RunBuildCommand ...
func (xamarinCmd CommandModel) RunBuildCommand() (string, error) {
	mdtoolPth := "/Applications/Xamarin Studio.app/Contents/MacOS/mdtool"
	cmdArgs := []string{mdtoolPth, "build",
		xamarinCmd.SolutionFilePath,
		fmt.Sprintf("-c:%s", xamarinCmd.ConfigurationName),
		fmt.Sprintf("-p:%s", xamarinCmd.ProjectName),
	}
	log.Infof("$ %s", cmdex.PrintableCommandArgs(true, cmdArgs))
	fmt.Print("Running and analyzing log ...")
	cmd, err := cmdex.NewCommandFromSlice(cmdArgs)
	if err != nil {
		return "", fmt.Errorf("Failed to create Xamarin command, error: %s", err)
	}
	xamarinBuildOutput, err := cmd.RunAndReturnTrimmedCombinedOutput()
	if err != nil {
		return xamarinBuildOutput, fmt.Errorf("Failed to run Xamarin command, error: %s", err)
	}

	log.Debugf("xamarinBuildOutput: %s", xamarinBuildOutput)
	return xamarinBuildOutput, nil
}
예제 #5
0
func runCommandInDirWithEnvsAndOutput(cmdSlice []string, dir string, envs []string) (string, string, error) {
	cmd, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return "", "", err
	}

	if len(envs) > 0 {
		cmd.SetEnvs(envs)
	}

	if dir != "" {
		cmd.SetDir(dir)
	}

	log.Details("=> %s", cmdex.PrintableCommandArgs(false, cmdSlice))

	var errBuffer bytes.Buffer
	errWriter := bufio.NewWriter(&errBuffer)
	cmd.SetStderr(errWriter)

	var outBuffer bytes.Buffer
	outWriter := bufio.NewWriter(&outBuffer)
	cmd.SetStdout(outWriter)

	if err := cmd.Run(); err != nil {
		if errorutil.IsExitStatusError(err) {
			if !errorutil.IsExitStatusErrorStr(errBuffer.String()) {
				return "", "", errors.New(errBuffer.String())
			}

			if !errorutil.IsExitStatusErrorStr(outBuffer.String()) {
				return "", "", errors.New(outBuffer.String())
			}
		}

		return "", "", err
	}

	return outBuffer.String(), errBuffer.String(), nil
}
예제 #6
0
func runGradleTask(gradleTool, buildFile, tasks, options string) error {
	optionSlice, err := shellquote.Split(options)
	if err != nil {
		return err
	}

	taskSlice, err := shellquote.Split(tasks)
	if err != nil {
		return err
	}

	cmdSlice := []string{gradleTool, "--build-file", buildFile}
	cmdSlice = append(cmdSlice, taskSlice...)
	cmdSlice = append(cmdSlice, optionSlice...)

	log.Detail(cmdex.PrintableCommandArgs(false, cmdSlice))
	fmt.Println()

	cmd := cmdex.NewCommand(cmdSlice[0], cmdSlice[1:]...)
	cmd.SetStdout(os.Stdout)
	cmd.SetStderr(os.Stderr)
	return cmd.Run()
}
예제 #7
0
func find(dir, nameInclude, nameExclude string) ([]string, error) {
	cmdSlice := []string{"find", dir}
	cmdSlice = append(cmdSlice, "-name", nameInclude)
	cmdSlice = append(cmdSlice, "!", "-name", nameExclude)

	log.Detail(cmdex.PrintableCommandArgs(false, cmdSlice))

	out, err := cmdex.NewCommand(cmdSlice[0], cmdSlice[1:]...).RunAndReturnTrimmedOutput()
	if err != nil {
		return []string{}, err
	}

	split := strings.Split(out, "\n")
	files := []string{}
	for _, item := range split {
		trimmed := strings.TrimSpace(item)
		if trimmed != "" {
			files = append(files, trimmed)
		}
	}

	return files, nil
}
예제 #8
0
func execute(workDir string, bundleExec bool, cmdSlice []string) error {
	if len(cmdSlice) == 0 {
		return errors.New("no command specified")
	}

	if bundleExec {
		cmdSlice = append([]string{"bundle", "exec"}, cmdSlice...)
	}

	prinatableCmd := cmdex.PrintableCommandArgs(false, cmdSlice)
	log.Details("=> %s", prinatableCmd)

	if len(cmdSlice) == 1 {
		out, err := cmdex.RunCommandInDirAndReturnCombinedStdoutAndStderr(workDir, cmdSlice[0])
		log.Details(out)

		return err
	}

	out, err := cmdex.RunCommandInDirAndReturnCombinedStdoutAndStderr(workDir, cmdSlice[0], cmdSlice[1:len(cmdSlice)]...)
	log.Details(out)

	return err
}
예제 #9
0
// PrintableCmd ...
func (c ExportCommandModel) PrintableCmd() string {
	cmdSlice := c.cmdSlice()
	return cmdex.PrintableCommandArgs(false, cmdSlice)
}
// PrintableCommand ...
func (testCloud Model) PrintableCommand() string {
	cmdSlice := testCloud.submitCommandSlice()

	return cmdex.PrintableCommandArgs(true, cmdSlice)
}
예제 #11
0
func main() {
	configs := createConfigsModelFromEnvs()

	fmt.Println()
	configs.print()

	if err := configs.validate(); err != nil {
		log.Error("Issue with input: %s", err)
		os.Exit(1)
	}

	nugetPth := "/Library/Frameworks/Mono.framework/Versions/Current/bin/nuget"
	nugetRestoreCmdArgs := []string{nugetPth}

	if configs.NugetVersion == "latest" {
		fmt.Println()
		log.Info("Updating Nuget to latest version...")
		// "sudo $nuget update -self"
		cmdArgs := []string{"sudo", nugetPth, "update", "-self"}
		cmd, err := cmdex.NewCommandFromSlice(cmdArgs)
		if err != nil {
			log.Error("Failed to create command from args (%v), error: %s", cmdArgs, err)
			os.Exit(1)
		}

		cmd.SetStdout(os.Stdout)
		cmd.SetStderr(os.Stderr)

		log.Done("$ %s", cmdex.PrintableCommandArgs(false, cmdArgs))

		if err := cmd.Run(); err != nil {
			log.Error("Failed to update nuget, error: %s", err)
			os.Exit(1)
		}
	} else if configs.NugetVersion != "" {
		fmt.Println()
		log.Info("Downloading Nuget %s version...", configs.NugetVersion)
		tmpDir, err := pathutil.NormalizedOSTempDirPath("__nuget__")
		if err != nil {
			log.Error("Failed to create tmp dir, error: %s", err)
			os.Exit(1)
		}

		downloadPth := filepath.Join(tmpDir, "nuget.exe")

		// https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe
		nugetURL := fmt.Sprintf("https://dist.nuget.org/win-x86-commandline/v%s/nuget.exe", configs.NugetVersion)

		log.Detail("Download URL: %s", nugetURL)

		if err := DownloadFile(nugetURL, downloadPth); err != nil {
			log.Warn("Download failed, error: %s", err)

			// https://dist.nuget.org/win-x86-commandline/v3.4.4/NuGet.exe
			nugetURL = fmt.Sprintf("https://dist.nuget.org/win-x86-commandline/v%s/NuGet.exe", configs.NugetVersion)

			log.Detail("Retry download URl: %s", nugetURL)

			if err := DownloadFile(nugetURL, downloadPth); err != nil {
				log.Error("Failed to download nuget, error: %s", err)
				os.Exit(1)
			}
		}

		nugetRestoreCmdArgs = []string{constants.MonoPath, downloadPth}
	}

	fmt.Println()
	log.Info("Restoring Nuget packages...")

	nugetRestoreCmdArgs = append(nugetRestoreCmdArgs, "restore", configs.XamarinSolution)

	if err := retry.Times(1).Try(func(attempt uint) error {
		if attempt > 0 {
			log.Warn("Attempt %d failed, retrying...", attempt)
		}

		log.Done("$ %s", cmdex.PrintableCommandArgs(false, nugetRestoreCmdArgs))

		cmd, err := cmdex.NewCommandFromSlice(nugetRestoreCmdArgs)
		if err != nil {
			log.Error("Failed to create Nuget command, error: %s", err)
			os.Exit(1)
		}

		cmd.SetStdout(os.Stdout)
		cmd.SetStderr(os.Stderr)

		if err := cmd.Run(); err != nil {
			log.Error("Restore failed, error: %s", err)
			return err
		}
		return nil
	}); err != nil {
		log.Error("Nuget restore failed, error: %s", err)
		os.Exit(1)
	}
}
예제 #12
0
func main() {
	configs := createConfigsModelFromEnvs()

	fmt.Println()
	configs.print()

	if err := configs.validate(); err != nil {
		fail("Issue with input: %s", err)
	}

	customOptions := []string{}
	if configs.CarthageOptions != "" {
		options, err := shellquote.Split(configs.CarthageOptions)
		if err != nil {
			fail("Failed to shell split CarthageOptions (%s), error: %s", configs.CarthageOptions)
		}
		customOptions = options
	}

	//
	// Exit if bootstrap is cached
	log.Info("Check if cache is available")

	hasCachedItems, err := isCacheAvailable(configs.SourceDir)
	if err != nil {
		fail("Failed to check cached files, error: %s", err)
	}

	log.Detail("has cahched items: %v", hasCachedItems)

	if configs.CarthageCommand == "bootstrap" && hasCachedItems {
		log.Done("Using cached dependencies for bootstrap command. If you would like to force update your dependencies, select `update` as CarthageCommand and re-run your build.")
		os.Exit(0)
	}

	fmt.Println()
	// ---

	//
	// Run carthage command
	log.Info("Running Carthage command")

	args := append([]string{configs.CarthageCommand}, customOptions...)
	cmd := cmdex.NewCommand("carthage", args...)

	if configs.GithubAccessToken != "" {
		log.Detail("Appending GITHUB_ACCESS_TOKEN to process environments")

		cmd.AppendEnvs([]string{fmt.Sprintf("GITHUB_ACCESS_TOKEN=%s", configs.GithubAccessToken)})
	}

	cmd.SetStdout(os.Stdout)
	cmd.SetStderr(os.Stderr)

	log.Done("$ %s", cmdex.PrintableCommandArgs(false, cmd.GetCmd().Args))
	fmt.Println()

	if err := cmd.Run(); err != nil {
		fail("Carthage command failed, error: %s", err)
	}
	// ---

	//
	// Create cache
	if configs.CarthageCommand == "bootstrap" {
		fmt.Println()
		log.Info("Creating cache")

		cacheFilePth := filepath.Join(configs.SourceDir, carthageDirName, cacheFileName)

		swiftVersion, err := swiftVersion()
		if err != nil {
			fail("Failed to get swift version, error: %s", err)
		}

		resolvedFilePath := filepath.Join(configs.SourceDir, resolvedFileName)
		resolved, err := contentsOfCartfileResolved(resolvedFilePath)
		if err != nil {
			fail("Failed to get resolved file content, error: %s", err)
		}

		cacheContent := fmt.Sprintf("--Swift version: %s --Swift version \n --%s: %s --%s", swiftVersion, resolvedFileName, resolved, resolvedFileName)

		carthageDir := filepath.Join(configs.SourceDir, carthageDirName)
		if exist, err := pathutil.IsPathExists(carthageDir); err != nil {
			fail("Failed to check if dir exists at (%s), error: %s", carthageDir, err)
		} else if !exist {
			if err := os.Mkdir(carthageDir, 0777); err != nil {
				fail("Failed to create dir (%s), error: %s", carthageDir, err)
			}
		}

		if err := fileutil.WriteStringToFile(cacheFilePth, cacheContent); err != nil {
			fail("Failed to write cahe file, error: %s", err)
		}

		log.Done("Cachefile: %s", cacheFilePth)
	}
	// ---
}
func main() {
	configs := createConfigsModelFromEnvs()

	fmt.Println()
	configs.print()

	if err := configs.validate(); err != nil {
		registerFail("Issue with input: %s", err)
	}

	//
	// Determining calabash-android version
	fmt.Println()
	log.Info("Determining calabash-android version...")

	rubyCommand, err := rubycmd.NewRubyCommandModel()
	if err != nil {
		registerFail("Failed to create ruby command, err: %s", err)
	}

	calabashAndroidVersion := ""
	useBundler := false

	if configs.GemFilePath != "" {
		if exist, err := pathutil.IsPathExists(configs.GemFilePath); err != nil {
			registerFail("Failed to check if Gemfile exists at (%s) exist, error: %s", configs.GemFilePath, err)
		} else if exist {
			log.Detail("Gemfile exists at: %s", configs.GemFilePath)

			gemfileDir := filepath.Dir(configs.GemFilePath)
			gemfileLockPth := filepath.Join(gemfileDir, "Gemfile.lock")

			if exist, err := pathutil.IsPathExists(gemfileLockPth); err != nil {
				registerFail("Failed to check if Gemfile.lock exists at (%s), error: %s", gemfileLockPth, err)
			} else if exist {
				log.Detail("Gemfile.lock exists at: %s", gemfileLockPth)

				version, err := calabashAndroidVersionFromGemfileLock(gemfileLockPth)
				if err != nil {
					registerFail("Failed to get calabash-android version from Gemfile.lock, error: %s", err)
				}

				log.Detail("calabash-android version in Gemfile.lock: %s", version)

				calabashAndroidVersion = version
				useBundler = true
			} else {
				log.Warn("Gemfile.lock doest no find with calabash-android gem at: %s", gemfileLockPth)
			}
		} else {
			log.Warn("Gemfile doest no find with calabash-android gem at: %s", configs.GemFilePath)
		}
	}

	if configs.CalabashAndroidVersion != "" {
		log.Detail("calabash-android version in configs: %s", configs.CalabashAndroidVersion)

		calabashAndroidVersion = configs.CalabashAndroidVersion
		useBundler = false
	}

	if calabashAndroidVersion == "" {
		log.Done("using calabash-android latest version")
	} else {
		log.Done("using calabash-android version: %s", calabashAndroidVersion)
	}
	// ---

	//
	// Intsalling calabash-android gem
	fmt.Println()
	log.Info("Installing calabash-android gem...")

	calabashAndroidArgs := []string{}

	// If Gemfile given with calabash-android and calabash_android_version input does not override calabash-android version
	// Run `bundle install`
	// Run calabash-android with `bundle exec`
	if useBundler {
		bundleInstallArgs := []string{"bundle", "install", "--jobs", "20", "--retry", "5"}

		// bundle install
		bundleInstallCmd, err := rubyCommand.Command(false, bundleInstallArgs)
		if err != nil {
			registerFail("Failed to create command, error: %s", err)
		}

		bundleInstallCmd.AppendEnvs([]string{"BUNDLE_GEMFILE=" + configs.GemFilePath})

		log.Detail("$ %s", cmdex.PrintableCommandArgs(false, bundleInstallArgs))

		if err := bundleInstallCmd.Run(); err != nil {
			registerFail("bundle install failed, error: %s", err)
		}
		// ---

		calabashAndroidArgs = []string{"bundle", "exec"}
	}

	calabashAndroidArgs = append(calabashAndroidArgs, "calabash-android")

	// If no need to use bundler
	if !useBundler {
		if calabashAndroidVersion != "" {
			// ... and calabash-android version detected
			// Install calabash-android detetcted version with `gem install`
			// Append version param to calabash-android command
			installed, err := rubyCommand.IsGemInstalled("calabash-android", calabashAndroidVersion)
			if err != nil {
				registerFail("Failed to check if calabash-android (v%s) installed, error: %s", calabashAndroidVersion, err)
			}

			if !installed {
				installCommands, err := rubyCommand.GemInstallCommands("calabash-android", calabashAndroidVersion)
				if err != nil {
					registerFail("Failed to create gem install commands, error: %s", err)
				}

				for _, installCommand := range installCommands {
					log.Detail("$ %s", cmdex.PrintableCommandArgs(false, installCommand.GetCmd().Args))

					if err := installCommand.Run(); err != nil {
						registerFail("command failed, error: %s", err)
					}
				}
			} else {
				log.Detail("calabash-android %s installed", calabashAndroidVersion)
			}
		} else {
			// ... and using latest version of calabash-android
			// Install calabash-android latest version with `gem install`

			installCommands, err := rubyCommand.GemInstallCommands("calabash-android", "")
			if err != nil {
				registerFail("Failed to create gem install commands, error: %s", err)
			}

			for _, installCommand := range installCommands {
				log.Detail("$ %s", cmdex.PrintableCommandArgs(false, installCommand.GetCmd().Args))

				if err := installCommand.Run(); err != nil {
					registerFail("command failed, error: %s", err)
				}
			}
		}
	}
	// ---

	//
	// Search for debug.keystore
	fmt.Println()
	log.Info("Search for debug.keystore...")

	debugKeystorePth := ""
	homeDir := pathutil.UserHomeDir()

	// $HOME/.android/debug.keystore
	androidDebugKeystorePth := filepath.Join(homeDir, ".android", "debug.keystore")
	debugKeystorePth = androidDebugKeystorePth

	if exist, err := pathutil.IsPathExists(androidDebugKeystorePth); err != nil {
		registerFail("Failed to check if debug.keystore exists at (%s), error: %s", androidDebugKeystorePth, err)
	} else if !exist {
		log.Warn("android debug keystore not exist at: %s", androidDebugKeystorePth)

		// $HOME/.local/share/Mono for Android/debug.keystore
		xamarinDebugKeystorePth := filepath.Join(homeDir, ".local", "share", "Mono for Android", "debug.keystore")

		log.Detail("checking xamarin debug keystore at: %s", xamarinDebugKeystorePth)

		if exist, err := pathutil.IsPathExists(xamarinDebugKeystorePth); err != nil {
			registerFail("Failed to check if debug.keystore exists at (%s), error: %s", xamarinDebugKeystorePth, err)
		} else if !exist {
			log.Warn("xamarin debug keystore not exist at: %s", xamarinDebugKeystorePth)
			log.Detail("generating debug keystore")

			// `keytool -genkey -v -keystore "#{debug_keystore}" -alias androiddebugkey -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "CN=Android Debug,O=Android,C=US"`
			keytoolArgs := []string{"keytool", "-genkey", "-v", "-keystore", debugKeystorePth, "-alias", "androiddebugkey", "-storepass", "android", "-keypass", "android", "-keyalg", "RSA", "-keysize", "2048", "-validity", "10000", "-dname", "CN=Android Debug,O=Android,C=US"}

			cmd, err := cmdex.NewCommandFromSlice(keytoolArgs)
			if err != nil {
				registerFail("Failed to create command, error: %s", err)
			}

			log.Detail("$ %s", cmdex.PrintableCommandArgs(false, keytoolArgs))

			if err := cmd.Run(); err != nil {
				registerFail("Failed to generate debug.keystore, error: %s", err)
			}

			log.Detail("using debug keystore: %s", debugKeystorePth)
		} else {
			log.Detail("using xamarin debug keystore: %s", xamarinDebugKeystorePth)

			debugKeystorePth = xamarinDebugKeystorePth
		}
	} else {
		log.Detail("using android debug keystore: %s", androidDebugKeystorePth)
	}
	// ---

	//
	// Resign apk with debug.keystore
	fmt.Println()
	log.Info("Resign apk with debug.keystore...")

	resignArgs := []string{"calabash-android", "resign", configs.ApkPath}
	resignCmd, err := rubyCommand.Command(useBundler, resignArgs)
	if err != nil {
		registerFail("Failed to create command, error: %s", err)
	}

	log.Detail("$ %s", cmdex.PrintableCommandArgs(false, resignArgs))
	fmt.Println()

	resignCmd.SetStdout(os.Stdout)
	resignCmd.SetStderr(os.Stderr)

	if err := resignCmd.Run(); err != nil {
		registerFail("Failed to run command, error: %s", err)
	}
	// ---

	//
	// Run calabash-android
	fmt.Println()
	log.Info("Running calabash-android test...")

	testArgs := []string{"calabash-android", "run", configs.ApkPath}
	testCmd, err := rubyCommand.Command(useBundler, testArgs)
	if err != nil {
		registerFail("Failed to create command, error: %s", err)
	}

	log.Detail("$ %s", cmdex.PrintableCommandArgs(false, testArgs))
	fmt.Println()

	testCmd.SetStdout(os.Stdout)
	testCmd.SetStderr(os.Stderr)

	if err := testCmd.Run(); err != nil {
		registerFail("Failed to run command, error: %s", err)
	}
	// ---

	if err := exportEnvironmentWithEnvman("BITRISE_XAMARIN_TEST_RESULT", "succeeded"); err != nil {
		log.Warn("Failed to export environment: %s, error: %s", "BITRISE_XAMARIN_TEST_RESULT", err)
	}
}
// PrintableCommand ...
func (nunitConsole Model) PrintableCommand() string {
	cmdSlice := nunitConsole.commandSlice()

	return cmdex.PrintableCommandArgs(true, cmdSlice)
}
// PrintableCommand ...
func (xbuild Model) PrintableCommand() string {
	cmdSlice := xbuild.buildCommandSlice()

	return cmdex.PrintableCommandArgs(true, cmdSlice)
}
// PrintableCommand ...
func (mdtool Model) PrintableCommand() string {
	cmdSlice := mdtool.buildCommandSlice()

	return cmdex.PrintableCommandArgs(true, cmdSlice)
}