invoke-toolkit 0.0.57__tar.gz → 0.0.58__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/PKG-INFO +1 -1
  2. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/extensions/tasks/create.py +6 -5
  3. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/templates/package-template/pyproject.toml.jinja +3 -5
  4. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/extensions/test_create.py +139 -1
  5. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/collection.py +10 -0
  6. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/echo.yaml +2 -0
  7. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/no-dedupe.yaml +2 -0
  8. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/no-echo.yaml +2 -0
  9. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/package/invoke.yml +3 -0
  10. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/package/tasks/__init__.py +6 -0
  11. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/runtime.py +6 -0
  12. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/underscores/tasks.py +6 -0
  13. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/yaml/explicit.py +9 -0
  14. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/yaml/tasks.py +6 -0
  15. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/yml/explicit.py +9 -0
  16. invoke_toolkit-0.0.58/tests/original_invoke/_support/configs/yml/tasks.py +6 -0
  17. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/utils/test_fzf.py +12 -7
  18. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/.gitignore +0 -0
  19. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/LICENSE.txt +0 -0
  20. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/README.md +0 -0
  21. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/pyproject.toml +0 -0
  22. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/__init__.py +0 -0
  23. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/__main__.py +0 -0
  24. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/collections.py +0 -0
  25. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/completion.py +0 -0
  26. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/config/__init__.py +0 -0
  27. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/config/config.py +0 -0
  28. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/config/registry.py +0 -0
  29. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/config/schema.py +0 -0
  30. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/config/status_helper.py +0 -0
  31. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/context/__init__.py +0 -0
  32. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/context/context.py +0 -0
  33. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/context/types.py +0 -0
  34. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/executor.py +0 -0
  35. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/extensions/__init__.py +0 -0
  36. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/extensions/tasks/__init__.py +0 -0
  37. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/extensions/tasks/config.py +0 -0
  38. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/extensions/tasks/dist.py +0 -0
  39. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/extensions/tasks/shell.py +0 -0
  40. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/loader/entrypoint.py +0 -0
  41. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/log/__init__.py +0 -0
  42. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/log/logger.py +0 -0
  43. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/output/__init__.py +0 -0
  44. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/output/console.py +0 -0
  45. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/output/utils.py +0 -0
  46. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/parser.py +0 -0
  47. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/program/__init__.py +0 -0
  48. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/program/main.py +0 -0
  49. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/program/program.py +0 -0
  50. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/runners/__init__.py +0 -0
  51. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/runners/rich.py +0 -0
  52. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/scripts/__init__.py +0 -0
  53. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/scripts/loader.py +0 -0
  54. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/tasks/__init__.py +0 -0
  55. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/tasks/autocomplete.py +0 -0
  56. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/tasks/cache.py +0 -0
  57. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/tasks/tasks.py +0 -0
  58. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/tasks/types.py +0 -0
  59. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/testing.py +0 -0
  60. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/utils/__init__.py +0 -0
  61. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/utils/fzf.py +0 -0
  62. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/utils/inspection.py +0 -0
  63. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/utils/singleton.py +0 -0
  64. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/src/invoke_toolkit/utils/text.py +0 -0
  65. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/templates/package-template/.gitignore.jinja +0 -0
  66. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/templates/package-template/README.md.jinja +0 -0
  67. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/templates/package-template/copier.yml +0 -0
  68. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/templates/package-template/src/{{package_slug}}/__init__.py.jinja +0 -0
  69. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/templates/package-template/src/{{package_slug}}/tasks.py.jinja +0 -0
  70. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/__init__.py +0 -0
  71. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/conftest.py +0 -0
  72. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/examples/cached_completion/tasks.py +0 -0
  73. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/examples/config_schema/tasks.py +0 -0
  74. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/examples/enum_select_size/tasks.py +0 -0
  75. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/examples/fzf_selector/tasks.py +0 -0
  76. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/examples/literal_set_level/tasks.py +0 -0
  77. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/extensions/conftest.py +0 -0
  78. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/extensions/test_config_tasks.py +0 -0
  79. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/extensions/test_package_template_entrypoint.py +0 -0
  80. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/extensions/test_shell_tasks.py +0 -0
  81. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/__init__.py +0 -0
  82. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/all-four/invoke.json +0 -0
  83. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/all-four/invoke.py +0 -0
  84. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/all-four/invoke.yml +0 -0
  85. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/json/invoke.json +0 -0
  86. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/json-and-python/invoke.json +0 -0
  87. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/json-and-python/invoke.py +0 -0
  88. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/python/invoke.py +0 -0
  89. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/three-of-em/invoke.json +0 -0
  90. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/three-of-em/invoke.py +0 -0
  91. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/three-of-em/invoke.yml +0 -0
  92. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/configs/yml/invoke.yml +0 -0
  93. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/_support/has_modules.py +0 -0
  94. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/conftest.py +0 -0
  95. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/original_invoke/test_config.py +0 -0
  96. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/program/main.py +0 -0
  97. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/program/tasks/__init__.py +0 -0
  98. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/program/tasks/coll1.py +0 -0
  99. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/script/test_script.py +0 -0
  100. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/tasks/test_cache.py +0 -0
  101. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/tasks/test_extensions_config.py +0 -0
  102. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_annotated_help.py +0 -0
  103. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_cofig_class.py +0 -0
  104. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_collection.py +0 -0
  105. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_collection_configure.py +0 -0
  106. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_completion_with_choices.py +0 -0
  107. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_config_helper.py +0 -0
  108. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_config_registry.py +0 -0
  109. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_config_schema.py +0 -0
  110. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_console.py +0 -0
  111. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_context_class.py +0 -0
  112. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_disable_status_cli.py +0 -0
  113. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_enum_arguments.py +0 -0
  114. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_executor.py +0 -0
  115. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_file_completion.py +0 -0
  116. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_global_context.py +0 -0
  117. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_help_flags.py +0 -0
  118. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_invoke_compatibility.py +0 -0
  119. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_loader.py +0 -0
  120. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_parsing.py +0 -0
  121. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_proctitle.py +0 -0
  122. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_program_with_collection.py +0 -0
  123. {invoke_toolkit-0.0.57 → invoke_toolkit-0.0.58}/tests/test_toplevel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: invoke-toolkit
