corio 2.3.1__tar.gz → 2.3.2a2__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 (171) hide show
  1. {corio-2.3.1 → corio-2.3.2a2}/PKG-INFO +1 -1
  2. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/api.py +1 -2
  3. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/releaser.py +72 -27
  4. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/repository.py +34 -0
  5. {corio-2.3.1 → corio-2.3.2a2}/corio/pyproject.package.toml +2 -2
  6. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_infra.py +118 -1
  7. corio-2.3.2a2/corio/version/__init__.py +14 -0
  8. {corio-2.3.1 → corio-2.3.2a2}/corio.egg-info/PKG-INFO +1 -1
  9. {corio-2.3.1 → corio-2.3.2a2}/pyproject.toml +2 -2
  10. corio-2.3.1/corio/version/__init__.py +0 -7
  11. {corio-2.3.1 → corio-2.3.2a2}/LICENSE +0 -0
  12. {corio-2.3.1 → corio-2.3.2a2}/README.md +0 -0
  13. {corio-2.3.1 → corio-2.3.2a2}/corio/__init__.py +0 -0
  14. {corio-2.3.1 → corio-2.3.2a2}/corio/ai/__init__.py +0 -0
  15. {corio-2.3.1 → corio-2.3.2a2}/corio/ai/agentic.py +0 -0
  16. {corio-2.3.1 → corio-2.3.2a2}/corio/ai/infer.py +0 -0
  17. {corio-2.3.1 → corio-2.3.2a2}/corio/aio.py +0 -0
  18. {corio-2.3.1 → corio-2.3.2a2}/corio/api.py +0 -0
  19. {corio-2.3.1 → corio-2.3.2a2}/corio/augmentation.py +0 -0
  20. {corio-2.3.1 → corio-2.3.2a2}/corio/av.py +0 -0
  21. {corio-2.3.1 → corio-2.3.2a2}/corio/caching.py +0 -0
  22. {corio-2.3.1 → corio-2.3.2a2}/corio/constants.py +0 -0
  23. {corio-2.3.1 → corio-2.3.2a2}/corio/context.py +0 -0
  24. {corio-2.3.1 → corio-2.3.2a2}/corio/dataclass.py +0 -0
  25. {corio-2.3.1 → corio-2.3.2a2}/corio/datatype.py +0 -0
  26. {corio-2.3.1 → corio-2.3.2a2}/corio/db/__init__.py +0 -0
  27. {corio-2.3.1 → corio-2.3.2a2}/corio/db/document.py +0 -0
  28. {corio-2.3.1 → corio-2.3.2a2}/corio/debug.py +0 -0
  29. {corio-2.3.1 → corio-2.3.2a2}/corio/dm.py +0 -0
  30. {corio-2.3.1 → corio-2.3.2a2}/corio/dns/__init__.py +0 -0
  31. {corio-2.3.1 → corio-2.3.2a2}/corio/dns/client.py +0 -0
  32. {corio-2.3.1 → corio-2.3.2a2}/corio/dns/dm.py +0 -0
  33. {corio-2.3.1 → corio-2.3.2a2}/corio/dns/proxy.py +0 -0
  34. {corio-2.3.1 → corio-2.3.2a2}/corio/dns/server.py +0 -0
  35. {corio-2.3.1 → corio-2.3.2a2}/corio/docker/__init__.py +0 -0
  36. {corio-2.3.1 → corio-2.3.2a2}/corio/dt.py +0 -0
  37. {corio-2.3.1 → corio-2.3.2a2}/corio/encrypt.py +0 -0
  38. {corio-2.3.1 → corio-2.3.2a2}/corio/entrypoint.py +0 -0
  39. {corio-2.3.1 → corio-2.3.2a2}/corio/env.py +0 -0
  40. {corio-2.3.1 → corio-2.3.2a2}/corio/function.py +0 -0
  41. {corio-2.3.1 → corio-2.3.2a2}/corio/google_api.py +0 -0
  42. {corio-2.3.1 → corio-2.3.2a2}/corio/ha/__init__.py +0 -0
  43. {corio-2.3.1 → corio-2.3.2a2}/corio/ha/constants.py +0 -0
  44. {corio-2.3.1 → corio-2.3.2a2}/corio/ha/core.py +0 -0
  45. {corio-2.3.1 → corio-2.3.2a2}/corio/ha/supervisor.py +0 -0
  46. {corio-2.3.1 → corio-2.3.2a2}/corio/ha/utils.py +0 -0
  47. {corio-2.3.1 → corio-2.3.2a2}/corio/hash.py +0 -0
  48. {corio-2.3.1 → corio-2.3.2a2}/corio/hfh.py +0 -0
  49. {corio-2.3.1 → corio-2.3.2a2}/corio/hook.py +0 -0
  50. {corio-2.3.1 → corio-2.3.2a2}/corio/https.py +0 -0
  51. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/__init__.py +0 -0
  52. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/incrementor_pyproject.py +0 -0
  53. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/project.py +0 -0
  54. {corio-2.3.1 → corio-2.3.2a2}/corio/infra/stack.py +0 -0
  55. {corio-2.3.1 → corio-2.3.2a2}/corio/inherit.py +0 -0
  56. {corio-2.3.1 → corio-2.3.2a2}/corio/inspection.py +0 -0
  57. {corio-2.3.1 → corio-2.3.2a2}/corio/interface/__init__.py +0 -0
  58. {corio-2.3.1 → corio-2.3.2a2}/corio/interface/context.py +0 -0
  59. {corio-2.3.1 → corio-2.3.2a2}/corio/interface/controls.py +0 -0
  60. {corio-2.3.1 → corio-2.3.2a2}/corio/interface/interface.py +0 -0
  61. {corio-2.3.1 → corio-2.3.2a2}/corio/iterator.py +0 -0
  62. {corio-2.3.1 → corio-2.3.2a2}/corio/jsn.py +0 -0
  63. {corio-2.3.1 → corio-2.3.2a2}/corio/json_fix.py +0 -0
  64. {corio-2.3.1 → corio-2.3.2a2}/corio/logs.py +0 -0
  65. {corio-2.3.1 → corio-2.3.2a2}/corio/markup.py +0 -0
  66. {corio-2.3.1 → corio-2.3.2a2}/corio/merging.py +0 -0
  67. {corio-2.3.1 → corio-2.3.2a2}/corio/metric.py +0 -0
  68. {corio-2.3.1 → corio-2.3.2a2}/corio/mqtt.py +0 -0
  69. {corio-2.3.1 → corio-2.3.2a2}/corio/name.py +0 -0
  70. {corio-2.3.1 → corio-2.3.2a2}/corio/net.py +0 -0
  71. {corio-2.3.1 → corio-2.3.2a2}/corio/netrc.py +0 -0
  72. {corio-2.3.1 → corio-2.3.2a2}/corio/openai.py +0 -0
  73. {corio-2.3.1 → corio-2.3.2a2}/corio/parallel.py +0 -0
  74. {corio-2.3.1 → corio-2.3.2a2}/corio/path/__init__.py +0 -0
  75. {corio-2.3.1 → corio-2.3.2a2}/corio/path/app.py +0 -0
  76. {corio-2.3.1 → corio-2.3.2a2}/corio/path/path.py +0 -0
  77. {corio-2.3.1 → corio-2.3.2a2}/corio/path/type.py +0 -0
  78. {corio-2.3.1 → corio-2.3.2a2}/corio/paths.py +0 -0
  79. {corio-2.3.1 → corio-2.3.2a2}/corio/patterns.py +0 -0
  80. {corio-2.3.1 → corio-2.3.2a2}/corio/pdf.py +0 -0
  81. {corio-2.3.1 → corio-2.3.2a2}/corio/plat.py +0 -0
  82. {corio-2.3.1 → corio-2.3.2a2}/corio/process.py +0 -0
  83. {corio-2.3.1 → corio-2.3.2a2}/corio/profiling.py +0 -0
  84. {corio-2.3.1 → corio-2.3.2a2}/corio/rand.py +0 -0
  85. {corio-2.3.1 → corio-2.3.2a2}/corio/sec.py +0 -0
  86. {corio-2.3.1 → corio-2.3.2a2}/corio/semantic.py +0 -0
  87. {corio-2.3.1 → corio-2.3.2a2}/corio/sets.py +0 -0
  88. {corio-2.3.1 → corio-2.3.2a2}/corio/setup/__init__.py +0 -0
  89. {corio-2.3.1 → corio-2.3.2a2}/corio/spaces.py +0 -0
  90. {corio-2.3.1 → corio-2.3.2a2}/corio/strings.py +0 -0
  91. {corio-2.3.1 → corio-2.3.2a2}/corio/tabular.py +0 -0
  92. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/__init__.py +0 -0
  93. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/conftest.py +0 -0
  94. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/helpers.py +0 -0
  95. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_caching.py +0 -0
  96. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_datatype.py +0 -0
  97. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_dns.py +0 -0
  98. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_dt.py +0 -0
  99. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_encrypt.py +0 -0
  100. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_env.py +0 -0
  101. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_hash.py +0 -0
  102. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_hook.py +0 -0
  103. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_iterator.py +0 -0
  104. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_jsn.py +0 -0
  105. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_name.py +0 -0
  106. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_path.py +0 -0
  107. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_patterns.py +0 -0
  108. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_rand.py +0 -0
  109. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_strings.py +0 -0
  110. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_toml.py +0 -0
  111. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_tools.py +0 -0
  112. {corio-2.3.1 → corio-2.3.2a2}/corio/tests/test_yml.py +0 -0
  113. {corio-2.3.1 → corio-2.3.2a2}/corio/tokenization.py +0 -0
  114. {corio-2.3.1 → corio-2.3.2a2}/corio/toml.py +0 -0
  115. {corio-2.3.1 → corio-2.3.2a2}/corio/tools.py +0 -0
  116. {corio-2.3.1 → corio-2.3.2a2}/corio/unicode.py +0 -0
  117. {corio-2.3.1 → corio-2.3.2a2}/corio/version/version.py +0 -0
  118. {corio-2.3.1 → corio-2.3.2a2}/corio/webhook.py +0 -0
  119. {corio-2.3.1 → corio-2.3.2a2}/corio/yml.py +0 -0
  120. {corio-2.3.1 → corio-2.3.2a2}/corio/youtube.py +0 -0
  121. {corio-2.3.1 → corio-2.3.2a2}/corio.egg-info/SOURCES.txt +0 -0
  122. {corio-2.3.1 → corio-2.3.2a2}/corio.egg-info/dependency_links.txt +0 -0
  123. {corio-2.3.1 → corio-2.3.2a2}/corio.egg-info/entry_points.txt +0 -0
  124. {corio-2.3.1 → corio-2.3.2a2}/corio.egg-info/requires.txt +0 -0
  125. {corio-2.3.1 → corio-2.3.2a2}/corio.egg-info/top_level.txt +0 -0
  126. {corio-2.3.1 → corio-2.3.2a2}/scripts/add-service +0 -0
  127. {corio-2.3.1 → corio-2.3.2a2}/scripts/add-user-path +0 -0
  128. {corio-2.3.1 → corio-2.3.2a2}/scripts/add-ve-shell +0 -0
  129. {corio-2.3.1 → corio-2.3.2a2}/scripts/apt-essentials +0 -0
  130. {corio-2.3.1 → corio-2.3.2a2}/scripts/apt-headless +0 -0
  131. {corio-2.3.1 → corio-2.3.2a2}/scripts/auth-token +0 -0
  132. {corio-2.3.1 → corio-2.3.2a2}/scripts/compose-update +0 -0
  133. {corio-2.3.1 → corio-2.3.2a2}/scripts/compress-dir +0 -0
  134. {corio-2.3.1 → corio-2.3.2a2}/scripts/cru +0 -0
  135. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-build-bases +0 -0
  136. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-build-bases-dev +0 -0
  137. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-install-deps +0 -0
  138. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-install-prod +0 -0
  139. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-prune +0 -0
  140. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-sandbox +0 -0
  141. {corio-2.3.1 → corio-2.3.2a2}/scripts/docker-sandbox-init +0 -0
  142. {corio-2.3.1 → corio-2.3.2a2}/scripts/docs-deploy +0 -0
  143. {corio-2.3.1 → corio-2.3.2a2}/scripts/download +0 -0
  144. {corio-2.3.1 → corio-2.3.2a2}/scripts/encrypt-secrets +0 -0
  145. {corio-2.3.1 → corio-2.3.2a2}/scripts/fmtr-test-script +0 -0
  146. {corio-2.3.1 → corio-2.3.2a2}/scripts/git-clone +0 -0
  147. {corio-2.3.1 → corio-2.3.2a2}/scripts/ha-addon-launch +0 -0
  148. {corio-2.3.1 → corio-2.3.2a2}/scripts/infra +0 -0
  149. {corio-2.3.1 → corio-2.3.2a2}/scripts/install-browser +0 -0
  150. {corio-2.3.1 → corio-2.3.2a2}/scripts/install-docker +0 -0
  151. {corio-2.3.1 → corio-2.3.2a2}/scripts/install-ts +0 -0
  152. {corio-2.3.1 → corio-2.3.2a2}/scripts/install-ys +0 -0
  153. {corio-2.3.1 → corio-2.3.2a2}/scripts/mirror-dir +0 -0
  154. {corio-2.3.1 → corio-2.3.2a2}/scripts/opt-dev-init +0 -0
  155. {corio-2.3.1 → corio-2.3.2a2}/scripts/parse-args +0 -0
  156. {corio-2.3.1 → corio-2.3.2a2}/scripts/pypi-check +0 -0
  157. {corio-2.3.1 → corio-2.3.2a2}/scripts/pypi-reserve +0 -0
  158. {corio-2.3.1 → corio-2.3.2a2}/scripts/run-script +0 -0
  159. {corio-2.3.1 → corio-2.3.2a2}/scripts/run-tests +0 -0
  160. {corio-2.3.1 → corio-2.3.2a2}/scripts/set-password +0 -0
  161. {corio-2.3.1 → corio-2.3.2a2}/scripts/set-secure-path +0 -0
  162. {corio-2.3.1 → corio-2.3.2a2}/scripts/set-user-sudo +0 -0
  163. {corio-2.3.1 → corio-2.3.2a2}/scripts/snips-install +0 -0
  164. {corio-2.3.1 → corio-2.3.2a2}/scripts/ssh-auth +0 -0
  165. {corio-2.3.1 → corio-2.3.2a2}/scripts/ssh-serve +0 -0
  166. {corio-2.3.1 → corio-2.3.2a2}/scripts/tasmota-config +0 -0
  167. {corio-2.3.1 → corio-2.3.2a2}/scripts/tasmota-flash +0 -0
  168. {corio-2.3.1 → corio-2.3.2a2}/scripts/tasmota-terminal +0 -0
  169. {corio-2.3.1 → corio-2.3.2a2}/scripts/vlc-tn +0 -0
  170. {corio-2.3.1 → corio-2.3.2a2}/scripts/vm-launch +0 -0
  171. {corio-2.3.1 → corio-2.3.2a2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corio
3
- Version: 2.3.1
3
+ Version: 2.3.2a2
4
4
  Summary: Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML
5
5
  Author-email: Frontmatter AI <innovative.fowler@mask.pro.fmtr.dev>
6
6
  License-Expression: Apache-2.0
@@ -39,11 +39,10 @@ class Api(api.Base):
39
39
  self,
40
40
  name: str,
41
41
  pinned: str = None,
42
- increment: bool = True,
43
42
  build: bool = False,
44
43
  release: bool = True,
45
44
  cache: bool = True,
46
45
  ):
