Skip to content

refactor: make cli modular#390

Merged
steveiliop56 merged 4 commits intomainfrom
refactor/cli
Oct 6, 2025
Merged

refactor: make cli modular#390
steveiliop56 merged 4 commits intomainfrom
refactor/cli

Conversation

@steveiliop56
Copy link
Copy Markdown
Member

@steveiliop56 steveiliop56 commented Oct 6, 2025

Summary by CodeRabbit

  • New Features
    • Added CLI commands for creating users, generating TOTP (with QR output), and verifying users — each supports interactive flows and flag-based input.
  • Refactor
    • CLI startup and command registration reworked; program now uses a consolidated Run entry path.
  • Revert/Removal
    • Legacy nested user/totp command entrypoints and old exported command variables removed.
  • Other
    • Version output behavior remains unchanged.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 6, 2025

Warning

Rate limit exceeded

@steveiliop56 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fa62ba2 and e1dcbda.

📒 Files selected for processing (1)
  • cmd/verify.go (1 hunks)

Walkthrough

Reworks CLI orchestration to a struct-based rootCmd with a Run entrypoint, adds top-level create/verify/generate commands, replaces the version command with a struct wrapper, and removes legacy nested user and totp subcommand packages and their exported command variables.

Changes

Cohort / File(s) Summary
Root CLI refactor
cmd/root.go, main.go, cmd/version.go
Replaced global init-style wiring with a rootCmd struct; added Register(), GetCmd(), and Run() flows; main.go now calls cmd.Run(); version command reimplemented as versionCmd with Register()/GetCmd() and run.
New top-level commands
cmd/create.go, cmd/verify.go, cmd/generate.go
Added top-level create, verify, and generate commands supporting interactive and flag modes, bcrypt hashing/verification, TOTP generation/validation, Docker escaping behavior, and zerolog logging.
Removed legacy nested commands
cmd/user/user.go, cmd/user/create/create.go, cmd/user/verify/verify.go, cmd/totp/totp.go, cmd/totp/generate/generate.go
Deleted legacy user and totp package command files, removing exported *cobra.Command variables and their init-time flag registrations and run logic.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant OS as OS
  participant Main as main.go
  participant Root as rootCmd.Run()
  participant Viper as Viper
  participant Cobra as Cobra
  participant Sub as Subcommand.Register()

  OS->>Main: start
  Main->>Root: Run()
  activate Root
  Root->>Viper: instantiate/load config, bind env
  Root->>Cobra: build root cobra.Command
  Root->>Sub: Register() each subcommand (create/verify/generate/version)
  Sub-->>Root: attach subcommands
  Root->>Cobra: Execute()
  deactivate Root
Loading
sequenceDiagram
  autonumber
  participant User as Operator
  participant CLI as create command
  participant Form as huh form (optional)
  participant Bcrypt as bcrypt
  participant Log as zerolog

  User->>CLI: invoke create (flags or -i)
  alt interactive
    CLI->>Form: prompt username/password/docker
    Form-->>CLI: inputs
  end
  CLI->>CLI: validate username/password
  CLI->>Bcrypt: GenerateFromPassword(password)
  Bcrypt-->>CLI: hash / error
  alt docker output
    CLI->>CLI: escape `$` in hash
  end
  CLI->>Log: emit created user info
Loading
sequenceDiagram
  autonumber
  participant User as Operator
  participant CLI as verify command
  participant Parse as utils.ParseUser
  participant Bcrypt as bcrypt
  participant TOTP as totp validation
  participant Log as zerolog

  User->>CLI: invoke verify (flags or -i)
  alt interactive
    CLI->>CLI: collect inputs
  end
  CLI->>Parse: ParseUser(userString)
  Parse-->>CLI: {username, hash, totpSecret}
  CLI->>CLI: compare usernames
  CLI->>Bcrypt: CompareHashAndPassword(hash, password)
  Bcrypt-->>CLI: ok / fail
  alt totpSecret present
    CLI->>TOTP: validate(code, secret)
    TOTP-->>CLI: ok / fail
  end
  CLI->>Log: emit verification result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

I tap my paws on keys so bright,
New roots sprout commands in tidy light.
Old burrows closed, new tunnels clear,
Create, verify, and TOTP appear.
With hashes, codes, and version cheer — I thump and ship without a fear. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “refactor: make cli modular” accurately captures the core change of this pull request, which restructures the CLI into separate modular commands and refactors the root command handling.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Oct 6, 2025

