diff --git a/src/supernote_module_generator/helptext.py b/src/supernote_module_generator/helptext.py index a6494dc..2c9d1fe 100644 --- a/src/supernote_module_generator/helptext.py +++ b/src/supernote_module_generator/helptext.py @@ -62,7 +62,7 @@ --description Package description; use "" to omit. --javascript-name JavaScript feature name. --android-namespace Java-style Android namespace. - --package-version Initial semantic version [default: 0.1.0]. + --package-version Local feature package version [default: 0.1.0]. --package-manager Package manager for local linking. --skip-install Do not install the local dependency. @@ -85,11 +85,15 @@ Non-interactive behavior: Input is never requested. PACKAGE is always required. Without --yes, - --starter and every other output-affecting decision are required. Repeat - --starter to select both families. With --yes, the C/C++ starter is selected, - the description is omitted, the version is 0.1.0, names are derived - when valid, and installation is enabled. Conflicting lockfiles require - --package-manager. + --starter and every initial feature-metadata decision are required. Repeat + --starter to select both families. With --yes, omitted choices use documented + defaults: C/C++ starter, empty description, version 0.1.0, derived names, and + dependency installation unless --skip-install is present. Explicit options + still override those defaults. Conflicting lockfiles require --package-manager. + +Version boundary: + --package-version belongs to this local feature package. It does not change + versionCode or versionName in the plugin root's PluginConfig.json. Name inference: Use the unscoped package name, remove an initial react-native-, local-, or @@ -131,7 +135,7 @@ Package manager when refresh is required. --skip-install Skip a required dependency refresh. --build Run an Android build after verification. - -y, --yes Accept the displayed update plan. + -y, --yes Update without asking for confirmation. -h, --help Show help. Output options: @@ -143,9 +147,10 @@ --debug Include internal diagnostics and tracebacks. Behavior: - Update shows what will be replaced, preserved, and changed in the parent - plugin. Confirmation defaults to Yes. Dependencies are refreshed only when - package metadata or the local link changes. Update always targets one feature. + Without --yes, interactive Update shows what will be preserved and + regenerated; confirmation defaults to Yes. Dependencies are refreshed only + when the parent dependency entry or installed local link needs repair. Update + always targets one feature. Examples: supernote-module update @@ -233,10 +238,10 @@ --debug Include internal diagnostics and tracebacks. Confirmation: - Interactive removal always requires the exact package name. Removing all - requires REMOVE ALL. --yes is accepted only with an unambiguous target. - Build output is preserved by default. --yes never enables its deletion; - pass --delete-build-files explicitly when that cleanup is intended. + Without --yes, interactive removal requires the exact package name; removing + all requires REMOVE ALL. --yes bypasses that prompt only when the target is + unambiguous. Build output is preserved by default. --yes never enables its + deletion; pass --delete-build-files explicitly when cleanup is intended. Recovery: Implementation source is retained until parent changes, dependency refresh, @@ -277,9 +282,10 @@ --debug Include internal diagnostics and tracebacks. Behavior: - Doctor checks the JavaScript, Android, Kotlin/KSP, C23/C++23, NDK, CMake, - Gradle, and JSI requirements used by the plugin-level V2 runtime. It also - reports the target-device runtime boundary that cannot be proven locally. + Doctor checks JavaScript, Kotlin/KSP, Gradle, Java 17 through 23 (Java 17 is + recommended), Android SDK/NDK tools, NDK Clang with C23/C++23, CMake, and JSI + requirements used by the plugin-level V2 runtime. It also reports the target- + device runtime boundary that cannot be proven locally. Examples: supernote-module doctor diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 28353ff..32b0ccd 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -146,6 +146,33 @@ def test_add_help_preserves_multiline_example(tmp_path: Path): ) in stdout +def test_help_describes_defaults_as_overridable_and_versions_as_separate(): + add = COMMAND_HELP["add"] + normalized = " ".join(add.split()) + + assert "omitted choices use documented" in normalized + assert "unless --skip-install is present" in normalized + assert "Explicit options still override those defaults" in normalized + assert "Local feature package version" in normalized + assert "versionCode or versionName" in normalized + assert "With --yes, the C/C++ starter is selected" not in normalized + + +def test_help_matches_update_remove_and_doctor_behavior(): + update = " ".join(COMMAND_HELP["update"].split()) + remove = " ".join(COMMAND_HELP["remove"].split()) + doctor = " ".join(COMMAND_HELP["doctor"].split()) + + assert "Update without asking for confirmation" in update + assert "parent dependency entry or installed local link" in update + assert "Accept the displayed update plan" not in update + assert "Without --yes, interactive removal requires" in remove + assert "--yes bypasses that prompt only when the target is" in remove + assert "Java 17 through 23" in doctor + assert "Java 17 is" in doctor and "recommended" in doctor + assert "NDK Clang with C23/C++23" in doctor + + def test_version_is_exact_and_works_outside_plugin(tmp_path: Path): assert invoke(["--version"], tmp_path) == ( 0,