47
46
  project = Project(name, pinned=pinned)
48
47
 
49
- project.releaser.run(increment=increment, build=build, release=release, cache=cache)
48
+ project.releaser.run(build=build, release=release, cache=cache)
@@ -40,13 +40,12 @@ class Releaser(Inherit[Project]):
40
40
  """
41
41
 
42
42
  @logger.instrument("Releasing {self.paths.name_ns}...")
43
- def run(self, increment: bool = True, build: bool = False, release: bool = True, cache: bool = True):
43
+ def run(self, build: bool = False, release: bool = True, cache: bool = True):
44
44
 
45
45
  from corio.infra.stack import ProductionPrivate, ProductionPublic
46
46
 
47
- if increment:
48
- self.repo.fetch()
49
- self.increment()
47
+ self.repo.fetch()
48
+ self.increment()
50
49
 
51
50
  is_passed = self.tester.run()
52
51
  if not is_passed:
@@ -55,9 +54,9 @@ class Releaser(Inherit[Project]):
55
54
  else:
56
55
  raise RuntimeError("Tests failed. Aborting release.")
57
56
 
58
- if increment:
59
- self.repo.push()
60
- self.repo.fetch()
57
+ self.commit()
58
+ self.repo.push()
59
+ self.repo.fetch()
61
60
 
62
61
  stack_types = []
63
62
  if build:
@@ -78,22 +77,28 @@ class Releaser(Inherit[Project]):
78
77
  def message(self):
79
78
  return f"Release version {self.version}"
80
79
 
81
- @logger.instrument("Incrementing version numbers {self.repo.origin.url}...")
82
- def increment(self):
83
- """
84
-
85
- Increment version numbers in project files, create a new commit, and rebase the release branch.
86
-
87
- """
88
- repo = self.repo
80
+ @cached_property
81
+ def main_ref(self):
82
+ return self.repo.lookup_reference("refs/heads/main")
89
83
 
90
- main_ref = repo.lookup_reference("refs/heads/main") # todo raise if not main?
91
- parent = main_ref.peel(vcs.Commit)
84
+ @cached_property
85
+ def parent_commit(self):
86
+ return self.main_ref.peel(vcs.Commit)
92
87
 
88
+ @cached_property
89
+ def index(self):
90
+ index = self.repo.index
93
91
  # Make sure we're building on main's HEAD (not whatever HEAD currently is).
94
- index = repo.index
95
- index.read_tree(parent.tree)
92
+ index.read_tree(self.parent_commit.tree)
93
+ return index
94
+
95
+ @logger.instrument("Applying version incrementors {self.repo.origin.url}...")
96
+ def increment(self):
97
+ """
96
98
 