Codecov Report

❌ Patch coverage is 0% with 299 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.66%. Comparing base (30fe695) to head (e1dcbda).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cmd/generate.go 0.00% 78 Missing ⚠️
cmd/verify.go 0.00% 72 Missing ⚠️
cmd/root.go 0.00% 70 Missing ⚠️
cmd/create.go 0.00% 57 Missing ⚠️
cmd/version.go 0.00% 21 Missing ⚠️
main.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #390      +/-   ##
==========================================
- Coverage   25.43%   24.66%   -0.78%     
==========================================
  Files          36       34       -2     
  Lines        2587     2668      +81     
==========================================
  Hits          658      658              
- Misses       1893     1974      +81     
  Partials       36       36              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread cmd/create.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
cmd/root.go (1)

128-137: Consider consistent command creation pattern.

The userCmd and totpCmd are created inline with plain &cobra.Command{} literals, while the root command uses a structured type with newRootCmd(). This is functionally correct (these are simple parent commands without run logic), but for consistency you might consider:

-	userCmd := &cobra.Command{
-		Use:   "user",
-		Short: "User utilities",
-		Long:  `Utilities for creating and verifying tinyauth compatible users.`,
-	}
-	totpCmd := &cobra.Command{
-		Use:   "totp",
-		Short: "Totp utilities",
-		Long:  `Utilities for creating and verifying totp codes.`,
-	}
+	userCmd := newUserCmd()
+	totpCmd := newTotpCmd()

This would require adding simple wrapper functions, but it unifies the pattern and makes future extensions (e.g., adding a run function to these commands) easier.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30fe695 and 74a3603.

📒 Files selected for processing (11)
  • cmd/create.go (1 hunks)
  • cmd/generate.go (1 hunks)
  • cmd/root.go (2 hunks)
  • cmd/totp/generate/generate.go (0 hunks)
  • cmd/totp/totp.go (0 hunks)
  • cmd/user/create/create.go (0 hunks)
  • cmd/user/user.go (0 hunks)
  • cmd/user/verify/verify.go (0 hunks)
  • cmd/verify.go (1 hunks)
  • cmd/version.go (1 hunks)
  • main.go (1 hunks)
💤 Files with no reviewable changes (5)
  • cmd/user/verify/verify.go
  • cmd/totp/totp.go
  • cmd/user/user.go
  • cmd/user/create/create.go
  • cmd/totp/generate/generate.go
🧰 Additional context used
🧬 Code graph analysis (6)
cmd/version.go (2)
cmd/root.go (1)
  • Run (123-152)
internal/config/config.go (3)
  • Version (5-5)
  • CommitHash (6-6)
  • BuildTimestamp (7-7)
cmd/verify.go (2)
cmd/root.go (1)
  • Run (123-152)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
cmd/root.go (3)
internal/config/config.go (2)
  • Config (17-44)
  • Version (5-5)
internal/utils/app_utils.go (1)
  • GetLogLevel (116-135)
internal/bootstrap/app_bootstrap.go (1)
  • NewBootstrapApp (40-44)
cmd/create.go (1)
cmd/root.go (1)
  • Run (123-152)
cmd/generate.go (2)
cmd/root.go (1)
  • Run (123-152)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
main.go (1)
cmd/root.go (1)
  • Run (123-152)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
cmd/root.go (1)

98-121: LGTM!

The config loading, validation, and bootstrap logic is well-structured. Error handling with log.Fatal() is appropriate for a CLI application.

Comment thread cmd/create.go Outdated
Comment thread cmd/root.go
Comment thread cmd/root.go Outdated
Comment thread cmd/verify.go Outdated
Co-authored-by: Ryc O'Chet <Rycochet@users.noreply.github.com>
Comment thread cmd/verify.go
Comment on lines +62 to +79
huh.NewInput().Title("User (username:hash:totp)").Value(&c.user).Validate((func(s string) error {
if s == "" {
return errors.New("user cannot be empty")
}
return nil
})),
huh.NewInput().Title("Username").Value(&c.username).Validate((func(s string) error {
if s == "" {
return errors.New("username cannot be empty")
}
return nil
})),
huh.NewInput().Title("Password").Value(&c.password).Validate((func(s string) error {
if s == "" {
return errors.New("password cannot be empty")
}
return nil
})),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the user as in user1:foo, the username is the user1 and the password is your password in plain text.

