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()
}
// Submit ...
func (testCloud Model) Submit(callback CaptureLineCallback) error {
	cmdSlice := testCloud.submitCommandSlice()

	command, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return err
	}

	cmd := *command.GetCmd()

	// Redirect output
	stdoutReader, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}

	scanner := bufio.NewScanner(stdoutReader)
	go func() {
		for scanner.Scan() {
			line := scanner.Text()
			if callback != nil {
				callback(line)
			}
		}
	}()
	if err := scanner.Err(); err != nil {
		return err
	}

	if err := cmd.Start(); err != nil {
		return err
	}

	return cmd.Wait()
}
func cmdExist(cmdSlice []string) bool {
	if len(cmdSlice) == 0 {
		return false
	}

	cmd, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return false
	}

	return (cmd.Run() == nil)
}
// Run ...
func (nunitConsole Model) Run() error {
	cmdSlice := nunitConsole.commandSlice()

	command, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return err
	}

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

	return command.Run()
}
// Run ...
func (xbuild Model) Run() error {
	cmdSlice := xbuild.buildCommandSlice()

	command, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return err
	}

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

	return command.Run()
}
// Command ...
func (command RubyCommandModel) Command(useBundle bool, cmdSlice []string) (*cmdex.CommandModel, error) {
	if useBundle {
		cmdSlice = append([]string{"bundle", "exec"}, cmdSlice...)
	}

	if command.sudoNeeded(cmdSlice) {
		cmdSlice = append([]string{"sudo"}, cmdSlice...)
	}

	cmd, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return nil, err
	}

	return cmd, nil
}
// Run ...
func (mdtool Model) Run() error {
	cmdSlice := mdtool.buildCommandSlice()

	command, err := cmdex.NewCommandFromSlice(cmdSlice)
	if err != nil {
		return err
	}

	/*
		command.SetStdout(os.Stdout)
		command.SetStderr(os.Stderr)

		return command.Run()
	*/

	return runCommandInDiagnosticMode(*command, "Loading projects", diagnosticModeWaitTime, diagnosticModeForceWaitTime, true)
}
Exemple #8
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
}
Exemple #9
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
}
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)
	}
}
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)
	}
}