99
+ Apply incrementors and stage changed files.
100
+
101
+ """
97
102
  # Apply incrementors (they edit files in the working tree), then stage results.
98
103
  for incrementor in self.incrementors:
99
104
  paths = incrementor.apply()
@@ -104,18 +109,22 @@ class Releaser(Inherit[Project]):
104
109
 
105
110
  for path in paths:
106
111
  rel = str(Path(path).relative_to(self.paths.repo))
107
- index.add(rel)
112
+ self.index.add(rel)
108
113
 
109
- index.write()
110
- tree = index.write_tree(repo)
114
+ self.index.write()
115
+
116
+ @logger.instrument("Committing release changes {self.repo.origin.url}...")
117
+ def commit(self):
118
+ repo = self.repo
119
+ tree = self.index.write_tree(repo)
111
120
 
112
121
  commit_id = repo.create_commit(
113
- main_ref.name,
122
+ self.main_ref.name,
114
123
  repo.default_signature,
115
124
  repo.default_signature,
116
125
  self.message,
117
126
  tree,
118
- [parent.id],
127
+ [self.parent_commit.id],
119
128
  )
120
129
 
121
130
  try:
@@ -218,8 +227,28 @@ class IncrementorVersion(Incrementor):
218
227
  @logger.instrument('Incrementing release version in-memory for "{self.paths.name_ns}"...')
219
228
  def apply(self) -> Path | list[Path] | None:
220
229
  old = self.versions.old
230
+
231
+ old_tag = f"v{old}"
232
+ has_old_tag = old_tag in self.repo.tags.all
233
+
221
234
  if self.versions.pinned:
222
235
  new = self.versions.pinned
236
+ if not has_old_tag and new != old:
237
+ logger.warning(
238
+ f'Current version tag "{old_tag}" was not found. '
239
+ f'Using pinned version "{new}" and continuing.'
240
+ )
241
+ elif not has_old_tag:
242
+ logger.warning(
243
+ f'Current version tag "{old_tag}" was not found. '
244
+ f'Assuming previous release failed and reusing version "{new}".'
245
+ )
246
+ elif not has_old_tag:
247
+ logger.warning(
248
+ f'Current version tag "{old_tag}" was not found. '
249
+ f'Assuming previous release failed and reusing version "{old}".'
250
+ )
251
+ new = old
223
252
  elif old.prerelease:
224
253
  new = old.bump_prerelease()
225
254
  else:
@@ -370,17 +399,33 @@ class ReleaseGithub(Release):
370
399
 
371
400
  """
