feat(gnovm): add interactive gno init wizard#5557
Open
davd-gzl wants to merge 31 commits intognolang:masterfrom
Open
feat(gnovm): add interactive gno init wizard#5557davd-gzl wants to merge 31 commits intognolang:masterfrom
gno init wizard#5557davd-gzl wants to merge 31 commits intognolang:masterfrom
Conversation
Promote 'gno init' to a top-level command with an interactive wizard that scaffolds realm, package, or run script projects with template files. Supports --bare flag for gnomod.toml-only creation, non-TTY fallback, go-back navigation with '<', and input validation with retry loops. Assisted-By: Claude (OpenCode)
Collaborator
🛠 PR Checks Summary🔴 Pending initial approval by a review team member, or review from tech-staff Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Member
|
@davd-gzl, could you please tag a/ux in your PRs and link the related UX issues? |
Allow 'gno init p/nt/hello' and 'gno init r/demo/foo' as shortcuts for their fully-qualified gno.land equivalents. Assisted-By: Claude (OpenCode)
Add reusable prompt primitives in tm2/pkg/commands/ that work with the existing IO interface and require zero new dependencies: - PromptString, PromptChoice, PromptSelect, PromptConfirm - ErrGoBack sentinel for back-navigation - Choice and SelectItem types for structured input 28 test cases covering normal flows, edge cases, and ErrGoBack.
…e flag - Replace local prompt/readLine/isTerminal/errGoBack with shared PromptString/PromptChoice/ErrGoBack from tm2/pkg/commands - Add --template flag for non-interactive template selection (e.g. gno init --template dao gno.land/r/demo/foo) - Add resolveTemplate() with case-insensitive lookup and helpful error messages listing available template names - Add mutual exclusion check: --bare and --template cannot combine - Fix writeGnomod to return WriteFile error instead of ignoring it - Fix realm template Render(path) → Render(_) (unused param lint) - Add how-to-add-template doc comment to mod_init_templates.go - Simplify mod_test.go: remove dead fields, extract testIO helpers, add TestResolveTemplate, TestModInitWithTemplateFlag, TestModInitBareAndTemplateExclusive - Alias tm2/pkg/errors as terrors to avoid shadowing stdlib errors - Use errors.Is() for ErrGoBack sentinel checks
Rename prxxxx_mod_init_template.md → pr5557_mod_init_template.md. Update content to document shared prompt primitives, external TUI library alternative considered and rejected, and updated key files.
- initTemplate uses Dir field instead of SourcePath/TestPath;
renderTemplateDir walks the directory, renders all .tmpl files,
and uses filename (minus .tmpl) as Go template for output name
(e.g. {{.PkgName}}.gno.tmpl → <pkg>.gno). Supports complex
multi-file templates without special-casing.
- Rename template files: source.gno.tmpl → {{.PkgName}}.gno.tmpl,
test.gno.tmpl → {{.PkgName}}_test.gno.tmpl,
run source.gno.tmpl → main.gno.tmpl
- Remove ErrGoBack sentinel and go-back navigation from wizard.
Backspace cannot be detected in line-buffered terminal mode, and
alternative go-back keys conflict with valid PromptString input.
Wizard is now a linear flow; Ctrl+C to restart.
- Simplify execModInit: replace step-machine loop with straight-line code.
- Update ADR with directory-based template docs and ErrGoBack rejection.
- execInitRun now prompts for script name (default derived from
directory name), producing e.g. run/create_proposal.gno instead
of hardcoded run/main.gno
- Run template filename uses {{.ScriptName}}.gno.tmpl
- Template comment shows full gnokey maketx run command with the
script path (e.g. ./create_proposal.gno)
- Add ScriptName field to templateData
- Extract validateName as a top-level function
- Error on file conflict in writeModule and execInitRun
…n, bare+gno exclusive - execInitRunScript now accepts initTemplate param and uses the template registry + --template flag instead of hardcoding runTemplatesFS - Write all rendered files (not just the first) in execInitRunScript - Error on --bare + .gno argument (mutually exclusive) - Remove dead kindRun branch in argument path (kindFromPath never returns kindRun) - Sort map keys for deterministic output in writeModule, execInitRun, execInitRunScript - Fix display path (filepath.Join instead of string concat) - Add TestModInitBareAndGnoExclusive test - Update ADR to reflect current state
davd-gzl
commented
Apr 21, 2026
| @@ -0,0 +1,168 @@ | |||
| // Interactive prompt primitives for CLI wizard flows. | |||
Member
Author
There was a problem hiding this comment.
This will be reused in a future PR (wizard gnokey maketx)
- PromptChoice: choices is map[string]Choice, returns key string, defaultKey string param (empty = no default) - PromptSelect: keeps []SelectItem (order matters — first item is default/most important), returns Name string - Both return string keys instead of int indices — callers switch on key instead of indexing parallel slices - Remove ChoiceMenu, SelectItem.IsDefault, strings.ToLower - Add package-level doc comment
- Add ScriptPath to templateData (e.g. run/create_proposal.gno) so template comment shows the full runnable path - Fix gnokey flags: single-dash (Go flag convention), not -- - Use 1000000ugnot instead of 1gnot for gas-fee - Template shows ./run/<name>.gno paths for both gno run and gnokey
…solidate run script funcs - Non-interactive mode now scaffolds template files when a module path is provided (only --bare skips templates). Previously non-interactive + path only created gnomod.toml, making the feature useless in CI/scripts. - Add validateGnoPath: rejects absolute paths, path traversal (..), and empty/invalid script names in .gno arguments. - Consolidate execInitRunScript + execInitRun into single writeRunScript function; execInitRun now just prompts for script name and delegates. - Resolve template before writing gnomod.toml to prevent partial writes on unknown template errors. - Pre-allocate created slices (fix prealloc lint warnings). - Remove terrors alias (only one usage, replaced with fmt.Errorf). - Fix prompt capitalization: [P]ackage → [p]ackage. - Use path.Join instead of filepath.Join in mod_init_templates.go (embedded FS always uses forward slashes). - Remove PromptConfirm from ADR key functions list (was removed earlier). - Add tests: TestValidateGnoPath, TestModInitBareNoPath, TestModInitUnknownTemplateNoPartialWrite, update TestModInitNonInteractive and TestModInitWithTemplateFlag to verify template files are created. Assisted-By: Claude (OpenCode)
…ate conflict - Add 'init' to the auto-generated subcommand list in gnovm/cmd/gno/README.md so 'make generate' is clean (unblocks CI 'main / build'). - Extract renderModuleFiles() to pre-check template file conflicts before writing gnomod.toml. Previously, if a rendered target file already existed on disk, gnomod.toml was written first and then writeModule returned an error, leaving an orphan gnomod.toml. All three non-bare paths (non-interactive-with-arg, interactive-with-arg, full-wizard) now render and validate templates before any disk write. - Add TestModInitTemplateFileConflictNoPartialWrite regression test. Assisted-By: Claude (claude-opus-4.7)
- Add 'gno mod init' as a deprecated alias of 'gno init' that forwards
to execModInit and prints a deprecation warning on stderr. Keeps
existing scripts, Makefiles, and CI pipelines working.
- Tighten validateGnoPath: check for cleaned == '..' or '../...' prefix
instead of a plain HasPrefix('..') so legitimate names like
'..bar/hello.gno' are not false-positived as traversal.
- Rename the namespace prompt label from 'Address or namespace' to
'Namespace' — validateName only accepts [a-z0-9_]+, so advertising
addresses was misleading.
- Make insertPathLetter idempotent: if the path already has an '/r/' or
'/p/' segment after the domain, return it unchanged instead of
inserting a second letter.
- Add a TODO in renderTemplateDir noting that nested template
directories are intentionally skipped for v1.
- Extract scaffoldModule / scaffoldModuleWith helpers. The three
non-bare, non-run code paths (non-interactive-with-arg,
interactive-with-arg, wizard-end) all did the same
resolve → render-precheck → writeGnomod → writeModule sequence;
consolidating removes ~40 lines of duplication and makes the
invariant (no orphan gnomod.toml) obvious.
- Update ADR: document the deprecation alias and the new non-interactive
fallback semantics; refresh the 'Key Files' function list.
- Add TestModInitDeprecatedAlias, extra TestInsertPathLetter idempotency
cases, and a TestValidateGnoPath 'dotdot prefix not traversal' case.
Assisted-By: Claude (claude-opus-4.7)
The default kind is package ('p'), so capitalize it ([P]ackage) so the
default is visually obvious at a glance, consistent with common CLI
conventions.
Assisted-By: Claude (claude-opus-4.7)
…irectories Replace the cargo-new-style subdirectory scaffolding with a simpler model: 'gno init <modpath>' always creates gnomod.toml and template files directly in the current directory. The only case where 'gno init' creates directories is the '.gno' run-script branch (e.g. 'gno init run/hello.gno'). This removes prepareTargetDir, the in-place fallback, rollback machinery, displayDir threading, and all related helpers (joinDisplay, inPlace, rollbackCreatedDir). Since we only ever write individual files and never mkdir, a failed init cannot leave orphan directories — no cleanup needed. - Bail out early if gnomod.toml already exists in CWD. - validateModulePath runs before any filesystem side effects. - Pre-render and conflict-check template files before writing gnomod.toml. - Next-steps hint: 'Next: gno test .' (or generic add-code hint for --bare). Uses 'gno test .' rather than './...' because the recursive pattern requires a gnowork.toml, which a freshly-scaffolded module lacks. Tests: drop TestModInitInPlace, simplify TestModInitInvalidPathRejected, update all path expectations to drop subdir prefixes. Remove in_place.txtar; rewrite other init txtar files for the new CWD-based layout. Assisted-By: Claude (claude-opus-4.7)
…mod-init-template
…init - gno mod init: preserve original bare behavior, print hint pointing to 'gno init', drop 'deprecated' wording. The alias never triggers the interactive wizard and only writes gnomod.toml. - Add doc comments on every PR-added function and type. - Use slices.Sorted(maps.Keys(...)) and drop the sortedKeys helper. - Replace validateGnoPath manual checks with filepath.IsLocal. - Use strings.Cut in insertPathLetter. - Merge duplicate branches in execModInit. - scaffoldModuleWith renders files once (was rendering twice); absorbs the writeModule helper. - Merge promptModuleKind's two parallel maps into a single source of truth. - Rename testdata 'mod_init_deprecated.txtar' to 'mod_init_legacy.txtar' and update assertions. Assisted-By: Claude (claude-opus-4.7)
- Merge scaffoldModule and scaffoldModuleWith into one function. - Factor writeFiles helper (conflict-check + sorted write) reused by both module scaffolding and run-script writing. - Add kindLabel helper and runScriptDir constant. - Flatten promptModuleKind to a single slice of kind entries (no more double-map pattern). - Linearize execModInit wizard tail via resolveOrPickTemplate helper. - validateGnoPath now returns the parsed script name, reused by writeRunScript instead of recomputing it from the path. - Rename newModInitDeprecatedCmd to newModInitLegacyCmd to match the user-facing wording. No behavior change. All init txtars and unit tests pass. Assisted-By: Claude (claude-opus-4.7)
The previous CI run failed in gno.land/pkg/integration with a 'txDispatcher subscription unexpectedly closed' panic in tm2/pkg/bft/rpc/core/mempool.go:413. This PR does not touch tm2/pkg/bft or gno.land/pkg/integration; the failure is a test-shutdown race unrelated to the changes in this PR. Assisted-By: Claude (claude-opus-4.7)
- Extract ~500 lines of init-related code from mod.go into a new gnovm/cmd/gno/init.go so mod.go holds only 'gno mod' subcommands (download, graph, tidy, why). Move matching tests into init_test.go. - Accept bech32 addresses (g1...) as a namespace in the interactive prompt via a new validateNamespace/isBech32Address helper. - In writeRunScript, render templates before calling os.MkdirAll so a render failure no longer leaves orphan run/ directories on disk. - Update ADR Key Files table to reflect the init.go / init_test.go split. Assisted-By: opencode (claude-opus-4.7)
…naming 'gno mod init' is just a gno mod subcommand that creates a bare gnomod.toml. It isn't a legacy shim — move it back next to the other mod subcommands and rename newModInitLegacyCmd to newModInitCmd. Move its test from init_test.go to mod_test.go accordingly. Assisted-By: opencode (claude-opus-4.7)
- TestWriteRunScriptNoOrphanDir: verifies that template render failure in writeRunScript does not leave behind a stray run/ directory. - TestModInitBareNoArgsErrors: locks in the new 'module path is required with --bare' error for 'gno mod init' called with no arguments (previously silently created gnomod.toml with empty module). - TestModInitRunTemplateFlag: verifies --template is honored on the .gno shorthand path (basic succeeds; unknown template fails cleanly without creating the run/ directory). Assisted-By: opencode (claude-opus-4.7)
Two of the three regression tests from the previous commit belong at the CLI layer — replace them with txtar scenarios under testdata/init/: - mod_init_no_args.txtar: `gno mod init` with no args must error. - run_template_flag.txtar: `--template basic` on .gno shorthand succeeds. - run_unknown_template_no_orphan.txtar: unknown --template fails without creating an orphan run/ directory. Keep TestWriteRunScriptNoOrphanDir as a Go test because it needs to inject a broken initTemplate into writeRunScript — unreachable via CLI. Also rename mod_init_legacy.txtar to mod_init.txtar and drop the 'legacy' wording from its header to match the newModInitCmd rename. Assisted-By: opencode (claude-opus-4.7)
Drop 13 Go tests from init_test.go and one from mod_test.go that duplicated CLI behavior already exercised by txtar scenarios. Keep Go tests only for helpers, prompts, and internal injection cases (e.g. writeRunScript render failure). Add three txtars to plug the resulting gaps: - gno_file_conflict.txtar - bare_and_gno_exclusive.txtar - bare_no_args.txtar Assisted-By: opencode (claude-opus-4.7)
gno init wizard
davd-gzl
added a commit
to davd-gzl/gno
that referenced
this pull request
Apr 23, 2026
… wizard - Rename quickstart.md → cheatsheet.md - Add categories: Developer & Contributor - Developer: add airgap transaction, gnokey query auth/accounts, gnodev flags - Contributor: build/test Go, start a local chain (gnoland start), update golden files, lint/format Go - Reference gno init wizard (gnolang#5557) - Reference one-line installer (gnolang#5492) - Add default gnodev test account mnemonic Assisted-By: OpenCode (claude-opus-4.6)
This was referenced Apr 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promote 'gno init' to a top-level command with an interactive wizard that scaffolds realm, package, or run script projects with template files. Supports --bare flag for gnomod.toml-only creation, non-TTY fallback, and input validation with retry loops.
Related: #5460
Next step will be
gnokey maketxwizard