corio 2.2.2a2__tar.gz → 2.2.2a4__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 (159) hide show
  1. {corio-2.2.2a2 → corio-2.2.2a4}/PKG-INFO +1 -1
  2. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/incrementor_pyproject.py +112 -35
  3. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/releaser.py +23 -2
  4. {corio-2.2.2a2 → corio-2.2.2a4}/corio/pyproject.package.toml +2 -2
  5. corio-2.2.2a4/corio/tests/test_infra.py +163 -0
  6. {corio-2.2.2a2 → corio-2.2.2a4}/corio.egg-info/PKG-INFO +1 -1
  7. {corio-2.2.2a2 → corio-2.2.2a4}/corio.egg-info/SOURCES.txt +1 -0
  8. {corio-2.2.2a2 → corio-2.2.2a4}/pyproject.toml +2 -2
  9. {corio-2.2.2a2 → corio-2.2.2a4}/LICENSE +0 -0
  10. {corio-2.2.2a2 → corio-2.2.2a4}/README.md +0 -0
  11. {corio-2.2.2a2 → corio-2.2.2a4}/corio/__init__.py +0 -0
  12. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ai/__init__.py +0 -0
  13. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ai/agentic.py +0 -0
  14. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ai/infer.py +0 -0
  15. {corio-2.2.2a2 → corio-2.2.2a4}/corio/aio.py +0 -0
  16. {corio-2.2.2a2 → corio-2.2.2a4}/corio/api.py +0 -0
  17. {corio-2.2.2a2 → corio-2.2.2a4}/corio/augmentation.py +0 -0
  18. {corio-2.2.2a2 → corio-2.2.2a4}/corio/av.py +0 -0
  19. {corio-2.2.2a2 → corio-2.2.2a4}/corio/caching.py +0 -0
  20. {corio-2.2.2a2 → corio-2.2.2a4}/corio/constants.py +0 -0
  21. {corio-2.2.2a2 → corio-2.2.2a4}/corio/context.py +0 -0
  22. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dataclass.py +0 -0
  23. {corio-2.2.2a2 → corio-2.2.2a4}/corio/datatype.py +0 -0
  24. {corio-2.2.2a2 → corio-2.2.2a4}/corio/db/__init__.py +0 -0
  25. {corio-2.2.2a2 → corio-2.2.2a4}/corio/db/document.py +0 -0
  26. {corio-2.2.2a2 → corio-2.2.2a4}/corio/debug.py +0 -0
  27. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dm.py +0 -0
  28. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dns/__init__.py +0 -0
  29. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dns/client.py +0 -0
  30. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dns/dm.py +0 -0
  31. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dns/proxy.py +0 -0
  32. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dns/server.py +0 -0
  33. {corio-2.2.2a2 → corio-2.2.2a4}/corio/docker/__init__.py +0 -0
  34. {corio-2.2.2a2 → corio-2.2.2a4}/corio/dt.py +0 -0
  35. {corio-2.2.2a2 → corio-2.2.2a4}/corio/encrypt.py +0 -0
  36. {corio-2.2.2a2 → corio-2.2.2a4}/corio/entrypoint.py +0 -0
  37. {corio-2.2.2a2 → corio-2.2.2a4}/corio/env.py +0 -0
  38. {corio-2.2.2a2 → corio-2.2.2a4}/corio/function.py +0 -0
  39. {corio-2.2.2a2 → corio-2.2.2a4}/corio/google_api.py +0 -0
  40. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ha/__init__.py +0 -0
  41. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ha/constants.py +0 -0
  42. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ha/core.py +0 -0
  43. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ha/supervisor.py +0 -0
  44. {corio-2.2.2a2 → corio-2.2.2a4}/corio/ha/utils.py +0 -0
  45. {corio-2.2.2a2 → corio-2.2.2a4}/corio/hash.py +0 -0
  46. {corio-2.2.2a2 → corio-2.2.2a4}/corio/hfh.py +0 -0
  47. {corio-2.2.2a2 → corio-2.2.2a4}/corio/hook.py +0 -0
  48. {corio-2.2.2a2 → corio-2.2.2a4}/corio/https.py +0 -0
  49. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/__init__.py +0 -0
  50. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/api.py +0 -0
  51. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/project.py +0 -0
  52. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/repository.py +0 -0
  53. {corio-2.2.2a2 → corio-2.2.2a4}/corio/infra/stack.py +0 -0
  54. {corio-2.2.2a2 → corio-2.2.2a4}/corio/inherit.py +0 -0
  55. {corio-2.2.2a2 → corio-2.2.2a4}/corio/inspection.py +0 -0
  56. {corio-2.2.2a2 → corio-2.2.2a4}/corio/interface/__init__.py +0 -0
  57. {corio-2.2.2a2 → corio-2.2.2a4}/corio/interface/context.py +0 -0
  58. {corio-2.2.2a2 → corio-2.2.2a4}/corio/interface/controls.py +0 -0
  59. {corio-2.2.2a2 → corio-2.2.2a4}/corio/interface/interface.py +0 -0
  60. {corio-2.2.2a2 → corio-2.2.2a4}/corio/iterator.py +0 -0
  61. {corio-2.2.2a2 → corio-2.2.2a4}/corio/jsn.py +0 -0
  62. {corio-2.2.2a2 → corio-2.2.2a4}/corio/json_fix.py +0 -0
  63. {corio-2.2.2a2 → corio-2.2.2a4}/corio/logs.py +0 -0
  64. {corio-2.2.2a2 → corio-2.2.2a4}/corio/markup.py +0 -0
  65. {corio-2.2.2a2 → corio-2.2.2a4}/corio/merging.py +0 -0
  66. {corio-2.2.2a2 → corio-2.2.2a4}/corio/metric.py +0 -0
  67. {corio-2.2.2a2 → corio-2.2.2a4}/corio/mqtt.py +0 -0
  68. {corio-2.2.2a2 → corio-2.2.2a4}/corio/name.py +0 -0
  69. {corio-2.2.2a2 → corio-2.2.2a4}/corio/net.py +0 -0
  70. {corio-2.2.2a2 → corio-2.2.2a4}/corio/netrc.py +0 -0
  71. {corio-2.2.2a2 → corio-2.2.2a4}/corio/openai.py +0 -0
  72. {corio-2.2.2a2 → corio-2.2.2a4}/corio/parallel.py +0 -0
  73. {corio-2.2.2a2 → corio-2.2.2a4}/corio/path/__init__.py +0 -0
  74. {corio-2.2.2a2 → corio-2.2.2a4}/corio/path/app.py +0 -0
  75. {corio-2.2.2a2 → corio-2.2.2a4}/corio/path/path.py +0 -0
  76. {corio-2.2.2a2 → corio-2.2.2a4}/corio/path/type.py +0 -0
  77. {corio-2.2.2a2 → corio-2.2.2a4}/corio/paths.py +0 -0
  78. {corio-2.2.2a2 → corio-2.2.2a4}/corio/patterns.py +0 -0
  79. {corio-2.2.2a2 → corio-2.2.2a4}/corio/pdf.py +0 -0
  80. {corio-2.2.2a2 → corio-2.2.2a4}/corio/plat.py +0 -0
  81. {corio-2.2.2a2 → corio-2.2.2a4}/corio/process.py +0 -0
  82. {corio-2.2.2a2 → corio-2.2.2a4}/corio/profiling.py +0 -0
  83. {corio-2.2.2a2 → corio-2.2.2a4}/corio/rand.py +0 -0
  84. {corio-2.2.2a2 → corio-2.2.2a4}/corio/sec.py +0 -0
  85. {corio-2.2.2a2 → corio-2.2.2a4}/corio/semantic.py +0 -0
  86. {corio-2.2.2a2 → corio-2.2.2a4}/corio/sets.py +0 -0
  87. {corio-2.2.2a2 → corio-2.2.2a4}/corio/setup/__init__.py +0 -0
  88. {corio-2.2.2a2 → corio-2.2.2a4}/corio/spaces.py +0 -0
  89. {corio-2.2.2a2 → corio-2.2.2a4}/corio/strings.py +0 -0
  90. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tabular.py +0 -0
  91. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/__init__.py +0 -0
  92. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/conftest.py +0 -0
  93. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/helpers.py +0 -0
  94. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_caching.py +0 -0
  95. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_datatype.py +0 -0
  96. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_encrypt.py +0 -0
  97. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_env.py +0 -0
  98. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_jsn.py +0 -0
  99. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_path.py +0 -0
  100. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tests/test_yaml.py +0 -0
  101. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tokenization.py +0 -0
  102. {corio-2.2.2a2 → corio-2.2.2a4}/corio/toml.py +0 -0
  103. {corio-2.2.2a2 → corio-2.2.2a4}/corio/tools.py +0 -0
  104. {corio-2.2.2a2 → corio-2.2.2a4}/corio/unicode.py +0 -0
  105. {corio-2.2.2a2 → corio-2.2.2a4}/corio/version/__init__.py +0 -0
  106. {corio-2.2.2a2 → corio-2.2.2a4}/corio/version/version.py +0 -0
  107. {corio-2.2.2a2 → corio-2.2.2a4}/corio/webhook.py +0 -0
  108. {corio-2.2.2a2 → corio-2.2.2a4}/corio/yml.py +0 -0
  109. {corio-2.2.2a2 → corio-2.2.2a4}/corio/youtube.py +0 -0
  110. {corio-2.2.2a2 → corio-2.2.2a4}/corio.egg-info/dependency_links.txt +0 -0
  111. {corio-2.2.2a2 → corio-2.2.2a4}/corio.egg-info/entry_points.txt +0 -0
  112. {corio-2.2.2a2 → corio-2.2.2a4}/corio.egg-info/requires.txt +0 -0
  113. {corio-2.2.2a2 → corio-2.2.2a4}/corio.egg-info/top_level.txt +0 -0
  114. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/add-service +0 -0
  115. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/add-user-path +0 -0
  116. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/add-ve-shell +0 -0
  117. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/apt-essentials +0 -0
  118. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/apt-headless +0 -0
  119. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/auth-token +0 -0
  120. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/compose-update +0 -0
  121. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/compress-dir +0 -0
  122. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/cru +0 -0
  123. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-build-bases +0 -0
  124. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-build-bases-dev +0 -0
  125. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-install-deps +0 -0
  126. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-install-prod +0 -0
  127. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-prune +0 -0
  128. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-sandbox +0 -0
  129. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docker-sandbox-init +0 -0
  130. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/docs-deploy +0 -0
  131. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/download +0 -0
  132. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/encrypt-secrets +0 -0
  133. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/fmtr-test-script +0 -0
  134. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/git-clone +0 -0
  135. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/ha-addon-launch +0 -0
  136. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/infra +0 -0
  137. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/infra-sync +0 -0
  138. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/install-browser +0 -0
  139. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/install-docker +0 -0
  140. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/install-ts +0 -0
  141. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/install-ys +0 -0
  142. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/mirror-dir +0 -0
  143. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/opt-dev-init +0 -0
  144. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/parse-args +0 -0
  145. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/pypi-check +0 -0
  146. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/pypi-reserve +0 -0
  147. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/run-script +0 -0
  148. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/set-password +0 -0
  149. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/set-secure-path +0 -0
  150. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/set-user-sudo +0 -0
  151. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/snips-install +0 -0
  152. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/ssh-auth +0 -0
  153. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/ssh-serve +0 -0
  154. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/tasmota-config +0 -0
  155. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/tasmota-flash +0 -0
  156. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/tasmota-terminal +0 -0
  157. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/vlc-tn +0 -0
  158. {corio-2.2.2a2 → corio-2.2.2a4}/scripts/vm-launch +0 -0
  159. {corio-2.2.2a2 → corio-2.2.2a4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corio
3
- Version: 2.2.2a2
3
+ Version: 2.2.2a4
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,12 +1,15 @@
1
1
  from copy import deepcopy
2
2
  from functools import cached_property
3
3
  from itertools import chain
4
+ from packaging.requirements import Requirement, InvalidRequirement
5
+ from packaging.utils import canonicalize_name
4
6
 
5
7
  from corio.constants import Constants
6
8
  from corio.infra.releaser import Incrementor
7
9
  from corio.iterator import dedupe
8
10
  from corio.logs import logger
9
- from corio.path import Path
11
+ from corio.path import Path, PackagePaths
12
+ from corio.path.path import Metadata
10
13
  from corio.toml import ensure_table
11
14
 
12
15
 
@@ -25,6 +28,86 @@ class IncrementorPyproject(Incrementor):
25
28
  def name_command(self) -> str:
26
29
  return self.paths.name_ns.replace(".", self.ENTRYPOINT_COMMAND_SEP)
27
30
 
31
+ @cached_property
32
+ def editables(self) -> dict[str, Metadata]:
33
+ data = self.path.read_toml()
34
+ sources = data.get("tool", {}).get("uv", {}).get("sources", {})
35
+
36
+ editables = {}
37
+ for key, source in sources.items():
38
+ if not isinstance(source, dict):
39
+ continue
40
+ if not source.get("editable"):
41
+ continue
42
+
43
+ source_path = source.get("path")
44
+ if not source_path:
45
+ logger.warning(f'Editable source "{key}" is missing "path". Skipping.')
46
+ continue
47
+ path_repo = (self.paths.repo / str(source_path)).resolve()
48
+ if not path_repo.exists():
49
+ continue
50
+
51
+ try:
52
+ paths = PackagePaths(path_repo)
53
+ except Exception as exception:
54
+ logger.warning(f'Failed to resolve editable source at "{path_repo}". Skipping. {exception!r}')
55
+ continue
56
+
57
+ metadata = paths.metadata
58
+ if metadata.version_obj.prerelease and not self.versions.is_pre:
59
+ raise ValueError(
60
+ f'Editable dependency "{paths.name_ns}" is pre-release '
61
+ f'({metadata.version_obj.prerelease}) while "{self.paths.name_ns}" is release. Refusing to pin.'
62
+ )
63
+
64
+ editables[paths.name_ns] = metadata
65
+ editables[canonicalize_name(paths.name_ns)] = metadata
66
+
67
+ return editables
68
+
69
+ def _pin_editable(self, dep: str) -> str:
70
+ try:
71
+ requirement = Requirement(dep)
72
+ except InvalidRequirement:
73
+ return dep
74
+
75
+ if requirement.specifier:
76
+ return dep
77
+ if requirement.url:
78
+ return dep
79
+
80
+ metadata = self.editables.get(requirement.name)
81
+ if metadata is None:
82
+ metadata = self.editables.get(canonicalize_name(requirement.name))
83
+ if metadata is None:
84
+ return dep
85
+
86
+ extras = ""
87
+ if requirement.extras:
88
+ extras = f"[{','.join(sorted(requirement.extras))}]"
89
+
90
+ marker = ""
91
+ if requirement.marker:
92
+ marker = f"; {requirement.marker}"
93
+
94
+ pinned = f"{requirement.name}{extras}=={metadata.version}{marker}"
95
+ logger.info(f'Pinning editable dependency "{dep}" -> "{pinned}".')
96
+ return pinned
97
+
98
+ def _process_deps(self, deps: str|list[str]) -> str|list[str]:
99
+
100
+ if isinstance(deps, list):
101
+ deps=[self._process_deps(dep) for dep in deps]
102
+ deps=dedupe(deps)
103
+ return deps
104
+
105
+ dep=deps
106
+ dep=self._pin_editable(dep)
107
+
108
+ return dep
109
+
110
+
28
111
  def apply(self) -> Path | list[Path] | None:
29
112
  if not self.path.exists():
30
113
  logger.info(f'pyproject.toml not found: "{self.path}". Skipping.')
@@ -43,6 +126,7 @@ class IncrementorPyproject(Incrementor):
43
126
  self.path.write_toml(data)
44
127
  return self.path
45
128
 
129
+
46
130
  @property
47
131
  def _author(self) -> str:
48
132
  if self.paths.metadata.is_client:
@@ -106,36 +190,23 @@ class IncrementorPyproject(Incrementor):
106
190
  values_resolved += resolve_values(value)
107
191
  return values_resolved
108
192
 
109
- install = dedupe(resolve_values("install")) if "install" in dependencies else []
193
+
110
194
  extras = {key: dedupe(resolve_values(key)) for key in dependencies}
111
- extras.pop("install", None)
195
+ install = extras.pop("install", [])
112
196
  extras["all"] = dedupe(list(chain.from_iterable(extras.values())))
113
197
  return install, extras
114
198
 
115
- def _get_dependencies(self, data) -> dict[str, list[str]]:
116
- table = data
117
- for key in self.DEPENDENCIES_SECTION_PATH:
118
- if key not in table:
119
- return {}
120
- table = table[key]
121
-
122
- if table is None:
123
- return {}
124
- return {str(key): [str(value) for value in values] for key, values in table.items()}
125
199
 
126
200
  def _enrich_toml(self, data):
127
- old = self.versions.old
128
- new = self._bump(old)
129
- if old != new:
130
- logger.info(f'Incrementing version "{self.path}" {old} {Constants.ARROW_RIGHT} {new}...')
131
- self.paths.metadata.version = str(new)
201
+ version = str(self.version)
202
+ logger.info(f'Applying release version "{version}" to "{self.path}"...')
132
203
 
133
204
  metadata = ensure_table(data, ("tool", "corio", "metadata"))
134
- metadata["version"] = self.paths.metadata.version
205
+ metadata["version"] = version
135
206
 
136
207
  project = ensure_table(data, ("project",))
137
208
  project["name"] = self.paths.name_ns
138
- project["version"] = self.paths.metadata.version
209
+ project["version"] = version
139
210
  project["description"] = self.paths.metadata.description
140
211
  project["keywords"] = self.paths.metadata.keywords
141
212
  project["readme"] = self.paths.readme.name
@@ -146,18 +217,32 @@ class IncrementorPyproject(Incrementor):
146
217
  elif "license-files" in project:
147
218
  del project["license-files"]
148
219
 
149
- dependencies = self._get_dependencies(data)
150
- if dependencies:
151
- install, extras = self._flatten_dependencies(dependencies)
220
+
221
+ deps_corio = data.get("tool", {}).get("corio", {}).get("dependencies", None)
222
+ if deps_corio is not None:
223
+ install, extras = self._flatten_dependencies(deps_corio)
152
224
  project["dependencies"] = install
153
225
  project["optional-dependencies"] = extras
154
-
155
- if "dev" in extras:
156
- dependency_groups = ensure_table(data, ("dependency-groups",))
157
- dependency_groups["dev"] = list(extras["dev"])
158
226
  else:
159
227
  logger.info(f'No dependencies section found in "{self.path}". Skipping dependency enrichment.')
160
228
 
229
+
230
+ deps = project.get("dependencies")
231
+ if deps is not None:
232
+ project["dependencies"] = self._process_deps(deps)
233
+
234
+ optionals = project.get("optional-dependencies")
235
+ if optionals is not None:
236
+ optionals = {
237
+ key: self._process_deps(values)
238
+ for key, values in optionals.items()
239
+ }
240
+ project["optional-dependencies"] = optionals
241
+
242
+ if "dev" in optionals:
243
+ dependency_groups = ensure_table(data, ("dependency-groups",))
244
+ dependency_groups["dev"] = list(optionals["dev"])
245
+
161
246
  urls = ensure_table(project, ("urls",))
162
247
  urls["Homepage"] = self.repo_url
163
248
 
@@ -187,11 +272,3 @@ class IncrementorPyproject(Incrementor):
187
272
  del setuptools["script-files"]
188
273
 
189
274
  return data
190
-
191
- def _bump(self, version):
192
- if self.versions.pinned:
193
- return self.versions.pinned
194
-
195
- if version.prerelease:
196
- return version.bump_prerelease()
197
- return version.bump_patch()
@@ -45,6 +45,10 @@ class Releaser(Inherit[Project]):
45
45
 
46
46
  from corio.infra.stack import ProductionPrivate, ProductionPublic
47
47
 
48
+ if increment:
49
+ self.repo.fetch()
50
+ self.increment()
51
+
48
52
  is_passed = self.tester.run()
49
53
  if not is_passed:
50
54
  if self.versions.is_pre:
@@ -53,8 +57,6 @@ class Releaser(Inherit[Project]):
53
57
  raise RuntimeError("Tests failed. Aborting release.")
54
58
 
55
59
  if increment:
56
- self.repo.fetch()
57
- self.increment()
58
60
  self.repo.push()
59
61
  self.repo.fetch()
60
62
 
@@ -157,6 +159,7 @@ class Releaser(Inherit[Project]):
157
159
 
158
160
  return IndexList[Incrementor](
159
161
  [
162
+ IncrementorVersion(self),
160
163
  IncrementorPyproject(self),
161
164
  IncrementorHomeAssistantAddon(self),
162
165
  IncrementorChangelog(self),
@@ -212,6 +215,24 @@ class Incrementor(Inherit[Releaser]):
212
215
  raise NotImplementedError
213
216
 
214
217
 
218
+ class IncrementorVersion(Incrementor):
219
+ @logger.instrument('Incrementing release version in-memory for "{self.paths.name_ns}"...')
220
+ def apply(self) -> Path | list[Path] | None:
221
+ old = self.versions.old
222
+ if self.versions.pinned:
223
+ new = self.versions.pinned
224
+ elif old.prerelease:
225
+ new = old.bump_prerelease()
226
+ else:
227
+ new = old.bump_patch()
228
+
229
+ if old != new:
230
+ logger.info(f'Incrementing runtime version {old} {Constants.ARROW_RIGHT} {new}...')
231
+
232
+ self.paths.metadata.version = str(new)
233
+ return None
234
+
235
+
215
236
 
216
237
 
217
238
 
@@ -64,7 +64,7 @@ secrets = ["encrypt", "env.io", "yaml", "logging", "sets", "vcs"]
64
64
  cli = ["sets", "logging"]
65
65
 
66
66
  [tool.corio.metadata]
67
- version = "2.2.2-alpha002"
67
+ version = "2.2.2-alpha004"
68
68
  port = 0
69
69
  base = "python"
70
70
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
@@ -94,7 +94,7 @@ corio = ["pyproject.package.toml"]
94
94
 
95
95
  [project]
96
96
  name = "corio"
97
- version = "2.2.2-alpha002"
97
+ version = "2.2.2-alpha004"
98
98
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
99
99
  readme = "README.md"
100
100
  dependencies = []
@@ -0,0 +1,163 @@
1
+ from types import SimpleNamespace
2
+
3
+ from packaging.requirements import Requirement
4
+
5
+ from corio.infra.incrementor_pyproject import IncrementorPyproject
6
+ from corio.path import Path
7
+
8
+
9
+ def _write_editable_repo(path_repo: Path, name: str, version: str) -> None:
10
+ (path_repo / "pyproject.toml").write_text("", encoding="utf-8")
11
+ path_package = path_repo / name
12
+ path_package.mkdir(parents=True)
13
+ (path_package / "pyproject.package.toml").write_text(
14
+ f'[tool.corio.metadata]\nversion = "{version}"\n',
15
+ encoding="utf-8",
16
+ )
17
+
18
+
19
+ def _make_incrementor(path_repo: Path, is_pre: bool = False) -> IncrementorPyproject:
20
+ parent = SimpleNamespace(
21
+ paths=SimpleNamespace(
22
+ repo=path_repo,
23
+ pyproject_repo=path_repo / "pyproject.toml",
24
+ name_ns="corio",
25
+ ),
26
+ versions=SimpleNamespace(is_pre=is_pre),
27
+ )
28
+ return IncrementorPyproject(parent)
29
+
30
+
31
+ def test_pin_editables_and_flatten_dependencies(tmp_path):
32
+ path_main_repo = Path(tmp_path / "corio")
33
+ path_main_repo.mkdir(parents=True)
34
+
35
+ path_haco_repo = Path(path_main_repo / "haco")
36
+ path_haco_repo.mkdir(parents=True)
37
+ _write_editable_repo(path_haco_repo, name="haco", version="1.2.3")
38
+
39
+ (path_main_repo / "pyproject.toml").write_text(
40
+ '[tool.uv.sources.haco]\npath = "haco"\neditable = true\n',
41
+ encoding="utf-8",
42
+ )
43
+
44
+ incrementor = _make_incrementor(path_main_repo)
45
+
46
+ assert incrementor._pin_editable("haco") == "haco==1.2.3"
47
+ assert incrementor._pin_editable("requests") == "requests"
48
+
49
+ install, extras = incrementor._flatten_dependencies(
50
+ {
51
+ "install": ["haco", "requests"],
52
+ "dev": ["haco"],
53
+ }
54
+ )
55
+
56
+ assert install == ["haco", "requests"]
57
+ assert extras == {"dev": ["haco"], "all": ["haco"]}
58
+
59
+
60
+ def test_pin_editables_resolves_uv_source_path(tmp_path):
61
+ path_main_repo = Path(tmp_path / "app")
62
+ path_main_repo.mkdir(parents=True)
63
+
64
+ path_corio_repo = Path(tmp_path / "corio")
65
+ path_corio_repo.mkdir(parents=True)
66
+ _write_editable_repo(path_corio_repo, name="corio", version="1.2.3")
67
+
68
+ (path_main_repo / "pyproject.toml").write_text(
69
+ '[tool.uv.sources.corio]\npath = "../corio"\neditable = true\n',
70
+ encoding="utf-8",
71
+ )
72
+
73
+ incrementor = _make_incrementor(path_main_repo)
74
+ assert incrementor._pin_editable("corio") == "corio==1.2.3"
75
+
76
+
77
+ def test_pin_editables_preserves_extras_and_skips_existing_specifiers(tmp_path):
78
+ path_main_repo = Path(tmp_path / "corio")
79
+ path_main_repo.mkdir(parents=True)
80
+
81
+ path_haco_repo = Path(path_main_repo / "haco")
82
+ path_haco_repo.mkdir(parents=True)
83
+ _write_editable_repo(path_haco_repo, name="haco", version="1.2.3")
84
+
85
+ (path_main_repo / "pyproject.toml").write_text(
86
+ '[tool.uv.sources.haco]\npath = "haco"\neditable = true\n',
87
+ encoding="utf-8",
88
+ )
89
+
90
+ incrementor = _make_incrementor(path_main_repo)
91
+
92
+ dep = incrementor._pin_editable("haco[version.dev,logging,sets,yaml,debug,caching,api,mqtt]")
93
+ req = Requirement(dep)
94
+ assert req.name == "haco"
95
+ assert req.extras == {"version.dev", "logging", "sets", "yaml", "debug", "caching", "api", "mqtt"}
96
+ assert str(req.specifier) == "==1.2.3"
97
+
98
+ assert incrementor._pin_editable("haco==1.0.0") == "haco==1.0.0"
99
+ assert incrementor._pin_editable("haco>=1.0.0") == "haco>=1.0.0"
100
+
101
+
102
+ def test_pin_editables_raises_on_prerelease_when_current_is_release(tmp_path):
103
+ path_main_repo = Path(tmp_path / "corio")
104
+ path_main_repo.mkdir(parents=True)
105
+
106
+ path_haco_repo = Path(path_main_repo / "haco")
107
+ path_haco_repo.mkdir(parents=True)
108
+ _write_editable_repo(path_haco_repo, name="haco", version="1.2.3-rc.1")
109
+
110
+ (path_main_repo / "pyproject.toml").write_text(
111
+ '[tool.uv.sources.haco]\npath = "haco"\neditable = true\n',
112
+ encoding="utf-8",
113
+ )
114
+
115
+ incrementor = _make_incrementor(path_main_repo, is_pre=False)
116
+
117
+ try:
118
+ _ = incrementor.editables
119
+ except ValueError as exception:
120
+ assert 'Editable dependency "haco" is pre-release' in str(exception)
121
+ else:
122
+ raise AssertionError("Expected ValueError for prerelease editable dependency")
123
+
124
+
125
+ def test_pin_editables_allows_prerelease_when_current_is_prerelease(tmp_path):
126
+ path_main_repo = Path(tmp_path / "corio")
127
+ path_main_repo.mkdir(parents=True)
128
+
129
+ path_haco_repo = Path(path_main_repo / "haco")
130
+ path_haco_repo.mkdir(parents=True)
131
+ _write_editable_repo(path_haco_repo, name="haco", version="1.2.3-rc.1")
132
+
133
+ (path_main_repo / "pyproject.toml").write_text(
134
+ '[tool.uv.sources.haco]\npath = "haco"\neditable = true\n',
135
+ encoding="utf-8",
136
+ )
137
+
138
+ incrementor = _make_incrementor(path_main_repo, is_pre=True)
139
+
140
+ assert incrementor._pin_editable("haco") == "haco==1.2.3-rc.1"
141
+
142
+
143
+ def test_process_deps_pins_project_dependencies(tmp_path):
144
+ path_main_repo = Path(tmp_path / "corio")
145
+ path_main_repo.mkdir(parents=True)
146
+
147
+ path_haco_repo = Path(path_main_repo / "haco")
148
+ path_haco_repo.mkdir(parents=True)
149
+ _write_editable_repo(path_haco_repo, name="haco", version="1.2.3")
150
+
151
+ (path_main_repo / "pyproject.toml").write_text(
152
+ '[tool.uv.sources.haco]\npath = "haco"\neditable = true\n',
153
+ encoding="utf-8",
154
+ )
155
+
156
+ incrementor = _make_incrementor(path_main_repo)
157
+
158
+ dependencies = ["haco", "requests>=2"]
159
+ optional_dev = ["haco[logging]", "pytest"]
160
+
161
+ assert incrementor._process_deps(dependencies) == ["haco==1.2.3", "requests>=2"]
162
+ assert incrementor._process_deps(optional_dev) == ["haco[logging]==1.2.3", "pytest"]
163
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corio
3
- Version: 2.2.2a2
3
+ Version: 2.2.2a4
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
@@ -104,6 +104,7 @@ corio/tests/test_caching.py
104
104
  corio/tests/test_datatype.py
105
105
  corio/tests/test_encrypt.py
106
106
  corio/tests/test_env.py
107
+ corio/tests/test_infra.py
107
108
  corio/tests/test_jsn.py
108
109
  corio/tests/test_path.py
109
110
  corio/tests/test_yaml.py
@@ -64,7 +64,7 @@ secrets = ["encrypt", "env.io", "yaml", "logging", "sets", "vcs"]
64
64
  cli = ["sets", "logging"]
65
65
 
66
66
  [tool.corio.metadata]
67
- version = "2.2.2-alpha002"
67
+ version = "2.2.2-alpha004"
68
68
  port = 0
69
69
  base = "python"
70
70
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
@@ -94,7 +94,7 @@ corio = ["pyproject.package.toml"]
94
94
 
95
95
  [project]
96
96
  name = "corio"
97
- version = "2.2.2-alpha002"
97
+ version = "2.2.2-alpha004"
98
98
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
99
99
  readme = "README.md"
100
100
  dependencies = []
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