372
401
 
402
+ @cached_property
403
+ def previous_version(self):
404
+ return self.repo.get_most_recent_release_tag(
405
+ include_pre=self.versions.is_pre,
406
+ before=self.version,
407
+ )
408
+
409
+ @property
410
+ def previous_tag(self):
411
+ if not self.previous_version:
412
+ return None
413
+ return self.previous_version.tag
414
+
373
415
  @property
374
416
  def url(self):
375
- return f"{self.repo_url}/compare/v{self.versions.old}...v{self.versions.new}"
417
+ if not self.previous_tag:
418
+ return None
419
+ return f"{self.repo_url}/compare/{self.previous_tag}...{self.tag}"
376
420
 
377
421
  @property
378
422
  def body(self):
379
423
  path_changelog = self.incrementors.cls[IncrementorChangelog].dest
380
424
  if path_changelog.exists():
381
425
  return path_changelog.read_text()
382
- else:
383
- return f'**Full Changelog**: [{self.versions.old} {Constants.ARROW_RIGHT} {self.versions.new}]({self.url})'
426
+ if not self.previous_version:
427
+ return None
428
+ return f'**Full Changelog**: [{self.previous_tag} {Constants.ARROW_RIGHT} {self.tag}]({self.url})'
384
429
 
385
430
  def release(self):
