half-orm-dev 0.16.0a9__py3-none-any.whl
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.
- half_orm_dev/__init__.py +1 -0
- half_orm_dev/cli/__init__.py +9 -0
- half_orm_dev/cli/commands/__init__.py +56 -0
- half_orm_dev/cli/commands/apply.py +13 -0
- half_orm_dev/cli/commands/clone.py +102 -0
- half_orm_dev/cli/commands/init.py +331 -0
- half_orm_dev/cli/commands/new.py +15 -0
- half_orm_dev/cli/commands/patch.py +317 -0
- half_orm_dev/cli/commands/prepare.py +21 -0
- half_orm_dev/cli/commands/prepare_release.py +119 -0
- half_orm_dev/cli/commands/promote_to.py +127 -0
- half_orm_dev/cli/commands/release.py +344 -0
- half_orm_dev/cli/commands/restore.py +14 -0
- half_orm_dev/cli/commands/sync.py +13 -0
- half_orm_dev/cli/commands/todo.py +73 -0
- half_orm_dev/cli/commands/undo.py +17 -0
- half_orm_dev/cli/commands/update.py +73 -0
- half_orm_dev/cli/commands/upgrade.py +191 -0
- half_orm_dev/cli/main.py +103 -0
- half_orm_dev/cli_extension.py +38 -0
- half_orm_dev/database.py +1389 -0
- half_orm_dev/hgit.py +1025 -0
- half_orm_dev/hop.py +167 -0
- half_orm_dev/manifest.py +43 -0
- half_orm_dev/modules.py +456 -0
- half_orm_dev/patch.py +281 -0
- half_orm_dev/patch_manager.py +1694 -0
- half_orm_dev/patch_validator.py +335 -0
- half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +34 -0
- half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +2 -0
- half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +3 -0
- half_orm_dev/patches/log +2 -0
- half_orm_dev/patches/sql/half_orm_meta.sql +208 -0
- half_orm_dev/release_manager.py +2841 -0
- half_orm_dev/repo.py +1562 -0
- half_orm_dev/templates/.gitignore +15 -0
- half_orm_dev/templates/MANIFEST.in +1 -0
- half_orm_dev/templates/Pipfile +13 -0
- half_orm_dev/templates/README +25 -0
- half_orm_dev/templates/conftest_template +42 -0
- half_orm_dev/templates/init_module_template +10 -0
- half_orm_dev/templates/module_template_1 +12 -0
- half_orm_dev/templates/module_template_2 +6 -0
- half_orm_dev/templates/module_template_3 +3 -0
- half_orm_dev/templates/relation_test +23 -0
- half_orm_dev/templates/setup.py +81 -0
- half_orm_dev/templates/sql_adapter +9 -0
- half_orm_dev/templates/warning +12 -0
- half_orm_dev/utils.py +49 -0
- half_orm_dev/version.txt +1 -0
- half_orm_dev-0.16.0a9.dist-info/METADATA +935 -0
- half_orm_dev-0.16.0a9.dist-info/RECORD +58 -0
- half_orm_dev-0.16.0a9.dist-info/WHEEL +5 -0
- half_orm_dev-0.16.0a9.dist-info/licenses/AUTHORS +3 -0
- half_orm_dev-0.16.0a9.dist-info/licenses/LICENSE +14 -0
- half_orm_dev-0.16.0a9.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/conftest.py +329 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Release command group - Unified release management.
|
|
3
|
+
|
|
4
|
+
Groups all release-related commands under 'half_orm dev release':
|
|
5
|
+
- release new: Prepare next release stage file
|
|
6
|
+
- release promote: Promote stage to rc or production
|
|
7
|
+
|
|
8
|
+
Replaces legacy commands:
|
|
9
|
+
- prepare-release → release new
|
|
10
|
+
- promote-to → release promote
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import click
|
|
14
|
+
import sys
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
from half_orm_dev.repo import Repo
|
|
18
|
+
from half_orm_dev.release_manager import (
|
|
19
|
+
ReleaseManagerError,
|
|
20
|
+
ReleaseFileError,
|
|
21
|
+
ReleaseVersionError
|
|
22
|
+
)
|
|
23
|
+
from half_orm import utils
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@click.group()
|
|
27
|
+
def release():
|
|
28
|
+
"""
|
|
29
|
+
Release management commands.
|
|
30
|
+
|
|
31
|
+
Prepare, promote, and deploy releases with this unified command group.
|
|
32
|
+
|
|
33
|
+
\b
|
|
34
|
+
Common workflow:
|
|
35
|
+
1. half_orm dev release new <level>
|
|
36
|
+
2. half_orm dev patch add <patch_id>
|
|
37
|
+
3. half_orm dev release promote rc
|
|
38
|
+
4. half_orm dev release promote prod
|
|
39
|
+
"""
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@release.command('new')
|
|
44
|
+
@click.argument(
|
|
45
|
+
'level',
|
|
46
|
+
type=click.Choice(['patch', 'minor', 'major'], case_sensitive=False)
|
|
47
|
+
)
|
|
48
|
+
def release_new(level: str) -> None:
|
|
49
|
+
"""
|
|
50
|
+
Prepare next release stage file.
|
|
51
|
+
|
|
52
|
+
Creates releases/X.Y.Z-stage.txt based on production version and
|
|
53
|
+
semantic versioning increment level.
|
|
54
|
+
|
|
55
|
+
\b
|
|
56
|
+
LEVEL: Version increment type (patch, minor, or major)
|
|
57
|
+
|
|
58
|
+
\b
|
|
59
|
+
Semantic versioning rules:
|
|
60
|
+
• patch: Bug fixes, minor changes (1.3.5 → 1.3.6)
|
|
61
|
+
• minor: New features, backward compatible (1.3.5 → 1.4.0)
|
|
62
|
+
• major: Breaking changes (1.3.5 → 2.0.0)
|
|
63
|
+
|
|
64
|
+
\b
|
|
65
|
+
Workflow:
|
|
66
|
+
1. Read production version from model/schema.sql
|
|
67
|
+
2. Calculate next version (patch/minor/major)
|
|
68
|
+
3. Create releases/X.Y.Z-stage.txt
|
|
69
|
+
4. Commit and push to reserve version globally
|
|
70
|
+
|
|
71
|
+
\b
|
|
72
|
+
Requirements:
|
|
73
|
+
• Must be on ho-prod branch
|
|
74
|
+
• Repository must be clean (no uncommitted changes)
|
|
75
|
+
• Must be synced with origin/ho-prod
|
|
76
|
+
|
|
77
|
+
\b
|
|
78
|
+
Examples:
|
|
79
|
+
Prepare patch release (production 1.3.5 → 1.3.6):
|
|
80
|
+
$ half_orm dev release new patch
|
|
81
|
+
|
|
82
|
+
Prepare minor release (production 1.3.5 → 1.4.0):
|
|
83
|
+
$ half_orm dev release new minor
|
|
84
|
+
|
|
85
|
+
Prepare major release (production 1.3.5 → 2.0.0):
|
|
86
|
+
$ half_orm dev release new major
|
|
87
|
+
|
|
88
|
+
\b
|
|
89
|
+
Next steps after release new:
|
|
90
|
+
• Create patches: half_orm dev patch new <patch_id>
|
|
91
|
+
• Add to release: half_orm dev patch add <patch_id>
|
|
92
|
+
• Promote to RC: half_orm dev release promote rc
|
|
93
|
+
"""
|
|
94
|
+
# Normalize level to lowercase
|
|
95
|
+
level = level.lower()
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
# Get Repo singleton
|
|
99
|
+
repo = Repo()
|
|
100
|
+
|
|
101
|
+
# Get ReleaseManager
|
|
102
|
+
release_mgr = repo.release_manager
|
|
103
|
+
|
|
104
|
+
click.echo(f"Preparing {level} release...")
|
|
105
|
+
click.echo()
|
|
106
|
+
|
|
107
|
+
# Prepare release
|
|
108
|
+
result = release_mgr.prepare_release(level)
|
|
109
|
+
|
|
110
|
+
# Extract result info
|
|
111
|
+
version = result['version']
|
|
112
|
+
stage_file = result['file']
|
|
113
|
+
previous_version = result['previous_version']
|
|
114
|
+
|
|
115
|
+
# Success message
|
|
116
|
+
click.echo(f"✅ {utils.Color.bold('Release prepared successfully!')}")
|
|
117
|
+
click.echo()
|
|
118
|
+
click.echo(f" Previous version: {utils.Color.bold(previous_version)}")
|
|
119
|
+
click.echo(f" New version: {utils.Color.bold(version)}")
|
|
120
|
+
click.echo(f" Stage file: {utils.Color.bold(stage_file)}")
|
|
121
|
+
click.echo()
|
|
122
|
+
click.echo(f"📝 Next steps:")
|
|
123
|
+
click.echo(f" 1. Create patches: {utils.Color.bold(f'half_orm dev patch new <patch_id>')}")
|
|
124
|
+
click.echo(f" 2. Add to release: {utils.Color.bold(f'half_orm dev patch add <patch_id>')}")
|
|
125
|
+
click.echo(f" 3. Promote to RC: {utils.Color.bold('half_orm dev release promote rc')}")
|
|
126
|
+
click.echo()
|
|
127
|
+
|
|
128
|
+
except ReleaseManagerError as e:
|
|
129
|
+
# Handle validation errors (branch, clean, sync, etc.)
|
|
130
|
+
click.echo(f"❌ {utils.Color.red('Release preparation failed:')}", err=True)
|
|
131
|
+
click.echo(f" {str(e)}", err=True)
|
|
132
|
+
sys.exit(1)
|
|
133
|
+
|
|
134
|
+
except ReleaseFileError as e:
|
|
135
|
+
# Handle file errors (missing schema, stage exists, etc.)
|
|
136
|
+
click.echo(f"❌ {utils.Color.red('File error:')}", err=True)
|
|
137
|
+
click.echo(f" {str(e)}", err=True)
|
|
138
|
+
sys.exit(1)
|
|
139
|
+
|
|
140
|
+
except ReleaseVersionError as e:
|
|
141
|
+
# Handle version errors (invalid format, calculation, etc.)
|
|
142
|
+
click.echo(f"❌ {utils.Color.red('Version error:')}", err=True)
|
|
143
|
+
click.echo(f" {str(e)}", err=True)
|
|
144
|
+
sys.exit(1)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@release.command('promote')
|
|
148
|
+
@click.argument('target', type=click.Choice(['rc', 'prod'], case_sensitive=False))
|
|
149
|
+
def release_promote(target: str) -> None:
|
|
150
|
+
"""
|
|
151
|
+
Promote stage release to RC or production.
|
|
152
|
+
|
|
153
|
+
Promotes the smallest stage release to RC (rc1, rc2, etc.) or promotes
|
|
154
|
+
an RC to production. Merges archived patch code into ho-prod and
|
|
155
|
+
manages branch cleanup. Must be run from ho-prod branch.
|
|
156
|
+
|
|
157
|
+
\b
|
|
158
|
+
TARGET: Either 'rc' or 'prod'
|
|
159
|
+
• rc: Promotes stage to release candidate (with branch cleanup)
|
|
160
|
+
• prod: Promotes RC to production release (generates schema dumps)
|
|
161
|
+
|
|
162
|
+
\b
|
|
163
|
+
Complete workflow for RC:
|
|
164
|
+
1. Detect smallest stage release (sequential promotion)
|
|
165
|
+
2. Validate single active RC rule
|
|
166
|
+
3. Acquire distributed lock on ho-prod
|
|
167
|
+
4. Merge archived patches code into ho-prod
|
|
168
|
+
5. Rename stage file to RC file (git mv)
|
|
169
|
+
6. Commit and push promotion
|
|
170
|
+
7. Send rebase notifications to active branches
|
|
171
|
+
8. Cleanup patch branches
|
|
172
|
+
9. Release lock
|
|
173
|
+
|
|
174
|
+
\b
|
|
175
|
+
Complete workflow for Production:
|
|
176
|
+
1. Detect latest RC file
|
|
177
|
+
2. Validate sequential version rule
|
|
178
|
+
3. Acquire distributed lock on ho-prod
|
|
179
|
+
4. Restore database and apply all patches
|
|
180
|
+
5. Generate schema-X.Y.Z.sql and metadata-X.Y.Z.sql
|
|
181
|
+
6. Update schema.sql symlink
|
|
182
|
+
7. Rename RC file to production file (git mv)
|
|
183
|
+
8. Commit and push promotion
|
|
184
|
+
9. Release lock
|
|
185
|
+
|
|
186
|
+
\b
|
|
187
|
+
Examples:
|
|
188
|
+
Promote smallest stage release to RC:
|
|
189
|
+
$ half_orm dev release promote rc
|
|
190
|
+
|
|
191
|
+
Output:
|
|
192
|
+
✓ Promoted 1.3.5-stage → 1.3.5-rc1
|
|
193
|
+
✓ Merged 3 patches into ho-prod
|
|
194
|
+
✓ Deleted 3 patch branches
|
|
195
|
+
✓ Notified 2 active branches
|
|
196
|
+
|
|
197
|
+
Promote RC to production:
|
|
198
|
+
$ half_orm dev release promote prod
|
|
199
|
+
|
|
200
|
+
Output:
|
|
201
|
+
✓ Promoted 1.3.5-rc1 → 1.3.5
|
|
202
|
+
✓ Generated schema-1.3.5.sql
|
|
203
|
+
✓ Generated metadata-1.3.5.sql
|
|
204
|
+
✓ Updated schema.sql → schema-1.3.5.sql
|
|
205
|
+
|
|
206
|
+
\b
|
|
207
|
+
Next steps after promote rc:
|
|
208
|
+
• Test RC: Run integration tests
|
|
209
|
+
• Fix issues: Create patches, add to new stage, promote again
|
|
210
|
+
• Deploy: half_orm dev release promote prod
|
|
211
|
+
|
|
212
|
+
\b
|
|
213
|
+
Next steps after promote prod:
|
|
214
|
+
• Tag release: git tag v1.3.5
|
|
215
|
+
• Deploy to production: Use db upgrade on production servers
|
|
216
|
+
• Start next cycle: half_orm dev release new patch
|
|
217
|
+
|
|
218
|
+
\b
|
|
219
|
+
Raises:
|
|
220
|
+
click.ClickException: If validations fail or workflow errors occur
|
|
221
|
+
"""
|
|
222
|
+
try:
|
|
223
|
+
# Get repository instance
|
|
224
|
+
repo = Repo()
|
|
225
|
+
|
|
226
|
+
# Delegate to ReleaseManager
|
|
227
|
+
click.echo(f"Promoting release to {target.upper()}...")
|
|
228
|
+
click.echo()
|
|
229
|
+
|
|
230
|
+
result = repo.release_manager.promote_to(target.lower())
|
|
231
|
+
|
|
232
|
+
# Display success message
|
|
233
|
+
click.echo(f"✓ {utils.Color.green('Success!')}")
|
|
234
|
+
click.echo()
|
|
235
|
+
|
|
236
|
+
# Target-specific output
|
|
237
|
+
if target.lower() == 'rc':
|
|
238
|
+
# RC promotion output
|
|
239
|
+
click.echo(f" Promoted: {utils.Color.bold(result['from_file'])} → {utils.Color.bold(result['to_file'])}")
|
|
240
|
+
patches = result.get('patches_merged')
|
|
241
|
+
if patches:
|
|
242
|
+
click.echo(f" Patches merged: {utils.Color.bold(str(len(patches)))} patch(es)")
|
|
243
|
+
click.echo(f" Branches cleaned: {utils.Color.bold(str(len(result['branches_deleted'])))} branch(es)")
|
|
244
|
+
|
|
245
|
+
if result.get('notified_branches'):
|
|
246
|
+
click.echo(f" Notified: {len(result['notified_branches'])} active branch(es)")
|
|
247
|
+
|
|
248
|
+
click.echo()
|
|
249
|
+
click.echo("📝 Next steps:")
|
|
250
|
+
click.echo(f" • Test RC thoroughly")
|
|
251
|
+
click.echo(f" • Fix issues: Create patch, add to new stage, promote again")
|
|
252
|
+
click.echo(f" • Deploy to production: {utils.Color.bold('half_orm dev release promote prod')}")
|
|
253
|
+
|
|
254
|
+
else:
|
|
255
|
+
# Production promotion output
|
|
256
|
+
click.echo(f" Promoted: {utils.Color.bold(result['from_file'])} → {utils.Color.bold(result['to_file'])}")
|
|
257
|
+
click.echo(f" Version: {utils.Color.bold(result['version'])}")
|
|
258
|
+
|
|
259
|
+
if result.get('schema_file'):
|
|
260
|
+
click.echo(f" Schema: {utils.Color.bold(result['schema_file'])}")
|
|
261
|
+
if result.get('metadata_file'):
|
|
262
|
+
click.echo(f" Metadata: {utils.Color.bold(result['metadata_file'])}")
|
|
263
|
+
if result.get('symlink_updated'):
|
|
264
|
+
click.echo(f" Symlink: schema.sql → {utils.Color.bold(result['schema_file'])}")
|
|
265
|
+
|
|
266
|
+
click.echo()
|
|
267
|
+
click.echo("📝 Next steps:")
|
|
268
|
+
click.echo(f""" • Tag release: {utils.Color.bold(f'git tag v{result["version"]}')}""")
|
|
269
|
+
click.echo(f" • Deploy to production servers: {utils.Color.bold('half_orm dev db upgrade')}")
|
|
270
|
+
click.echo(f" • Start next cycle: {utils.Color.bold('half_orm dev release new patch')}")
|
|
271
|
+
|
|
272
|
+
click.echo()
|
|
273
|
+
|
|
274
|
+
except ReleaseManagerError as e:
|
|
275
|
+
raise click.ClickException(str(e))
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@release.command('hotfix')
|
|
279
|
+
@click.argument('patch_id', type=str)
|
|
280
|
+
def release_hotfix(patch_id: str) -> None:
|
|
281
|
+
"""
|
|
282
|
+
Create emergency hotfix release (NOT IMPLEMENTED YET).
|
|
283
|
+
|
|
284
|
+
Creates a hotfix release that bypasses the normal stage → rc → prod
|
|
285
|
+
workflow for critical production issues.
|
|
286
|
+
|
|
287
|
+
\b
|
|
288
|
+
Args:
|
|
289
|
+
patch_id: Patch identifier for the hotfix
|
|
290
|
+
|
|
291
|
+
\b
|
|
292
|
+
Example:
|
|
293
|
+
$ half_orm dev release hotfix critical-security-fix
|
|
294
|
+
|
|
295
|
+
\b
|
|
296
|
+
Status: 🚧 Not implemented - planned for future release
|
|
297
|
+
"""
|
|
298
|
+
click.echo("🚧 Hotfix release creation not implemented yet")
|
|
299
|
+
click.echo()
|
|
300
|
+
click.echo("Planned workflow:")
|
|
301
|
+
click.echo(" 1. Create ho-patch/PATCH_ID from ho-prod")
|
|
302
|
+
click.echo(" 2. Create releases/X.Y.Z-hotfixN.txt")
|
|
303
|
+
click.echo(" 3. Emergency deployment workflow")
|
|
304
|
+
click.echo()
|
|
305
|
+
raise NotImplementedError("Hotfix release creation not yet implemented")
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@release.command('apply')
|
|
309
|
+
@click.argument('version', type=str, required=False)
|
|
310
|
+
def release_apply(version: Optional[str] = None) -> None:
|
|
311
|
+
"""
|
|
312
|
+
Test complete release before deployment (NOT IMPLEMENTED YET).
|
|
313
|
+
|
|
314
|
+
Applies all patches from a release file to test the complete
|
|
315
|
+
release workflow before production deployment.
|
|
316
|
+
|
|
317
|
+
\b
|
|
318
|
+
Args:
|
|
319
|
+
version: Release version to test (e.g., "1.3.5-rc1")
|
|
320
|
+
If not provided, applies latest RC
|
|
321
|
+
|
|
322
|
+
\b
|
|
323
|
+
Examples:
|
|
324
|
+
Test latest RC:
|
|
325
|
+
$ half_orm dev release apply
|
|
326
|
+
|
|
327
|
+
Test specific RC:
|
|
328
|
+
$ half_orm dev release apply 1.3.5-rc1
|
|
329
|
+
|
|
330
|
+
Test stage release:
|
|
331
|
+
$ half_orm dev release apply 1.3.5-stage
|
|
332
|
+
|
|
333
|
+
\b
|
|
334
|
+
Status: 🚧 Not implemented - planned for future release
|
|
335
|
+
"""
|
|
336
|
+
click.echo("🚧 Release testing not implemented yet")
|
|
337
|
+
click.echo()
|
|
338
|
+
click.echo("Planned workflow:")
|
|
339
|
+
click.echo(" 1. Restore database from model/schema.sql")
|
|
340
|
+
click.echo(" 2. Apply all patches from release file")
|
|
341
|
+
click.echo(" 3. Run comprehensive tests")
|
|
342
|
+
click.echo(" 4. Validate final state")
|
|
343
|
+
click.echo()
|
|
344
|
+
raise NotImplementedError("Release apply not yet implemented")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sync command - Synchronize the Python package with the database model
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from half_orm_dev.repo import Repo
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command()
|
|
10
|
+
def sync_package():
|
|
11
|
+
"""Synchronize the Python package with the database model."""
|
|
12
|
+
repo = Repo()
|
|
13
|
+
repo.sync_package()
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO command - Placeholder for unimplemented Git-centric commands
|
|
3
|
+
|
|
4
|
+
Single function with multiple aliases for all commands to implement.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@click.command()
|
|
11
|
+
@click.pass_context
|
|
12
|
+
def todo(ctx):
|
|
13
|
+
"""
|
|
14
|
+
Placeholder for unimplemented Git-centric commands.
|
|
15
|
+
|
|
16
|
+
All legacy commands (prepare, undo, release, new) removed in v0.16.0.
|
|
17
|
+
New patch-centric workflow commands not yet implemented.
|
|
18
|
+
|
|
19
|
+
Target Git-centric architecture:
|
|
20
|
+
- ho-prod + ho-patch/patch-name branches
|
|
21
|
+
- Patches/patch-name/ directory structure
|
|
22
|
+
- releases/X.Y.Z-stage.txt → rc → production workflow
|
|
23
|
+
- PatchManager integration via repo.patch_manager
|
|
24
|
+
- Single active development rule (one RC at a time)
|
|
25
|
+
- Developer responsibility for conflict management
|
|
26
|
+
"""
|
|
27
|
+
command_name = ctx.info_name
|
|
28
|
+
|
|
29
|
+
# Map of command → description for helpful error messages
|
|
30
|
+
command_descriptions = {
|
|
31
|
+
# 🚧 New Git-centric commands
|
|
32
|
+
'init-project': 'Initialize new project with ho-prod branch and Patches/ structure',
|
|
33
|
+
'create-patch': 'Create ho-patch/patch-name branch with Patches/patch-name/ directory',
|
|
34
|
+
'apply-patch': 'Apply current patch files using PatchManager.apply_patch_files()',
|
|
35
|
+
'add-to-release': 'Add patch to releases/X.Y.Z-stage.txt and merge to ho-prod',
|
|
36
|
+
'prepare-release': 'Create next releases/X.Y.Z-stage.txt file',
|
|
37
|
+
'promote-to': "Promote stage → target ('rc', 'prod') with automatic branch cleanup",
|
|
38
|
+
'update': 'Apply patches in production (adapt for Git-centric)',
|
|
39
|
+
'upgrade': 'Apply patches in production (adapt for Git-centric)',
|
|
40
|
+
|
|
41
|
+
# ♻️ Commands to implement
|
|
42
|
+
'create-hotfix': 'Create emergency hotfix bypassing normal workflow',
|
|
43
|
+
'rollback': 'Rollback database to previous version using backups/',
|
|
44
|
+
'sync-package': 'Synchronize Python package with database model',
|
|
45
|
+
'restore': 'Restore database to specific version (adapt for new backups)',
|
|
46
|
+
'list-patches': 'List all patches in Patches/ directory',
|
|
47
|
+
'status': 'Show development status with patch/release information',
|
|
48
|
+
'apply-release': 'Apply next release',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
description = command_descriptions.get(command_name, 'Git-centric command')
|
|
52
|
+
|
|
53
|
+
raise NotImplementedError(
|
|
54
|
+
f"Command '{command_name}' not implemented in v0.16.0\n"
|
|
55
|
+
f"Description: {description}\n\n"
|
|
56
|
+
f"Legacy commands removed - use new patch-centric workflow:\n"
|
|
57
|
+
f"See docs/half_orm_dev.md for architecture details.\n"
|
|
58
|
+
f"Current working: PatchManager (102 tests), HGit, Repo integration."
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Create aliases for ALL commands (new + adapted)
|
|
63
|
+
# 🚧 New Git-centric commands
|
|
64
|
+
add_to_release = todo
|
|
65
|
+
apply_release = todo
|
|
66
|
+
create_hotfix = todo
|
|
67
|
+
rollback = todo
|
|
68
|
+
list_patches = todo
|
|
69
|
+
status = todo
|
|
70
|
+
|
|
71
|
+
# ♻️ Commands to adapt (also in todo for now)
|
|
72
|
+
sync_package = todo # Keep functionality, adapt to new architecture
|
|
73
|
+
restore = todo # Adapt for new backup/restore logic
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Undo command - Undo the last release
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from half_orm_dev.repo import Repo
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command()
|
|
10
|
+
@click.option(
|
|
11
|
+
'-d', '--database-only', is_flag=True,
|
|
12
|
+
help='Restore the database to the previous release.'
|
|
13
|
+
)
|
|
14
|
+
def undo(database_only):
|
|
15
|
+
"""Undo the last release."""
|
|
16
|
+
repo = Repo()
|
|
17
|
+
repo.undo_release(database_only)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Update command - Fetch and list available production releases.
|
|
3
|
+
|
|
4
|
+
Equivalent to 'apt update' - read-only operation that shows
|
|
5
|
+
available releases without making any changes.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
from half_orm_dev.repo import Repo
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@click.command()
|
|
13
|
+
def update():
|
|
14
|
+
"""
|
|
15
|
+
Fetch and list available production releases.
|
|
16
|
+
|
|
17
|
+
Synchronizes with origin (git fetch --tags) and displays available
|
|
18
|
+
releases for production upgrade. Makes NO modifications to database
|
|
19
|
+
or repository.
|
|
20
|
+
|
|
21
|
+
By default, shows only production releases (v1.3.6, v1.4.0).
|
|
22
|
+
Use --allow-rc to include release candidates (v1.3.6-rc1).
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
# List production releases only
|
|
26
|
+
half_orm dev update
|
|
27
|
+
|
|
28
|
+
# Include RC releases
|
|
29
|
+
half_orm dev update --allow-rc
|
|
30
|
+
"""
|
|
31
|
+
repo = Repo()
|
|
32
|
+
|
|
33
|
+
# Direct access to ReleaseManager (KISS principle)
|
|
34
|
+
result = repo.release_manager.update_production()
|
|
35
|
+
|
|
36
|
+
# Format and display results
|
|
37
|
+
_display_update_results(result)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _display_update_results(result):
|
|
41
|
+
"""
|
|
42
|
+
Format and display update results to user.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
result: Dict from ReleaseManager.update_production()
|
|
46
|
+
"""
|
|
47
|
+
click.echo("\nFetching releases from origin... ✓\n")
|
|
48
|
+
|
|
49
|
+
current = result['current_version']
|
|
50
|
+
click.echo(f"Current production version: {current}")
|
|
51
|
+
|
|
52
|
+
if not result['has_updates']:
|
|
53
|
+
click.echo("\n✓ Production is up to date. No upgrades available.")
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
click.echo("\nAvailable releases for upgrade:")
|
|
57
|
+
for rel in result['available_releases']:
|
|
58
|
+
rel_type = rel['type'].upper() if rel['type'] != 'production' else ''
|
|
59
|
+
type_label = f" ({rel_type})" if rel_type else ""
|
|
60
|
+
patch_count = len(rel['patches'])
|
|
61
|
+
click.echo(f" → {rel['version']}{type_label} - {patch_count} patches")
|
|
62
|
+
|
|
63
|
+
if result['upgrade_path']:
|
|
64
|
+
click.echo("\nUpgrade path (sequential):")
|
|
65
|
+
path_str = " → ".join([current] + result['upgrade_path'])
|
|
66
|
+
click.echo(f" {path_str}")
|
|
67
|
+
|
|
68
|
+
click.echo("\nTo upgrade:")
|
|
69
|
+
click.echo(" half_orm dev upgrade (apply all)")
|
|
70
|
+
if result['upgrade_path']:
|
|
71
|
+
first_version = result['upgrade_path'][0]
|
|
72
|
+
click.echo(f" half_orm dev upgrade --to-release={first_version} (apply specific)")
|
|
73
|
+
click.echo(" half_orm dev upgrade --dry-run (simulate)")
|