half-orm-dev 1.0.0a7__tar.gz → 1.0.0a8__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.
- {half_orm_dev-1.0.0a7/half_orm_dev.egg-info → half_orm_dev-1.0.0a8}/PKG-INFO +1 -1
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migration_manager.py +86 -26
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/repo.py +4 -12
- half_orm_dev-1.0.0a8/half_orm_dev/version.txt +1 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8/half_orm_dev.egg-info}/PKG-INFO +1 -1
- half_orm_dev-1.0.0a7/half_orm_dev/version.txt +0 -1
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/AUTHORS +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/LICENSE +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/README.md +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/__init__.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/bootstrap_manager.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/__init__.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/__init__.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/apply.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/bootstrap.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/check.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/clone.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/init.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/migrate.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/patch.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/release.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/restore.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/revert_migration.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/set_git_origin.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/sync.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/todo.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/undo.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/update.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/commands/upgrade.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli/main.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/cli_extension.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/database.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/decorators.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/file_executor.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/hgit.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/1/00_move_to_hop.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/1/01_txt_to_toml.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/4/00_toml_dict_format.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/4/01_add_bootstrap_table.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/4/02_move_patches_to_subdirs.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/5/01_update_pyproject_dependency.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/18/0/00_add_async_support.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/18/0/01_update_default_tests.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/hop/BREAKING_CHANGES-1.0.0.md +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/modules.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patch_manager.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patch_validator.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patches/log +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/patches/sql/half_orm_meta.sql +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/release_file.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/release_manager.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/scripts/repair-metadata.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/.gitignore +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/MANIFEST.in +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/README +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/conftest_template +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/git-hooks/pre-commit +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/git-hooks/prepare-commit-msg +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/init_module_template +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/module_stub_template +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/module_template_1 +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/module_template_2 +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/module_template_3 +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/pyproject.toml +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/relation_test +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/sql_adapter +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/warning +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/utils.py +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev.egg-info/SOURCES.txt +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev.egg-info/dependency_links.txt +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev.egg-info/entry_points.txt +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev.egg-info/requires.txt +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev.egg-info/top_level.txt +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/pyproject.toml +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/setup.cfg +0 -0
- {half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/setup.py +0 -0
|
@@ -313,6 +313,9 @@ class MigrationManager:
|
|
|
313
313
|
f"Continuing with migration attempt."
|
|
314
314
|
)
|
|
315
315
|
|
|
316
|
+
# Ensure all active branches are in sync with origin before touching anything
|
|
317
|
+
self._ensure_active_branches_synced()
|
|
318
|
+
|
|
316
319
|
# Get pending migrations
|
|
317
320
|
pending = self.get_pending_migrations(current_version, target_version)
|
|
318
321
|
|
|
@@ -452,6 +455,72 @@ class MigrationManager:
|
|
|
452
455
|
except Exception:
|
|
453
456
|
pass # remote tag may already be gone
|
|
454
457
|
|
|
458
|
+
def _ensure_active_branches_synced(self) -> None:
|
|
459
|
+
"""Verify all active branches are in sync with origin before migration.
|
|
460
|
+
|
|
461
|
+
Branches that are behind are fast-forwarded automatically (no local commits
|
|
462
|
+
at risk). Branches that are ahead or diverged block the migration — the
|
|
463
|
+
developer must push or resolve before proceeding.
|
|
464
|
+
|
|
465
|
+
Raises:
|
|
466
|
+
MigrationManagerError: if any active branch is ahead or diverged.
|
|
467
|
+
"""
|
|
468
|
+
repo = self._repo
|
|
469
|
+
git_repo = repo.hgit._HGit__git_repo
|
|
470
|
+
current_branch = git_repo.active_branch.name
|
|
471
|
+
|
|
472
|
+
try:
|
|
473
|
+
branches_status = repo.hgit.get_active_branches_status()
|
|
474
|
+
except Exception:
|
|
475
|
+
return # can't determine status, proceed cautiously
|
|
476
|
+
|
|
477
|
+
patch_branches = [b['name'] for b in branches_status.get('patch_branches', [])]
|
|
478
|
+
release_branches = [b['name'] for b in branches_status.get('release_branches', [])]
|
|
479
|
+
staged_branches = [b['name'] for b in branches_status.get('staged_branches', [])]
|
|
480
|
+
active_branches = release_branches + patch_branches + staged_branches
|
|
481
|
+
|
|
482
|
+
blocked = []
|
|
483
|
+
for branch in active_branches:
|
|
484
|
+
try:
|
|
485
|
+
synced, status = repo.hgit.is_branch_synced(branch)
|
|
486
|
+
if synced:
|
|
487
|
+
continue
|
|
488
|
+
if status == 'behind':
|
|
489
|
+
# Fast-forward: no local commits at risk
|
|
490
|
+
repo.hgit.checkout(branch)
|
|
491
|
+
git_repo.git.merge('--ff-only', f'origin/{branch}')
|
|
492
|
+
elif status in ('ahead', 'diverged'):
|
|
493
|
+
blocked.append((branch, status))
|
|
494
|
+
except Exception:
|
|
495
|
+
pass # branch may not exist locally, skip
|
|
496
|
+
|
|
497
|
+
# Return to original branch
|
|
498
|
+
try:
|
|
499
|
+
repo.hgit.checkout(current_branch)
|
|
500
|
+
except Exception:
|
|
501
|
+
pass
|
|
502
|
+
|
|
503
|
+
if blocked:
|
|
504
|
+
ahead = [(b, s) for b, s in blocked if s == 'ahead']
|
|
505
|
+
diverged = [(b, s) for b, s in blocked if s == 'diverged']
|
|
506
|
+
parts = []
|
|
507
|
+
if ahead:
|
|
508
|
+
branch_list = ', '.join(b for b, _ in ahead)
|
|
509
|
+
parts.append(
|
|
510
|
+
f" Branches ahead of origin (unpushed commits) — push first:\n"
|
|
511
|
+
+ '\n'.join(f" git push origin {b}" for b, _ in ahead)
|
|
512
|
+
)
|
|
513
|
+
if diverged:
|
|
514
|
+
parts.append(
|
|
515
|
+
f" Branches diverged from origin (local and remote have diverged) "
|
|
516
|
+
f"— rebase or merge to resolve:\n"
|
|
517
|
+
+ '\n'.join(f" {b}" for b, _ in diverged)
|
|
518
|
+
)
|
|
519
|
+
raise MigrationManagerError(
|
|
520
|
+
f"Migration blocked: active branches are not in sync with origin.\n"
|
|
521
|
+
+ '\n'.join(parts)
|
|
522
|
+
)
|
|
523
|
+
|
|
455
524
|
def _regenerate_modules_after_migration(
|
|
456
525
|
self, from_version: str, to_version: str
|
|
457
526
|
) -> None:
|
|
@@ -468,50 +537,41 @@ class MigrationManager:
|
|
|
468
537
|
package_name = repo.name
|
|
469
538
|
package_dir = str(Path(repo.base_dir) / package_name)
|
|
470
539
|
|
|
471
|
-
# Regenerate all modules (idempotent thanks to global reset in generate())
|
|
472
|
-
_modules.generate(repo)
|
|
473
|
-
|
|
474
|
-
# Stage the entire package directory
|
|
475
|
-
repo.hgit.add(package_dir)
|
|
476
|
-
|
|
477
|
-
# Nothing changed — nothing to do
|
|
478
|
-
staged = git_repo.git.diff('--cached', '--name-only')
|
|
479
|
-
if not staged.strip():
|
|
480
|
-
return
|
|
481
|
-
|
|
482
|
-
# Commit on ho-prod
|
|
483
540
|
commit_msg = (
|
|
484
541
|
f"[HOP] Regenerate modules (migration {from_version} → {to_version})"
|
|
485
542
|
)
|
|
486
|
-
repo.hgit.commit('-m', commit_msg)
|
|
487
|
-
repo.hgit.push_branch('ho-prod')
|
|
488
543
|
|
|
489
|
-
#
|
|
544
|
+
# Collect active branches before moving around
|
|
490
545
|
try:
|
|
491
546
|
branches_status = repo.hgit.get_active_branches_status()
|
|
492
547
|
except Exception:
|
|
493
|
-
|
|
548
|
+
branches_status = {}
|
|
494
549
|
|
|
495
550
|
patch_branches = [b['name'] for b in branches_status.get('patch_branches', [])]
|
|
496
551
|
release_branches = [b['name'] for b in branches_status.get('release_branches', [])]
|
|
497
552
|
staged_branches = [b['name'] for b in branches_status.get('staged_branches', [])]
|
|
498
|
-
|
|
553
|
+
# ho-prod first, then active branches
|
|
554
|
+
all_branches = ['ho-prod'] + release_branches + patch_branches + staged_branches
|
|
499
555
|
|
|
500
|
-
|
|
501
|
-
f"[HOP] Sync modules from ho-prod (migration {from_version} → {to_version})"
|
|
502
|
-
)
|
|
503
|
-
for branch in target_branches:
|
|
556
|
+
for branch in all_branches:
|
|
504
557
|
try:
|
|
505
558
|
repo.hgit.checkout(branch)
|
|
506
|
-
|
|
559
|
+
# generate() reads existing files and preserves developer code sections
|
|
560
|
+
_modules.generate(repo)
|
|
507
561
|
repo.hgit.add(package_dir)
|
|
508
|
-
if not git_repo.git.
|
|
562
|
+
if not git_repo.git.diff('--cached', '--name-only').strip():
|
|
509
563
|
continue
|
|
510
|
-
repo.hgit.commit('-m',
|
|
511
|
-
|
|
564
|
+
repo.hgit.commit('-m', commit_msg)
|
|
565
|
+
try:
|
|
566
|
+
repo.hgit.push_branch(branch)
|
|
567
|
+
except Exception as push_err:
|
|
568
|
+
sys.stderr.write(
|
|
569
|
+
f"Warning: could not push {branch} after module regeneration "
|
|
570
|
+
f"(diverged branch?): {push_err}\n"
|
|
571
|
+
)
|
|
512
572
|
except Exception as e:
|
|
513
573
|
sys.stderr.write(
|
|
514
|
-
f"Warning: could not
|
|
574
|
+
f"Warning: could not regenerate modules on {branch}: {e}\n"
|
|
515
575
|
)
|
|
516
576
|
|
|
517
577
|
repo.hgit.checkout('ho-prod')
|
|
@@ -690,18 +690,10 @@ class Repo:
|
|
|
690
690
|
remote_ref = f"origin/{branch}"
|
|
691
691
|
try:
|
|
692
692
|
synced, status = self.hgit.is_branch_synced(branch)
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
file=sys.stderr
|
|
698
|
-
)
|
|
699
|
-
# Only reset when the remote is ahead of local ("behind") or
|
|
700
|
-
# branches have diverged. Never reset an "ahead" branch —
|
|
701
|
-
# that would orphan local commits that have not been pushed
|
|
702
|
-
# yet (e.g. the "Create patch directory" commit from
|
|
703
|
-
# `hop patch create` before the first push).
|
|
704
|
-
if not synced and status in ("behind", "diverged"):
|
|
693
|
+
# Only fast-forward when origin is strictly ahead (no local commits
|
|
694
|
+
# at risk). Never reset on diverged branches — that would destroy
|
|
695
|
+
# unmerged local work.
|
|
696
|
+
if not synced and status == "behind":
|
|
705
697
|
self.hgit._HGit__git_repo.git.reset('--hard', remote_ref)
|
|
706
698
|
except GitCommandError:
|
|
707
699
|
# Remote branch may not exist yet, continue without reset
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.0-a8
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0.0-a7
|
|
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
|
{half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/1/00_move_to_hop.py
RENAMED
|
File without changes
|
{half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/1/01_txt_to_toml.py
RENAMED
|
File without changes
|
{half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/17/4/00_toml_dict_format.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/0/18/0/00_add_async_support.py
RENAMED
|
File without changes
|
|
File without changes
|
{half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/migrations/hop/BREAKING_CHANGES-1.0.0.md
RENAMED
|
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
|
{half_orm_dev-1.0.0a7 → half_orm_dev-1.0.0a8}/half_orm_dev/templates/git-hooks/prepare-commit-msg
RENAMED
|
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
|