nextmv 1.7.4.dev5__tar.gz → 1.8.0.dev1__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 (415) hide show
  1. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/PKG-INFO +1 -1
  2. nextmv-1.8.0.dev1/nextmv/__about__.py +1 -0
  3. nextmv-1.8.0.dev1/nextmv/cache.py +431 -0
  4. nextmv-1.8.0.dev1/nextmv/cli/cache/__init__.py +21 -0
  5. nextmv-1.8.0.dev1/nextmv/cli/cache/delete.py +48 -0
  6. nextmv-1.8.0.dev1/nextmv/cli/cache/get.py +27 -0
  7. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/push.py +13 -0
  8. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/main.py +2 -0
  9. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/__init__.py +20 -4
  10. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/client.py +29 -4
  11. nextmv-1.8.0.dev1/nextmv/cloud/package.py +1246 -0
  12. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/executor.py +4 -7
  13. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/polling.py +8 -5
  14. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/test_configuration.py +0 -5
  15. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cloud/test_client.py +91 -0
  16. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cloud/test_package.py +7 -7
  17. nextmv-1.8.0.dev1/tests/test_cache.py +412 -0
  18. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_manifest.py +3 -3
  19. nextmv-1.7.4.dev5/nextmv/__about__.py +0 -1
  20. nextmv-1.7.4.dev5/nextmv/cloud/package.py +0 -349
  21. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/.gitignore +0 -0
  22. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/.python-version +0 -0
  23. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/CONTRIBUTING.md +0 -0
  24. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/LICENSE +0 -0
  25. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/README.md +0 -0
  26. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/__entrypoint__.py +0 -0
  27. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/__init__.py +0 -0
  28. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/_serialization.py +0 -0
  29. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/account.py +0 -0
  30. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/base_model.py +0 -0
  31. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/__init__.py +0 -0
  32. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/__init__.py +0 -0
  33. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/acceptance/__init__.py +0 -0
  34. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/acceptance/create.py +0 -0
  35. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/acceptance/delete.py +0 -0
  36. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/acceptance/get.py +0 -0
  37. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/acceptance/list.py +0 -0
  38. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/acceptance/update.py +0 -0
  39. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/account/__init__.py +0 -0
  40. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/account/create.py +0 -0
  41. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/account/delete.py +0 -0
  42. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/account/get.py +0 -0
  43. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/account/update.py +0 -0
  44. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/__init__.py +0 -0
  45. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/create.py +0 -0
  46. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/delete.py +0 -0
  47. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/exists.py +0 -0
  48. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/get.py +0 -0
  49. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/list.py +0 -0
  50. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/app/update.py +0 -0
  51. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/__init__.py +0 -0
  52. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/create.py +0 -0
  53. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/delete.py +0 -0
  54. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/get.py +0 -0
  55. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/list.py +0 -0
  56. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/metadata.py +0 -0
  57. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/batch/update.py +0 -0
  58. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/data/__init__.py +0 -0
  59. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/data/upload.py +0 -0
  60. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/ensemble/__init__.py +0 -0
  61. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/ensemble/create.py +0 -0
  62. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/ensemble/delete.py +0 -0
  63. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/ensemble/get.py +0 -0
  64. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/ensemble/list.py +0 -0
  65. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/ensemble/update.py +0 -0
  66. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/input_set/__init__.py +0 -0
  67. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/input_set/create.py +0 -0
  68. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/input_set/delete.py +0 -0
  69. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/input_set/get.py +0 -0
  70. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/input_set/list.py +0 -0
  71. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/input_set/update.py +0 -0
  72. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/__init__.py +0 -0
  73. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/create.py +0 -0
  74. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/delete.py +0 -0
  75. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/exists.py +0 -0
  76. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/get.py +0 -0
  77. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/list.py +0 -0
  78. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/instance/update.py +0 -0
  79. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/managed_input/__init__.py +0 -0
  80. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/managed_input/create.py +0 -0
  81. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/managed_input/delete.py +0 -0
  82. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/managed_input/get.py +0 -0
  83. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/managed_input/list.py +0 -0
  84. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/managed_input/update.py +0 -0
  85. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/__init__.py +0 -0
  86. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/app/__init__.py +0 -0
  87. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/app/create.py +0 -0
  88. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/app/get.py +0 -0
  89. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/app/list.py +0 -0
  90. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/app/update.py +0 -0
  91. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/subscription/__init__.py +0 -0
  92. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/subscription/create.py +0 -0
  93. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/subscription/delete.py +0 -0
  94. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/subscription/get.py +0 -0
  95. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/subscription/list.py +0 -0
  96. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/version/__init__.py +0 -0
  97. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/version/create.py +0 -0
  98. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/version/get.py +0 -0
  99. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/version/list.py +0 -0
  100. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/marketplace/version/update.py +0 -0
  101. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/__init__.py +0 -0
  102. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/cancel.py +0 -0
  103. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/create.py +0 -0
  104. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/delete.py +0 -0
  105. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/get.py +0 -0
  106. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/input.py +0 -0
  107. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/list.py +0 -0
  108. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/logs.py +0 -0
  109. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/metadata.py +0 -0
  110. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/run/track.py +0 -0
  111. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/__init__.py +0 -0
  112. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/create.py +0 -0
  113. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/delete.py +0 -0
  114. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/get.py +0 -0
  115. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/list.py +0 -0
  116. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/metadata.py +0 -0
  117. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/scenario/update.py +0 -0
  118. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/secrets/__init__.py +0 -0
  119. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/secrets/create.py +0 -0
  120. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/secrets/delete.py +0 -0
  121. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/secrets/get.py +0 -0
  122. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/secrets/list.py +0 -0
  123. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/secrets/update.py +0 -0
  124. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/__init__.py +0 -0
  125. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/create.py +0 -0
  126. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/delete.py +0 -0
  127. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/get.py +0 -0
  128. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/list.py +0 -0
  129. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/metadata.py +0 -0
  130. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/start.py +0 -0
  131. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/stop.py +0 -0
  132. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/shadow/update.py +0 -0
  133. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/__init__.py +0 -0
  134. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/create.py +0 -0
  135. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/delete.py +0 -0
  136. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/disable.py +0 -0
  137. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/domain/__init__.py +0 -0
  138. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/domain/delete.py +0 -0
  139. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/enable.py +0 -0
  140. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/get.py +0 -0
  141. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/sso/update.py +0 -0
  142. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/__init__.py +0 -0
  143. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/create.py +0 -0
  144. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/delete.py +0 -0
  145. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/get.py +0 -0
  146. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/list.py +0 -0
  147. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/metadata.py +0 -0
  148. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/start.py +0 -0
  149. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/stop.py +0 -0
  150. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/switchback/update.py +0 -0
  151. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/upload/__init__.py +0 -0
  152. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/upload/create.py +0 -0
  153. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/__init__.py +0 -0
  154. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/create.py +0 -0
  155. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/delete.py +0 -0
  156. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/exists.py +0 -0
  157. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/get.py +0 -0
  158. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/list.py +0 -0
  159. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/cloud/version/update.py +0 -0
  160. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/community/__init__.py +0 -0
  161. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/community/clone.py +0 -0
  162. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/community/list.py +0 -0
  163. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/configuration/__init__.py +0 -0
  164. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/configuration/config.py +0 -0
  165. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/configuration/create.py +0 -0
  166. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/configuration/delete.py +0 -0
  167. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/configuration/list.py +0 -0
  168. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/init.py +0 -0
  169. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/__init__.py +0 -0
  170. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/__init__.py +0 -0
  171. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/delete.py +0 -0
  172. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/get.py +0 -0
  173. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/list.py +0 -0
  174. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/register.py +0 -0
  175. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/registered.py +0 -0
  176. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/sync.py +0 -0
  177. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/app/update.py +0 -0
  178. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/__init__.py +0 -0
  179. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/create.py +0 -0
  180. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/get.py +0 -0
  181. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/input.py +0 -0
  182. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/list.py +0 -0
  183. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/logs.py +0 -0
  184. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/metadata.py +0 -0
  185. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/local/run/visuals.py +0 -0
  186. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/manifest/__init__.py +0 -0
  187. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/manifest/init.py +0 -0
  188. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/manifest/validate.py +0 -0
  189. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/__init__.py +0 -0
  190. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/serve.py +0 -0
  191. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/server.py +0 -0
  192. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/WORKFLOW.md +0 -0
  193. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/__init__.py +0 -0
  194. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/_helpers.py +0 -0
  195. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/acceptance.py +0 -0
  196. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/account.py +0 -0
  197. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/app.py +0 -0
  198. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/batch.py +0 -0
  199. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/community.py +0 -0
  200. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/ensemble.py +0 -0
  201. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/guide.py +0 -0
  202. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/input_set.py +0 -0
  203. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/instance.py +0 -0
  204. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/local.py +0 -0
  205. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/managed_input.py +0 -0
  206. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/profile.py +0 -0
  207. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/run.py +0 -0
  208. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/scenario.py +0 -0
  209. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/secrets.py +0 -0
  210. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/shadow.py +0 -0
  211. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/sso.py +0 -0
  212. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/switchback.py +0 -0
  213. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/mcp/tools/version.py +0 -0
  214. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/message.py +0 -0
  215. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/options.py +0 -0
  216. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cli/version.py +0 -0
  217. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/__init__.py +0 -0
  218. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/acceptance_test.py +0 -0
  219. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/account.py +0 -0
  220. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_acceptance.py +0 -0
  221. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_batch_scenario.py +0 -0
  222. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_ensemble.py +0 -0
  223. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_input_set.py +0 -0
  224. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_instance.py +0 -0
  225. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_managed_input.py +0 -0
  226. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_run.py +0 -0
  227. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_secrets.py +0 -0
  228. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_shadow.py +0 -0
  229. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_switchback.py +0 -0
  230. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_utils.py +0 -0
  231. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/application/_version.py +0 -0
  232. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/assets.py +0 -0
  233. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/batch_experiment.py +0 -0
  234. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/community.py +0 -0
  235. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/ensemble.py +0 -0
  236. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/input_set.py +0 -0
  237. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/instance.py +0 -0
  238. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/integration.py +0 -0
  239. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/marketplace.py +0 -0
  240. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/scenario.py +0 -0
  241. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/secrets.py +0 -0
  242. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/shadow.py +0 -0
  243. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/sso.py +0 -0
  244. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/switchback.py +0 -0
  245. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/url.py +0 -0
  246. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/cloud/version.py +0 -0
  247. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/content_format.py +0 -0
  248. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/deprecated.py +0 -0
  249. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/input.py +0 -0
  250. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/__init__.py +0 -0
  251. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/application.py +0 -0
  252. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/geojson_handler.py +0 -0
  253. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/local.py +0 -0
  254. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/plotly_handler.py +0 -0
  255. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/registry.py +0 -0
  256. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/local/runner.py +0 -0
  257. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/logger.py +0 -0
  258. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/manifest.py +0 -0
  259. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/model.py +0 -0
  260. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/options.py +0 -0
  261. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/output.py +0 -0
  262. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/run.py +0 -0
  263. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/safe.py +0 -0
  264. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/status.py +0 -0
  265. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/binary_json.yaml +0 -0
  266. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/binary_json_opt.yaml +0 -0
  267. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/binary_multi-file.yaml +0 -0
  268. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/binary_multi-file_opt.yaml +0 -0
  269. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json.yaml +0 -0
  270. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_hello-world/.gitignore +0 -0
  271. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_hello-world/README.md +0 -0
  272. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_hello-world/app.yaml +0 -0
  273. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_hello-world/go.mod +0 -0
  274. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_hello-world/input.json +0 -0
  275. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_hello-world/main.go +0 -0
  276. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_json_opt.yaml +0 -0
  277. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file.yaml +0 -0
  278. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_hello-world/.gitignore +0 -0
  279. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_hello-world/README.md +0 -0
  280. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_hello-world/app.yaml +0 -0
  281. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_hello-world/go.mod +0 -0
  282. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_hello-world/inputs/input.json +0 -0
  283. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_hello-world/main.go +0 -0
  284. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/go_multi-file_opt.yaml +0 -0
  285. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json.yaml +0 -0
  286. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_hello-world/.gitignore +0 -0
  287. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_hello-world/Main.java +0 -0
  288. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_hello-world/README.md +0 -0
  289. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_hello-world/app.yaml +0 -0
  290. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_hello-world/input.json +0 -0
  291. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_hello-world/pom.xml +0 -0
  292. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_json_opt.yaml +0 -0
  293. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file.yaml +0 -0
  294. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_hello-world/.gitignore +0 -0
  295. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_hello-world/Main.java +0 -0
  296. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_hello-world/README.md +0 -0
  297. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_hello-world/app.yaml +0 -0
  298. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_hello-world/inputs/input.json +0 -0
  299. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_hello-world/pom.xml +0 -0
  300. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/java_multi-file_opt.yaml +0 -0
  301. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json.yaml +0 -0
  302. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/.gitignore +0 -0
  303. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/README.md +0 -0
  304. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/app.yaml +0 -0
  305. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/input.json +0 -0
  306. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/main.py +0 -0
  307. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/pyproject.toml +0 -0
  308. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/uv.lock +0 -0
  309. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_class-assign/visualizations.py +0 -0
  310. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/.gitignore +0 -0
  311. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/README.md +0 -0
  312. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/README.md +0 -0
  313. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/app.yaml +0 -0
  314. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/input.json +0 -0
  315. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/main.py +0 -0
  316. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/pyproject.toml +0 -0
  317. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/uv.lock +0 -0
  318. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/allocation/visuals.py +0 -0
  319. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/README.md +0 -0
  320. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/app.yaml +0 -0
  321. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/input.json +0 -0
  322. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/main.py +0 -0
  323. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/pyproject.toml +0 -0
  324. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/uv.lock +0 -0
  325. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_demand-alloc/workflow/visuals.py +0 -0
  326. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/.gitignore +0 -0
  327. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/README.md +0 -0
  328. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/app.yaml +0 -0
  329. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/input.json +0 -0
  330. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/main.py +0 -0
  331. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/pyproject.toml +0 -0
  332. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_hello-world/uv.lock +0 -0
  333. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_json_opt.yaml +0 -0
  334. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file.yaml +0 -0
  335. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/.gitignore +0 -0
  336. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/README.md +0 -0
  337. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/app.yaml +0 -0
  338. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/inputs/input.json +0 -0
  339. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/main.py +0 -0
  340. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/pyproject.toml +0 -0
  341. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/uv.lock +0 -0
  342. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_class-assign/visualizations.py +0 -0
  343. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/README.md +0 -0
  344. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/README.md +0 -0
  345. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/app.yaml +0 -0
  346. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/input.json +0 -0
  347. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/main.py +0 -0
  348. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/pyproject.toml +0 -0
  349. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/uv.lock +0 -0
  350. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/allocation/visuals.py +0 -0
  351. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/.gitignore +0 -0
  352. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/README.md +0 -0
  353. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/app.yaml +0 -0
  354. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/inputs/input.json +0 -0
  355. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/main.py +0 -0
  356. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/pyproject.toml +0 -0
  357. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/uv.lock +0 -0
  358. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_demand-alloc/workflow/visuals.py +0 -0
  359. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/.gitignore +0 -0
  360. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/README.md +0 -0
  361. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/app.yaml +0 -0
  362. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/inputs/input.json +0 -0
  363. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/main.py +0 -0
  364. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/pyproject.toml +0 -0
  365. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_hello-world/uv.lock +0 -0
  366. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/templates/python_multi-file_opt.yaml +0 -0
  367. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/nextmv/uv_handler.py +0 -0
  368. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/pyproject.toml +0 -0
  369. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/__init__.py +0 -0
  370. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/__init__.py +0 -0
  371. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/manifest/__init__.py +0 -0
  372. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/manifest/test_init.py +0 -0
  373. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/test_init_cli_call.py +0 -0
  374. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/test_main.py +0 -0
  375. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/test_mcp.py +0 -0
  376. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cli/test_version.py +0 -0
  377. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cloud/__init__.py +0 -0
  378. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cloud/app.yaml +0 -0
  379. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cloud/test_instance.py +0 -0
  380. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/cloud/test_scenario.py +0 -0
  381. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/integration/__init__.py +0 -0
  382. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/integration/cloud/__init__.py +0 -0
  383. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/integration/cloud/test_integration_cloud.py +0 -0
  384. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/integration/cloud/test_integration_marketplace.py +0 -0
  385. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/local/__init__.py +0 -0
  386. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/local/test_application.py +0 -0
  387. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/local/test_executor.py +0 -0
  388. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/local/test_registry.py +0 -0
  389. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/local/test_runner.py +0 -0
  390. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/__init__.py +0 -0
  391. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options1.py +0 -0
  392. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options2.py +0 -0
  393. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options3.py +0 -0
  394. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options4.py +0 -0
  395. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options5.py +0 -0
  396. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options6.py +0 -0
  397. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/scripts/options7.py +0 -0
  398. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_base_model.py +0 -0
  399. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_entrypoint/__init__.py +0 -0
  400. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_entrypoint/test_entrypoint.py +0 -0
  401. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_input.py +0 -0
  402. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_inputs/test_data.csv +0 -0
  403. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_inputs/test_data.json +0 -0
  404. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_inputs/test_data.txt +0 -0
  405. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_logger.py +0 -0
  406. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_model.py +0 -0
  407. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_options.py +0 -0
  408. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_output.py +0 -0
  409. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_polling.py +0 -0
  410. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_run.py +0 -0
  411. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_safe.py +0 -0
  412. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_serialization.py +0 -0
  413. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_uv_handler.py +0 -0
  414. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/tests/test_version.py +0 -0
  415. {nextmv-1.7.4.dev5 → nextmv-1.8.0.dev1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextmv
3
- Version: 1.7.4.dev5
3
+ Version: 1.8.0.dev1
4
4
  Summary: The all-purpose Python SDK for Nextmv
5
5
  Project-URL: Homepage, https://www.nextmv.io
6
6
  Project-URL: Documentation, https://nextmv-py.docs.nextmv.io/en/latest/nextmv/
@@ -0,0 +1 @@
1
+ __version__ = "v1.8.0.dev1"
@@ -0,0 +1,431 @@
1
+ """
2
+ Module with the cache interface and operations for working with dependencies.
3
+
4
+ Functions
5
+ ---------
6
+ get_cache
7
+ Get general information about the cache, including number of dependencies and total size.
8
+ clear_cache
9
+ Delete the entire cache directory and recreate it empty.
10
+ dep_cache_key
11
+ Return a SHA-256 hex digest that uniquely identifies a single package.
12
+ get_cached_dep
13
+ Return the path to the cached per-package `installed.tar.gz` on a hit.
14
+ store_dep
15
+ Store a per-package `installed.tar.gz` into the cache and run LRU eviction.
16
+ format_bytes
17
+ Return a human-friendly string representation of a byte count.
18
+ """
19
+
20
+ import hashlib
21
+ import json
22
+ import os
23
+ import re
24
+ import shutil
25
+ import tempfile
26
+ from datetime import datetime, timezone
27
+ from pathlib import Path
28
+ from typing import Any
29
+
30
+ _CACHE_DIR = Path.home() / ".nextmv" / "cache"
31
+ """Root directory for all Nextmv cache data."""
32
+ _DEPS_CACHE_DIR = _CACHE_DIR / "deps"
33
+ """Directory storing per-package dependency tarballs."""
34
+ _CACHE_INFO_FILE = "cache_info.json"
35
+ """Name of the metadata file stored alongside each cached entry."""
36
+ _DEP_TARBALL_NAME = "installed.tar.gz"
37
+ """Name of the per-package tarball containing installed files for a single package."""
38
+ _MAX_DEPS = 2000
39
+ """Maximum number of individual package tarballs to keep in the cache."""
40
+ _MAX_DEP_BYTES = 5 * 1024**3
41
+ """Maximum total cache size in bytes (5 GiB)."""
42
+
43
+
44
+ def get_cache() -> dict[str, Any]:
45
+ """
46
+ Gets general information about the cache.
47
+
48
+ Returns
49
+ -------
50
+ dict[str, Any]
51
+ A dictionary containing information about the cache, such as the number of
52
+ dependencies cached and the total size of the cache in bytes.
53
+ """
54
+
55
+ num_deps, total_bytes = _cache_stats()
56
+
57
+ dependencies = []
58
+ if _DEPS_CACHE_DIR.is_dir():
59
+ for entry_dir in _DEPS_CACHE_DIR.iterdir():
60
+ if not entry_dir.is_dir():
61
+ continue
62
+
63
+ info_file = entry_dir / _CACHE_INFO_FILE
64
+ try:
65
+ with open(info_file) as f:
66
+ info = json.load(f)
67
+
68
+ tarball = entry_dir / _DEP_TARBALL_NAME
69
+ try:
70
+ tarball_size = format_bytes(tarball.stat().st_size)
71
+ except OSError:
72
+ tarball_size = ""
73
+
74
+ dependencies.append(
75
+ {
76
+ "key": entry_dir.name,
77
+ "name": info.get("name", ""),
78
+ "version": info.get("version", ""),
79
+ "last_used_at": info.get("last_used_at", ""),
80
+ "python_version": info.get("python_version", ""),
81
+ "platform": info.get("platform", ""),
82
+ "size": tarball_size,
83
+ }
84
+ )
85
+ except Exception:
86
+ pass
87
+
88
+ if dependencies:
89
+ dependencies.sort(key=lambda d: (d["last_used_at"], d["name"], d["version"]), reverse=True)
90
+
91
+ return {
92
+ "num_dependencies": num_deps,
93
+ "total_size": format_bytes(total_bytes),
94
+ "dependencies": dependencies,
95
+ }
96
+
97
+
98
+ def clear_cache() -> tuple[int, int]:
99
+ """
100
+ Delete the entire cache directory and recreate it empty.
101
+
102
+ Returns
103
+ -------
104
+ tuple[int, int]
105
+ A tuple of (num_deps_deleted, total_bytes_deleted).
106
+ """
107
+
108
+ if not _CACHE_DIR.exists():
109
+ return 0, 0
110
+
111
+ num_deps, total_bytes = _cache_stats()
112
+ shutil.rmtree(str(_CACHE_DIR))
113
+ _create_cache()
114
+
115
+ return num_deps, total_bytes
116
+
117
+
118
+ def dep_cache_key(name: str, version: str, python_version: str, platform: str) -> str:
119
+ """
120
+ Return a SHA-256 hex digest that uniquely identifies a single package wheel.
121
+
122
+ The key is derived from the normalised package name, version, target Python
123
+ version, and platform. Name normalisation follows PEP 503 so that
124
+ `pydantic-core` and `pydantic_core` map to the same key.
125
+
126
+ Parameters
127
+ ----------
128
+ name : str
129
+ The package name as it appears in the lockfile or wheel filename.
130
+ version : str
131
+ The pinned version string (e.g. `"2.23.4"`).
132
+ python_version : str
133
+ The target Python version string (e.g. `"3.11"`).
134
+ platform : str
135
+ The target platform string (e.g. `"aarch64-unknown-linux-gnu"`).
136
+
137
+ Returns
138
+ -------
139
+ str
140
+ A 64-character lowercase hex SHA-256 digest.
141
+ """
142
+
143
+ normalized = re.sub(r"[-_.]+", "_", name.lower())
144
+ raw = f"{normalized}=={version}|{python_version}|{platform}"
145
+
146
+ return hashlib.sha256(raw.encode()).hexdigest()
147
+
148
+
149
+ def get_cached_dep(pkg_key: str) -> Path | None:
150
+ """
151
+ Return the path to the cached `installed.tar.gz` for *pkg_key*, or `None`
152
+ on a miss.
153
+
154
+ The tarball contains the installed files for a single package archived under
155
+ `.nextmv/python/deps/`, ready to be concatenated with other per-package
156
+ tarballs to form the final `deps.tar.gz` (valid per RFC 1952).
157
+
158
+ On a cache hit `last_used_at` in the entry's `cache_info.json` is
159
+ updated to the current UTC time for LRU tracking.
160
+
161
+ Parameters
162
+ ----------
163
+ pkg_key : str
164
+ The cache key returned by :func:`dep_cache_key`.
165
+
166
+ Returns
167
+ -------
168
+ Path or None
169
+ Path to the `installed.tar.gz` file, or `None` when no entry exists.
170
+ """
171
+
172
+ entry_dir = _DEPS_CACHE_DIR / pkg_key
173
+ info_file = entry_dir / _CACHE_INFO_FILE
174
+ installed_tar = entry_dir / _DEP_TARBALL_NAME
175
+
176
+ if not installed_tar.is_file() or not info_file.is_file():
177
+ return None
178
+
179
+ # Update last_used_at for true LRU tracking.
180
+ try:
181
+ with open(info_file) as f:
182
+ info = json.load(f)
183
+
184
+ info["last_used_at"] = _now_iso()
185
+ _write_json_atomic(path=info_file, data=info)
186
+ except Exception:
187
+ pass
188
+
189
+ return installed_tar
190
+
191
+
192
+ def store_dep(
193
+ pkg_key: str,
194
+ tar_path: Path,
195
+ name: str,
196
+ version: str,
197
+ python_version: str,
198
+ platform: str,
199
+ max_entries: int = _MAX_DEPS,
200
+ max_bytes: int = _MAX_DEP_BYTES,
201
+ ) -> None:
202
+ """
203
+ Store a per-package `installed.tar.gz` in the cache and run LRU eviction.
204
+
205
+ The tarball must contain the installed files for a single package archived
206
+ under `.nextmv/python/deps/`. The copy is performed atomically via a
207
+ sibling temporary directory followed by a rename.
208
+
209
+ Parameters
210
+ ----------
211
+ pkg_key : str
212
+ The cache key returned by :func:`dep_cache_key`.
213
+ tar_path : Path
214
+ Path to the `installed.tar.gz` to cache.
215
+ name : str
216
+ The package name (e.g. `"pydantic-core"`).
217
+ version : str
218
+ The pinned version string (e.g. `"2.23.4"`).
219
+ python_version : str
220
+ The target Python version string (e.g. `"3.11"`).
221
+ platform : str
222
+ The target platform string (e.g. `"aarch64-unknown-linux-gnu"`).
223
+ max_entries : int, optional
224
+ Maximum number of package tarball entries to retain.
225
+ max_bytes : int, optional
226
+ Maximum total cache size in bytes.
227
+ """
228
+
229
+ _create_cache()
230
+ entry_dir = _DEPS_CACHE_DIR / pkg_key
231
+
232
+ with tempfile.TemporaryDirectory(dir=_DEPS_CACHE_DIR, prefix=f"{pkg_key}-tmp-", ignore_cleanup_errors=True) as _tmp:
233
+ tmp_entry = Path(_tmp)
234
+ shutil.copy2(str(tar_path), tmp_entry / _DEP_TARBALL_NAME)
235
+ now = _now_iso()
236
+ info = {
237
+ "created_at": now,
238
+ "last_used_at": now,
239
+ "name": name,
240
+ "version": version,
241
+ "python_version": python_version,
242
+ "platform": platform,
243
+ }
244
+ _write_json_atomic(path=tmp_entry / _CACHE_INFO_FILE, data=info)
245
+
246
+ # Rename into place; if the key already exists (race), keep existing.
247
+ if not entry_dir.exists():
248
+ tmp_entry.rename(entry_dir)
249
+
250
+ _evict_lru(max_entries=max_entries, max_bytes=max_bytes)
251
+
252
+
253
+ def format_bytes(size: int) -> str:
254
+ """
255
+ Return a human-friendly string representation of a byte count.
256
+
257
+ Parameters
258
+ ----------
259
+ size : int
260
+ The size in bytes to format.
261
+
262
+ Returns
263
+ -------
264
+ str
265
+ A human-friendly string using B, KiB, MiB, or GiB units.
266
+ """
267
+
268
+ if size < 1024:
269
+ return f"{size} B"
270
+ elif size < 1024 * 1024:
271
+ return f"{size / 1024:.2f} KiB"
272
+ elif size < 1024 * 1024 * 1024:
273
+ return f"{size / (1024 * 1024):.2f} MiB"
274
+ else:
275
+ return f"{size / (1024 * 1024 * 1024):.2f} GiB"
276
+
277
+
278
+ def _cache_stats() -> tuple[int, int]:
279
+ """
280
+ Return the number of cached dependency entries and their total size in bytes.
281
+
282
+ Returns
283
+ -------
284
+ tuple[int, int]
285
+ A tuple of (num_deps, total_bytes).
286
+ """
287
+
288
+ num_deps = 0
289
+ total_bytes = 0
290
+
291
+ if not _DEPS_CACHE_DIR.is_dir():
292
+ return num_deps, total_bytes
293
+
294
+ for entry_dir in _DEPS_CACHE_DIR.iterdir():
295
+ if entry_dir.is_dir():
296
+ num_deps += 1
297
+ total_bytes += _dir_size(entry_dir)
298
+
299
+ return num_deps, total_bytes
300
+
301
+
302
+ def _create_cache() -> None:
303
+ """
304
+ Create the cache directories if they do not already exist.
305
+ """
306
+
307
+ _DEPS_CACHE_DIR.mkdir(parents=True, exist_ok=True)
308
+
309
+ # Remove leftover staging dirs from previous crashed/killed runs.
310
+ for entry in _DEPS_CACHE_DIR.iterdir():
311
+ if entry.is_dir() and "-tmp-" in entry.name:
312
+ shutil.rmtree(str(entry), ignore_errors=True)
313
+
314
+
315
+ def _evict_lru(max_entries: int = _MAX_DEPS, max_bytes: int = _MAX_DEP_BYTES) -> int:
316
+ """
317
+ Remove the least-recently-used per-package tarball cache entries until both
318
+ caps are satisfied.
319
+
320
+ Parameters
321
+ ----------
322
+ max_entries : int, optional
323
+ Maximum number of package tarball entries to retain.
324
+ max_bytes : int, optional
325
+ Maximum total cache size in bytes.
326
+
327
+ Returns
328
+ -------
329
+ int
330
+ The number of entries that were removed.
331
+ """
332
+
333
+ if not _DEPS_CACHE_DIR.is_dir():
334
+ return 0
335
+
336
+ entries = []
337
+ for entry_dir in _DEPS_CACHE_DIR.iterdir():
338
+ if not entry_dir.is_dir() or "-tmp-" in entry_dir.name:
339
+ continue
340
+
341
+ info_file = entry_dir / _CACHE_INFO_FILE
342
+ # If the info file has problems, treat the entry as very old.
343
+ try:
344
+ with open(info_file) as f:
345
+ info = json.load(f)
346
+
347
+ last_used = datetime.fromisoformat(info["last_used_at"])
348
+ except Exception:
349
+ last_used = datetime.min.replace(tzinfo=timezone.utc)
350
+
351
+ entries.append(
352
+ {
353
+ "last_used": last_used,
354
+ "dir": entry_dir,
355
+ "size": _dir_size(entry_dir),
356
+ }
357
+ )
358
+
359
+ entries.sort(key=lambda e: e["last_used"])
360
+
361
+ total = sum(e["size"] for e in entries)
362
+ evicted = 0
363
+ while entries and (len(entries) > max_entries or total > max_bytes):
364
+ oldest = entries.pop(0)
365
+ shutil.rmtree(str(oldest["dir"]), ignore_errors=True)
366
+ total -= oldest["size"]
367
+ evicted += 1
368
+
369
+ return evicted
370
+
371
+
372
+ def _now_iso() -> str:
373
+ """
374
+ Return the current UTC time as an ISO-8601 string.
375
+
376
+ Returns
377
+ -------
378
+ str
379
+ Current UTC time as an ISO-8601 string.
380
+ """
381
+
382
+ return datetime.now(tz=timezone.utc).isoformat()
383
+
384
+
385
+ def _dir_size(path: Path) -> int:
386
+ """
387
+ Return the total size in bytes of all files under path.
388
+
389
+ Parameters
390
+ ----------
391
+ path : Path
392
+ The directory path to calculate the size of.
393
+
394
+ Returns
395
+ -------
396
+ int
397
+ Total size in bytes of all files under path.
398
+ """
399
+
400
+ total = 0
401
+ for root, _, files in os.walk(path):
402
+ for fname in files:
403
+ try:
404
+ total += os.path.getsize(os.path.join(root, fname))
405
+ except OSError:
406
+ pass
407
+
408
+ return total
409
+
410
+
411
+ def _write_json_atomic(path: Path, data: dict) -> None:
412
+ """
413
+ Write data as JSON to path atomically via a sibling temporary file.
414
+
415
+ Parameters
416
+ ----------
417
+ path : Path
418
+ The path to write the JSON data to.
419
+ data : dict
420
+ The data to write as JSON.
421
+ """
422
+
423
+ with tempfile.NamedTemporaryFile(mode="w", dir=path.parent, prefix=".tmp-", delete=False) as f:
424
+ json.dump(data, f, indent=2)
425
+ tmp = Path(f.name)
426
+
427
+ try:
428
+ os.replace(tmp, path)
429
+ except Exception as e:
430
+ tmp.unlink(missing_ok=True)
431
+ raise e
@@ -0,0 +1,21 @@
1
+ """
2
+ This module defines the cache command tree for the Nextmv CLI.
3
+ """
4
+
5
+ import typer
6
+
7
+ from nextmv.cli.cache.delete import app as delete_app
8
+ from nextmv.cli.cache.get import app as get_app
9
+
10
+ # Set up subcommand application.
11
+ app = typer.Typer()
12
+ app.add_typer(delete_app)
13
+ app.add_typer(get_app)
14
+
15
+
16
+ @app.callback()
17
+ def callback() -> None:
18
+ """
19
+ Manage the cache used for Nextmv operations.
20
+ """
21
+ pass
@@ -0,0 +1,48 @@
1
+ """
2
+ This module defines the cache delete command for the Nextmv CLI.
3
+ """
4
+
5
+ import typer
6
+
7
+ from nextmv.cache import clear_cache, format_bytes
8
+ from nextmv.cli.message import confirmation, info, success
9
+ from nextmv.cli.options import YesOption
10
+
11
+ # Set up subcommand application.
12
+ app = typer.Typer()
13
+
14
+
15
+ @app.command()
16
+ def delete(yes: YesOption = False) -> None:
17
+ """
18
+ Deletes the Nextmv cache and resets it to an empty state.
19
+
20
+ This action is permanent and cannot be undone. Use the --yes flag to skip
21
+ the confirmation prompt.
22
+
23
+ [bold][underline]Examples[/underline][/bold]
24
+
25
+ - Delete the Nextmv cache.
26
+ $ [dim]nextmv cache delete[/dim]
27
+
28
+ - Delete the Nextmv cache without confirmation prompt.
29
+ $ [dim]nextmv cache delete --yes[/dim]
30
+ """
31
+
32
+ deps, bytes_deleted = clear_cache()
33
+ if deps == 0 and bytes_deleted == 0:
34
+ info("Nothing to delete: cache is already empty.")
35
+ return
36
+
37
+ if not yes:
38
+ confirm = confirmation(
39
+ "Are you sure you want to delete the Nextmv cache? This action cannot be undone.",
40
+ )
41
+
42
+ if not confirm:
43
+ info("The Nextmv cache will not be deleted.")
44
+ return
45
+
46
+ size_str = format_bytes(bytes_deleted)
47
+ dep_label = "dependency" if deps == 1 else "dependencies"
48
+ success(f"Deleted [magenta]{deps}[/magenta] {dep_label} ([magenta]{size_str}[/magenta]) from the cache.")
@@ -0,0 +1,27 @@
1
+ """
2
+ This module defines the cache get command for the Nextmv CLI.
3
+ """
4
+
5
+ import typer
6
+
7
+ from nextmv.cache import get_cache
8
+ from nextmv.cli.message import print_json, success
9
+
10
+ # Set up subcommand application.
11
+ app = typer.Typer()
12
+
13
+
14
+ @app.command()
15
+ def get() -> None:
16
+ """
17
+ Gets general information about the Nextmv cache.
18
+
19
+ [bold][underline]Examples[/underline][/bold]
20
+
21
+ - Get cache information.
22
+ $ [dim]nextmv cache get[/dim]
23
+ """
24
+
25
+ info = get_cache()
26
+ success("Cache information retrieved successfully.")
27
+ print_json(info)
@@ -40,6 +40,13 @@ def push(
40
40
  metavar="MANIFEST_PATH",
41
41
  ),
42
42
  ] = None,