3
- Version: 0.0.57
3
+ Version: 0.0.58
4
4
  Summary: A set of extended APIs for PyInvoke for composable scripts, plugins and richer output
5
5
  Project-URL: Documentation, https://github.com/D3f0/invoke-toolkit#readme
6
6
  Project-URL: Issues, https://github.com/D3f0/invoke-toolkit/issues
@@ -65,7 +65,7 @@ def _get_template() -> str:
65
65
  script_template = dedent(rf"""
66
66
  #!/usr/bin/env -S uv run --script
67
67
  # /// script
68
- # requires-python = ">=3.10"
68
+ # requires-python = ">=3.11"
69
69
  # dependencies = [
70
70
  # "invoke-toolkit{version_for_template}",
71
71
  # ]
@@ -322,9 +322,9 @@ def package(
322
322
  template_data = {
323
323
  "package_name": actual_name,
324
324
  "package_slug": package_slug,
325
- "collection_name": package_slug,
325
+ "collection_name": extension_short_name,
326
326
  "extension_short_name": extension_short_name,
327
- "python_version": "3.10",
327
+ "python_version": "3.11",
328
328
  }
329
329
 
330
330
  run_copy(
@@ -342,9 +342,10 @@ def package(
342
342
  dedent(
343
343
  f"""
344
344
  [yellow]Next steps:[/yellow]
345
- cd {actual_name}
345
+ cd {target_path}
346
346
  uv sync
347
- uv pip install -e .
347
+ # Test your package
348
+ uv run --directory {target_path} -m invoke-toolkit -l
348
349
  """
349
350
  ).strip()
350
351
  )
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "{{ package_name }}"
7
- dynamic = ["version"]
7
+ version = "0.1.0"
8
8
  description = "{{ project_description }}"
9
9
  readme = "README.md"
10
10
  requires-python = ">={{ python_version }}"
@@ -17,9 +17,10 @@ classifiers = [
17
17
  "Intended Audience :: Developers",
18
18
  "License :: OSI Approved :: MIT License",
19
19
  "Programming Language :: Python :: 3",
20
- "Programming Language :: Python :: 3.10",
21
20
  "Programming Language :: Python :: 3.11",
22
21
  "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
23
24
  ]
24
25
  dependencies = [
25
26
  "invoke-toolkit", # Requires invoke-toolkit, any version
@@ -28,8 +29,5 @@ dependencies = [
28
29
  [project.entry-points."invoke_toolkit.collection"]
29
30
  "{{ extension_short_name }}" = "{{ package_slug }}:collection"
30
31
 
31
- [tool.hatch.version]
32
- path = "src/{{ package_slug }}/__init__.py"
33
-
34
32
  [tool.hatch.build.targets.wheel]
35
33
  packages = ["src/{{ package_slug }}"]
@@ -274,7 +274,7 @@ def _verify_python_requirement(lines):
274
274
  """Verify requires-python field exists and has correct value."""
275
275
  for line in lines:
276
276
  if "requires-python" in line:
277
- assert ">=3.10" in line, f"Expected requires-python >=3.10, got: '{line}'"
277
+ assert ">=3.11" in line, f"Expected requires-python >=3.11, got: '{line}'"
278
278
  return
279
279
 
280
280
  raise AssertionError("requires-python field not found in metadata")
@@ -658,6 +658,144 @@ def test_package_uses_git_config_template(
658
658
  assert (pkg_dir / "pyproject.toml").exists(), "pyproject.toml should exist"
659
659
 
660
660
 
661
+ def _assert_cli_examples_use_name(
662
+ short_name: str, pkg_dir: Path, package_slug: str
663
+ ) -> None:
664
+ """
665
+ Helper: asserts that the rendered README.md and __init__.py use ``short_name``
666
+ (the intk-visible collection name) in all CLI usage examples, and that no
667
+ raw Jinja placeholders leaked through.
668
+ """
669
+ # --- README.md checks ---
670
+ readme_path = pkg_dir / "README.md"
671
+ assert readme_path.exists(), "README.md was not generated"
672
+ readme = readme_path.read_text(encoding="utf-8")
673
+
674
+ assert f"collection named `{short_name}`" in readme, (
675
+ f"README should reference '{short_name}' in the collection listing sentence, "
676
+ f"but got:\n{readme}"
677
+ )
678
+ assert f"`{short_name}.hello`" in readme, (
679
+ f"README should reference '{short_name}' in the task list entry, "
680
+ f"but got:\n{readme}"
681
+ )
682
+ assert f"intk {short_name}.hello" in readme, (
683
+ f"README should reference '{short_name}' in the example command, "
684
+ f"but got:\n{readme}"
685
+ )
686
+ assert "{{ collection_name }}" not in readme, (
687
+ "Jinja variable {{ collection_name }} was not rendered in README.md"
688
+ )
689
+ assert "{{ package_name }}" not in readme, (
690
+ "Jinja variable {{ package_name }} was not rendered in README.md"
691
+ )
692
+
693
+ # --- __init__.py comment checks ---
694
+ init_path = pkg_dir / "src" / package_slug / "__init__.py"
695
+ assert init_path.exists(), "__init__.py was not generated"
696
+ init = init_path.read_text(encoding="utf-8")
697
+
698
+ assert f"intk {short_name}.hello" in init, (
699
+ f"__init__.py example comment should reference '{short_name}' for 'hello', "
700
+ f"but got:\n{init}"
701
+ )
702
+ assert f"intk {short_name}.my_task" in init, (
703
+ f"__init__.py example comment should reference '{short_name}' for 'my_task', "
704
+ f"but got:\n{init}"
705
+ )
706
+ assert f"intk {short_name}.tasks.hello" in init, (
707
+ f"__init__.py 'NOT' comment should reference '{short_name}' for nested 'tasks.hello', "
708
+ f"but got:\n{init}"
709
+ )
710
+ assert f"intk {short_name}.utils.my_task" in init, (
711
+ f"__init__.py 'NOT' comment should reference '{short_name}' for nested 'utils.my_task', "
712
+ f"but got:\n{init}"
713
+ )
714
+ assert "{{ collection_name }}" not in init, (
715
+ "Jinja variable {{ collection_name }} was not rendered in __init__.py"
716
+ )
717
+ assert "{{ package_name }}" not in init, (
718
+ "Jinja variable {{ package_name }} was not rendered in __init__.py"
719
+ )
720
+
721
+
722
+ def test_template_cli_examples_use_collection_name_unprefixed(
723
+ tmp_path: Path,
724
+ monkeypatch: pytest.MonkeyPatch,
725
+ ):
726
+ """
727
+ Regression test (non-prefixed package): verifies that the CLI usage examples
728
+ in README.md and __init__.py use the package slug as the collection name.
729
+
730
+ For a package named ``my-readme-pkg`` (no ``invoke-toolkit-`` prefix) the
731
+ intk-visible name is the full slug ``my_readme_pkg``.
732
+ """
733
+ import invoke_toolkit
734
+
735
+ invoke_toolkit_path = Path(invoke_toolkit.__file__).parent
736
+ default_template = (
737
+ invoke_toolkit_path.parent.parent / "templates" / "package-template"
738
+ )
739
+ if not default_template.exists():
740
+ pytest.skip("Default template not found in development setup")
741
+
742
+ monkeypatch.chdir(tmp_path)
743
+
744
+ package_name = "my-readme-pkg"
745
+ package_slug = package_name.replace("-", "_")
746
+ # Non-prefixed: collection_name == package_slug
747
+ expected_short_name = package_slug
748
+
749
+ x = TestingToolkitProgram()
750
+ x.run(["", "-x", "create.package", "--name", package_name])
751
+
752
+ _assert_cli_examples_use_name(
753
+ expected_short_name, tmp_path / package_name, package_slug
754
+ )
755
+
756
+
757
+ def test_template_cli_examples_use_collection_name_prefixed(
758
+ tmp_path: Path,
759
+ monkeypatch: pytest.MonkeyPatch,
760
+ ):
761
+ """
762
+ Regression test (invoke-toolkit-prefixed package): verifies that the CLI
763
+ usage examples use only the short name after stripping the ``invoke-toolkit-``
764
+ prefix, not the full package name.
765
+
766
+ For ``--name my-pkg --ext-name myext`` the full package name becomes
767
+ ``invoke-toolkit-myext``, but intk exposes it as ``myext``.
768
+ """
769
+ import invoke_toolkit
770
+
771
+ invoke_toolkit_path = Path(invoke_toolkit.__file__).parent
772
+ default_template = (
773
+ invoke_toolkit_path.parent.parent / "templates" / "package-template"
774
+ )
775
+ if not default_template.exists():
776
+ pytest.skip("Default template not found in development setup")
777
+
778
+ monkeypatch.chdir(tmp_path)
779
+
780
+ ext_name = "myext"
781
+ full_package_name = f"invoke-toolkit-{ext_name}"
782
+ package_slug = full_package_name.replace("-", "_")
783
+ # Prefixed: collection_name == ext_name (the part after "invoke-toolkit-")
784
+ expected_short_name = ext_name
785
+
786
+ x = TestingToolkitProgram()
787
+ x.run(["", "-x", "create.package", "--name", "ignored", "--ext-name", ext_name])
788
+
789
+ pkg_dir = tmp_path / full_package_name
790
+ _assert_cli_examples_use_name(expected_short_name, pkg_dir, package_slug)
791
+
792
+ # Extra guard: the full package name must NOT appear as the collection name
793
+ readme = (pkg_dir / "README.md").read_text(encoding="utf-8")
794
+ assert f"intk {full_package_name}.hello" not in readme, (
795
+ "README must not use the full prefixed package name as the collection name"
796
+ )
797
+
798
+
661
799
  def test_package_template_priority_explicit_over_git_config(
662
800
  tmp_path: Path,
663
801
  monkeypatch: pytest.MonkeyPatch,
@@ -0,0 +1,10 @@
1
+ from invoke import Collection, ctask # pylint: disable=no-name-in-module
2
+
3
+
4
+ @ctask
5
+ def go(c):
6
+ c.run("false") # Ensures a kaboom if mocking fails
7
+
8
+
9
+ ns = Collection(go)
10
+ ns.configure({"run": {"echo": True}})
@@ -0,0 +1,2 @@
1
+ tasks:
2
+ dedupe: false
@@ -0,0 +1,3 @@
1
+ outer:
2
+ inner:
3
+ hooray: "package"
@@ -0,0 +1,6 @@
1
+ from invoke import task
2
+
3
+
4
+ @task
5
+ def mytask(c):
6
+ assert c.outer.inner.hooray == "package"
@@ -0,0 +1,6 @@
1
+ from invoke import task
2
+
3
+
4
+ @task
5
+ def mytask(c):
6
+ assert c.outer.inner.hooray == "yaml"
@@ -0,0 +1,6 @@
1
+ from invoke import task
2
+
3
+
4
+ @task
5
+ def i_have_underscores(c):
6
+ pass
@@ -0,0 +1,9 @@
1
+ from invoke import task, Collection
2
+
3
+
4
+ @task
5
+ def mytask(c):
6
+ assert c.outer.inner.hooray == "yaml"
7
+
8
+
9
+ ns = Collection(mytask)
@@ -0,0 +1,6 @@
1
+ from invoke import task
2
+
3
+
4
+ @task
5
+ def mytask(c):
6
+ assert c.outer.inner.hooray == "yaml"
@@ -0,0 +1,9 @@
1
+ from invoke import task, Collection
2
+
3
+
4
+ @task
5
+ def mytask(c):
6
+ assert c.outer.inner.hooray == "yml"
7
+
8
+
9
+ ns = Collection(mytask)
@@ -0,0 +1,6 @@
1
+ from invoke import task
2
+
3
+
4
+ @task
5
+ def mytask(c):
6
+ assert c.outer.inner.hooray == "yml"
@@ -633,17 +633,22 @@ def test_show_fzf_warning_only_shows_once(capsys):
633
633
  assert occurrences == 1
634
634
 
635
635
 
636
- def test_show_fzf_warning_respects_config(capsys):
636
+ def test_show_fzf_warning_respects_config(capsys, caplog):
637
637
  """Test that warning can be disabled via config."""
638
- ctx = Context()
639
- ctx.config._config["fuzzy_finder"] = {"show_warnings": False}
638
+ import logging
640
639
 
641
- # Reset the global warning flag
642
- import invoke_toolkit.utils.fzf as fzf_module
640
+ # Suppress invoke's DEBUG log output so it doesn't leak into capsys.err
641
+ # when a root-level DEBUG handler is left active by earlier tests.
642
+ with caplog.at_level(logging.CRITICAL, logger="invoke"):
643
+ ctx = Context()
644
+ ctx.config._config["fuzzy_finder"] = {"show_warnings": False}
643
645
 
644
- fzf_module._fzf_warning_shown = False
646
+ # Reset the global warning flag
647
+ import invoke_toolkit.utils.fzf as fzf_module
645
648
 
646
- _show_fzf_warning(ctx, force_fallback=False)
649
+ fzf_module._fzf_warning_shown = False
650
+
651
+ _show_fzf_warning(ctx, force_fallback=False)
647
652
 
648
653
  # Should not output anything when warnings disabled
649
654
  captured = capsys.readouterr()