refactor: one file per command and per MCP tool; flatten internal/tiger - #179
Conversation
There was a problem hiding this comment.
Only really looked at the CLI part but that generally looks good to me 👍
I just wonder if we can clear up a bit where the shared helpers actually lie I find it a bit confusing that e.g. checkStdinIsTTY and readPasswordFromTerminal are still in db.go.
I asked claude about other unclear cases and it suggested a rule set like this:
Claude output
- Used by one command → that command's file.
- Used by several commands in one group → the group file (
db.go,service.go). - Used across groups, must stay in
package cmd(test-override vars, cobra types) → a named package-level file:completion.go,flag.go, or a newterminal.go. - Used across groups, no dependency on
cmd→internal/utilorinternal/common. - Used by both CLI and MCP →
internal/common(already the documented rule; this just makes it the same rule rather than a separate one).
Claude Stop
And it says these functions would have to be moved then:
Claude output
checkStdinIsTTY,readPasswordFromTerminal— indb.go, used byservice_update_password.go,read_replica.go,password_recovery.go→ rule 3, newterminal.go, joined byreadString(currently squatting inroot.go).generateSecurePassword— indb.go, nothing db-specific, used by theservice update-password --auto-generatepath → rule 4,internal/util.serviceIDCompletion— inservice.go, used by both groups → rule 3,completion.go, which exists for exactly this.updateNumberBuffer— inoauth.go, borrowed bymcp_install.go→ rule 3, alongside the other shared TUI bits.password_recovery.go— currently two flows in one file. The rotation trio (promptAndResetPassword→resetServicePassword→updateAndSaveServicePassword) is the genuinely shared kernel and is duplicated ininternal/mcp/service_update_password.go→ rule 5,internal/common. Everything else (bubbletea menu,testConnectionWithPassword,isAuthenticationError,testSaveAndLaunchPsqlWithPassword) is reachable only fromdb connect→ rule 1, fold intodb_connect.go, which also resolves the currentpassword_recovery.go→launchPsqlback-reference. File stops existing.
This seems sensible to me, but curious what you think? Not sure if we want to fold it in here if you agree.
Also:
Claude output
- CLAUDE.md:480 and :994 still say .goreleaser.yml; this PR renamed it to .goreleaser.yaml.
- docs/CODE_REVIEW.md (11 refs) and docs/DECISIONS.md:45 still point at internal/tiger/…. Point-in-time artifacts, so arguably delete rather than fix — but they're the only stale paths left in the repo.
|
Yes, totally agree that we could (and should) go further with the restructuring. This was just kind of intended to be a big initial push in the right direction, with hopefully more smaller (and easier to review) PRs to follow 🤞. |
Pure file/package reorganization to make the repo easier to navigate. Three changes:
Moved everything from
internal/tiger/up intointernal/. The extra level of hierarchy wasn't buying us anything.Split the CLI command files so each command gets its own file in
internal/cmd/, named to match the command in snake_case (tiger service create→service_create.go).service.gowas 2000+ lines anddb.goandmcp.goweren't far behind. Group commands keep their own file and hold the helpers shared across their subcommands. Test files follow the same layout, with package-wide test scaffolding inmain_test.go.Split the MCP tool files the same way — one file per tool, each laid out as input/output schemas, then a
new*Tool()constructor, then the handler. Tool registration moved intoserver.go, so adding a tool is one new file plus oneaddToolline.No behavior changes. The only code that isn't a straight move is the MCP tool registration: the inline
&mcp.Tool{...}literals becamenew*Tool()functions, andregisterServiceTools/registerDatabaseToolsare now just lists ofaddToolcalls. Everything else is byte-identical to before, verified by diffing every top-level declaration's source text against main.CLAUDE.md and docs/development.md are updated to describe the new conventions.