main() is one call into internal/cli (closes #160) #178

Merged
clawbot merged 1 commits from issue-160-cli-package into next 2026-10-19 07:53:10 +02:00
Collaborator

main() in cmd/netwatch-server/main.go is now os.Exit(cli.Main(os.Stderr, Appname, Version, os.Args[1:], cli.RunServer)), as CODE_STYLEGUIDE_GO.md and REPO_POLICIES.md ask of cmd/ (#160).

The new package internal/cli, whose doc comment says it runs netwatch-server from its command line, runs the check-cidr and prepare-data-dir subcommands with the same arguments, messages and exit codes bin/entrypoint.sh relies on, and otherwise the server, with the fx wiring moved unchanged from main. No existing package's doc covers this work, hence a new one. Appname and Version stay in main, where the build sets Version with -X main.Version.

What the diff does not show:

  • Main takes the command line after the program's name, so the checks read len(args) == 2 && args[0] == ... where they read len(os.Args) == 3 && os.Args[1] == ....
  • Main takes the writer for errors and the function that runs the server; the tests that call Main give it a buffer and a function that fails them, so no test starts the server.
  • The function behind prepare-data-dir also takes the volume and the user's name, which Main gives as /data and netwatch. The subcommands' own tests reach them through export_test.go, with a temporary directory and the user the test runs as.

Partially verified: the test image has no netwatch user, so the test of Main with prepare-data-dir /etc checks for the error from looking up netwatch; the path check is tested on prepareDataDir.

Judgement call: the server keeps fx's Run, which exits the process with status 1 itself when the start, the listener or the stop fails; Main returns 0 once Run returns.

Model: opus-5-5

`main()` in `cmd/netwatch-server/main.go` is now `os.Exit(cli.Main(os.Stderr, Appname, Version, os.Args[1:], cli.RunServer))`, as `CODE_STYLEGUIDE_GO.md` and `REPO_POLICIES.md` ask of `cmd/` (https://git.eeqj.de/sneak/netwatch/issues/160). The new package `internal/cli`, whose doc comment says it runs `netwatch-server` from its command line, runs the `check-cidr` and `prepare-data-dir` subcommands with the same arguments, messages and exit codes `bin/entrypoint.sh` relies on, and otherwise the server, with the `fx` wiring moved unchanged from `main`. No existing package's doc covers this work, hence a new one. `Appname` and `Version` stay in `main`, where the build sets `Version` with `-X main.Version`. What the diff does not show: - `Main` takes the command line after the program's name, so the checks read `len(args) == 2 && args[0] == ...` where they read `len(os.Args) == 3 && os.Args[1] == ...`. - `Main` takes the writer for errors and the function that runs the server; the tests that call `Main` give it a buffer and a function that fails them, so no test starts the server. - The function behind `prepare-data-dir` also takes the volume and the user's name, which `Main` gives as `/data` and `netwatch`. The subcommands' own tests reach them through `export_test.go`, with a temporary directory and the user the test runs as. Partially verified: the test image has no `netwatch` user, so the test of `Main` with `prepare-data-dir /etc` checks for the error from looking up `netwatch`; the path check is tested on `prepareDataDir`. Judgement call: the server keeps fx's `Run`, which exits the process with status 1 itself when the start, the listener or the stop fails; `Main` returns 0 once `Run` returns. Model: opus-5-5
clawbot added the needs-review label 2026-10-19 06:21:29 +02:00
clawbot self-assigned this 2026-10-19 06:21:29 +02:00
Author
Collaborator
  1. internal/cli/cli_test.go: no test runs Main, so the argument checks and the choice of subcommand moved out of main (internal/cli/cli.go lines 33 and 41) are untested; a mistake there, such as netwatch-server check-cidr 10.0.0.0/8 starting the server, would leave every test passing. #160 asks for a test of each subcommand's accepted and refused input, and the TODO.md entry says the unit tests give each subcommand its input; they give it to the functions behind the subcommands instead. Acceptable: tests that call cli.Main with check-cidr and an accepted and a refused CIDR, and with prepare-data-dir and a path outside /data, and check the exit code each returns.
  2. internal/cli/cli.go lines 26 to 28: the doc comment says Main returns the exit code, but when the server fails to start or to stop, fx's Run exits the process with status 1 and Main never returns. Acceptable: the doc comment says so, as the one on runServer does.
  3. README.md line 210: netwatch-server is written without backticks, where the rest of README.md writes it as netwatch-server. Acceptable: backticks.

Model: opus-5-5

1. `internal/cli/cli_test.go`: no test runs `Main`, so the argument checks and the choice of subcommand moved out of `main` (`internal/cli/cli.go` lines 33 and 41) are untested; a mistake there, such as `netwatch-server check-cidr 10.0.0.0/8` starting the server, would leave every test passing. https://git.eeqj.de/sneak/netwatch/issues/160 asks for a test of each subcommand's accepted and refused input, and the `TODO.md` entry says the unit tests give each subcommand its input; they give it to the functions behind the subcommands instead. Acceptable: tests that call `cli.Main` with `check-cidr` and an accepted and a refused CIDR, and with `prepare-data-dir` and a path outside `/data`, and check the exit code each returns. 2. `internal/cli/cli.go` lines 26 to 28: the doc comment says `Main` returns the exit code, but when the server fails to start or to stop, fx's `Run` exits the process with status 1 and `Main` never returns. Acceptable: the doc comment says so, as the one on `runServer` does. 3. `README.md` line 210: `netwatch-server` is written without backticks, where the rest of `README.md` writes it as `netwatch-server`. Acceptable: backticks. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 06:40:51 +02:00
clawbot force-pushed issue-160-cli-package from 1a7966b97a to 84213bf29f 2026-10-19 06:49:25 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-19 06:49:50 +02:00
Author
Collaborator
  1. TestMainRunsCheckCIDR and TestMainRunsPrepareDataDir call cli.Main and check the exit code; Main now takes the function that runs the server (cli.RunServer from main) and the tests pass one that fails them, so a break in the dispatch fails a test without starting the server. The test image has no netwatch user, so there prepare-data-dir /etc exits 1 at the user lookup; the path check stays tested on prepareDataDir.
  2. Done: Main's doc comment says that when the server fails to start or to stop, fx's Run exits the process with status 1 and Main never returns.
  3. Done.

Model: opus-5-5

1. `TestMainRunsCheckCIDR` and `TestMainRunsPrepareDataDir` call `cli.Main` and check the exit code; `Main` now takes the function that runs the server (`cli.RunServer` from `main`) and the tests pass one that fails them, so a break in the dispatch fails a test without starting the server. The test image has no `netwatch` user, so there `prepare-data-dir /etc` exits 1 at the user lookup; the path check stays tested on `prepareDataDir`. 2. Done: `Main`'s doc comment says that when the server fails to start or to stop, fx's `Run` exits the process with status 1 and `Main` never returns. 3. Done. Model: opus-5-5
Author
Collaborator
  1. internal/cli/cli_test.go lines 31 to 43, TestMainRunsPrepareDataDir: the test passes as long as Main returns 1 for prepare-data-dir /etc without starting the server, whatever it runs. If Main ran the check-cidr code for prepare-data-dir, or looked up a user other than netwatch, every test would still pass, and the image would never start. That leaves the choice of subcommand untested for prepare-data-dir, which is the gap the earlier review's first finding was about. Acceptable: a test of cli.Main with prepare-data-dir that fails when Main runs anything other than the prepare-data-dir code for user netwatch. For example, the test can check what Main writes for /etc; Main can take the writer, as the subcommands do.
  2. Comments that still say the tests build the application the way main does, although since this change cli.RunServer does it: internal/config/config_test.go lines 16 and 34 (requireConfigError, requireTrustedProxies); internal/reportbuf/reportbuf_test.go startApp, startBuffer and startBufferWithHandlers ("through fx, as main does"); and internal/server/routes_test.go line 25 (newServer, "the same constructors as main", but main lists none now). Acceptable: they name cli.RunServer, as the comment in internal/globals/globals.go now does.

Model: opus-5-5

1. `internal/cli/cli_test.go` lines 31 to 43, `TestMainRunsPrepareDataDir`: the test passes as long as `Main` returns 1 for `prepare-data-dir /etc` without starting the server, whatever it runs. If `Main` ran the `check-cidr` code for `prepare-data-dir`, or looked up a user other than `netwatch`, every test would still pass, and the image would never start. That leaves the choice of subcommand untested for `prepare-data-dir`, which is the gap the earlier review's first finding was about. Acceptable: a test of `cli.Main` with `prepare-data-dir` that fails when `Main` runs anything other than the `prepare-data-dir` code for user `netwatch`. For example, the test can check what `Main` writes for `/etc`; `Main` can take the writer, as the subcommands do. 2. Comments that still say the tests build the application the way `main` does, although since this change `cli.RunServer` does it: `internal/config/config_test.go` lines 16 and 34 (`requireConfigError`, `requireTrustedProxies`); `internal/reportbuf/reportbuf_test.go` `startApp`, `startBuffer` and `startBufferWithHandlers` ("through fx, as main does"); and `internal/server/routes_test.go` line 25 (`newServer`, "the same constructors as main", but `main` lists none now). Acceptable: they name `cli.RunServer`, as the comment in `internal/globals/globals.go` now does. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 07:01:25 +02:00
clawbot force-pushed issue-160-cli-package from 84213bf29f to 703e3e7c6e 2026-10-19 07:09:23 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-19 07:09:44 +02:00
Author
Collaborator
  1. Main now takes the writer for errors, and TestMainRunsPrepareDataDir checks that prepare-data-dir /etc exits 1 writing exactly the error from looking up netwatch; running the check-cidr code or looking up root in its place each made it fail, and both were reverted.
  2. Done: those comments in internal/config/config_test.go, internal/reportbuf/reportbuf_test.go and internal/server/routes_test.go now name cli.RunServer; no other comment said it.

Model: opus-5-5

1. `Main` now takes the writer for errors, and `TestMainRunsPrepareDataDir` checks that `prepare-data-dir /etc` exits 1 writing exactly the error from looking up `netwatch`; running the `check-cidr` code or looking up `root` in its place each made it fail, and both were reverted. 2. Done: those comments in `internal/config/config_test.go`, `internal/reportbuf/reportbuf_test.go` and `internal/server/routes_test.go` now name `cli.RunServer`; no other comment said it. Model: opus-5-5
Author
Collaborator
  1. The doc comment on Main (internal/cli/cli.go lines 30 to 32), the TODO.md entry, the commit message and the PR body each say the tests give Main a buffer for stderr. TestMainRunsCheckCIDR (internal/cli/cli_test.go line 24) gives it io.Discard. Acceptable: TestMainRunsCheckCIDR gives Main a buffer too, or those sentences say what the tests actually pass.

Model: opus-5-5

1. The doc comment on `Main` (`internal/cli/cli.go` lines 30 to 32), the `TODO.md` entry, the commit message and the PR body each say the tests give `Main` a buffer for stderr. `TestMainRunsCheckCIDR` (`internal/cli/cli_test.go` line 24) gives it `io.Discard`. Acceptable: `TestMainRunsCheckCIDR` gives `Main` a buffer too, or those sentences say what the tests actually pass. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 07:32:26 +02:00
clawbot force-pushed issue-160-cli-package from 703e3e7c6e to 91be54d328 2026-10-19 07:40:00 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-19 07:40:13 +02:00
Author
Collaborator
  1. Done: TestMainRunsCheckCIDR gives Main a buffer and checks that 10.0.0.0/8 writes nothing and 1.2.3/32 writes an error starting TRUSTED_PROXIES "1.2.3/32": .

Judgement call: on re-reading, the doc comments on Main and RunServer and the PR body now also name a failed listener, since internal/server/http.go then asks fx to stop with exit code 1; the commit message and PR body say the function behind prepare-data-dir, not the subcommand, takes the volume and the user's name.

Model: opus-5-5

1. Done: `TestMainRunsCheckCIDR` gives `Main` a buffer and checks that `10.0.0.0/8` writes nothing and `1.2.3/32` writes an error starting `TRUSTED_PROXIES "1.2.3/32": `. Judgement call: on re-reading, the doc comments on `Main` and `RunServer` and the PR body now also name a failed listener, since `internal/server/http.go` then asks fx to stop with exit code 1; the commit message and PR body say the function behind `prepare-data-dir`, not the subcommand, takes the volume and the user's name. Model: opus-5-5
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot added 1 commit 2026-10-19 07:52:23 +02:00
cmd/netwatch-server/main.go parsed the command line, ran the check-cidr
and prepare-data-dir subcommands and built the fx application itself;
the Go style guide puts all of that in internal/ or pkg/. The new
package internal/cli does it, with the same arguments, messages and
exit codes. main() is now os.Exit(cli.Main(os.Stderr, Appname, Version,
os.Args[1:], cli.RunServer)): Main takes the writer for errors and the
function that runs the server, so its tests give it a buffer and a
function that fails them. Appname and Version stay in main, where the
build sets Version. The function behind prepare-data-dir also takes the
volume and the user's name, so its own tests give it a temporary
directory and the user they run as.

Model: opus-5-5
clawbot force-pushed issue-160-cli-package from 91be54d328 to bd157ac970 2026-10-19 07:52:23 +02:00 Compare
clawbot merged commit 7a3c706fe6 into next 2026-10-19 07:53:10 +02:00
clawbot deleted branch issue-160-cli-package 2026-10-19 07:53:10 +02:00
clawbot removed the needs-review label 2026-10-19 07:53:10 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#178