43
+ no_cache: Annotated[
44
+ bool,
45
+ typer.Option(
46
+ "--no-cache",
47
+ help="Do not read from or write to the Nextmv dependency cache for [magenta]Python[/magenta] applications.",
48
+ ),
49
+ ] = False,
43
50
  # Options for version control.
44
51
  version_id: Annotated[
45
52
  str | None,
@@ -184,6 +191,7 @@ def push(
184
191
  update_instance_id=update_instance_id,
185
192
  create_defined=create_defined,
186
193
  create_instance_id=create_instance_id,
194
+ no_cache=no_cache,
187
195
  )
188
196
 
189
197
 
@@ -199,6 +207,7 @@ def handle_push(
199
207
  update_instance_id: str | None,
200
208
  create_defined: bool,
201
209
  create_instance_id: str | None,
210
+ no_cache: bool = False,
202
211
  ) -> str:
203
212
  """
204
213
  Handle the core push flow: push the application, create a version, and link it to an instance.
@@ -227,6 +236,9 @@ def handle_push(
227
236
  Whether --create-instance-id was provided.
228
237
  create_instance_id : str | None
229
238
  The instance ID to create.
239
+ no_cache : bool
240
+ Whether to disable the dependency cache when packaging Python
241
+ applications.
230
242
 
231
243
  Returns
232
244
  -------
@@ -242,6 +254,7 @@ def handle_push(
242
254
  app_dir=app_dir,
243
255
  verbose=True,
244
256
  rich_print=True,
257
+ no_cache=no_cache,
245
258
  )
246
259
 
247
260
  now = datetime.now(timezone.utc)
@@ -23,6 +23,7 @@ import rich
23
23
  import typer
24
24
  from typer import rich_utils
25
25
 
26
+ from nextmv.cli.cache import app as cache_app
26
27
  from nextmv.cli.cloud import app as cloud_app
27
28
  from nextmv.cli.community import app as community_app
28
29
  from nextmv.cli.configuration import app as configuration_app
@@ -52,6 +53,7 @@ app = typer.Typer(
52
53
 
53
54
  # Register subcommands. The `name` parameter is required when the subcommand
54
55
  # module has a callback function defined.
56
+ app.add_typer(cache_app, name="cache")
55
57
  app.add_typer(cloud_app, name="cloud")
56
58
  app.add_typer(community_app, name="community")
57
59
  app.add_typer(configuration_app, name="configuration")
@@ -414,7 +414,7 @@ class Application(
414
414
  # Re-throw the exception if it is not the expected 404 error.
415
415
  raise e from None
416
416
 
417
- def push( # noqa: C901
417
+ def push(
418
418
  self,
419
419
  manifest: Manifest | None = None,
420
420
  app_dir: str | None = None,
@@ -422,6 +422,7 @@ class Application(
422
422
  model: Model | None = None,
423
423
  model_configuration: ModelConfiguration | None = None,
424
424
  rich_print: bool = False,
425
+ no_cache: bool = False,
425
426
  ) -> None:
426
427
  """
427
428
  Push an app to Nextmv Cloud.
@@ -457,6 +458,13 @@ class Application(
457
458
  with `model`.
458
459
  rich_print : bool, default=False
459
460
  Whether to use rich printing when verbose output is enabled.
461
+ no_cache : bool, default=False
462
+ When working with Python, dependencies are cached to speed up
463
+ subsequent pushes. Setting no_cache to True will skip using the
464
+ cache and force a fresh build of all dependencies. This is useful
465
+ when you want to ensure that you are pushing the most up-to-date
466
+ versions of your dependencies, or if you are encountering issues
467
+ with the cache and want to rule it out as a potential cause.
460
468
 
461
469
  Raises
462
470
  ------
@@ -550,9 +558,17 @@ class Application(
550
558
  if (model is None and model_configuration is not None) or (model is not None and model_configuration is None):
551
559
  raise ValueError("model and model_configuration must be provided together")
552
560
 
553
- package._run_build_command(app_dir, manifest.build, verbose, rich_print)
554
- package._run_pre_push_command(app_dir, manifest.pre_push, verbose, rich_print)
555
- tar_file, output_dir = package._package(app_dir, manifest, model, model_configuration, verbose, rich_print)
561
+ package.run_build_command(app_dir, manifest.build, verbose, rich_print)
562
+ package.run_pre_push_command(app_dir, manifest.pre_push, verbose, rich_print)
563
+ tar_file, output_dir = package.package(
564
+ app_dir,
565
+ manifest,
566
+ model,
567
+ model_configuration,
568
+ verbose,
569
+ rich_print,
570
+ no_cache,
571
+ )
556
572
  self.__update_app_binary(tar_file, manifest, verbose, rich_print)
557
573
 
558
574
  try: