func ciStatus(cmd *Command, args *Args) { ref := "HEAD" if !args.IsParamsEmpty() { ref = args.RemoveParam(0) } localRepo, err := github.LocalRepo() utils.Check(err) project, err := localRepo.MainProject() utils.Check(err) sha, err := git.Ref(ref) if err != nil { err = fmt.Errorf("Aborted: no revision could be determined from '%s'", ref) } utils.Check(err) if args.Noop { ui.Printf("Would request CI status for %s\n", sha) } else { gh := github.NewClient(project.Host) response, err := gh.FetchCIStatus(project, sha) utils.Check(err) state := response.State if len(response.Statuses) == 0 { state = "" } var exitCode int switch state { case "success": exitCode = 0 case "failure", "error": exitCode = 1 case "pending": exitCode = 2 default: exitCode = 3 } if flagCiStatusVerbose && len(response.Statuses) > 0 { verboseFormat(response.Statuses) } else { if state != "" { ui.Println(state) } else { ui.Println("no status") } } os.Exit(exitCode) } }
func runVersion(cmd *Command, args *Args) { gitVersion, err := git.Version() utils.Check(err) ghVersion := fmt.Sprintf("hub version %s", Version) ui.Println(gitVersion) ui.Println(ghVersion) os.Exit(0) }
/* $ gh ci-status > (prints CI state of HEAD and exits with appropriate code) > One of: success (0), error (1), failure (1), pending (2), no status (3) $ gh ci-status -v > (prints CI state of HEAD, the URL to the CI build results and exits with appropriate code) > One of: success (0), error (1), failure (1), pending (2), no status (3) $ gh ci-status BRANCH > (prints CI state of BRANCH and exits with appropriate code) > One of: success (0), error (1), failure (1), pending (2), no status (3) $ gh ci-status SHA > (prints CI state of SHA and exits with appropriate code) > One of: success (0), error (1), failure (1), pending (2), no status (3) */ func ciStatus(cmd *Command, args *Args) { ref := "HEAD" if !args.IsParamsEmpty() { ref = args.RemoveParam(0) } localRepo, err := github.LocalRepo() utils.Check(err) project, err := localRepo.MainProject() utils.Check(err) sha, err := git.Ref(ref) if err != nil { err = fmt.Errorf("Aborted: no revision could be determined from '%s'", ref) } utils.Check(err) if args.Noop { ui.Printf("Would request CI status for %s\n", sha) } else { state, targetURL, exitCode, err := fetchCiStatus(project, sha) utils.Check(err) if flagCiStatusVerbose && targetURL != "" { ui.Printf("%s: %s\n", state, targetURL) } else { ui.Println(state) } os.Exit(exitCode) } }
func (updater *Updater) PromptForUpdate() (err error) { config := autoUpdateConfig() if config == "never" || !updater.timeToUpdate() { return } releaseName, version := updater.latestReleaseNameAndVersion() if version != "" && version != updater.CurrentVersion { switch config { case "always": err = updater.updateTo(releaseName, version) default: ui.Println("There is a newer version of hub available.") ui.Printf("Would you like to update? ([Y]es/[N]o/[A]lways/N[e]ver): ") var confirm string fmt.Scan(&confirm) always := utils.IsOption(confirm, "a", "always") if always || utils.IsOption(confirm, "y", "yes") { err = updater.updateTo(releaseName, version) } saveAutoUpdateConfiguration(confirm, always) } } return }
func (c *Command) PrintUsage() { if c.Runnable() { ui.Printf("usage: %s\n\n", c.FormattedUsage()) } ui.Println(strings.Trim(c.Long, "\n")) }
func runHelp(helpCmd *Command, args *Args) { if args.IsParamsEmpty() { printUsage() os.Exit(0) } if args.HasFlags("-a", "--all") { args.After("echo", "\nhub custom commands\n") args.After("echo", " ", strings.Join(customCommands(), " ")) return } command := args.FirstParam() if command == "hub" { err := displayManPage("hub.1", args) if err != nil { utils.Check(err) } } if c := lookupCmd(command); c != nil { if !args.HasFlags("--plain-text") { manPage := fmt.Sprintf("hub-%s.1", c.Name()) err := displayManPage(manPage, args) if err == nil { return } } ui.Println(c.HelpText()) os.Exit(0) } }
func (updater *Updater) Update() (err error) { config := autoUpdateConfig() if config == "never" { ui.Println("Update is disabled") return } releaseName, version := updater.latestReleaseNameAndVersion() if version == "" { ui.Println("There is no newer version of hub available.") return } if version == updater.CurrentVersion { ui.Printf("You're already on the latest version: %s\n", version) } else { err = updater.updateTo(releaseName, version) } return }
func showRelease(cmd *Command, args *Args) { tagName := cmd.Arg(0) if tagName == "" { utils.Check(fmt.Errorf("Missing argument TAG")) } localRepo, err := github.LocalRepo() utils.Check(err) project, err := localRepo.MainProject() utils.Check(err) gh := github.NewClient(project.Host) if args.Noop { ui.Printf("Would display information for `%s' release\n", tagName) } else { release, err := gh.FetchRelease(project, tagName) utils.Check(err) body := strings.TrimSpace(release.Body) ui.Println(release.Name) if body != "" { ui.Printf("\n%s\n", body) } if flagReleaseShowDownloads { ui.Printf("\n## Downloads\n\n") for _, asset := range release.Assets { ui.Println(asset.DownloadUrl) } if release.ZipballUrl != "" { ui.Println(release.ZipballUrl) ui.Println(release.TarballUrl) } } } args.NoForward() }
func report(reportedError error, stack string) { title, body, err := reportTitleAndBody(reportedError, stack) utils.Check(err) project := NewProject(hubProjectOwner, hubProjectName, GitHubHost) gh := NewClient(project.Host) issue, err := gh.CreateIssue(project, title, body, []string{"Crash Report"}) utils.Check(err) ui.Println(issue.HTMLURL) }
func release(cmd *Command, args *Args) { runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, client *github.Client) { if args.Noop { ui.Printf("Would request list of releases for %s\n", project) } else { releases, err := client.Releases(project) utils.Check(err) var outputs []string for _, release := range releases { out := fmt.Sprintf("%s (%s)\n%s", release.Name, release.TagName, release.Body) outputs = append(outputs, out) } ui.Println(strings.Join(outputs, "\n\n")) } }) }
func report(reportedError error, stack string) { title, body, err := reportTitleAndBody(reportedError, stack) utils.Check(err) project := NewProject(hubProjectOwner, hubProjectName, GitHubHost) gh := NewClient(project.Host) params := map[string]interface{}{ "title": title, "body": body, "labels": []string{"Crash Report"}, } issue, err := gh.CreateIssue(project, params) utils.Check(err) ui.Println(issue.HtmlUrl) }
func (updater *Updater) updateTo(releaseName, version string) (err error) { ui.Printf("Updating gh to %s...\n", version) downloadURL := fmt.Sprintf("https://%s/github/hub/releases/download/%s/hub%s_%s_%s.zip", updater.Host, releaseName, version, runtime.GOOS, runtime.GOARCH) path, err := downloadFile(downloadURL) if err != nil { return } exec, err := unzipExecutable(path) if err != nil { return } err, _ = goupdate.New().FromFile(exec) if err == nil { ui.Println("Done!") } return }
func createIssue(cmd *Command, args *Args) { runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, gh *github.Client) { if args.Noop { ui.Printf("Would create an issue for %s\n", project) } else { title, body, err := getTitleAndBodyFromFlags(flagIssueMessage, flagIssueFile) utils.Check(err) if title == "" { title, body, err = writeIssueTitleAndBody(project) utils.Check(err) } issue, err := gh.CreateIssue(project, title, body, flagIssueLabels) utils.Check(err) ui.Println(issue.HTMLURL) } }) }
func printBrowseOrCopy(args *Args, msg string, openBrowser bool, performCopy bool) { if performCopy { if err := clipboard.WriteAll(msg); err != nil { ui.Errorf("Error copying %s to clipboard:\n%s\n", msg, err.Error()) } } if openBrowser { launcher, err := utils.BrowserLauncher() utils.Check(err) args.Replace(launcher[0], "", launcher[1:]...) args.AppendParams(msg) } if !openBrowser && !performCopy { args.AfterFn(func() error { ui.Println(msg) return nil }) } }
func listReleases(cmd *Command, args *Args) { localRepo, err := github.LocalRepo() utils.Check(err) project, err := localRepo.MainProject() utils.Check(err) gh := github.NewClient(project.Host) if args.Noop { ui.Printf("Would request list of releases for %s\n", project) } else { releases, err := gh.FetchReleases(project) utils.Check(err) for _, release := range releases { if !release.Draft || flagReleaseIncludeDrafts { ui.Println(release.TagName) } } } args.NoForward() }
func createIssue(cmd *Command, args *Args) { localRepo, err := github.LocalRepo() utils.Check(err) project, err := localRepo.MainProject() utils.Check(err) gh := github.NewClient(project.Host) var title string var body string var editor *github.Editor if cmd.FlagPassed("message") { title, body = readMsg(flagIssueMessage) } else if cmd.FlagPassed("file") { title, body, err = readMsgFromFile(flagIssueFile) utils.Check(err) } else { cs := git.CommentChar() message := strings.Replace(fmt.Sprintf(` # Creating an issue for %s # # Write a message for this issue. The first block of # text is the title and the rest is the description. `, project), "#", cs, -1) editor, err := github.NewEditor("ISSUE", "issue", message) utils.Check(err) title, body, err = editor.EditTitleAndBody() utils.Check(err) } if title == "" { utils.Check(fmt.Errorf("Aborting creation due to empty issue title")) } params := map[string]interface{}{ "title": title, "body": body, "labels": flagIssueLabels, "assignees": flagIssueAssignees, } if flagIssueMilestone > 0 { params["milestone"] = flagIssueMilestone } if args.Noop { ui.Printf("Would create issue `%s' for %s\n", params["title"], project) os.Exit(0) } else { issue, err := gh.CreateIssue(project, params) utils.Check(err) if editor != nil { editor.DeleteFile() } if flagIssueBrowse { launcher, err := utils.BrowserLauncher() utils.Check(err) args.Replace(launcher[0], "", launcher[1:]...) args.AppendParams(issue.HtmlUrl) } else { ui.Println(issue.HtmlUrl) os.Exit(0) } } }
func printError(err error, stack string) { ui.Printf("%v\n\n", err) ui.Println(stack) }
func createRelease(cmd *Command, args *Args) { if args.IsParamsEmpty() { utils.Check(fmt.Errorf("Missed argument TAG")) return } tag := args.LastParam() runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, client *github.Client) { release, err := client.Release(project, tag) utils.Check(err) if release == nil { commitish := flagReleaseCommitish if commitish == "" { currentBranch, err := localRepo.CurrentBranch() utils.Check(err) commitish = currentBranch.ShortName() } title, body, err := getTitleAndBodyFromFlags(flagReleaseMessage, flagReleaseFile) utils.Check(err) var editor *github.Editor if title == "" { cs := git.CommentChar() message, err := renderReleaseTpl(cs, tag, project.Name, commitish) utils.Check(err) editor, err = github.NewEditor("RELEASE", "release", message) utils.Check(err) title, body, err = editor.EditTitleAndBody() utils.Check(err) } params := octokit.ReleaseParams{ TagName: tag, TargetCommitish: commitish, Name: title, Body: body, Draft: flagReleaseDraft, Prerelease: flagReleasePrerelease, } release, err = client.CreateRelease(project, params) utils.Check(err) if editor != nil { defer editor.DeleteFile() } } if len(flagReleaseAssets) > 0 { paths := make([]string, 0) for _, asset := range flagReleaseAssets { finder := assetFinder{} p, err := finder.Find(asset) utils.Check(err) paths = append(paths, p...) } uploader := assetUploader{ Client: client, Release: release, } err = uploader.UploadAll(paths) if err != nil { ui.Println("") utils.Check(err) } } ui.Printf("\n%s\n", release.HTMLURL) }) }
func alias(command *Command, args *Args) { var shell string if args.ParamsSize() > 0 { shell = args.FirstParam() } else { shell = os.Getenv("SHELL") } if shell == "" { cmd := "hub alias <shell>" if flagAliasScript { cmd = "hub alias -s <shell>" } utils.Check(fmt.Errorf("Error: couldn't detect shell type. Please specify your shell with `%s`", cmd)) } shells := []string{"bash", "zsh", "sh", "ksh", "csh", "tcsh", "fish"} shell = filepath.Base(shell) var validShell bool for _, s := range shells { if s == shell { validShell = true break } } if !validShell { err := fmt.Errorf("hub alias: unsupported shell\nsupported shells: %s", strings.Join(shells, " ")) utils.Check(err) } if flagAliasScript { var alias string switch shell { case "csh", "tcsh": alias = "alias git hub" default: alias = "alias git=hub" } ui.Println(alias) } else { var profile string switch shell { case "bash": profile = "~/.bash_profile" case "zsh": profile = "~/.zshrc" case "ksh": profile = "~/.profile" case "fish": profile = "~/.config/fish/config.fish" case "csh": profile = "~/.cshrc" case "tcsh": profile = "~/.tcshrc" default: profile = "your profile" } msg := fmt.Sprintf("# Wrap git automatically by adding the following to %s:\n", profile) ui.Println(msg) var eval string switch shell { case "fish": eval = `eval (hub alias -s)` case "csh", "tcsh": eval = "eval \"`hub alias -s`\"" default: eval = `eval "$(hub alias -s)"` } ui.Println(eval) } os.Exit(0) }
func printCommands(cmds []*cmd.Cmd) { for _, c := range cmds { ui.Println(c) } }
func runVersion(cmd *Command, args *Args) { ui.Println(version.FullVersion()) os.Exit(0) }
func createRelease(cmd *Command, args *Args) { tagName := cmd.Arg(0) if tagName == "" { utils.Check(fmt.Errorf("Missing argument TAG")) return } localRepo, err := github.LocalRepo() utils.Check(err) project, err := localRepo.CurrentProject() utils.Check(err) gh := github.NewClient(project.Host) commitish := flagReleaseCommitish if commitish == "" { currentBranch, err := localRepo.CurrentBranch() utils.Check(err) commitish = currentBranch.ShortName() } var title string var body string var editor *github.Editor if cmd.FlagPassed("message") { title, body = readMsg(flagReleaseMessage) } else if cmd.FlagPassed("file") { title, body, err = readMsgFromFile(flagReleaseFile) utils.Check(err) } else { cs := git.CommentChar() message, err := renderReleaseTpl("Creating", cs, tagName, project.String(), commitish) utils.Check(err) editor, err := github.NewEditor("RELEASE", "release", message) utils.Check(err) title, body, err = editor.EditTitleAndBody() utils.Check(err) } if title == "" { utils.Check(fmt.Errorf("Aborting release due to empty release title")) } params := &github.Release{ TagName: tagName, TargetCommitish: commitish, Name: title, Body: body, Draft: flagReleaseDraft, Prerelease: flagReleasePrerelease, } var release *github.Release if args.Noop { ui.Printf("Would create release `%s' for %s with tag name `%s'\n", title, project, tagName) } else { release, err = gh.CreateRelease(project, params) utils.Check(err) ui.Println(release.HtmlUrl) } uploadAssets(gh, release, flagReleaseAssets, args) if editor != nil { editor.DeleteFile() } os.Exit(0) }
func runVersion(cmd *Command, args *Args) { ui.Println(version.FullVersion()) args.NoForward() }
func alias(command *Command, args *Args) { var shell string if args.ParamsSize() > 0 { shell = args.FirstParam() } else { shell = os.Getenv("SHELL") } if shell == "" { cmd := "hub alias <shell>" if flagAliasScript { cmd = "hub alias -s <shell>" } utils.Check(fmt.Errorf("Error: couldn't detect shell type. Please specify your shell with `%s`", cmd)) } shells := []string{"bash", "zsh", "sh", "ksh", "csh", "tcsh", "fish"} shell = filepath.Base(shell) var validShell bool for _, s := range shells { if s == shell { validShell = true break } } if !validShell { err := fmt.Errorf("hub alias: unsupported shell\nsupported shells: %s", strings.Join(shells, " ")) utils.Check(err) } if flagAliasScript { var alias string switch shell { case "csh", "tcsh": alias = "alias git hub" default: alias = "alias git=hub" } ui.Println(alias) } else { var profile string switch shell { case "bash": profile = "~/.bash_profile" case "zsh": profile = "~/.zshrc" case "ksh": profile = "~/.profile" case "fish": profile = "~/.config/fish/functions/git.fish" case "csh": profile = "~/.cshrc" case "tcsh": profile = "~/.tcshrc" default: profile = "your profile" } msg := fmt.Sprintf("# Wrap git automatically by adding the following to %s:\n", profile) ui.Println(msg) var eval string switch shell { case "fish": eval = `function git --description 'Alias for hub, which wraps git to provide extra functionality with GitHub.' hub $argv end` case "csh", "tcsh": eval = "eval \"`hub alias -s`\"" default: eval = `eval "$(hub alias -s)"` } indent := regexp.MustCompile(`(?m)^\t+`) eval = indent.ReplaceAllStringFunc(eval, func(match string) string { return strings.Repeat(" ", len(match)*4) }) ui.Println(eval) } os.Exit(0) }