feat: add distributed service scaffold commands#55
Conversation
|
Warning Review limit reached
More reviews will be available in 9 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds a new top-level ChangesService Command Feature
Sequence DiagramsequenceDiagram
participant CLI as CLI
participant Harness as ManifestHarness
participant Cargo as Cargo(subprocess)
participant Distributed as LocalDistributedCrate
CLI->>Harness: prepare harness options (target, entrypoint, mode)
Harness->>Distributed: resolve local distributed crate path
Harness->>Cargo: write temp workspace + main.rs and run `cargo run --manifest-path`
Cargo->>Harness: stdout JSON manifest or SQL schema
Harness->>CLI: return parsed manifest JSON or written SQL output
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
c90f90f to
6d7ba4e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/commands/service/mod.rs`:
- Around line 547-567: ScaffoldNames::new must reject inputs that produce
invalid Rust identifiers: after computing package_name, crate_ident
(package_name.replace('-', "_")) and model_struct
(to_pascal_case(&package_name)), call the existing is_rust_ident helper to
validate both crate_ident and model_struct (and view_struct if you want) and
return an Err if any are invalid; update the function (ScaffoldNames::new) to
perform these checks before constructing Self and include a clear error message,
referencing the symbols package_name, crate_ident, model_struct, view_struct,
and the is_rust_ident helper so generated scaffolds won't produce identifiers
starting with digits or otherwise invalid Rust names.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a86c273d-0559-4f8f-8cf1-d000bdbc844c
📒 Files selected for processing (4)
README.mdsrc/commands/mod.rssrc/commands/service/mod.rssrc/main.rs
5a55335 to
de56772
Compare
Implements [[tasks/hops-service-create-microsvc-scaffold]]. Updates [[customize-hops-service-scaffold-and-schema-output]]. Updates [[gitops-knative-service-scaffold]]. Updates [[replace-model-booleans-with-repeatable-model]]. Updates [[add-service-bus-flag]]. Updates [[make-service-read-models-opt-in]]. Updates [[rename-service-create-to-scaffold]]. Updates [[add-service-scaffold-github-workflows]].
de56772 to
8bdd30d
Compare
Replace the ~2100-line in-CLI generation logic (ScaffoldNames/ModelScaffold/ MessageHandler, all the *_rs / *_yaml templates, Knative broker/trigger inference, GitHub workflow rendering) with a thin adapter over the new distributed_tooling crate. The CLI now: - keeps the clap surface (ScaffoldArgs + Framework/Transport/Store/Bus/ GitopsPromote enums) and maps it to distributed_tooling::ServiceScaffoldSpec via From impls; - computes output_dir + the relative distributed dependency path as before; - calls generate_service_scaffold(), writes each GeneratedFile (creating parents, honoring FileMode::Executable), prints warnings, and runs the EnsureGithubRepository post-create action via the existing gh logic; - keeps describe/schema and the manifest compile-harness unchanged. Generation rules now live in (and are tested by) distributed_tooling. Verified byte-for-byte identical output against the previous implementation across five variants (HTTP, model+read-models, Knative+bus+gitops+promote, full GitHub, and preview-only) — the only intended difference is the generated service.rs builder (Service::new().with_repo(repo)). Dependency uses the meta-repo sibling path (../distributed/distributed_tooling); a git dependency will replace it for released/standalone builds. cli mod.rs: 2589 -> 930 lines. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The `../distributed/distributed_tooling` path dep only resolves in the meta-repo sibling layout; standalone hops-cli CI checks out only this repo, so the build failed reading the missing Cargo.toml. distributed is public, so a plain HTTPS git dep resolves with no secrets. Tracks the PR #53 branch until the crate is published to crates.io. Co-Authored-By: Claude Opus 4.8 <[email protected]>
distributed v1.5.0 published distributed_tooling, so drop the temporary git-branch dependency in favor of the registry version. No git source or secrets needed; the crate only pulls in serde_json. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Summary
hops service scaffoldfor Distributed microsvc crates with handler/service/manifest modules;service createremains a hidden compatibility alias--model <name>for aggregate generation; no--modelflags generate stateless handlers and nosrc/modelsmodulesrc/models/todo.rs, withsrc/models/mod.rsas the index/re-export plus sharedCommandInput--read-models; default scaffolds do not generatesrc/read_models, do not register tables, andservice schemaemits no read-model SQL--commandand repeatable--event--transport knativeplus--knative; generated Knative services use Distributed's CloudEvents ingress and manifest transportknative--transportfor ingress shape (http/knative) and add--bus rabbitmq|kafka|psql|natsfor bus backend selection--gitopsto scaffold a Helm deploy chart under.gitops/deploy--gitops-promote argo|fluxto scaffold.gitops/promotewith an Argo CDApplicationor FluxGitRepository/HelmReleasepointed at.gitops/deploy--github <owner/repo>to configure release automation and create the target GitHub repo viagh repo create <owner/repo> --privatewhen it does not already exist--githubgenerates.github/workflows/version.yamlusingunbounded-tech/workflow-vnext-tagand.github/workflows/release.yamlusingunbounded-tech/workflow-simple-release--github-preview <owner/repo>to generate a preview promotion workflow usingunbounded-tech/workflows-gitopsand a.gitops/preview/helmpromotion chart--github-promote <owner/repo>to generate a permanent environment promotion workflow usingunbounded-tech/workflows-gitopsand a.gitops/promote/helmpromotion chartghcr.io/<owner>/<repo>when--githubis providedtodo->todo-commandsandtodo-eventstodo.create-> trigger ontodo-commandscheckout-saga.started-> trigger oncheckout-saga-eventsgithub-projects.issue.created-> trigger ongithub-projects-events--busis provided, generated GitOps values includebus.kindand deploy resources exposeHOPS_BUS--storageas a visible alias for--store, and--outputas a visible alias forservice schema --out[workspace]tableTests
cargo checkcargo test commands::servicecargo testrustfmt --check src/commands/service/mod.rsgit diff --checkhops service --helplistsscaffoldand notcreate;hops service scaffold --helpshows--model <MODEL>,--read-models,--bus <BUS>,--github <OWNER/REPO>,--github-preview <OWNER/REPO>, and--github-promote <OWNER/REPO>;--models,--no-models, and--no-read-modelsare absenthops service scaffold read-model-default --path .tmp/read-model-default --command todo.pingcargo checkpassed, nosrc/models, nosrc/read_models,service describereturnstables: [], and stdoutservice schemais emptyhops service scaffold read-model-explicit --path .tmp/read-model-explicit --model todo --read-models --command todo.createcargo checkpassed, generatedsrc/models/todo.rsandsrc/read_models/mod.rs,service describereturnstodo_views, andservice schemaemits onlytodo_viewshops service scaffold model-file-multi --path .tmp/model-file-multi --model todo --model somethingelse --command todo.create --command somethingelse.complete --read-modelscargo check,service describe, andservice schemapassed; generatedsrc/models/todo.rs,src/models/somethingelse.rs, andsrc/models/mod.rstodo_viewsandsomethingelse_viewshops service scaffold model-file-knative --path .tmp/model-file-knative --transport knative --gitops --gitops-promote flux --model todo --command todo.create --event github-projects.issue.created --bus kafkacargo checkpassed;.gitops/deploycontains Knative Service/Brokers/Triggers,.gitops/promotecontains FluxHelmRelease, and generated values/env includekafkagh:hops service scaffold test-domain --path .tmp/github-workflows --github hops-ops/test-domain --github-preview hops-ops/test-previews --github-promote hops-ops/test-staging --transport knative --bus nats --command test-domain.create --event github-projects.issue.createdgh repo view hops-ops/test-domain --json nameWithOwnerthengh repo create hops-ops/test-domain --privateversion.yaml,release.yaml,preview.yaml,promote.yaml,.gitops/preview/helm,.gitops/promote/helm, and.gitops/deploy;cargo checkpassedservice describereturns the Knative command/event manifest withtables: []; stdoutservice schemais empty--bus rabbitmqand--bus psqlboth compile and emitbus.kindplusHOPS_BUSservice describe, stdoutservice schema, andservice schema --output /tmp/todo-custom.sqlall succeededoutbox_messagesNotes
--busis carried in generated GitOps config/runtime env for now.DEPLOY_KEYfor vnext tagging andGH_ORG_ACTIONS_REPO_WRITE_PACKAGESfor GitOps environment repo writes.cargo fmt --checkstill reports unrelated formatting drift already present outside this service command change; this PR intentionally avoids that formatter churn.