Example #1
0
File: issue.go Project: jueyang/hub
/*
  $ hub issue
*/
func issue(cmd *Command, args *Args) {
	runInLocalRepo(func(localRepo *github.GitHubRepo, project *github.Project, gh *github.Client) {
		if args.Noop {
			ui.Printf("Would request list of issues for %s\n", project)
		} else {
			issues, err := gh.Issues(project)
			utils.Check(err)
			for _, issue := range issues {
				var url string
				// use the pull request URL if we have one
				if issue.PullRequest.HTMLURL != "" {
					url = issue.PullRequest.HTMLURL
				} else {
					url = issue.HTMLURL
				}

				if flagIssueAssignee == "" ||
					strings.EqualFold(issue.Assignee.Login, flagIssueAssignee) {
					// "nobody" should have more than 1 million github issues
					ui.Printf("% 7d] %s ( %s )\n", issue.Number, issue.Title, url)
				}
			}
		}
	})
}
Example #2
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)
	}
}
Example #3
0
func downloadRelease(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)

	release, err := gh.FetchRelease(project, tagName)
	utils.Check(err)

	for _, asset := range release.Assets {
		ui.Printf("Downloading %s ...\n", asset.Name)
		err := downloadReleaseAsset(asset, gh)
		utils.Check(err)
	}

	args.NoForward()
}
Example #4
0
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
}
Example #5
0
File: commands.go Project: d2s/hub
func (c *Command) PrintUsage() {
	if c.Runnable() {
		ui.Printf("usage: %s\n\n", c.FormattedUsage())
	}

	ui.Println(strings.Trim(c.Long, "\n"))
}
Example #6
0
File: fork.go Project: github/hub
func fork(cmd *Command, args *Args) {
	localRepo, err := github.LocalRepo()
	utils.Check(err)

	project, err := localRepo.MainProject()
	if err != nil {
		utils.Check(fmt.Errorf("Error: repository under 'origin' remote is not a GitHub project"))
	}

	config := github.CurrentConfig()
	host, err := config.PromptForHost(project.Host)
	if err != nil {
		utils.Check(github.FormatError("forking repository", err))
	}

	originRemote, err := localRepo.OriginRemote()
	if err != nil {
		utils.Check(fmt.Errorf("Error creating fork: %s", err))
	}

	forkProject := github.NewProject(host.User, project.Name, project.Host)
	newRemoteName := forkProject.Owner

	client := github.NewClient(project.Host)
	existingRepo, err := client.Repository(forkProject)
	if err == nil {
		var parentURL *github.URL
		if parent := existingRepo.Parent; parent != nil {
			parentURL, _ = github.ParseURL(parent.HTMLURL)
		}
		if parentURL == nil || !project.SameAs(parentURL.Project) {
			err = fmt.Errorf("Error creating fork: %s already exists on %s",
				forkProject, forkProject.Host)
			utils.Check(err)
		}
	} else {
		if !args.Noop {
			newRepo, err := client.ForkRepository(project)
			utils.Check(err)
			forkProject.Owner = newRepo.Owner.Login
			forkProject.Name = newRepo.Name
		}
	}

	args.NoForward()
	if !flagForkNoRemote {
		originURL := originRemote.URL.String()
		url := forkProject.GitURL("", "", true)
		args.Before("git", "remote", "add", "-f", newRemoteName, originURL)
		args.Before("git", "remote", "set-url", newRemoteName, url)

		args.AfterFn(func() error {
			ui.Printf("new remote: %s\n", newRemoteName)
			return nil
		})
	}
}
Example #7
0
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)
	}
}
Example #8
0
File: issue.go Project: pcorpet/hub
func listIssues(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 issues for %s\n", project)
	} else {
		filters := map[string]interface{}{}
		if cmd.FlagPassed("state") {
			filters["state"] = flagIssueState
		}
		if cmd.FlagPassed("assignee") {
			filters["assignee"] = flagIssueAssignee
		}

		issues, err := gh.FetchIssues(project, filters)
		utils.Check(err)

		maxNumWidth := 0
		for _, issue := range issues {
			if numWidth := len(strconv.Itoa(issue.Number)); numWidth > maxNumWidth {
				maxNumWidth = numWidth
			}
		}

		colorize := ui.IsTerminal(os.Stdout)
		for _, issue := range issues {
			if issue.PullRequest != nil {
				continue
			}

			ui.Printf(formatIssue(issue, flagIssueFormat, colorize))
		}
	}

	os.Exit(0)
}
Example #9
0
func (c *Config) PromptForUser(host string) (user string) {
	user = os.Getenv("GITHUB_USER")
	if user != "" {
		return
	}

	ui.Printf("%s username: ", host)
	user = c.scanLine()

	return
}
Example #10
0
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()
}
Example #11
0
func (c *Config) PromptForPassword(host, user string) (pass string) {
	pass = os.Getenv("GITHUB_PASSWORD")
	if pass != "" {
		return
	}

	ui.Printf("%s password for %s (never stored): ", host, user)
	if IsTerminal(os.Stdout) {
		pass = string(gopass.GetPasswd())
	} else {
		pass = c.scanLine()
	}

	return
}
Example #12
0
func verboseFormat(statuses []github.CIStatus) {
	colorize := ui.IsTerminal(os.Stdout)

	contextWidth := 0
	for _, status := range statuses {
		if len(status.Context) > contextWidth {
			contextWidth = len(status.Context)
		}
	}

	for _, status := range statuses {
		var color int
		var stateMarker string
		switch status.State {
		case "success":
			stateMarker = "✔︎"
			color = 32
		case "failure", "error":
			stateMarker = "✖︎"
			color = 31
		case "pending":
			stateMarker = "●"
			color = 33
		}

		if colorize {
			stateMarker = fmt.Sprintf("\033[%dm%s\033[0m", color, stateMarker)
		}

		if status.TargetUrl == "" {
			ui.Printf("%s\t%s\n", stateMarker, status.Context)
		} else {
			ui.Printf("%s\t%-*s\t%s\n", stateMarker, contextWidth, status.Context, status.TargetUrl)
		}
	}
}
Example #13
0
File: config.go Project: github/hub
func (c *Config) PromptForPassword(host, user string) (pass string) {
	pass = os.Getenv("GITHUB_PASSWORD")
	if pass != "" {
		return
	}

	ui.Printf("%s password for %s (never stored): ", host, user)
	if ui.IsTerminal(os.Stdin) {
		if password, err := getPassword(); err == nil {
			pass = password
		}
	} else {
		pass = c.scanLine()
	}

	return
}
Example #14
0
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"))
		}
	})
}
Example #15
0
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
}
Example #16
0
File: issue.go Project: jueyang/hub
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)
		}
	})
}
Example #17
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
}
Example #18
0
func (c *Config) selectHost() *Host {
	options := len(c.Hosts)

	if options == 1 {
		return c.Hosts[0]
	}

	prompt := "Select host:\n"
	for idx, host := range c.Hosts {
		prompt += fmt.Sprintf(" %d. %s\n", idx+1, host.Host)
	}
	prompt += fmt.Sprint("> ")

	ui.Printf(prompt)
	index := c.scanLine()
	i, err := strconv.Atoi(index)
	if err != nil || i < 1 || i > options {
		utils.Check(fmt.Errorf("Error: must enter a number [1-%d]", options))
	}

	return c.Hosts[i-1]
}
Example #19
0
File: help.go Project: github/hub
func runHelp(helpCmd *Command, args *Args) {
	if args.IsParamsEmpty() {
		args.AfterFn(func() error {
			ui.Println(helpText)
			return nil
		})
		return
	}

	if args.HasFlags("-a", "--all") {
		args.AfterFn(func() error {
			ui.Printf("\nhub custom commands\n\n  %s\n", strings.Join(customCommands(), "  "))
			return nil
		})
		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())
		args.NoForward()
	}
}
Example #20
0
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()
}
Example #21
0
func printError(err error, stack string) {
	ui.Printf("%v\n\n", err)
	ui.Println(stack)
}
Example #22
0
func create(command *Command, args *Args) {
	_, err := git.Dir()
	if err != nil {
		err = fmt.Errorf("'create' must be run from inside a git repository")
		utils.Check(err)
	}

	var newRepoName string
	if args.IsParamsEmpty() {
		newRepoName, err = utils.DirName()
		utils.Check(err)
	} else {
		reg := regexp.MustCompile("^[^-]")
		if !reg.MatchString(args.FirstParam()) {
			err = fmt.Errorf("invalid argument: %s", args.FirstParam())
			utils.Check(err)
		}
		newRepoName = args.FirstParam()
	}

	config := github.CurrentConfig()
	host, err := config.DefaultHost()
	if err != nil {
		utils.Check(github.FormatError("creating repository", err))
	}

	owner := host.User
	if strings.Contains(newRepoName, "/") {
		split := strings.SplitN(newRepoName, "/", 2)
		owner = split[0]
		newRepoName = split[1]
	}

	project := github.NewProject(owner, newRepoName, host.Host)
	gh := github.NewClient(project.Host)

	var action string
	if gh.IsRepositoryExist(project) {
		ui.Printf("%s already exists on %s\n", project, project.Host)
		action = "set remote origin"
	} else {
		action = "created repository"
		if !args.Noop {
			repo, err := gh.CreateRepository(project, flagCreateDescription, flagCreateHomepage, flagCreatePrivate)
			utils.Check(err)
			project = github.NewProject(repo.FullName, "", project.Host)
		}
	}

	localRepo, err := github.LocalRepo()
	utils.Check(err)

	remote, _ := localRepo.OriginRemote()
	if remote == nil || remote.Name != "origin" {
		url := project.GitURL("", "", true)
		args.Replace("git", "remote", "add", "-f", "origin", url)
	} else {
		args.Replace("git", "remote", "-v")
	}

	args.After("echo", fmt.Sprintf("%s:", action), project.String())
}
Example #23
0
File: issue.go Project: github/hub
func listIssues(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 issues for %s\n", project)
	} else {
		flagFilters := map[string]string{
			"state":     flagIssueState,
			"assignee":  flagIssueAssignee,
			"milestone": flagIssueMilestoneFilter,
			"creator":   flagIssueCreator,
			"mentioned": flagIssueMentioned,
			"labels":    flagIssueLabelsFilter,
			"sort":      flagIssueSort,
		}
		filters := map[string]interface{}{}
		for flag, filter := range flagFilters {
			if cmd.FlagPassed(flag) {
				filters[flag] = filter
			}
		}

		if flagIssueSortAscending {
			filters["direction"] = "asc"
		}

		if cmd.FlagPassed("since") {
			if sinceTime, err := time.ParseInLocation("2006-01-02", flagIssueSince, time.Local); err == nil {
				filters["since"] = sinceTime.Format(time.RFC3339)
			} else {
				filters["since"] = flagIssueSince
			}
		}

		issues, err := gh.FetchIssues(project, filters)
		utils.Check(err)

		maxNumWidth := 0
		for _, issue := range issues {
			if numWidth := len(strconv.Itoa(issue.Number)); numWidth > maxNumWidth {
				maxNumWidth = numWidth
			}
		}

		colorize := ui.IsTerminal(os.Stdout)
		for _, issue := range issues {
			if issue.PullRequest != nil {
				continue
			}

			ui.Printf(formatIssue(issue, flagIssueFormat, colorize))
		}
	}

	args.NoForward()
}
Example #24
0
File: issue.go Project: github/hub
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, editor, err = readMsgFromFile(flagIssueFile, flagIssueEdit, "ISSUE", "issue")
		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)

		workdir, err := git.WorkdirName()
		utils.Check(err)
		template, err := github.ReadTemplate(github.IssueTemplate, workdir)
		utils.Check(err)
		if template != "" {
			message = template + "\n" + message
		}

		editor, err := github.NewEditor("ISSUE", "issue", message)
		utils.Check(err)

		title, body, err = editor.EditTitleAndBody()
		utils.Check(err)
	}

	if editor != nil {
		defer editor.DeleteFile()
	}

	if title == "" {
		utils.Check(fmt.Errorf("Aborting creation due to empty issue title"))
	}

	params := map[string]interface{}{
		"title": title,
		"body":  body,
	}

	if len(flagIssueLabels) > 0 {
		params["labels"] = flagIssueLabels
	}

	if len(flagIssueAssignees) > 0 {
		params["assignees"] = flagIssueAssignees
	}

	if flagIssueMilestone > 0 {
		params["milestone"] = flagIssueMilestone
	}

	args.NoForward()
	if args.Noop {
		ui.Printf("Would create issue `%s' for %s\n", params["title"], project)
	} else {
		issue, err := gh.CreateIssue(project, params)
		utils.Check(err)

		printBrowseOrCopy(args, issue.HtmlUrl, flagIssueBrowse, flagIssueCopy)
	}
}
Example #25
0
File: sync.go Project: github/hub
func sync(cmd *Command, args *Args) {
	localRepo, err := github.LocalRepo()
	utils.Check(err)

	remote, err := localRepo.MainRemote()
	utils.Check(err)

	defaultBranch := localRepo.MasterBranch().ShortName()
	fullDefaultBranch := fmt.Sprintf("refs/remotes/%s/%s", remote.Name, defaultBranch)
	currentBranch := ""
	if curBranch, err := localRepo.CurrentBranch(); err == nil {
		currentBranch = curBranch.ShortName()
	}

	err = git.Spawn("fetch", "--prune", "--quiet", "--progress", remote.Name)
	utils.Check(err)

	branchToRemote := map[string]string{}
	if lines, err := git.ConfigAll("branch.*.remote"); err == nil {
		configRe := regexp.MustCompile(`^branch\.(.+?)\.remote (.+)`)

		for _, line := range lines {
			if matches := configRe.FindStringSubmatch(line); len(matches) > 0 {
				branchToRemote[matches[1]] = matches[2]
			}
		}
	}

	branches, err := git.LocalBranches()
	utils.Check(err)

	var green,
		lightGreen,
		red,
		lightRed,
		resetColor string

	if ui.IsTerminal(os.Stdout) {
		green = "\033[32m"
		lightGreen = "\033[32;1m"
		red = "\033[31m"
		lightRed = "\033[31;1m"
		resetColor = "\033[0m"
	}

	for _, branch := range branches {
		fullBranch := fmt.Sprintf("refs/heads/%s", branch)
		remoteBranch := fmt.Sprintf("refs/remotes/%s/%s", remote.Name, branch)
		gone := false

		if branchToRemote[branch] == remote.Name {
			if upstream, err := git.SymbolicFullName(fmt.Sprintf("%s@{upstream}", branch)); err == nil {
				remoteBranch = upstream
			} else {
				remoteBranch = ""
				gone = true
			}
		} else if !git.HasFile(strings.Split(remoteBranch, "/")...) {
			remoteBranch = ""
		}

		if remoteBranch != "" {
			diff, err := git.NewRange(fullBranch, remoteBranch)
			utils.Check(err)

			if diff.IsIdentical() {
				continue
			} else if diff.IsAncestor() {
				if branch == currentBranch {
					git.Quiet("merge", "--ff-only", "--quiet", remoteBranch)
				} else {
					git.Quiet("update-ref", fullBranch, remoteBranch)
				}
				ui.Printf("%sUpdated branch %s%s%s (was %s).\n", green, lightGreen, branch, resetColor, diff.A[0:7])
			} else {
				ui.Errorf("warning: `%s' seems to contain unpushed commits\n", branch)
			}
		} else if gone {
			diff, err := git.NewRange(fullBranch, fullDefaultBranch)
			utils.Check(err)

			if diff.IsAncestor() {
				if branch == currentBranch {
					git.Quiet("checkout", "--quiet", defaultBranch)
					currentBranch = defaultBranch
				}
				git.Quiet("branch", "-D", branch)
				ui.Printf("%sDeleted branch %s%s%s (was %s).\n", red, lightRed, branch, resetColor, diff.A[0:7])
			} else {
				ui.Errorf("warning: `%s' was deleted on %s, but appears not merged into %s\n", branch, remote.Name, defaultBranch)
			}
		}
	}

	args.NoForward()
}
Example #26
0
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)
	})
}
Example #27
0
File: issue.go Project: pcorpet/hub
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)
		}
	}
}
Example #28
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)

	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, editor, err = readMsgFromFile(flagReleaseFile, flagReleaseEdit, "RELEASE", "release")
		utils.Check(err)
	} else {
		cs := git.CommentChar()
		message, err := renderReleaseTpl("Creating", cs, tagName, project.String(), flagReleaseCommitish)
		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: flagReleaseCommitish,
		Name:            title,
		Body:            body,
		Draft:           flagReleaseDraft,
		Prerelease:      flagReleasePrerelease,
	}

	var release *github.Release

	args.NoForward()
	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)

		printBrowseOrCopy(args, release.HtmlUrl, flagReleaseBrowse, flagReleaseCopy)
	}

	if editor != nil {
		editor.DeleteFile()
	}

	uploadAssets(gh, release, flagReleaseAssets, args)
}
Example #29
0
func editRelease(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)

	release, err := gh.FetchRelease(project, tagName)
	utils.Check(err)

	params := map[string]interface{}{}
	commitish := release.TargetCommitish

	if cmd.FlagPassed("commitish") {
		params["target_commitish"] = flagReleaseCommitish
		commitish = flagReleaseCommitish
	}

	if cmd.FlagPassed("draft") {
		params["draft"] = flagReleaseDraft
	}

	if cmd.FlagPassed("prerelease") {
		params["prerelease"] = flagReleasePrerelease
	}

	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, editor, err = readMsgFromFile(flagReleaseFile, flagReleaseEdit, "RELEASE", "release")
		utils.Check(err)

		if title == "" {
			utils.Check(fmt.Errorf("Aborting editing due to empty release title"))
		}
	} else {
		cs := git.CommentChar()
		message, err := renderReleaseTpl("Editing", cs, tagName, project.String(), commitish)
		utils.Check(err)

		message = fmt.Sprintf("%s\n\n%s\n%s", release.Name, release.Body, message)
		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 editing due to empty release title"))
		}
	}

	if title != "" {
		params["name"] = title
	}
	if body != "" {
		params["body"] = body
	}

	if len(params) > 0 {
		if args.Noop {
			ui.Printf("Would edit release `%s'\n", tagName)
		} else {
			release, err = gh.EditRelease(release, params)
			utils.Check(err)
		}

		if editor != nil {
			editor.DeleteFile()
		}
	}

	uploadAssets(gh, release, flagReleaseAssets, args)
	args.NoForward()
}