Expand description
§kick-rs-cli
cargo kick— companion CLI for the kick-rs framework.
§Install
cargo install kick-rs-cliThis installs a cargo-kick binary, which cargo picks up as the
kick subcommand.
§Usage
§cargo kick new <name>
Scaffolds a new kick-rs project with a working hello module:
cargo kick new my-app
cd my-app
cargo run
# server starts on 0.0.0.0:3000
curl http://localhost:3000/hello
# {"message":"Hello from kick-rs!"}Generated layout:
my-app/
├── Cargo.toml # depends on kick-rs (macros + config features)
├── README.md # quick run instructions
├── .env.example
├── .gitignore
└── src/
├── main.rs # bootstrap() + tokio runtime
└── modules/
├── mod.rs
└── hello/
├── mod.rs # define_module(...) -> Module
└── handlers.rs # greet, greet_namedFlags:
--path <PATH>— write into a different directory (defaults to./<name>).--force— write into an existing directory. Existing files inside are NOT removed.
§cargo kick g module <name>
Generates a new module skeleton inside an existing kick-rs project:
cd my-app
cargo kick g module posts
# ✓ generated module at .../my-app/src/modules/posts
# next: register it in main.rs via
# .module(modules::posts::define())Emits src/modules/<name>/{mod.rs,handlers.rs} and idempotently
appends pub mod <name>; to src/modules/mod.rs. The project root
is auto-detected by walking up from cwd until src/modules/mod.rs
is found.
Module names must be valid Rust identifiers: lowercase letters / digits / underscores, starting with a letter. Hyphens are rejected (Rust modules can’t have them).
Flags:
--path <PATH>— override project-root detection.--force— overwrite existing files inside the module directory.
§cargo kick g service <module>/<name>
Generates a #[service]-derived stub inside an existing module:
cd my-app
cargo kick g service users/email_sender
# ✓ generated service at .../src/modules/users/email_sender.rs
# next: in src/modules/users/mod.rs, add
# use email_sender::EmailSender;
# ...
# .service::<EmailSender>()Emits src/modules/<module>/<name>.rs containing a #[service]
struct (PascalCase derived from the snake_case file name) and
idempotently appends pub mod <name>; to that module’s mod.rs.
Both halves of the spec must be valid snake_case identifiers. The
parent module must already exist (use g module first).
Flags:
--path <PATH>— override project-root detection.--force— overwrite the service file if it already exists.
§cargo kick g contributor <module>/<name>
Generates a #[contributor]-derived stub inside an existing module:
cd my-app
cargo kick g contributor users/load_current_user
# ✓ generated contributor at .../src/modules/users/load_current_user.rs
# next: register on the module's define() builder (or directly on
# bootstrap()) — in src/modules/users/mod.rs add
# use load_current_user::LoadCurrentUser;
# ...
# .contribute(LoadCurrentUser)Emits src/modules/<module>/<name>.rs with a #[contributor] async
fn (PascalCase name derived from the snake_case file) and a stub
<Name>Out output struct. Idempotently appends pub mod <name>; to
the parent module’s mod.rs.
Flags:
--path <PATH>— override project-root detection.--force— overwrite the contributor file if it already exists.
§Auto-registration
By default each g subcommand also writes the wiring needed to use
the generated code:
| Generator | Edits |
|---|---|
g module | Inserts .module(modules::<name>::define()) into src/main.rs |
g service | Inserts use <name>::<Pascal>; + .service::<Pascal>() in parent mod.rs |
g contributor | Inserts use <name>::<Pascal>; + .contribute(Pascal) in parent mod.rs |
Insertion is conservative and text-level (no syn round-trip), so
formatting, comments, and blank-line layout are preserved. The
target file must use the known patterns (bootstrap() chain,
define_module(...) chain) — if not, the CLI prints the exact
snippet to paste and leaves the file untouched.
Each g subcommand accepts a --no-register flag to skip the
insertion if you’d rather wire things up yourself.
§cargo kick add <feature>
Toggle an opt-in kick-rs feature on the umbrella dep in your
project’s Cargo.toml:
cargo kick add openapi
# ✓ added `openapi` to kick-rs features in Cargo.toml
cargo kick add openapi
# · `openapi` already enabled on kick-rs
cargo kick add list
# kick-rs features that `cargo kick add` knows about:
# macros — `#[service]`, `#[contributor]`, `#[get]`/`#[post]`/...
# config — Layered env / dotenv / TOML / JSON config loader
# openapi — OpenApiPlugin + paths!() — serve /openapi.json
# devtools — /__debug introspection endpoint (also needs .with_devtools())The mutation uses toml_edit so the rest of your Cargo.toml
(comments, alignment, key order) is left untouched. A bare
kick-rs = "0.1" is promoted to the inline-table form
kick-rs = { version = "0.1", features = ["..."] } so the
features array has a place to live.
Flags:
--path <PATH>— override project-root detection.--dep-name <NAME>— mutate a differently-named dep (rare; defaults tokick-rs).
§cargo kick info
Print a snapshot of the current kick-rs project — package version,
the kick-rs dep version + enabled features, and every module on
disk with the services and contributors registered on each:
$ cargo kick info
kick-rs project: my-app 0.1.0
root: /path/to/my-app
kick-rs dep: 0.1.0
features: macros, config, openapi
modules (2):
- hello (prefix /hello)
- posts (prefix /posts)
services: PostService
contributors: LoadPostModule detail is parsed from the same define_module(...),
.prefix(...), .service::<...>(), .contribute(...) patterns
the scaffold + generators emit. Custom builder wrappers fall back to
a directory-name-only entry.
Flags:
--path <PATH>— override project-root detection.--dep-name <NAME>— inspect a renamed dep (defaults tokick-rs).
§cargo kick dev
Watch the project’s source tree and restart cargo run on save:
cargo kick dev
# cargo kick dev — starting initial run in `/path/to/my-app`
# watching /path/to/my-app/src
# Ctrl-C to quit.
#
# <cargo's normal output — compile, run, stdout/stderr of your app>
#
# (touch src/main.rs)
#
# cargo kick dev — change detected; restartingFiles trigger a restart when they match Rust source / TOML / common
template extensions, and aren’t inside target/, .git/,
node_modules/, or any editor temp file (~-suffixed). Events are
debounced 250ms (configurable) so editor save storms produce one
restart, not N.
Flags:
--path <PATH>— override project-root detection.--watch <DIR>— extra directories to watch (repeatable; useful fortemplates/,static/, etc).--debounce-ms <MS>— debounce window, default250.
Process-tree cleanup: cargo spawns the built binary as its
grandchild. kick dev puts cargo in its own process group on
spawn (Unix setpgid / Windows CREATE_NEW_PROCESS_GROUP) and
sends the kill signal to the whole group on restart (kill -KILL -<pgid> on Unix, taskkill /F /T /PID on Windows) so the bound
port releases immediately. No extra deps — both platforms use the
OS’s bundled kill utility.
§cargo kick check
Lint a kick-rs project for common misconfigurations the compiler doesn’t catch. Useful as a CI gate after running generators.
cargo kick check
# kick-rs check: ✓ clean
# (exit 0)
# … or, when something's wrong:
# kick-rs check: 1 finding(s)
#
# [RK_K_UNMOUNTED_MODULE] module `orphan` is declared in src/modules/mod.rs
# but not mounted in src/main.rs (expected `.module(modules::orphan::define())`)
# → /path/to/my-app/src/main.rs
# (exit 1)Lints today:
| Code | What it catches |
|---|---|
RK_K_UNMOUNTED_MODULE | pub mod X; exists but main.rs doesn’t call .module(modules::X::define()) |
RK_K_STALE_PUB_MOD | pub mod X; whose src/modules/X/ directory (or .rs file) doesn’t exist |
RK_K_UNREGISTERED_SERVICE | #[service] pub struct Foo in a file but no .service::<Foo>() in parent mod.rs |
RK_K_UNREGISTERED_CONTRIBUTOR | #[contributor] pub async fn Foo in a file but no .contribute(Foo) in parent mod.rs |
Pure-text scanners — no cargo check invocation, no syn parse.
Recognizes the shapes the scaffold + cargo kick g produce; exotic
hand-written wiring may slip through.
Flags:
--path <PATH>— override project-root detection.
§Status
new, g module, g service, g contributor, add, info,
dev, check today. Everything from the SPEC’s CLI surface is
shipped.
§License
MIT — see the workspace root.
Modules§
- add
cargo kick add <feature>— toggle an opt-inkick-rsfeature in the project’s Cargo.toml.- check
cargo kick check— lint an existing kick-rs project for common misconfigurations the compiler doesn’t catch.- dev
cargo kick dev— watch the project’s source tree and restart the app on save.- generate
cargo kick g— codegen into an existing kick-rs project.- info
cargo kick info— print a snapshot of the current kick-rs project.- new
cargo kick new— scaffold a new kick-rs project.- register
- Conservative text-level edits to wire generated code into the existing builder chains.
- templates
- Compile-time-embedded starter templates for
cargo kick new.