386
431
  url = f"{self.repo_api_url}/releases"
@@ -2,6 +2,7 @@ import pygit2 as vcs
2
2
  from functools import cached_property
3
3
  from typing import Any
4
4
 
5
+ from corio import version
5
6
  from corio.inherit import Inherit
6
7
  from corio.logs import logger
7
8
  from corio.path import Path
@@ -61,6 +62,39 @@ class Repository(vcs.Repository):
61
62
 
62
63
  return self.origin.push(specs, callbacks=self.callbacks)
63
64
 
65
+ def get_most_recent_release_tag(self, include_pre: bool = True, before=None):
66
+ before_version = None
67
+ if before is not None:
68
+ if isinstance(before, str):
69
+ before = before.removeprefix("v")
70
+ before_version = version.parse(before)
71
+ else:
72
+ before_version = before
73
+
74
+ candidates = []
75
+ for tag in self.tags.all:
76
+ if not tag.startswith("v"):
77
+ continue
78
+ text = tag.removeprefix("v")
79
+ try:
80
+ parsed = version.parse(text)
81
+ except ValueError:
82
+ continue
83
+
84
+ if before_version is not None and parsed >= before_version:
85
+ continue
86
+
87
+ if not include_pre and parsed.prerelease:
88
+ continue
89
+
90
+ candidates.append(parsed)
91
+
92
+ if not candidates:
93
+ return None
94
+
95
+ candidates.sort(reverse=True)
96
+ return candidates[0]
97
+
64
98
 
