Пример #1
0
func verboseLog(cmd *Cmd) {
	if os.Getenv("HUB_VERBOSE") != "" {
		msg := fmt.Sprintf("$ %s %s", cmd.Name, strings.Join(cmd.Args, " "))
		if ui.IsTerminal(os.Stderr) {
			msg = fmt.Sprintf("\033[35m%s\033[0m", msg)
		}
		ui.Errorln(msg)
	}
}
Пример #2
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 ui.IsTerminal(os.Stdout) {
		pass = string(gopass.GetPasswd())
	} else {
		pass = c.scanLine()
	}

	return
}
Пример #3
0
func newHttpClient(testHost string, verbose bool) *http.Client {
	var testURL *url.URL
	if testHost != "" {
		testURL, _ = url.Parse(testHost)
	}
	tr := &verboseTransport{
		Transport: &http.Transport{
			Proxy: proxyFromEnvironment,
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout: 10 * time.Second,
		},
		Verbose:     verbose,
		OverrideURL: testURL,
		Out:         ui.Stderr,
		Colorized:   ui.IsTerminal(os.Stderr),
	}

	// Implement CheckRedirect callback to fix issues with net/http.
	fixupCheckRedirect := func(req *http.Request, via []*http.Request) error {
		// net/http doesn't send a Host header on redirect requests.
		// TODO: Find or file a Go bug.
		if req.Host == "" {
			req.Host = req.URL.Host
		}

		// Maintain headers after redirect.
		// https://github.com/golang/go/issues/4800
		for key, val := range via[0].Header {
			if req.Host != via[0].Host && strings.EqualFold(key, "Authorization") {
				continue
			}
			req.Header[key] = val
		}

		// remainder should match http/Client.defaultCheckRedirect()
		if len(via) >= 10 {
			return errors.New("stopped after 10 redirects")
		}

		return nil
	}

	return &http.Client{Transport: tr, CheckRedirect: fixupCheckRedirect}
}
Пример #4
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 ui.IsTerminal(os.Stdin) {
		if password, err := getPassword(); err == nil {
			pass = password
		}
	} else {
		pass = c.scanLine()
	}

	return
}
Пример #5
0
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)
}
Пример #6
0
func newHttpClient(testHost string, verbose bool) *http.Client {
	var testURL *url.URL
	if testHost != "" {
		testURL, _ = url.Parse(testHost)
	}
	tr := &verboseTransport{
		Transport: &http.Transport{
			Proxy: proxyFromEnvironment,
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout: 10 * time.Second,
		},
		Verbose:     verbose,
		OverrideURL: testURL,
		Out:         ui.Stderr,
		Colorized:   ui.IsTerminal(os.Stderr),
	}
	return &http.Client{Transport: tr}
}
Пример #7
0
Файл: http.go Проект: github/hub
func newHttpClient(testHost string, verbose bool) *http.Client {
	var testURL *url.URL
	if testHost != "" {
		testURL, _ = url.Parse(testHost)
	}
	tr := &verboseTransport{
		Transport: &http.Transport{
			Proxy: proxyFromEnvironment,
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout: 10 * time.Second,
		},
		Verbose:     verbose,
		OverrideURL: testURL,
		Out:         ui.Stderr,
		Colorized:   ui.IsTerminal(os.Stderr),
	}

	return &http.Client{
		Transport: tr,
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			if len(via) > 2 {
				return fmt.Errorf("too many redirects")
			} else {
				for key, vals := range via[0].Header {
					lkey := strings.ToLower(key)
					if !strings.HasPrefix(lkey, "x-original-") && via[0].Host == req.URL.Host || lkey != "authorization" {
						req.Header[key] = vals
					}
				}
				return nil
			}
		},
	}
}
Пример #8
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)
		}
	}
}
Пример #9
0
Файл: sync.go Проект: 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()
}
Пример #10
0
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()
}