Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughImplements a full CLI project-init flow (creates project dir, Changes
Sequence Diagram(s)sequenceDiagram
participant User as "User"
participant CLI as "CLI (cmd/root.go)"
participant FS as "File System"
participant Prompt as "Prompts"
participant Git as "Git"
participant GH as "GitHub (gh)"
rect rgba(200,230,201,0.5)
User->>CLI: run init command
CLI->>CLI: resolve target dir & project name
end
rect rgba(187,222,251,0.5)
CLI->>FS: create project dir, write `.gitignore`, `README.md`
CLI->>Prompt: ask for LICENSE choice & visibility
Prompt-->>CLI: license selection / visibility
CLI->>FS: write `LICENSE` (if chosen)
end
rect rgba(255,224,178,0.5)
CLI->>Git: init repo
CLI->>GH: create repository (without `--push`)
GH-->>CLI: returns repo URL
CLI->>Git: commit & push branch
Git-->>CLI: pushed
end
CLI->>User: display success with repo URL
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 143-152: At each of the four file existence checks (the blocks
using os.Stat for gitignorePath, licensePath, readmePath, and the .git repoPath)
don't treat any non-nil err as "exists"; instead first test if err != nil and if
so return or propagate a descriptive error (e.g., return fmt.Errorf("stat %s:
%w", <pathVar>, err)), then only if os.IsNotExist(err) perform creation (call
files.FetchGitignore, files.FetchLicense, files.FetchReadme or run git init) and
otherwise, when err == nil and !quiet, print the "already exists, skipping"
message; update the four checks to follow this pattern so permission/I/O errors
are surfaced rather than masked.
- Around line 224-238: The CLI parses --branch and --message but never uses them
when pushing; update run() to pass those values to the git operation by calling
repo.CommitAndPush with the parsed branch and message (or modify
repo.CreateGitHubRepo to accept branch/message and forward them to
repo.CommitAndPush). Specifically, replace or augment the current call to
repo.CreateGitHubRepo(dir, repoName, visibility, description) so that after
creating the remote you invoke repo.CommitAndPush(dir, repoName, branch,
message) (using the branch and message variables defined for the flags) so
user-specified -b/-m values are applied.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 86c4ffb9-c95d-43dc-a334-ff633097e719
📒 Files selected for processing (3)
.goreleaser.yamlMakefilecmd/root.go
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 241-246: The visibility variable is left empty when neither flag
is set, causing gh repo create to enter interactive mode; set an explicit
default (e.g., "public" or "private") where visibility is initialized so it's
never empty, update the code that builds the gh repo create invocation and the
CreateGitHubRepo call to always pass this explicit visibility value (referencing
the visibility variable and the CreateGitHubRepo function), and ensure the
default choice is documented in the flag handling so non-interactive workflows
never trigger prompts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c1f7ee6c-6e8e-43e4-b193-8bb2a4cb1793
📒 Files selected for processing (2)
cmd/root.gointernal/repo/repo.go
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
cmd/root.go (1)
120-130: Consider normalizing all paths to absolute.When
directory != ".", relative paths like../myprojectremain relative. Whilefilepath.Base()extracts the name correctly, subsequent operations could behave unexpectedly if any internal function changes the working directory.♻️ Optional improvement
func run() error { // Resolve directory dir := directory - if dir == "." { - var err error - dir, err = os.Getwd() + if !filepath.IsAbs(dir) { + wd, err := os.Getwd() if err != nil { return fmt.Errorf("could not get current directory: %w", err) } + dir = filepath.Join(wd, dir) } + dir = filepath.Clean(dir) repoName := filepath.Base(dir)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/root.go` around lines 120 - 130, The code in run() currently only resolves directory when directory == ".", leaving relative paths (e.g., "../myproject") unchanged; update run() to normalize directory to an absolute path by calling filepath.Abs on the resolved dir value (the variable dir derived from directory) before using filepath.Base; ensure you handle and return any error from filepath.Abs so repoName := filepath.Base(dir) always receives an absolute path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 164-189: The license prompt currently always calls
prompts.PromptSelect (using licenseOptions) even when the quiet flag is set;
change the logic in the block that handles missing LICENSE so that it first
checks the quiet boolean and skips prompting when quiet is true (e.g., print
"Skipping LICENSE." only when !quiet or silently return), or alternatively read
a provided --license flag before prompting; implement this by gating the call to
prompts.PromptSelect and the subsequent switch on the choice with an if !quiet {
... } block (references: prompts.PromptSelect, licenseOptions, FetchLicenseText,
licensePath, quiet).
- Around line 246-264: The printed GitHub URL uses the local "username" variable
which may not match the gh CLI authenticated account; update the post-create
messaging in cmd/root.go to determine the actual remote owner used by gh before
printing: either query the authenticated user via gh (e.g., run `gh api user
--jq .login`) and use that value when formatting the URL, or avoid embedding the
username and print a relative repo path (e.g., "github.com/<owner>/<repo>"
replaced by just "<repoName>" or "github.com/<repoName>"). Adjust the code
around the calls to repo.CreateGitHubRepo and the final fmt.Printf so it uses
the retrieved gh login (or the relative form) instead of the existing username
variable; ensure any errors from the gh query are handled and fall back
gracefully to the current behavior.
---
Nitpick comments:
In `@cmd/root.go`:
- Around line 120-130: The code in run() currently only resolves directory when
directory == ".", leaving relative paths (e.g., "../myproject") unchanged;
update run() to normalize directory to an absolute path by calling filepath.Abs
on the resolved dir value (the variable dir derived from directory) before using
filepath.Base; ensure you handle and return any error from filepath.Abs so
repoName := filepath.Base(dir) always receives an absolute path.
… auth user for URL
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 268-275: ghAuthenticatedUser currently runs the external "gh api
user" command with exec.Command and no deadline, which can hang indefinitely;
change it to use a context with a timeout (e.g. context.WithTimeout) and
exec.CommandContext so the process is killed if it exceeds the deadline, handle
the context error from cmd.Run (or cmd.Wait) and return empty string on
timeout/failure, and ensure Stdout is still captured from the command created in
ghAuthenticatedUser so the trimmed login is returned on success.
- Around line 259-262: The success message hardcodes "github.com"; update the
two fmt.Printf calls that print the repository URL to use the actual GitHub host
instead of the literal "github.com" by retrieving the configured hostname from
the GitHub client/config (use the existing variable that represents the host or
hostname from authentication/config, e.g., a ghHost or client.BaseURL/Host
value) and format the URL as "https://{host}/{ghUser}/{repoName}" (falling back
to printing just repoName if no host is available); change the fmt.Printf
invocations referenced here to use that host variable rather than the hardcoded
domain.
cmd/root.go
Outdated
| fmt.Printf("✓ Done! Repository available at https://github.com/%s/%s\n", ghUser, repoName) | ||
| } else { | ||
| fmt.Printf("✓ Done! Repository: %s\n", repoName) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Read the file around lines 259-262 to see the context
sed -n '250,270p' cmd/root.goRepository: shinokada/gitstart
Length of output: 712
🏁 Script executed:
#!/bin/bash
# Search for github.com references in the file
rg -n 'github\.com' cmd/root.goRepository: shinokada/gitstart
Length of output: 342
🏁 Script executed:
#!/bin/bash
# Search for any host/domain configuration or variables
rg -n 'host|domain|endpoint' cmd/root.go -iRepository: shinokada/gitstart
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Look for ghUser and repoName variable definitions to understand their content
rg -n -B5 -A5 'ghUser.*=' cmd/root.go | head -60Repository: shinokada/gitstart
Length of output: 463
🏁 Script executed:
#!/bin/bash
# Search for all gh CLI invocations to understand capabilities
rg -n 'gh"' cmd/root.go -A2Repository: shinokada/gitstart
Length of output: 187
🏁 Script executed:
#!/bin/bash
# Search for GitHub host/domain configuration across entire codebase
rg -n 'host|domain' . --type go | grep -v node_modules | head -30Repository: shinokada/gitstart
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Check if there's a config file or any host-related setup
fd -type f '\.gh|config' . | head -20Repository: shinokada/gitstart
Length of output: 232
🏁 Script executed:
#!/bin/bash
# Look at the broader context around ghAuthenticatedUser to understand its purpose
sed -n '255,280p' cmd/root.goRepository: shinokada/gitstart
Length of output: 772
🏁 Script executed:
#!/bin/bash
# Check if gh CLI has a way to get the configured host
# Look at the README or docs for this project
find . -name "README*" -o -name "*.md" | head -5 | xargs cat 2>/dev/null | head -100Repository: shinokada/gitstart
Length of output: 3826
🏁 Script executed:
#!/bin/bash
# Search for any gh host configuration or enterprise setup in codebase
rg -n 'api\.github|GITHUB_HOST|gh.*host' . --type goRepository: shinokada/gitstart
Length of output: 159
🏁 Script executed:
#!/bin/bash
# Check if gh CLI is used elsewhere and how
rg -n 'exec.Command.*"gh"' .Repository: shinokada/gitstart
Length of output: 139
🏁 Script executed:
#!/bin/bash
# Look at the complete file structure to understand the project better
ls -laRepository: shinokada/gitstart
Length of output: 1091
🏁 Script executed:
#!/bin/bash
# Check if gh CLI can retrieve the current host
# Search for any references to gh config or host retrieval
rg -n 'gh.*config|host|GITHUB' . --type goRepository: shinokada/gitstart
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Search the README for any mention of GitHub Enterprise or alternate hosts
cat README.md | grep -i "enterprise\|host\|instance" || echo "No matches found"Repository: shinokada/gitstart
Length of output: 78
🏁 Script executed:
#!/bin/bash
# Check if repo.CreateRepository uses gh repo create which may handle different hosts
rg -n 'CreateRepository|gh repo create' -B5 -A10 internal/repo/Repository: shinokada/gitstart
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Check if gh repo create command in the codebase uses any hostname configuration
find . -name "*.go" -exec grep -l "repo.Create\|gh.*repo" {} \;Repository: shinokada/gitstart
Length of output: 99
🏁 Script executed:
#!/bin/bash
# Look at the repo package to see how gh repo create is called
cat internal/repo/repo.goRepository: shinokada/gitstart
Length of output: 2478
🏁 Script executed:
#!/bin/bash
# Check if there are any flags or environment variables related to host in the codebase
rg -n '\-\-hostname|GITHUB_HOST|GH_HOST' .Repository: shinokada/gitstart
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Look at the full root.go to understand the complete context and see if there's any host configuration
wc -l cmd/root.go && head -50 cmd/root.goRepository: shinokada/gitstart
Length of output: 1169
🏁 Script executed:
#!/bin/bash
# Verify if gh CLI can retrieve the current configured host
# This would be the correct way to get the host dynamically
gh config get host 2>&1 || echo "Command may not be available in test environment"Repository: shinokada/gitstart
Length of output: 136
🏁 Script executed:
#!/bin/bash
# Check GitHub CLI documentation or common usage for getting the current host
# Search for any existing patterns in the codebase that might retrieve host info
rg -n 'gh.*config|gh.*api.*host' .Repository: shinokada/gitstart
Length of output: 44
🏁 Script executed:
#!/bin/bash
# Verify the exact gh CLI capabilities by checking what gh repo create outputs
# Look at git history to see if this issue has been discussed
git log --oneline --all | grep -i "host\|url\|enterprise\|github.com" | head -10Repository: shinokada/gitstart
Length of output: 157
🏁 Script executed:
#!/bin/bash
# Check the gh CLI documentation or API to see if we can retrieve the current host
# The gh CLI stores configuration, let's check if there's a way to get hostname
rg -n 'hostname|GH_HOST' README.md || echo "Not in README"Repository: shinokada/gitstart
Length of output: 75
🏁 Script executed:
#!/bin/bash
# Look at the recent git commit that mentions "gh auth user for URL"
git show a984327 --no-patch --format="%B%n%n" && git show a984327 --statRepository: shinokada/gitstart
Length of output: 2510
🏁 Script executed:
#!/bin/bash
# Check if gh repo create accepts a hostname flag or if the host comes from environment
# Search for how gh repo create is invoked in the code
rg -n 'gh.*repo.*create' -B3 -A3 internal/repo/repo.goRepository: shinokada/gitstart
Length of output: 487
🏁 Script executed:
#!/bin/bash
# Check GitHub CLI documentation for getting the current host
# Look for any gh command that might return the configured host
gh api user --jq 'env' 2>&1 | head -5 || echo "Checking alternative methods..."
gh config list 2>&1 | head -10 || echo "gh config list not available"Repository: shinokada/gitstart
Length of output: 388
🏁 Script executed:
#!/bin/bash
# Verify the actual behavior - gh repo create works with any configured host
# and the URL output from gh would use the correct host
# Let's see what information is available from gh
gh repo view --json url 2>&1 || echo "Need an existing repo to test"Repository: shinokada/gitstart
Length of output: 190
🏁 Script executed:
#!/bin/bash
# Check if there's a way to query the current host from gh CLI configuration
env | grep -i github || echo "No GitHub-related env vars"Repository: shinokada/gitstart
Length of output: 88
Success message hardcodes github.com, which fails for GitHub Enterprise or other configured hosts.
When users authenticate gh to a GitHub Enterprise instance or alternative host via gh auth login --hostname, the repository is created on that host but the success message incorrectly prints https://github.com/%s/%s. The printed URL will be wrong for non-default hosts.
Suggested fix
- if ghUser != "" {
- fmt.Printf("✓ Done! Repository available at https://github.com/%s/%s\n", ghUser, repoName)
+ if ghUser != "" {
+ fmt.Printf("✓ Done! Repository created: %s/%s\n", ghUser, repoName)
} else {
fmt.Printf("✓ Done! Repository: %s\n", repoName)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fmt.Printf("✓ Done! Repository available at https://github.com/%s/%s\n", ghUser, repoName) | |
| } else { | |
| fmt.Printf("✓ Done! Repository: %s\n", repoName) | |
| } | |
| fmt.Printf("✓ Done! Repository created: %s/%s\n", ghUser, repoName) | |
| } else { | |
| fmt.Printf("✓ Done! Repository: %s\n", repoName) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@cmd/root.go` around lines 259 - 262, The success message hardcodes
"github.com"; update the two fmt.Printf calls that print the repository URL to
use the actual GitHub host instead of the literal "github.com" by retrieving the
configured hostname from the GitHub client/config (use the existing variable
that represents the host or hostname from authentication/config, e.g., a ghHost
or client.BaseURL/Host value) and format the URL as
"https://{host}/{ghUser}/{repoName}" (falling back to printing just repoName if
no host is available); change the fmt.Printf invocations referenced here to use
that host variable rather than the hardcoded domain.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cmd/root.go (1)
35-39:⚠️ Potential issue | 🟡 MinorValidate
--branchearly to avoid downstream git command failure.Since
branchis now used in Line [252], an empty/whitespace branch should be rejected inPreRunEinstead of failing later during git execution.Proposed fix
PreRunE: func(cmd *cobra.Command, args []string) error { if private && public { return fmt.Errorf("flags --private and --public are mutually exclusive") } + if strings.TrimSpace(branch) == "" { + return fmt.Errorf("flag --branch cannot be empty") + } return nil },Also applies to: 252-253
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/root.go` around lines 35 - 39, In PreRunE validate the branch flag early: check the branch variable (trim whitespace) and if it's empty return an error (e.g., "flag --branch must not be empty or whitespace") so downstream git calls won't fail; update the PreRunE function in cmd/root.go to perform this validation alongside the existing private/public check and return an error if branch is invalid.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 145-157: The code calls files.FetchGitignore regardless of whether
the optional language flag is set; update the .gitignore creation branch so
files.FetchGitignore is only invoked when language is non-empty: check the
language variable before calling files.FetchGitignore (and only print "Creating
.gitignore..." when language != ""), otherwise skip fetching the gitignore and
do not error—use gitignorePath, files.FetchGitignore, language and quiet to gate
the operation accordingly.
---
Outside diff comments:
In `@cmd/root.go`:
- Around line 35-39: In PreRunE validate the branch flag early: check the branch
variable (trim whitespace) and if it's empty return an error (e.g., "flag
--branch must not be empty or whitespace") so downstream git calls won't fail;
update the PreRunE function in cmd/root.go to perform this validation alongside
the existing private/public check and return an error if branch is invalid.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
cmd/root.go (1)
39-41: Normalizebranchonce inPreRunE(not just validate it).Line 39 uses
strings.TrimSpace(branch)only for the emptiness check, but the original untrimmed value is still used later (Line 259). Assign the trimmed value back so downstream operations use a sanitized branch name.Suggested diff
- if strings.TrimSpace(branch) == "" { + branch = strings.TrimSpace(branch) + if branch == "" { return fmt.Errorf("flag --branch cannot be empty") }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/root.go` around lines 39 - 41, In PreRunE, normalize the branch variable by assigning the trimmed value back before validation (replace the one-off strings.TrimSpace(branch) check with branch = strings.TrimSpace(branch)); then validate the now-normalized branch (e.g., if branch == "" return error) so all downstream uses of the branch variable (the later code that references branch) operate on the sanitized value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 150-163: Trim the language input once and use the trimmed value
for all checks and the fetch call: replace usages of strings.TrimSpace(language)
and the later files.FetchGitignore(language, gitignorePath) with a single
trimmed variable (e.g., trimmedLang) and call files.FetchGitignore(trimmedLang,
gitignorePath); ensure the empty-check, os.Stat branch, and error handling
reference this trimmed variable instead of the original language.
---
Nitpick comments:
In `@cmd/root.go`:
- Around line 39-41: In PreRunE, normalize the branch variable by assigning the
trimmed value back before validation (replace the one-off
strings.TrimSpace(branch) check with branch = strings.TrimSpace(branch)); then
validate the now-normalized branch (e.g., if branch == "" return error) so all
downstream uses of the branch variable (the later code that references branch)
operate on the sanitized value.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cmd/root.go (1)
66-87:⚠️ Potential issue | 🟡 MinorDry-run output is inaccurate for
--quietlicense behavior.Dry-run always says it would prompt/create
LICENSE, but runtime skips license prompting in quiet mode (Lines 178-180). This can mislead automation users.💡 Suggested fix
- prompts.DryRunPrompt("Would prompt for and create LICENSE file") + if quiet { + prompts.DryRunPrompt("Would skip LICENSE creation in quiet mode") + } else { + prompts.DryRunPrompt("Would prompt for and create LICENSE file") + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/root.go` around lines 66 - 87, The dry-run block always shows "Would prompt for and create LICENSE file" even though the actual behavior skips license prompting when quiet is true; update the dry-run output generation in the same routine that writes the prompts.DryRunPrompt lines to conditionally add the license-related DryRunPrompt only when the quiet flag is false (i.e., mirror the runtime check that skips license prompting), referencing the dry-run prompt code that emits "Would prompt for and create LICENSE file" and the quiet boolean so the dry-run accurately reflects runtime behavior.
🧹 Nitpick comments (1)
cmd/root.go (1)
127-275:run()is doing too much; split into step-level helpers.This function is now orchestration + step logic + user messaging. Extracting steps (e.g.,
ensureGitignore,ensureLicense,ensureReadme,ensureGitRepo,createRemoteAndPush) will reduce complexity and improve testability.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/root.go` around lines 127 - 275, The run() function mixes orchestration, step logic, and user messaging—extract each major block into focused helper functions to simplify testing and readability: create ensureGitignore(dir, language, quiet) to encapsulate the .gitignore logic (using files.FetchGitignore and os.Stat), ensureLicense(dir, quiet, description) to handle LICENSE selection and files.FetchLicenseText (preserve prompts.PromptSelect flow), ensureReadme(dir, repoName, description, quiet) for README.md creation (files.CreateReadme), ensureGitRepo(dir, quiet) for initializing the .git repo (repo.InitGitRepo), and createRemoteAndPush(dir, repoName, visibility, description, branch, message, quiet) to create the GitHub repo and commit/push (repo.CreateGitHubRepo and repo.CommitAndPush); move all user-facing prints out of the helpers or make them controlled by the quiet flag so run() becomes a simple orchestrator that calls these helpers in order, returns any errors they propagate, and keeps final ghAuthenticatedUser lookup and success message unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cmd/root.go`:
- Around line 151-165: The lang normalization only trims whitespace and should
be converted to the exact gitignore template name (or mapped from common
aliases) before calling files.FetchGitignore to avoid silent fallback; update
the code around the lang variable (where lang := strings.TrimSpace(language)) to
normalize/canonicalize values (e.g., map "python" -> "Python", "javascript" or
"nodejs" -> "Node", "node" -> "Node", etc.) or implement a small
normalizeLanguage(lang string) helper and pass the normalized value to
files.FetchGitignore(gitignoreLang, gitignorePath); keep the existing quiet
prints and error handling but ensure FetchGitignore receives the canonical
template name so GitHub lookups return the intended template.
---
Outside diff comments:
In `@cmd/root.go`:
- Around line 66-87: The dry-run block always shows "Would prompt for and create
LICENSE file" even though the actual behavior skips license prompting when quiet
is true; update the dry-run output generation in the same routine that writes
the prompts.DryRunPrompt lines to conditionally add the license-related
DryRunPrompt only when the quiet flag is false (i.e., mirror the runtime check
that skips license prompting), referencing the dry-run prompt code that emits
"Would prompt for and create LICENSE file" and the quiet boolean so the dry-run
accurately reflects runtime behavior.
---
Nitpick comments:
In `@cmd/root.go`:
- Around line 127-275: The run() function mixes orchestration, step logic, and
user messaging—extract each major block into focused helper functions to
simplify testing and readability: create ensureGitignore(dir, language, quiet)
to encapsulate the .gitignore logic (using files.FetchGitignore and os.Stat),
ensureLicense(dir, quiet, description) to handle LICENSE selection and
files.FetchLicenseText (preserve prompts.PromptSelect flow), ensureReadme(dir,
repoName, description, quiet) for README.md creation (files.CreateReadme),
ensureGitRepo(dir, quiet) for initializing the .git repo (repo.InitGitRepo), and
createRemoteAndPush(dir, repoName, visibility, description, branch, message,
quiet) to create the GitHub repo and commit/push (repo.CreateGitHubRepo and
repo.CommitAndPush); move all user-facing prints out of the helpers or make them
controlled by the quiet flag so run() becomes a simple orchestrator that calls
these helpers in order, returns any errors they propagate, and keeps final
ghAuthenticatedUser lookup and success message unchanged.
…guage casing for gitignore
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cmd/root.go (1)
35-43:⚠️ Potential issue | 🟠 MajorAdd message validation to PreRunE to fail fast before executing setup steps.
The
messageflag is passed directly togit commit(internal/repo/repo.go:47) without prior validation in PreRunE. A whitespace-only message would bypass all validation and fail only after expensive setup steps (directory creation, git initialization, GitHub repository creation) complete.Proposed fix
PreRunE: func(cmd *cobra.Command, args []string) error { if private && public { return fmt.Errorf("flags --private and --public are mutually exclusive") } branch = strings.TrimSpace(branch) if branch == "" { return fmt.Errorf("flag --branch cannot be empty") } + message = strings.TrimSpace(message) + if message == "" { + return fmt.Errorf("flag --message cannot be empty") + } return nil },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/root.go` around lines 35 - 43, PreRunE currently validates flags private/public and branch but does not validate the message flag; add a TrimSpace check for the message variable in PreRunE (alongside existing branch validation) and return an error like "flag --message cannot be empty" when message == "" so we fail fast before running setup steps; reference the PreRunE function and the message variable (which is later used by internal/repo/repo.go:47 for git commit) to locate where to add this check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/files/gitignore.go`:
- Around line 33-43: NormalizeLanguage currently returns the original raw lang
on blank/whitespace input which can lead to invalid downstream URLs; change it
to return an explicit empty string for blank input by adding an early check
(e.g. if lower == "" return "") before the alias/title-case logic in
NormalizeLanguage, and apply the same explicit-empty return fix to the other
normalization helper that currently returns the raw input for blank values so
callers can validate/fail fast.
---
Outside diff comments:
In `@cmd/root.go`:
- Around line 35-43: PreRunE currently validates flags private/public and branch
but does not validate the message flag; add a TrimSpace check for the message
variable in PreRunE (alongside existing branch validation) and return an error
like "flag --message cannot be empty" when message == "" so we fail fast before
running setup steps; reference the PreRunE function and the message variable
(which is later used by internal/repo/repo.go:47 for git commit) to locate where
to add this check.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 71643828-f696-43be-9932-ae9926a32852
📒 Files selected for processing (2)
cmd/root.gointernal/files/gitignore.go
…ard empty language
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
internal/files/gitignore.go (1)
53-53: Update URL to usemaininstead ofmaster.The github/gitignore repository now uses
mainas its default branch. Hardcodingmasteris outdated; switch tomainfor consistency with the repository's current state.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/files/gitignore.go` at line 53, The URL construction currently hardcodes the branch "master" in the string assigned to the variable url (fmt.Sprintf("https://raw.githubusercontent.com/github/gitignore/master/%s.gitignore", normalized)); update that string to use "main" instead of "master" so the repository's current default branch is referenced (i.e., change "master" → "main" in the url format that uses normalized).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/files/gitignore.go`:
- Around line 68-74: The current write in the function (using os.Create(dest)
and io.Copy(f, resp.Body)) can leave a partial/corrupt .gitignore if the copy
fails; change the implementation to write atomically by creating a temporary
file in the same directory (e.g., via os.CreateTemp(dir, "gitignore-*")), copy
resp.Body into that temp file, call Sync/Close on the temp file, then atomically
rename the temp file to dest with os.Rename; update error handling to remove the
temp file on failure and ensure the existing dest is only replaced on successful
completion (adjust the code around the io.Copy/Close calls in ensureGitignore /
the function that uses resp.Body).
---
Nitpick comments:
In `@internal/files/gitignore.go`:
- Line 53: The URL construction currently hardcodes the branch "master" in the
string assigned to the variable url
(fmt.Sprintf("https://raw.githubusercontent.com/github/gitignore/master/%s.gitignore",
normalized)); update that string to use "main" instead of "master" so the
repository's current default branch is referenced (i.e., change "master" →
"main" in the url format that uses normalized).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 347d8c26-0c5a-4677-9da8-36b5cdd8c49e
📒 Files selected for processing (3)
cmd/root.gointernal/files/gitignore.gointernal/repo/repo.go
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/repo/repo.go
Closes #
📑 Description
✅ Checks
ℹ Additional Information
Summary by CodeRabbit
New Features
Behavior Changes
Chores