65
99
 
66
100
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "corio"
3
- version = "2.3.1"
3
+ version = "2.3.2-alpha002"
4
4
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
5
5
  readme = "README.md"
6
6
  dependencies = []
@@ -83,7 +83,7 @@ Homepage = "https://github.com/fmtr/corio"
83
83
  corio = "corio.entrypoint:main"
84
84
 
85
85
  [tool.corio.metadata]
86
- version = "2.3.1"
86
+ version = "2.3.2-alpha002"
87
87
  port = 0
88
88
  base = "python"
89
89
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
@@ -2,8 +2,10 @@ from types import SimpleNamespace
2
2
 
3
3
  from packaging.requirements import Requirement
4
4
 
5
+ from corio import version
5
6
  from corio.infra.incrementor_pyproject import IncrementorPyproject, GeneratorTestEnvs
6
- from corio.infra.releaser import Tester as ReleaserTester
7
+ from corio.infra.releaser import Releaser, IncrementorVersion, Tester as ReleaserTester
8
+ from corio.infra.repository import Repository
7
9
  from corio.path import Path
8
10
 
9
11
 
@@ -319,3 +321,118 @@ def test_tester_run_returns_false_when_subprocess_fails(tmp_path, monkeypatch):
319
321
  monkeypatch.setattr(ReleaserTester, "run_subprocess", lambda self: 1)
