craft-application 4.2.0__tar.gz → 4.2.2__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 (191) hide show
  1. {craft_application-4.2.0/craft_application.egg-info → craft_application-4.2.2}/PKG-INFO +1 -1
  2. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/_version.py +2 -2
  3. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/application.py +50 -46
  4. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/models/base.py +1 -0
  5. {craft_application-4.2.0 → craft_application-4.2.2/craft_application.egg-info}/PKG-INFO +1 -1
  6. {craft_application-4.2.0 → craft_application-4.2.2}/docs/reference/changelog.rst +22 -0
  7. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/test_base.py +20 -0
  8. {craft_application-4.2.0 → craft_application-4.2.2}/.editorconfig +0 -0
  9. {craft_application-4.2.0 → craft_application-4.2.2}/.github/.jira_sync_config.yaml +0 -0
  10. {craft_application-4.2.0 → craft_application-4.2.2}/.github/ISSUE_TEMPLATE/bug.yaml +0 -0
  11. {craft_application-4.2.0 → craft_application-4.2.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  12. {craft_application-4.2.0 → craft_application-4.2.2}/.github/ISSUE_TEMPLATE/task.yaml +0 -0
  13. {craft_application-4.2.0 → craft_application-4.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  14. {craft_application-4.2.0 → craft_application-4.2.2}/.github/release-drafter.yaml +0 -0
  15. {craft_application-4.2.0 → craft_application-4.2.2}/.github/release-drafter.yml +0 -0
  16. {craft_application-4.2.0 → craft_application-4.2.2}/.github/renovate.json5 +0 -0
  17. {craft_application-4.2.0 → craft_application-4.2.2}/.github/workflows/check-renovate.yaml +0 -0
  18. {craft_application-4.2.0 → craft_application-4.2.2}/.github/workflows/cla-check.yaml +0 -0
  19. {craft_application-4.2.0 → craft_application-4.2.2}/.github/workflows/docs.yaml +0 -0
  20. {craft_application-4.2.0 → craft_application-4.2.2}/.github/workflows/release-drafter.yaml +0 -0
  21. {craft_application-4.2.0 → craft_application-4.2.2}/.github/workflows/release-publish.yaml +0 -0
  22. {craft_application-4.2.0 → craft_application-4.2.2}/.github/workflows/tests.yaml +0 -0
  23. {craft_application-4.2.0 → craft_application-4.2.2}/.gitignore +0 -0
  24. {craft_application-4.2.0 → craft_application-4.2.2}/.pre-commit-config.yaml +0 -0
  25. {craft_application-4.2.0 → craft_application-4.2.2}/.readthedocs.yaml +0 -0
  26. {craft_application-4.2.0 → craft_application-4.2.2}/.yamllint.yaml +0 -0
  27. {craft_application-4.2.0 → craft_application-4.2.2}/HACKING.rst +0 -0
  28. {craft_application-4.2.0 → craft_application-4.2.2}/LICENSE +0 -0
  29. {craft_application-4.2.0 → craft_application-4.2.2}/README.rst +0 -0
  30. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/__init__.py +0 -0
  31. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/_config.py +0 -0
  32. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/commands/__init__.py +0 -0
  33. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/commands/base.py +0 -0
  34. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/commands/lifecycle.py +0 -0
  35. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/commands/other.py +0 -0
  36. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/errors.py +0 -0
  37. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/git/__init__.py +0 -0
  38. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/git/_errors.py +0 -0
  39. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/git/_git_repo.py +0 -0
  40. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/git/_models.py +0 -0
  41. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/grammar.py +0 -0
  42. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/__init__.py +0 -0
  43. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/errors.py +0 -0
  44. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/launchpad.py +0 -0
  45. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/__init__.py +0 -0
  46. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/base.py +0 -0
  47. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/build.py +0 -0
  48. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/code.py +0 -0
  49. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/distro.py +0 -0
  50. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/project.py +0 -0
  51. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/models/recipe.py +0 -0
  52. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/launchpad/util.py +0 -0
  53. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/misc/instance_bashrc +0 -0
  54. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/models/__init__.py +0 -0
  55. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/models/constraints.py +0 -0
  56. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/models/grammar.py +0 -0
  57. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/models/metadata.py +0 -0
  58. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/models/project.py +0 -0
  59. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/py.typed +0 -0
  60. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/remote/__init__.py +0 -0
  61. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/remote/errors.py +0 -0
  62. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/remote/git.py +0 -0
  63. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/remote/utils.py +0 -0
  64. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/remote/worktree.py +0 -0
  65. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/secrets.py +0 -0
  66. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/__init__.py +0 -0
  67. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/base.py +0 -0
  68. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/config.py +0 -0
  69. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/lifecycle.py +0 -0
  70. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/package.py +0 -0
  71. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/provider.py +0 -0
  72. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/remotebuild.py +0 -0
  73. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/request.py +0 -0
  74. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/services/service_factory.py +0 -0
  75. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/__init__.py +0 -0
  76. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/callbacks.py +0 -0
  77. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/docs.py +0 -0
  78. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/error_formatting.py +0 -0
  79. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/logging.py +0 -0
  80. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/paths.py +0 -0
  81. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/platforms.py +0 -0
  82. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/repositories.py +0 -0
  83. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/retry.py +0 -0
  84. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/snap_config.py +0 -0
  85. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/string.py +0 -0
  86. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application/util/yaml.py +0 -0
  87. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application.egg-info/SOURCES.txt +0 -0
  88. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application.egg-info/dependency_links.txt +0 -0
  89. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application.egg-info/requires.txt +0 -0
  90. {craft_application-4.2.0 → craft_application-4.2.2}/craft_application.egg-info/top_level.txt +0 -0
  91. {craft_application-4.2.0 → craft_application-4.2.2}/docs/conf.py +0 -0
  92. {craft_application-4.2.0 → craft_application-4.2.2}/docs/explanation/build-plans.rst +0 -0
  93. {craft_application-4.2.0 → craft_application-4.2.2}/docs/explanation/index.rst +0 -0
  94. {craft_application-4.2.0 → craft_application-4.2.2}/docs/howto/index.rst +0 -0
  95. {craft_application-4.2.0 → craft_application-4.2.2}/docs/howto/partitions.rst +0 -0
  96. {craft_application-4.2.0 → craft_application-4.2.2}/docs/index.rst +0 -0
  97. {craft_application-4.2.0 → craft_application-4.2.2}/docs/reference/environment-variables.rst +0 -0
  98. {craft_application-4.2.0 → craft_application-4.2.2}/docs/reference/index.rst +0 -0
  99. {craft_application-4.2.0 → craft_application-4.2.2}/docs/reference/platforms.rst +0 -0
  100. {craft_application-4.2.0 → craft_application-4.2.2}/docs/tutorials/index.rst +0 -0
  101. {craft_application-4.2.0 → craft_application-4.2.2}/pyproject.toml +0 -0
  102. {craft_application-4.2.0 → craft_application-4.2.2}/setup.cfg +0 -0
  103. {craft_application-4.2.0 → craft_application-4.2.2}/tests/__init__.py +0 -0
  104. {craft_application-4.2.0 → craft_application-4.2.2}/tests/conftest.py +0 -0
  105. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/__init__.py +0 -0
  106. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/conftest.py +0 -0
  107. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/build-secrets/secret-source-folder/source-file.txt +0 -0
  108. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/build-secrets/testcraft.yaml +0 -0
  109. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/invalid_projects/build-error/testcraft.yaml +0 -0
  110. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/adoption/stderr +0 -0
  111. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/adoption/testcraft.yaml +0 -0
  112. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/basic/stderr +0 -0
  113. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/basic/testcraft.yaml +0 -0
  114. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/build-for-all/stderr +0 -0
  115. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/build-for-all/testcraft.yaml +0 -0
  116. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/environment/stderr +0 -0
  117. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/environment/testcraft.yaml +0 -0
  118. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/grammar/src/on-amd64-to-amd64/hello.txt +0 -0
  119. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/grammar/src/on-amd64-to-arm64/hello.txt +0 -0
  120. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/grammar/stderr +0 -0
  121. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/data/valid_projects/grammar/testcraft.yaml +0 -0
  122. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/launchpad/__init__.py +0 -0
  123. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/launchpad/conftest.py +0 -0
  124. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/launchpad/test_anonymous_access.py +0 -0
  125. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/services/__init__.py +0 -0
  126. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/services/test_lifecycle.py +0 -0
  127. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/services/test_provider.py +0 -0
  128. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/services/test_remotebuild.py +0 -0
  129. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/services/test_request.py +0 -0
  130. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/services/test_service_factory.py +0 -0
  131. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/test_application.py +0 -0
  132. {craft_application-4.2.0 → craft_application-4.2.2}/tests/integration/test_version.py +0 -0
  133. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/__init__.py +0 -0
  134. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/commands/__init__.py +0 -0
  135. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/commands/test_base.py +0 -0
  136. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/commands/test_lifecycle.py +0 -0
  137. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/commands/test_other.py +0 -0
  138. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/conftest.py +0 -0
  139. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/git/__init__.py +0 -0
  140. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/git/test_errors.py +0 -0
  141. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/git/test_git.py +0 -0
  142. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/__init__.py +0 -0
  143. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/conftest.py +0 -0
  144. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/models/__init__.py +0 -0
  145. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/models/test_base.py +0 -0
  146. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/models/test_code.py +0 -0
  147. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/test_launchpad.py +0 -0
  148. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/launchpad/test_util.py +0 -0
  149. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/__init__.py +0 -0
  150. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/project_models/basic_project.yaml +0 -0
  151. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/project_models/full_project.yaml +0 -0
  152. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/project_models/invalid_project.yaml +0 -0
  153. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/test_constraints.py +0 -0
  154. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/test_grammar.py +0 -0
  155. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/models/test_project.py +0 -0
  156. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/remote/__init__.py +0 -0
  157. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/remote/conftest.py +0 -0
  158. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/remote/test_errors.py +0 -0
  159. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/remote/test_utils.py +0 -0
  160. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/remote/test_worktree.py +0 -0
  161. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/__init__.py +0 -0
  162. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/conftest.py +0 -0
  163. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_config.py +0 -0
  164. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_lifecycle.py +0 -0
  165. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_package.py +0 -0
  166. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_provider.py +0 -0
  167. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_remotebuild.py +0 -0
  168. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_repositories.py +0 -0
  169. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_request.py +0 -0
  170. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/services/test_service_factory.py +0 -0
  171. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/test_application.py +0 -0
  172. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/test_errors.py +0 -0
  173. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/test_grammar.py +0 -0
  174. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/test_nothing.py +0 -0
  175. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/test_secrets.py +0 -0
  176. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/__init__.py +0 -0
  177. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/invalid_yaml/_README +0 -0
  178. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/invalid_yaml/duplicate_second_level.yaml-invalid +0 -0
  179. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/invalid_yaml/duplicate_top_level.yaml-invalid +0 -0
  180. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/invalid_yaml/unhashable.yaml-invalid +0 -0
  181. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_docs.py +0 -0
  182. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_error_formatting.py +0 -0
  183. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_logging.py +0 -0
  184. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_paths.py +0 -0
  185. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_platforms.py +0 -0
  186. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_retry.py +0 -0
  187. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_snap_config.py +0 -0
  188. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_string.py +0 -0
  189. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/test_yaml.py +0 -0
  190. {craft_application-4.2.0 → craft_application-4.2.2}/tests/unit/util/valid_yaml/empty.yaml +0 -0
  191. {craft_application-4.2.0 → craft_application-4.2.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: craft-application
3
- Version: 4.2.0
3
+ Version: 4.2.2
4
4
  Summary: A framework for *craft applications.
5
5
  Classifier: Development Status :: 5 - Production/Stable
6
6
  Classifier: Environment :: Console
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '4.2.0'
16
- __version_tuple__ = version_tuple = (4, 2, 0)
15
+ __version__ = version = '4.2.2'
16
+ __version_tuple__ = version_tuple = (4, 2, 2)
@@ -392,8 +392,9 @@ class Application:
392
392
  """Configure the application using any global arguments."""
393
393
 
394
394
  def _get_dispatcher(self) -> craft_cli.Dispatcher:
395
- """Configure this application. Should be called by the run method.
395
+ """Configure this application.
396
396
 
397
+ Should be called by the _run_inner method.
397
398
  Side-effect: This method may exit the process.
398
399
 
399
400
  :returns: A ready-to-run Dispatcher object
@@ -506,59 +507,62 @@ class Application:
506
507
  """
507
508
  return getattr(parsed_args, item, self.services.config.get(item))
508
509
 
509
- def run( # noqa: PLR0912,PLR0915 (too many branches, too many statements)
510
- self,
511
- ) -> int:
512
- """Bootstrap and run the application."""
513
- self._setup_logging()
514
- self._initialize_craft_parts()
510
+ def _run_inner(self) -> int:
511
+ """Actual run implementation."""
515
512
  dispatcher = self._get_dispatcher()
516
- craft_cli.emit.debug("Preparing application...")
517
-
518
- return_code = 1 # General error
519
- try:
520
- command = cast(
521
- commands.AppCommand,
522
- dispatcher.load_command(self.app_config),
513
+ command = cast(
514
+ commands.AppCommand,
515
+ dispatcher.load_command(self.app_config),
516
+ )
517
+ parsed_args = dispatcher.parsed_args()
518
+ platform = self.get_arg_or_config(parsed_args, "platform")
519
+ build_for = self.get_arg_or_config(parsed_args, "build_for")
520
+
521
+ # Some commands (e.g. remote build) can allow multiple platforms
522
+ # or build-fors, comma-separated. In these cases, we create the
523
+ # project using the first defined platform.
524
+ if platform and "," in platform:
525
+ platform = platform.split(",", maxsplit=1)[0]
526
+ if build_for and "," in build_for:
527
+ build_for = build_for.split(",", maxsplit=1)[0]
528
+
529
+ provider_name = command.provider_name(dispatcher.parsed_args())
530
+
531
+ craft_cli.emit.debug(f"Build plan: platform={platform}, build_for={build_for}")
532
+ self._pre_run(dispatcher)
533
+
534
+ managed_mode = command.run_managed(dispatcher.parsed_args())
535
+ if managed_mode or command.needs_project(dispatcher.parsed_args()):
536
+ self.services.project = self.get_project(
537
+ platform=platform, build_for=build_for
523
538
  )
524
- parsed_args = dispatcher.parsed_args()
525
- platform = self.get_arg_or_config(parsed_args, "platform")
526
- build_for = self.get_arg_or_config(parsed_args, "build_for")
527
539
 
528
- # Some commands (e.g. remote build) can allow multiple platforms
529
- # or build-fors, comma-separated. In these cases, we create the
530
- # project using the first defined platform.
531
- if platform and "," in platform:
532
- platform = platform.split(",", maxsplit=1)[0]
533
- if build_for and "," in build_for:
534
- build_for = build_for.split(",", maxsplit=1)[0]
540
+ self._configure_services(provider_name)
535
541
 
536
- provider_name = command.provider_name(dispatcher.parsed_args())
542
+ return_code = 1 # General error
543
+ if not managed_mode:
544
+ # command runs in the outer instance
545
+ craft_cli.emit.debug(f"Running {self.app.name} {command.name} on host")
546
+ return_code = dispatcher.run() or os.EX_OK
547
+ elif not self.is_managed():
548
+ # command runs in inner instance, but this is the outer instance
549
+ self.run_managed(platform, build_for)
550
+ return_code = os.EX_OK
551
+ else:
552
+ # command runs in inner instance
553
+ return_code = dispatcher.run() or 0
537
554
 
538
- craft_cli.emit.debug(
539
- f"Build plan: platform={platform}, build_for={build_for}"
540
- )
541
- self._pre_run(dispatcher)
555
+ return return_code
542
556
 
543
- managed_mode = command.run_managed(dispatcher.parsed_args())
544
- if managed_mode or command.needs_project(dispatcher.parsed_args()):
545
- self.services.project = self.get_project(
546
- platform=platform, build_for=build_for
547
- )
557
+ def run(self) -> int:
558
+ """Bootstrap and run the application."""
559
+ self._setup_logging()
560
+ self._initialize_craft_parts()
548
561
 
549
- self._configure_services(provider_name)
562
+ craft_cli.emit.debug("Preparing application...")
550
563
 
551
- if not managed_mode:
552
- # command runs in the outer instance
553
- craft_cli.emit.debug(f"Running {self.app.name} {command.name} on host")
554
- return_code = dispatcher.run() or os.EX_OK
555
- elif not self.is_managed():
556
- # command runs in inner instance, but this is the outer instance
557
- self.run_managed(platform, build_for)
558
- return_code = os.EX_OK
559
- else:
560
- # command runs in inner instance
561
- return_code = dispatcher.run() or 0
564
+ try:
565
+ return_code = self._run_inner()
562
566
  except craft_cli.ArgumentParsingError as err:
563
567
  print(err, file=sys.stderr) # to stderr, as argparse normally does
564
568
  craft_cli.emit.ended_ok()
@@ -38,6 +38,7 @@ class CraftBaseModel(pydantic.BaseModel):
38
38
  extra="forbid",
39
39
  populate_by_name=True,
40
40
  alias_generator=alias_generator,
41
+ coerce_numbers_to_str=True,
41
42
  )
42
43
 
43
44
  def marshal(self) -> dict[str, str | list[str] | dict[str, Any]]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: craft-application
3
- Version: 4.2.0
3
+ Version: 4.2.2
4
4
  Summary: A framework for *craft applications.
5
5
  Classifier: Development Status :: 5 - Production/Stable
6
6
  Classifier: Environment :: Console
@@ -2,6 +2,26 @@
2
2
  Changelog
3
3
  *********
4
4
 
5
+ 4.2.2 (2024-Sep-13)
6
+ -------------------
7
+
8
+ Application
9
+ ===========
10
+
11
+ - Add a ``_run_inner`` method to override or wrap the core run logic.
12
+
13
+ For a complete list of commits, check out the `4.2.2`_ release on GitHub.
14
+
15
+ 4.2.1 (2024-Sep-13)
16
+ -------------------
17
+
18
+ Models
19
+ ======
20
+
21
+ - Fix a regression where numeric part properties could not be parsed.
22
+
23
+ For a complete list of commits, check out the `4.2.1`_ release on GitHub.
24
+
5
25
  4.2.0 (2024-Sep-12)
6
26
  -------------------
7
27
 
@@ -244,3 +264,5 @@ For a complete list of commits, check out the `2.7.0`_ release on GitHub.
244
264
  .. _4.1.1: https://github.com/canonical/craft-application/releases/tag/4.1.1
245
265
  .. _4.1.2: https://github.com/canonical/craft-application/releases/tag/4.1.2
246
266
  .. _4.2.0: https://github.com/canonical/craft-application/releases/tag/4.2.0
267
+ .. _4.2.1: https://github.com/canonical/craft-application/releases/tag/4.2.1
268
+ .. _4.2.2: https://github.com/canonical/craft-application/releases/tag/4.2.2
@@ -19,6 +19,7 @@ from pathlib import Path
19
19
  import pydantic
20
20
  import pytest
21
21
  from craft_application import errors, models
22
+ from hypothesis import given, strategies
22
23
  from overrides import override
23
24
 
24
25
 
@@ -58,3 +59,22 @@ def test_model_reference_slug_errors():
58
59
  )
59
60
  assert str(err.value) == expected
60
61
  assert err.value.doc_slug == "/mymodel.html"
62
+
63
+
64
+ class CoerceModel(models.CraftBaseModel):
65
+
66
+ stringy: str
67
+
68
+
69
+ @given(
70
+ strategies.one_of(
71
+ strategies.integers(),
72
+ strategies.floats(),
73
+ strategies.decimals(),
74
+ strategies.text(),
75
+ )
76
+ )
77
+ def test_model_coerces_to_strings(value):
78
+ result = CoerceModel.model_validate({"stringy": value})
79
+
80
+ assert result.stringy == str(value)