← back to jmcampanini__grove-cli

Function bodies 172 total

All specs Real LLM only Function bodies
cmd.runCacheClear function · go · L20-L33 (14 LOC)
cmd/cache_clear.go
func runCacheClear(cmd *cobra.Command, _ []string) error {
	dir, err := cache.DefaultDir()
	if err != nil {
		return err
	}

	c := cache.New(dir, 0)
	if err := c.Clear(); err != nil {
		return err
	}

	_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Cache cleared.")
	return nil
}
cmd.runConfig function · go · L29-L43 (15 LOC)
cmd/config.go
func runConfig(cmd *cobra.Command, _ []string) error {
	rt, err := loadCommandRuntime()
	if err != nil {
		return err
	}

	var buf bytes.Buffer
	encoder := toml.NewEncoder(&buf)
	if err := encoder.Encode(rt.cfg); err != nil {
		return fmt.Errorf("failed to encode config: %w", err)
	}

	_, err = fmt.Fprint(cmd.OutOrStdout(), buf.String())
	return err
}
cmd.runCreate function · go · L48-L62 (15 LOC)
cmd/create.go
func runCreate(cmd *cobra.Command, args []string) error {
	phrase := args[0]

	rt, err := loadCommandRuntime()
	if err != nil {
		return err
	}

	ctx := &createContext{
		cfg:       rt.cfg,
		gitClient: rt.gitClient,
	}

	return executeCreate(cmd.OutOrStdout(), ctx, phrase)
}
cmd.executeCreate function · go · L64-L107 (44 LOC)
cmd/create.go
func executeCreate(stdout io.Writer, ctx *createContext, phrase string) error {
	if strings.TrimSpace(phrase) == "" {
		return errors.New("phrase cannot be empty")
	}

	namer := naming.NewLocalBranchNamer(ctx.cfg.LocalBranch, ctx.cfg.Slugify)

	workspacePath, err := ctx.gitClient.GetWorkspacePath()
	if err != nil {
		return fmt.Errorf("failed to get workspace path: %w", err)
	}

	branchName := namer.GenerateBranchName(phrase)
	if branchName == "" || branchName == ctx.cfg.LocalBranch.BranchPrefix {
		return fmt.Errorf(`phrase %q produces an empty branch name after slugification

Please provide a phrase with at least one alphanumeric character.
Examples:
  grove create "add user auth"
  grove create "fix-bug-123"`, phrase)
	}

	exists, err := ctx.gitClient.BranchExists(branchName, false)
	if err != nil {
		return fmt.Errorf("failed to check if branch exists: %w", err)
	}
	if exists {
		return fmt.Errorf("branch %q already exists; to use it: git worktree add <path> %s", branchName, branch
cmd.init function · go · L41-L48 (8 LOC)
cmd/init.go
func init() {
	initCmd.GroupID = "config"
	initCmd.Flags().BoolVar(&initBashFlag, "bash", false, "Output bash shell functions")
	initCmd.Flags().BoolVar(&initFishFlag, "fish", false, "Output fish shell functions")
	initCmd.Flags().BoolVar(&initZshFlag, "zsh", false, "Output zsh shell functions")
	initCmd.MarkFlagsMutuallyExclusive("bash", "fish", "zsh")
	rootCmd.AddCommand(initCmd)
}
cmd.runInit function · go · L50-L68 (19 LOC)
cmd/init.go
func runInit(cmd *cobra.Command, _ []string) error {
	gen := shell.NewFunctionGenerator()

	var output string
	switch {
	case initBashFlag:
		output = gen.GenerateBash()
	case initFishFlag:
		output = gen.GenerateFish()
	case initZshFlag:
		output = gen.GenerateZsh()
	default:
		_, _ = fmt.Fprintln(cmd.ErrOrStderr(), cmd.Long)
		return fmt.Errorf("specify a shell flag: --bash, --fish, or --zsh")
	}

	_, err := fmt.Fprint(cmd.OutOrStdout(), output)
	return err
}
cmd.runList function · go · L49-L62 (14 LOC)
cmd/list.go
func runList(cmd *cobra.Command, _ []string) error {
	rt, err := loadCommandRuntime()
	if err != nil {
		return err
	}

	ctx := &listContext{
		cfg:              rt.cfg,
		gitClient:        rt.gitClient,
		mainWorktreePath: rt.mainWorktreePath,
	}

	return executeList(cmd.OutOrStdout(), ctx, fzfFlag)
}
Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
cmd.executeList function · go · L64-L99 (36 LOC)
cmd/list.go
func executeList(w io.Writer, ctx *listContext, fzf bool) error {
	worktrees, err := ctx.gitClient.ListWorktrees()
	if err != nil {
		return fmt.Errorf("failed to list worktrees: %w", err)
	}

	var mainWT *git.Worktree
	var others []git.Worktree
	for i := range worktrees {
		if worktrees[i].AbsolutePath == ctx.mainWorktreePath {
			mainWT = &worktrees[i]
		} else {
			others = append(others, worktrees[i])
		}
	}

	sort.Slice(others, func(i, j int) bool {
		return others[i].AbsolutePath < others[j].AbsolutePath
	})

	namer := naming.NewLocalBranchNamer(ctx.cfg.LocalBranch, ctx.cfg.Slugify)
	prWorktreePrefix := ctx.cfg.PullRequest.WorktreePrefix

	if mainWT != nil {
		if err := writeWorktree(w, *mainWT, namer, prWorktreePrefix, fzf); err != nil {
			return err
		}
	}
	for _, wt := range others {
		if err := writeWorktree(w, wt, namer, prWorktreePrefix, fzf); err != nil {
			return err
		}
	}

	return nil
}
cmd.writeWorktree function · go · L101-L109 (9 LOC)
cmd/list.go
func writeWorktree(w io.Writer, wt git.Worktree, namer *naming.LocalBranchNamer, prWorktreePrefix string, fzf bool) error {
	if fzf {
		path, display := formatWorktree(wt, namer, prWorktreePrefix)
		_, err := fmt.Fprintf(w, "%s\t%s\n", path, display)
		return err
	}
	_, err := fmt.Fprintln(w, wt.AbsolutePath)
	return err
}
cmd.formatWorktree function · go · L111-L132 (22 LOC)
cmd/list.go
func formatWorktree(wt git.Worktree, namer *naming.LocalBranchNamer, prWorktreePrefix string) (path, display string) {
	name := getDisplayName(namer, wt.AbsolutePath)
	name = formatWorktreeName(name, filepath.Base(wt.AbsolutePath), prWorktreePrefix)

	switch wt.Ref.Type() {
	case git.WorktreeRefTypeBranch:
		branch, _ := wt.Ref.FullBranch()
		return wt.AbsolutePath, fmt.Sprintf("local branch %s %s", name, branch.Name)
	case git.WorktreeRefTypeTag:
		tag, _ := wt.Ref.FullTag()
		return wt.AbsolutePath, fmt.Sprintf("tag %s %s", name, tag.Name)
	case git.WorktreeRefTypeCommit:
		commit := wt.Ref.Commit()
		shortSHA := shortSHASafe(commit.SHA, 7)
		return wt.AbsolutePath, fmt.Sprintf("detached %s %s", name, shortSHA)
	default:
		// Unknown ref type - still show useful output
		commit := wt.Ref.Commit()
		shortSHA := shortSHASafe(commit.SHA, 7)
		return wt.AbsolutePath, fmt.Sprintf("unknown %s %s", name, shortSHA)
	}
}
cmd.getDisplayName function · go · L134-L141 (8 LOC)
cmd/list.go
func getDisplayName(namer *naming.LocalBranchNamer, absPath string) string {
	basename := filepath.Base(absPath)
	if namer.HasPrefix(basename) {
		return namer.ExtractFromAbsolutePath(absPath)
	}
	// Non-standard worktree name - mark with brackets
	return "[" + basename + "]"
}
cmd.shortSHASafe function · go · L143-L151 (9 LOC)
cmd/list.go
func shortSHASafe(sha string, maxLen int) string {
	if sha == "" {
		return "(no sha)"
	}
	if len(sha) <= maxLen {
		return sha
	}
	return sha[:maxLen]
}
cmd.formatWorktreeName function · go · L153-L158 (6 LOC)
cmd/list.go
func formatWorktreeName(displayName, dirName, prWorktreePrefix string) string {
	if prWorktreePrefix != "" && strings.HasPrefix(dirName, prWorktreePrefix) {
		return "[PR] " + displayName
	}
	return displayName
}
cmd.runPRCheckout function · go · L35-L66 (32 LOC)
cmd/pr_checkout.go
func runPRCheckout(cmd *cobra.Command, args []string) error {
	prNum, err := strconv.Atoi(args[0])
	if err != nil {
		return fmt.Errorf("invalid PR number: %s", args[0])
	}

	rt, err := loadCommandRuntime()
	if err != nil {
		return err
	}

	ctx := &prCheckoutContext{
		cfg:       rt.cfg,
		ghClient:  rt.newUncachedGitHubClient(),
		gitClient: rt.gitClient,
	}

	prInfo, err := ctx.ghClient.GetPullRequest(prNum)
	if err != nil {
		return fmt.Errorf("failed to get pull request: %w", err)
	}

	if prInfo.IsCrossRepository {
		return fmt.Errorf("PR #%d is from a fork, which is not yet supported.\nTip: You can manually add the fork as a remote and create a worktree with 'git worktree add'", prInfo.Number)
	}

	if prInfo.State == github.PRStateMerged || prInfo.State == github.PRStateClosed {
		_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Note: PR #%d is %s\n", prInfo.Number, strings.ToLower(string(prInfo.State)))
	}

	return checkoutPRWorktree(cmd.OutOrStdout(), cmd.ErrOrStderr(), ctx, prInfo)
}
cmd.checkoutPRWorktree function · go · L74-L141 (68 LOC)
cmd/pr_checkout.go
func checkoutPRWorktree(stdout, stderr io.Writer, ctx *prCheckoutContext, prInfo github.PullRequest) error {
	namer, err := naming.NewPullRequestNamer(ctx.cfg.PullRequest, ctx.cfg.Slugify)
	if err != nil {
		return fmt.Errorf("failed to create PR namer: %w", err)
	}

	prData := naming.PullRequestTemplateData{
		BranchName: prInfo.BranchName,
		Number:     prInfo.Number,
	}
	localBranch, err := namer.GenerateBranchName(prData)
	if err != nil {
		return fmt.Errorf("failed to generate branch name: %w", err)
	}

	worktreeName := namer.GenerateWorktreeName(localBranch)
	if worktreeName == "" {
		return fmt.Errorf("failed to generate worktree name: empty result")
	}

	worktrees, err := ctx.gitClient.ListWorktrees()
	if err != nil {
		return fmt.Errorf("failed to list worktrees: %w", err)
	}

	matcher := pr.NewMatcher(namer)
	existingWorktree := matcher.FindWorktreeForPR(prInfo, worktrees)

	if existingWorktree != nil {
		_, _ = fmt.Fprintf(stderr, "Worktree already exists\n")
		_, err := fmt
Repobility · severity-and-effort ranking · https://repobility.com
cmd.runPRList function · go · L39-L74 (36 LOC)
cmd/pr_list.go
func runPRList(cmd *cobra.Command, _ []string) error {
	rt, err := loadCommandRuntime()
	if err != nil {
		return err
	}
	cfg := rt.cfg

	gh, err := rt.newCachedGitHubClient()
	if err != nil {
		return err
	}

	namer, err := naming.NewPullRequestNamer(cfg.PullRequest, cfg.Slugify)
	if err != nil {
		return fmt.Errorf("failed to create PR namer: %w", err)
	}

	query := github.PRQuery{State: github.PRStateOpen}
	prs, err := gh.ListPullRequests(query, github.DefaultPRLimit)
	if err != nil {
		return fmt.Errorf("failed to list pull requests: %w", err)
	}

	worktrees, err := rt.gitClient.ListWorktrees()
	if err != nil {
		return fmt.Errorf("failed to list worktrees: %w", err)
	}

	matcher := pr.NewMatcher(namer)
	matches := matcher.MatchAll(prs, worktrees)

	if prListFzfFlag {
		return outputPRListFzf(cmd.OutOrStdout(), matches)
	}
	return outputPRListTable(cmd.OutOrStdout(), matches)
}
cmd.outputPRListTable function · go · L76-L130 (55 LOC)
cmd/pr_list.go
func outputPRListTable(w io.Writer, matches []pr.Match) error {
	if len(matches) == 0 {
		_, err := fmt.Fprintln(w, "No open pull requests found.")
		return err
	}

	purple := lipgloss.Color("99")
	gray := lipgloss.Color("245")
	lightGray := lipgloss.Color("241")

	headerStyle := lipgloss.NewStyle().Foreground(purple).Bold(true).Align(lipgloss.Center)
	cellStyle := lipgloss.NewStyle().Padding(0, 1)
	oddRowStyle := cellStyle.Foreground(gray)
	evenRowStyle := cellStyle.Foreground(lightGray)

	rows := make([][]string, len(matches))
	for i, match := range matches {
		localMarker := ""
		if match.HasWorktree() {
			localMarker = "\u2713" // checkmark
		}

		state := strings.ToLower(string(match.PR.State))
		updated := humanize.Time(match.PR.UpdatedAt)

		rows[i] = []string{
			fmt.Sprintf("%d", match.PR.Number),
			truncateString(match.PR.Title, 40),
			match.PR.AuthorLogin,
			truncateString(match.PR.BranchName, 30),
			state,
			localMarker,
			updated,
		}
	}

	t := table.New().
		Border
cmd.outputPRListFzf function · go · L132-L163 (32 LOC)
cmd/pr_list.go
func outputPRListFzf(w io.Writer, matches []pr.Match) error {
	for _, match := range matches {
		number := fmt.Sprintf("%d", match.PR.Number)

		state := strings.ToLower(string(match.PR.State))
		searchable := sanitizeFzfField(fmt.Sprintf("%d %s %s %s %s",
			match.PR.Number,
			match.PR.Title,
			match.PR.BranchName,
			match.PR.AuthorLogin,
			state,
		))

		localPrefix := ""
		if match.HasWorktree() {
			localPrefix = "\u2713 " // checkmark with space
		}
		display := sanitizeFzfField(fmt.Sprintf("%s#%d %s [%s] %s",
			localPrefix,
			match.PR.Number,
			match.PR.Title,
			match.PR.AuthorLogin,
			match.PR.BranchName,
		))

		_, err := fmt.Fprintf(w, "%s\t%s\t%s\n", number, searchable, display)
		if err != nil {
			return err
		}
	}
	return nil
}
cmd.sanitizeFzfField function · go · L165-L170 (6 LOC)
cmd/pr_list.go
func sanitizeFzfField(s string) string {
	s = strings.ReplaceAll(s, "\t", " ")
	s = strings.ReplaceAll(s, "\n", " ")
	s = strings.ReplaceAll(s, "\r", " ")
	return s
}
cmd.truncateString function · go · L172-L181 (10 LOC)
cmd/pr_list.go
func truncateString(s string, maxLen int) string {
	runes := []rune(s)
	if len(runes) <= maxLen {
		return s
	}
	if maxLen <= 3 {
		return string(runes[:maxLen])
	}
	return string(runes[:maxLen-3]) + "..."
}
cmd.handlePreviewError function · go · L42-L48 (7 LOC)
cmd/pr_preview.go
func handlePreviewError(cmd *cobra.Command, err error) error {
	if prPreviewFzfFlag {
		_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Error: %v\n", err)
		return nil
	}
	return err
}
cmd.detectPreviewWidth function · go · L50-L60 (11 LOC)
cmd/pr_preview.go
func detectPreviewWidth() int {
	if cols := os.Getenv("FZF_PREVIEW_COLUMNS"); cols != "" {
		if n, err := strconv.Atoi(cols); err == nil && n > 0 {
			return n
		}
	}
	if w, _, err := term.GetSize(int(os.Stdout.Fd())); err == nil && w > 0 {
		return w
	}
	return 80
}
cmd.applyColorMode function · go · L62-L85 (24 LOC)
cmd/pr_preview.go
func applyColorMode(mode string) error {
	// When stdout isn't a TTY (fzf preview, piped output), termenv can't query
	// the terminal for its background color and defaults to dark. Fall back to
	// COLORFGBG env var so AdaptiveColor picks the right variant.
	fi, err := os.Stdout.Stat()
	if err == nil && fi.Mode()&os.ModeCharDevice == 0 {
		if dark, ok := detectDarkBackgroundFromEnv(); ok {
			lipgloss.SetHasDarkBackground(dark)
		}
	}

	switch mode {
	case "auto":
		return nil
	case "always":
		lipgloss.SetColorProfile(termenv.ANSI256)
		return nil
	case "never":
		lipgloss.SetColorProfile(termenv.Ascii)
		return nil
	default:
		return fmt.Errorf("invalid color mode %q; valid modes: auto, always, never", mode)
	}
}
Repobility (the analyzer behind this table) · https://repobility.com
cmd.detectDarkBackgroundFromEnv function · go · L87-L97 (11 LOC)
cmd/pr_preview.go
func detectDarkBackgroundFromEnv() (dark bool, ok bool) {
	parts := strings.Split(os.Getenv("COLORFGBG"), ";")
	if len(parts) < 2 {
		return false, false
	}
	bg, err := strconv.Atoi(parts[len(parts)-1])
	if err != nil {
		return false, false
	}
	return bg < 7 || bg == 8, true
}
cmd.runPRPreview function · go · L99-L143 (45 LOC)
cmd/pr_preview.go
func runPRPreview(cmd *cobra.Command, args []string) error {
	if err := applyColorMode(prPreviewColorFlag); err != nil {
		return handlePreviewError(cmd, err)
	}

	prNum, err := strconv.Atoi(args[0])
	if err != nil {
		return handlePreviewError(cmd, fmt.Errorf("invalid PR number: %s", args[0]))
	}

	rt, err := loadCommandRuntime()
	if err != nil {
		return handlePreviewError(cmd, err)
	}

	gh, err := rt.newCachedGitHubClient()
	if err != nil {
		return handlePreviewError(cmd, err)
	}

	pr, err := gh.GetPullRequest(prNum)
	if err != nil {
		return handlePreviewError(cmd, err)
	}

	owner, repo, err := github.ParseRepoFromURL(pr.URL)
	if err != nil {
		return handlePreviewError(cmd, err)
	}

	threads, timeline, err := gh.GetPullRequestActivity(owner, repo, prNum)
	if err != nil {
		return handlePreviewError(cmd, err)
	}

	fileComments := make(map[string]int, len(threads))
	for _, t := range threads {
		fileComments[t.Path] += t.CommentCount
	}

	w := cmd.OutOrStdout()
	width := detectPrev
cmd.hyperlink function · go · L51-L56 (6 LOC)
cmd/pr_preview_render.go
func hyperlink(url, text string) string {
	if lipgloss.ColorProfile() == termenv.Ascii {
		return text
	}
	return termenv.Hyperlink(url, text)
}
cmd.stateColor function · go · L58-L71 (14 LOC)
cmd/pr_preview_render.go
func stateColor(state github.PRState) lipgloss.TerminalColor {
	switch state {
	case github.PRStateOpen:
		return colorGreen
	case github.PRStateDraft:
		return colorYellow
	case github.PRStateMerged:
		return colorPurple
	case github.PRStateClosed:
		return colorRed
	default:
		return colorGray
	}
}
cmd.checkIcon function · go · L77-L88 (12 LOC)
cmd/pr_preview_render.go
func checkIcon(conclusion github.CheckConclusion) string {
	switch conclusion {
	case github.CheckConclusionSuccess:
		return colorIcon(iconCheck, colorGreen)
	case github.CheckConclusionFailure, github.CheckConclusionTimedOut, github.CheckConclusionActionRequired:
		return colorIcon(iconCross, colorRed)
	case github.CheckConclusionCancelled, github.CheckConclusionSkipped:
		return colorIcon(iconCross, colorGray)
	default:
		return colorIcon(iconPending, colorYellow)
	}
}
cmd.reviewIcon function · go · L90-L99 (10 LOC)
cmd/pr_preview_render.go
func reviewIcon(state github.ReviewState) string {
	switch state {
	case github.ReviewStateApproved:
		return colorIcon(iconCheck, colorGreen)
	case github.ReviewStateChangesRequested:
		return colorIcon(iconCross, colorRed)
	default:
		return colorIcon(iconCircle, colorGray)
	}
}
cmd.labelColor function · go · L101-L110 (10 LOC)
cmd/pr_preview_render.go
func labelColor(hexColor string) lipgloss.Color {
	h := strings.TrimPrefix(hexColor, "#")
	if len(h) != 6 {
		return colorGray
	}
	if _, err := hex.DecodeString(h); err != nil {
		return colorGray
	}
	return lipgloss.Color("#" + h)
}
cmd.checkStatusText function · go · L112-L117 (6 LOC)
cmd/pr_preview_render.go
func checkStatusText(sc github.StatusCheck) string {
	if sc.Conclusion != "" {
		return string(sc.Conclusion)
	}
	return strings.ToLower(string(sc.Status))
}
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
cmd.branchInfo function · go · L119-L124 (6 LOC)
cmd/pr_preview_render.go
func branchInfo(branchName, baseRefName string) string {
	if baseRefName == "" {
		return branchName
	}
	return fmt.Sprintf("%s → %s", branchName, baseRefName)
}
cmd.renderLabels function · go · L126-L135 (10 LOC)
cmd/pr_preview_render.go
func renderLabels(labels []github.Label) string {
	if len(labels) == 0 {
		return ""
	}
	var parts []string
	for _, l := range labels {
		parts = append(parts, lipgloss.NewStyle().Foreground(labelColor(l.Color)).Render(l.Name))
	}
	return strings.Join(parts, lipgloss.NewStyle().Foreground(colorGray).Render(" · "))
}
cmd.formatStats function · go · L137-L143 (7 LOC)
cmd/pr_preview_render.go
func formatStats(pr github.PullRequest) string {
	return fmt.Sprintf("%d files  %s  %s",
		pr.FilesChanged,
		lipgloss.NewStyle().Foreground(colorGreen).Render(fmt.Sprintf("+%d", pr.LinesAdded)),
		lipgloss.NewStyle().Foreground(colorRed).Render(fmt.Sprintf("-%d", pr.LinesDeleted)),
	)
}
cmd.relativeTime function · go · L145-L169 (25 LOC)
cmd/pr_preview_render.go
func relativeTime(t time.Time) string {
	d := time.Since(t)
	switch {
	case d < time.Minute:
		return "just now"
	case d < time.Hour:
		m := int(d.Minutes())
		if m == 1 {
			return "1 min ago"
		}
		return fmt.Sprintf("%d mins ago", m)
	case d < 24*time.Hour:
		h := int(d.Hours())
		if h == 1 {
			return "1 hour ago"
		}
		return fmt.Sprintf("%d hours ago", h)
	default:
		days := int(d.Hours() / 24)
		if days == 1 {
			return "1 day ago"
		}
		return fmt.Sprintf("%d days ago", days)
	}
}
cmd.wrapBody function · go · L171-L199 (29 LOC)
cmd/pr_preview_render.go
func wrapBody(body string, width int) string {
	if body == "" {
		return ""
	}
	bodyWidth := max(width-4, 20)
	var lines []string
	for _, paragraph := range strings.Split(body, "\n") {
		if len(paragraph) <= bodyWidth {
			lines = append(lines, paragraph)
			continue
		}
		words := strings.Fields(paragraph)
		var line string
		for _, word := range words {
			if line == "" {
				line = word
			} else if len(line)+1+len(word) <= bodyWidth {
				line += " " + word
			} else {
				lines = append(lines, line)
				line = word
			}
		}
		if line != "" {
			lines = append(lines, line)
		}
	}
	return strings.Join(lines, "\n")
}
cmd.renderChecksLines function · go · L205-L223 (19 LOC)
cmd/pr_preview_render.go
func renderChecksLines(checks []github.StatusCheck) string {
	if len(checks) == 0 {
		return ""
	}
	var lines []string
	for _, sc := range checks {
		line := fmt.Sprintf("  %s %s %s",
			checkIcon(sc.Conclusion),
			sc.Name,
			lipgloss.NewStyle().Foreground(colorGray).Render(checkStatusText(sc)),
		)
		if sc.DetailURL != "" {
			link := hyperlink(sc.DetailURL, "[↗ details]")
			line += "  " + lipgloss.NewStyle().Foreground(colorCyan).Render(link)
		}
		lines = append(lines, line)
	}
	return strings.Join(lines, "\n")
}
cmd.deduplicateReviews function · go · L225-L237 (13 LOC)
cmd/pr_preview_render.go
func deduplicateReviews(reviews []github.Review) []github.Review {
	latest := make(map[string]github.Review, len(reviews))
	for _, r := range reviews {
		if existing, ok := latest[r.AuthorLogin]; !ok || r.SubmittedAt.After(existing.SubmittedAt) {
			latest[r.AuthorLogin] = r
		}
	}
	deduped := slices.Collect(maps.Values(latest))
	slices.SortFunc(deduped, func(a, b github.Review) int {
		return a.SubmittedAt.Compare(b.SubmittedAt)
	})
	return deduped
}
cmd.reviewActionText function · go · L239-L252 (14 LOC)
cmd/pr_preview_render.go
func reviewActionText(state github.ReviewState) string {
	switch state {
	case github.ReviewStateApproved:
		return "approved"
	case github.ReviewStateChangesRequested:
		return "requested changes"
	case github.ReviewStateCommented:
		return "commented"
	case github.ReviewStateDismissed:
		return "review dismissed"
	default:
		return strings.ToLower(string(state))
	}
}
Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
cmd.renderReviewLines function · go · L254-L268 (15 LOC)
cmd/pr_preview_render.go
func renderReviewLines(reviews []github.Review) string {
	if len(reviews) == 0 {
		return ""
	}
	deduped := deduplicateReviews(reviews)
	var lines []string
	for _, r := range deduped {
		lines = append(lines, fmt.Sprintf("  %s @%s %s",
			reviewIcon(r.State),
			r.AuthorLogin,
			lipgloss.NewStyle().Foreground(colorGray).Render(reviewActionText(r.State)),
		))
	}
	return strings.Join(lines, "\n")
}
cmd.isTestFile function · go · L275-L282 (8 LOC)
cmd/pr_preview_render.go
func isTestFile(path string) bool {
	base := filepath.Base(path)
	if slices.ContainsFunc(testFileSuffixes, func(s string) bool { return strings.HasSuffix(base, s) }) {
		return true
	}
	prefixed := "/" + path
	return slices.ContainsFunc(testDirSegments, func(s string) bool { return strings.Contains(prefixed, s) })
}
cmd.timelineEventIcon function · go · L284-L318 (35 LOC)
cmd/pr_preview_render.go
func timelineEventIcon(eventType github.TimelineEventType, details string) string {
	switch eventType {
	case github.TimelineEventReviewed:
		switch details {
		case "approved":
			return colorIcon(iconCheck, colorGreen)
		case "changes requested":
			return colorIcon(iconCross, colorRed)
		default:
			return colorIcon(iconComment, colorGray)
		}
	case github.TimelineEventCommented:
		return colorIcon(iconComment, colorCyan)
	case github.TimelineEventCommitted:
		return colorIcon(iconGitRef, colorPurple)
	case github.TimelineEventForcePushed:
		return colorIcon(iconZap, colorYellow)
	case github.TimelineEventLabeled:
		return colorIcon(iconTag, colorCyan)
	case github.TimelineEventMerged:
		return colorIcon(iconMerge, colorPurple)
	case github.TimelineEventClosed:
		return colorIcon(iconArchive, colorRed)
	case github.TimelineEventReopened:
		return colorIcon(iconReopened, colorGreen)
	case github.TimelineEventReadyForReview:
		return colorIcon(iconBell, colorGreen)
	case github.Timeli
cmd.timelineEventMessage function · go · L320-L350 (31 LOC)
cmd/pr_preview_render.go
func timelineEventMessage(e github.TimelineEvent) string {
	switch e.Type {
	case github.TimelineEventReviewed:
		return fmt.Sprintf("@%s %s", e.Actor, e.Details)
	case github.TimelineEventCommented:
		return fmt.Sprintf("@%s commented", e.Actor)
	case github.TimelineEventCommitted:
		if e.Details != "" {
			return fmt.Sprintf("@%s committed: %s", e.Actor, e.Details)
		}
		return fmt.Sprintf("@%s committed", e.Actor)
	case github.TimelineEventForcePushed:
		return fmt.Sprintf("@%s force pushed", e.Actor)
	case github.TimelineEventLabeled:
		return fmt.Sprintf("@%s added %s", e.Actor, e.Details)
	case github.TimelineEventMerged:
		return fmt.Sprintf("@%s merged", e.Actor)
	case github.TimelineEventClosed:
		return fmt.Sprintf("@%s closed", e.Actor)
	case github.TimelineEventReopened:
		return fmt.Sprintf("@%s reopened", e.Actor)
	case github.TimelineEventReadyForReview:
		return fmt.Sprintf("@%s marked ready for review", e.Actor)
	case github.TimelineEventConvertToDraft:
		return fmt.Sp
cmd.computeFileColumnWidths function · go · L358-L374 (17 LOC)
cmd/pr_preview_render.go
func computeFileColumnWidths(files []github.PullRequestFile, fileComments map[string]int) fileColumnWidths {
	var w fileColumnWidths
	for _, f := range files {
		if aw := len(strconv.Itoa(f.Additions)) + 1; aw > w.addWidth {
			w.addWidth = aw
		}
		if dw := len(strconv.Itoa(f.Deletions)) + 1; dw > w.delWidth {
			w.delWidth = dw
		}
		if c := fileComments[f.Path]; c > 0 {
			if cw := len(strconv.Itoa(c)); cw > w.commentWidth {
				w.commentWidth = cw
			}
		}
	}
	return w
}
cmd.formatFileEntry function · go · L381-L422 (42 LOC)
cmd/pr_preview_render.go
func formatFileEntry(f github.PullRequestFile, comments int, prURL string, contentWidth int, cw fileColumnWidths) string {
	added := lipgloss.NewStyle().Foreground(colorGreen).Render(fmt.Sprintf("%+*d", cw.addWidth, f.Additions))
	delStr := fmt.Sprintf("-%d", f.Deletions)
	deleted := lipgloss.NewStyle().Foreground(colorRed).Render(fmt.Sprintf("%*s", cw.delWidth, delStr))

	var linkCol string
	if prURL != "" {
		link := hyperlink(fileDiffURL(prURL, f.Path), "[↗]")
		linkCol = "  " + lipgloss.NewStyle().Foreground(colorCyan).Render(link)
	}

	var right string
	if cw.commentWidth > 0 {
		if comments > 0 {
			right = fmt.Sprintf("%s %*d%s  %s  %s", iconComment, cw.commentWidth, comments, linkCol, added, deleted)
		} else {
			commentColWidth := lipgloss.Width(fmt.Sprintf("%s %*d", iconComment, cw.commentWidth, 0))
			right = fmt.Sprintf("%s%s  %s  %s", strings.Repeat(" ", commentColWidth), linkCol, added, deleted)
		}
	} else {
		if linkCol != "" {
			right = fmt.Sprintf("%s  %s  %s", link
cmd.renderHeader function · go · L424-L455 (32 LOC)
cmd/pr_preview_render.go
func renderHeader(pr github.PullRequest) string {
	labelStyle := lipgloss.NewStyle().Foreground(colorPurple).Bold(true).Width(10)
	valueStyle := lipgloss.NewStyle().Foreground(colorGray)

	stateStr := lipgloss.NewStyle().
		Background(stateColor(pr.State)).
		Foreground(lipgloss.Color("0")).
		Bold(true).
		Padding(0, 1).
		Render(strings.ToUpper(string(pr.State)))
	titleLine := lipgloss.NewStyle().Bold(true).Render(fmt.Sprintf("#%d %s", pr.Number, pr.Title)) + "  " + stateStr

	row := func(label, value string) string {
		return labelStyle.Render(label) + valueStyle.Render(value)
	}

	var sb strings.Builder
	fmt.Fprintln(&sb, titleLine)
	fmt.Fprintln(&sb, row("Author", "@"+pr.AuthorLogin))
	fmt.Fprintln(&sb, row("Branch", branchInfo(pr.BranchName, pr.BaseRefName)))
	fmt.Fprintln(&sb, row("Changed", formatStats(pr)))

	if labels := renderLabels(pr.Labels); labels != "" {
		fmt.Fprintln(&sb, row("Labels", labels))
	}

	if pr.URL != "" {
		fmt.Fprintln(&sb, row("URL", hyperlink(pr.URL, pr
cmd.renderChecks function · go · L457-L469 (13 LOC)
cmd/pr_preview_render.go
func renderChecks(pr github.PullRequest) string {
	var parts []string
	if ciLines := renderChecksLines(pr.StatusChecks); ciLines != "" {
		parts = append(parts, sectionHeader("Checks")+"\n"+ciLines)
	}
	if reviewLines := renderReviewLines(pr.Reviews); reviewLines != "" {
		parts = append(parts, sectionHeader("Reviews")+"\n"+reviewLines)
	}
	if len(parts) == 0 {
		return ""
	}
	return strings.Join(parts, "\n\n")
}
Repobility · severity-and-effort ranking · https://repobility.com
cmd.scoreFiles function · go · L477-L493 (17 LOC)
cmd/pr_preview_render.go
func scoreFiles(files []github.PullRequestFile, fileComments map[string]int) []scoredFile {
	var scored []scoredFile
	for _, f := range files {
		if isTestFile(f.Path) {
			continue
		}
		comments := fileComments[f.Path]
		score := f.Additions + f.Deletions + (comments * 10)
		if score > 0 {
			scored = append(scored, scoredFile{comments: comments, file: f, score: score})
		}
	}
	slices.SortFunc(scored, func(a, b scoredFile) int {
		return b.score - a.score
	})
	return scored
}
cmd.selectHighActivityFiles function · go · L495-L511 (17 LOC)
cmd/pr_preview_render.go
func selectHighActivityFiles(scored []scoredFile) []scoredFile {
	var commented, uncommented []scoredFile
	for _, sf := range scored {
		if sf.comments > 0 {
			commented = append(commented, sf)
		} else {
			uncommented = append(uncommented, sf)
		}
	}

	result := commented
	remaining := targetHighActivityFiles - len(result)
	if remaining > 0 {
		result = append(result, uncommented[:min(remaining, len(uncommented))]...)
	}
	return result
}
cmd.renderHighActivity function · go · L513-L538 (26 LOC)
cmd/pr_preview_render.go
func renderHighActivity(scored []scoredFile, prURL string, contentWidth int) (string, []scoredFile) {
	shown := selectHighActivityFiles(scored)
	if len(shown) == 0 {
		return "", nil
	}

	shownComments := make(map[string]int, len(shown))
	var shownFiles []github.PullRequestFile
	for _, sf := range shown {
		shownFiles = append(shownFiles, sf.file)
		if sf.comments > 0 {
			shownComments[sf.file.Path] = sf.comments
		}
	}
	cw := computeFileColumnWidths(shownFiles, shownComments)

	header := sectionHeader(fmt.Sprintf("High Activity Files (%d)", len(shown)))
	var sb strings.Builder
	sb.WriteString(header)
	sb.WriteString("\n")
	for _, sf := range shown {
		sb.WriteString(formatFileEntry(sf.file, sf.comments, prURL, contentWidth, cw))
		sb.WriteString("\n")
	}
	return strings.TrimRight(sb.String(), "\n"), shown
}
page 1 / 4next ›