Comment thread cmd/create.go Outdated
Comment thread cmd/root.go
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
cmd/root.go (1)

16-21: Remove unused root field and dead conditional.

root *cobra.Command is never initialized; Lines 89-91 never run. Drop both for clarity.

 type rootCmd struct {
-	root *cobra.Command
 	cmd  *cobra.Command
 
 	viper *viper.Viper
 }
@@
-	if c.root != nil {
-		c.root.AddCommand(c.cmd)
-	}

Also applies to: 89-91

🧹 Nitpick comments (5)
cmd/root.go (5)

84-85: Handle Viper binding errors.

Binding env and flags can fail; fail fast with context.

-		c.viper.BindEnv(opt.name, envVar)
+		if err := c.viper.BindEnv(opt.name, envVar); err != nil {
+			log.Fatal().Err(err).Str("key", opt.name).Str("env", envVar).Msg("Failed to bind env var")
+		}
@@
-	c.viper.BindPFlags(c.cmd.Flags())
+	if err := c.viper.BindPFlags(c.cmd.Flags()); err != nil {
+		log.Fatal().Err(err).Msg("Failed to bind flags")
+	}

Also applies to: 87-87


30-35: Silence Cobra’s usage/errors on runtime failures.

Prevents duplicate help/error output on failures; keeps logs clean.

 	c.cmd = &cobra.Command{
 		Use:   "tinyauth",
 		Short: "The simplest way to protect your apps with a login screen",
 		Long:  `Tinyauth is a simple authentication middleware that adds a simple login screen or OAuth with Google, Github or any other provider to all of your docker apps.`,
 		Run:   c.run,
+		SilenceUsage:  true,
+		SilenceErrors: true,
 	}

37-38: Avoid redundant env strategies or add a key replacer.

You currently use both AutomaticEnv and per‑key BindEnv. Consider one:

  • Keep BindEnv per key and drop AutomaticEnv, or
  • Drop per‑key BindEnv and add a key replacer so AutomaticEnv maps dashes to underscores:
c.viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
c.viper.AutomaticEnv()

Either choice reduces duplication and surprise.

Also applies to: 82-85


112-114: Set zerolog global level and avoid redundant cast.

Ensure all loggers respect the level, not only log.Logger.

-	log.Logger = log.Level(zerolog.Level(utils.GetLogLevel(conf.LogLevel)))
+	level := utils.GetLogLevel(conf.LogLevel)
+	zerolog.SetGlobalLevel(level)
+	log.Logger = log.Level(level)

134-136: Capitalize TOTP in help strings.

Minor UX polish.

 	totpCmd := &cobra.Command{
 		Use:   "totp",
-		Short: "Totp utilities",
-		Long:  `Utilities for creating and verifying totp codes.`,
+		Short: "TOTP utilities",
+		Long:  `Utilities for creating and verifying TOTP codes.`,
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74a3603 and 04b075c.

📒 Files selected for processing (1)
  • cmd/root.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
cmd/root.go (3)
internal/config/config.go (2)
  • Config (17-44)
  • Version (5-5)
internal/utils/app_utils.go (1)
  • GetLogLevel (116-135)
internal/bootstrap/app_bootstrap.go (1)
  • NewBootstrapApp (40-44)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
cmd/root.go (1)

106-110: ip4_addr tag is supported by validator/v10
go-playground/validator v10 includes both ipv4 (simple format) and ip4_addr (resolvable endpoint) validators, so your use of ip4_addr is valid.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
cmd/create.go (1)

85-85: Password logging issue has been resolved.

The previous concern about logging the plaintext password has been addressed. The log line now only includes the username, which is appropriate.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04b075c and fa62ba2.

📒 Files selected for processing (2)
  • cmd/create.go (1 hunks)
  • cmd/verify.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
cmd/verify.go (2)
cmd/root.go (1)
  • Run (123-152)
internal/utils/user_utils.go (1)
  • ParseUser (63-92)
cmd/create.go (1)
cmd/root.go (1)
  • Run (123-152)

Comment thread cmd/verify.go Outdated
@steveiliop56 steveiliop56 merged commit 2f8fa39 into main Oct 6, 2025
8 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Oct 29, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Dec 21, 2025
@Rycochet Rycochet deleted the refactor/cli branch April 1, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants