Пример #1
0
func runMain(versionString string) error {
	// Make sure the version string is correct.
	task := "Parse the command line VERSION argument"
	ver, err := version.Parse(versionString)
	if err != nil {
		hint := `
The version string must be in the form of Major.Minor.Patch
and no part of the version string can be omitted.

`
		return errs.NewErrorWithHint(task, err, hint)
	}

	// In case -commit is set, set and commit the version string.
	if flagCommit {
		currentBranch, err := gitutil.CurrentBranch()
		if err != nil {
			return err
		}

		_, err = version.SetForBranch(ver, currentBranch)
		return err
	}

	// Otherwise just set the version.
	return version.Set(ver)
}
Пример #2
0
// ListTags returns the list of all release tags, sorted by the versions they represent.
func ListTags() (tags []string, err error) {
	var task = "Get release tags"

	// Get all release tags.
	stdout, err := git.RunCommand("tag", "--list", "v*.*.*")
	if err != nil {
		return nil, errs.NewError(task, err)
	}

	// Parse the output to get sortable versions.
	var vers []*version.Version
	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		line := scanner.Text()
		if line == "" {
			continue
		}
		line = line[1:] // strip "v"
		ver, _ := version.Parse(line)
		vers = append(vers, ver)
	}
	if err := scanner.Err(); err != nil {
		return nil, errs.NewError(task, err)
	}

	// Sort the versions.
	sort.Sort(version.Versions(vers))

	// Convert versions back to tag names and return.
	tgs := make([]string, 0, len(vers))
	for _, ver := range vers {
		tgs = append(tgs, "v"+ver.String())
	}
	return tgs, nil
}
Пример #3
0
func runMain(versionString string) error {
	if _, err := version.Parse(versionString); err != nil {
		return err
	}

	return pkg.Install(versionString, &pkg.InstallOptions{flagOwner, flagRepo})
}
Пример #4
0
func isReleaseLabel(label string) bool {
	// Label is always "release-x.y.z"
	if !strings.HasPrefix(label, "release-") {
		return false
	}

	// Skip "release-" and parse the rest as a version string.
	_, err := version.Parse(label[8:])
	return err == nil
}
Пример #5
0
func runMain(versionString string) error {
	// Make sure the version string is correct.
	ver, err := version.Parse(versionString)
	if err != nil {
		return err
	}

	// Set the version.
	return version.Set(ver)
}
Пример #6
0
func runMain(versionString string) error {
	if _, err := version.Parse(versionString); err != nil {
		return err
	}

	return pkg.Install(versionString, &pkg.InstallOptions{
		GitHubOwner:     flagOwner,
		GitHubRepo:      flagRepo,
		TargetDirectory: flagDst,
	})
}
Пример #7
0
func runMain(versionString string) (err error) {
	// Get issue tracker.
	tracker, err := modules.GetIssueTracker()
	if err != nil {
		return err
	}

	// Parse the version string.
	v, err := version.Parse(versionString)
	if err != nil {
		return err
	}

	// Get the relevant stories.
	task := fmt.Sprintf("Fetch stories assigned to release %v", v.BaseString())
	stories, err := tracker.ListStoriesByRelease(v)
	if err != nil {
		return errs.NewError(task, err)
	}
	if len(stories) == 0 {
		return errs.NewError(task, errors.New("no stories found"))
	}

	// Generate the release notes.
	nts := notes.GenerateReleaseNotes(v, stories)

	// Dump the release notes.
	encoder, err := notes.NewEncoder(notes.Encoding(flagFormat.Value()), os.Stdout)
	if err != nil {
		return err
	}

	return encoder.Encode(nts, &notes.EncodeOptions{
		Pretty: flagPretty,
	})
}
Пример #8
0
// Check whether SalsaFlow git hook is used. Prompts user to install our hook if it isn't.
//
// When the force argument is set to true, the hook is replaced when though the version matches.
func CheckAndUpsert(hookType HookType, force bool) error {
	// Declade some variables so that we can use goto.
	var confirmed bool

	// Ping the git hook with our secret argument.
	repoRoot, err := gitutil.RepositoryRootAbsolutePath()
	if err != nil {
		return err
	}

	hookDestPath := filepath.Join(repoRoot, ".git", "hooks", string(hookType))

	// Try to get the hook version.
	stdout, _, _ := shell.Run(hookDestPath, "-"+versionFlag)

	// In case the versions match, we are done here (unless force).
	installedVersion, err := version.Parse(strings.TrimSpace(stdout.String()))
	if !force && installedVersion != nil && installedVersion.String() == metadata.Version {
		return nil
	}

	// Get the hook executable absolute path. It's supposed to be installed
	// in the same directory as the salsaflow executable itself.
	task := "Get the executable folder absolute path"
	binDir, err := osext.ExecutableFolder()
	if err != nil {
		return errs.NewError(task, err)
	}
	hookExecutable := filepath.Join(binDir, getHookFileName(hookType))

	// Check whether there is a hook already present in the repository.
	// If there is no hook or there is a SalsaFlow hook returning a different version string,
	// we don't have to ask the user, we can just install the hook.
	task = fmt.Sprintf("Check whether there is a git %v hook already installed", hookType)
	if _, err := os.Stat(hookDestPath); err != nil {
		if os.IsNotExist(err) {
			return copyHook(hookType, hookExecutable, hookDestPath)
		}
		return errs.NewError(task, err)
	}
	if installedVersion != nil || force {
		return copyHook(hookType, hookExecutable, hookDestPath)
	}

	// Prompt the user to confirm the SalsaFlow git commit-task hook.
	task = fmt.Sprintf("Prompt the user to confirm the %v hook", hookType)
	confirmed, err = prompt.Confirm(`
I need my own git ` + string(hookType) + ` hook to be placed in the repository.
Shall I create or replace your current ` + string(hookType) + ` hook?`)
	fmt.Println()
	if err != nil {
		return errs.NewError(task, err)
	}
	if !confirmed {
		// User stubbornly refuses to let us overwrite their webhook.
		// Inform the init has failed and let them do their thing.
		fmt.Printf(`I need the hook in order to do my job!

Please make sure the executable located at

  %v

runs as your `+string(hookType)+` hook and run me again!

`, hookExecutable)
		return errs.NewError(task, fmt.Errorf("SalsaFlow git %v hook not detected", hookType))
	}

	return copyHook(hookType, hookExecutable, hookDestPath)
}
Пример #9
0
func Upgrade(opts *InstallOptions) error {
	// Get GitHub owner and repository names.
	var (
		owner = DefaultGitHubOwner
		repo  = DefaultGitHubRepo
	)
	if opts != nil {
		if opts.GitHubOwner != "" {
			owner = opts.GitHubOwner
		}
		if opts.GitHubRepo != "" {
			repo = opts.GitHubRepo
		}
	}

	// Instantiate a GitHub client.
	task := "Instantiate a GitHub client"
	client, err := newGitHubClient()
	if err != nil {
		return errs.NewError(task, err)
	}

	// Fetch the list of available GitHub releases.
	task = fmt.Sprintf("Fetch GitHub releases for %v/%v", owner, repo)
	log.Run(task)
	releases, _, err := client.Repositories.ListReleases(owner, repo, nil)
	if err != nil {
		return errs.NewError(task, err)
	}

	// Sort the releases by version and get the most recent release.
	task = "Select the most suitable GitHub release"
	var rs releaseSlice
	for i, release := range releases {
		// Skip drafts and pre-releases.
		if *release.Draft || *release.Prerelease {
			continue
		}
		// We expect the tag to be "v" + semver version string.
		version, err := version.Parse((*release.TagName)[1:])
		if err != nil {
			log.Warn(fmt.Sprintf("Tag format invalid for '%v', skipping...", release.TagName))
			continue
		}
		// Append the release to the list of releases.
		rs = append(rs, &githubRelease{
			version:  version,
			resource: &releases[i],
		})
	}
	if rs.Len() == 0 {
		return errs.NewError(task, errors.New("no suitable GitHub releases found"))
	}

	sort.Sort(rs)
	release := rs[len(rs)-1]

	// Make sure the selected release is more recent than this executable.
	currentVersion, err := version.Parse(metadata.Version)
	if err != nil {
		panic(err)
	}
	if release.version.String() == metadata.Version || release.version.LT(currentVersion.Version) {
		log.Log("SalsaFlow is up to date")
		asciiart.PrintThumbsUp()
		fmt.Println()
		return nil
	}

	// Prompt the user to confirm the upgrade.
	task = "Prompt the user to confirm upgrade"
	fmt.Println()
	confirmed, err := prompt.Confirm(fmt.Sprintf(
		"SalsaFlow version %v is available. Upgrade now?", release.version))
	if err != nil {
		return errs.NewError(task, err)
	}
	if !confirmed {
		return ErrAborted
	}
	fmt.Println()

	// Proceed to actually install the executables.
	return doInstall(client, owner, repo, release.resource.Assets, release.version.String())
}