320
322
 
321
323
  assert tester.run() is False
324
+
325
+
326
+ def test_repository_get_most_recent_release_tag_filters_and_orders():
327
+ repo = SimpleNamespace(tags=SimpleNamespace(all={
328
+ "v1.2.1",
329
+ "v1.2.2-rc.1",
330
+ "v1.2.2",
331
+ "v1.3.0-rc.1",
332
+ "junk",
333
+ }))
334
+
335
+ any_tag = Repository.get_most_recent_release_tag(repo, include_pre=True)
336
+ stable_tag = Repository.get_most_recent_release_tag(repo, include_pre=False)
337
+ previous_stable = Repository.get_most_recent_release_tag(
338
+ repo, include_pre=False, before=version.parse("1.2.2"),
339
+ )
340
+ previous_any = Repository.get_most_recent_release_tag(
341
+ repo, include_pre=True, before=version.parse("1.2.2"),
342
+ )
343
+
344
+ assert any_tag == version.parse("1.3.0-rc.1")
345
+ assert stable_tag == version.parse("1.2.2")
346
+ assert previous_stable == version.parse("1.2.1")
347
+ assert previous_any == version.parse("1.2.2-rc.1")
348
+ assert stable_tag.tag == "v1.2.2"
349
+
350
+
351
+ def _make_version_incrementor(*, old: str, pinned: str | None, tags: set[str]):
352
+ metadata = SimpleNamespace(version=old)
353
+ parent = SimpleNamespace(
354
+ paths=SimpleNamespace(name_ns="corio", metadata=metadata),
355
+ versions=SimpleNamespace(old=version.parse(old), pinned=version.parse(pinned) if pinned else None),
356
+ repo=SimpleNamespace(tags=SimpleNamespace(all=tags)),
357
+ )
358
+ return IncrementorVersion(parent), metadata
359
+
360
+
361
+ def test_incrementor_version_does_not_increment_when_old_tag_missing():
362
+ incrementor, metadata = _make_version_incrementor(
363
+ old="1.2.3",
364
+ pinned=None,
365
+ tags={"v1.2.2"},
366
+ )
367
+
368
+ incrementor.apply()
369
+
370
+ assert metadata.version == "1.2.3"
371
+
372
+
373
+ def test_incrementor_version_uses_pinned_even_when_old_tag_missing():
374
+ incrementor, metadata = _make_version_incrementor(
375
+ old="1.2.3",
376
+ pinned="2.0.0",
377
+ tags={"v1.2.2"},
378
+ )
379
+
380
+ incrementor.apply()
381
+
382
+ assert metadata.version == "2.0.0"
383
+
384
+
385
+ def test_releaser_run_commits_only_after_tests_pass(monkeypatch):
386
+ events = []
387
+
388
+ class _Repo:
389
+ def fetch(self):
390
+ events.append("fetch")
391
+
392
+ def push(self):
393
+ events.append("push")
394
+
395
+ releaser = Releaser(SimpleNamespace(
396
+ name="corio",
397
+ paths=SimpleNamespace(name_ns="corio", metadata=SimpleNamespace(is_dockerhub=False, is_pypi=False)),
398
+ ))
399
+ releaser.repo = _Repo()
400
+ releaser.tester = SimpleNamespace(run=lambda: events.append("tests") or True)
401
+
402
+ monkeypatch.setattr(Releaser, "increment", lambda self: events.append("increment"))
403
+ monkeypatch.setattr(Releaser, "commit", lambda self: events.append("commit"))
404
+
405
+ releaser.run(build=False, release=False)
406
+
407
+ assert events == ["fetch", "increment", "tests", "commit", "push", "fetch"]
408
+
409
+
410
+ def test_releaser_run_continues_when_pre_tests_fail(monkeypatch):
411
+ events = []
412
+
413
+ class _Repo:
414
+ def fetch(self):
415
+ events.append("fetch")
416
+
417
+ def push(self):
418
+ events.append("push")
419
+
420
+ releaser = Releaser(SimpleNamespace(
421
+ name="corio",
422
+ version=version.parse("1.2.3-rc.1"),
423
+ versions=SimpleNamespace(is_pre=True),
424
+ paths=SimpleNamespace(name_ns="corio", metadata=SimpleNamespace(is_dockerhub=False, is_pypi=False)),
425
+ ))
426
+ releaser.repo = _Repo()
427
+ releaser.tester = SimpleNamespace(run=lambda: events.append("tests") or False)
428
+
429
+ monkeypatch.setattr(Releaser, "increment", lambda self: events.append("increment"))
430
+ monkeypatch.setattr(Releaser, "commit", lambda self: events.append("commit"))
431
+
432
+ releaser.run(build=False, release=False)
433
+
434
+ assert events == ["fetch", "increment", "tests", "commit", "push", "fetch"]
435
+
436
+
437
+ def test_intentional_failure_for_testing():
438
+ assert False, "Intentional failing test for test-pipeline verification."
@@ -0,0 +1,14 @@
1
+ from corio.version.version import read, read_path, get
2
+
3
+ import semver
4
+
5
+ semver = semver
6
+
7
+
8
+ class Version(semver.Version):
9
+ @property
10
+ def tag(self) -> str:
11
+ return f"v{self}"
12
+
13
+
14
+ parse = Version.parse
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corio
3
- Version: 2.3.1
3
+ Version: 2.3.2a2
4
4
  Summary: Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML
5
5
  Author-email: Frontmatter AI <innovative.fowler@mask.pro.fmtr.dev>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "corio"
3
- version = "2.3.1"
3
+ version = "2.3.2-alpha002"
4
4
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
5
5
  readme = "README.md"
6
6
  dependencies = []
@@ -83,7 +83,7 @@ Homepage = "https://github.com/fmtr/corio"
83
83
  corio = "corio.entrypoint:main"
84
84
 
85
85
  [tool.corio.metadata]
86
- version = "2.3.1"
86
+ version = "2.3.2-alpha002"
87
87
  port = 0
88
88
  base = "python"
89
89
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
@@ -1,7 +0,0 @@
1
- from corio.version.version import read, read_path, get
2
-
3
- import semver
4
-
5
- semver = semver
6
- parse = semver.VersionInfo.parse
7
- Version = semver.Version
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes