half-orm-dev 1.0.0a20__tar.gz → 1.0.0a21__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 (80) hide show
  1. {half_orm_dev-1.0.0a20/half_orm_dev.egg-info → half_orm_dev-1.0.0a21}/PKG-INFO +1 -1
  2. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/repo.py +62 -27
  3. half_orm_dev-1.0.0a21/half_orm_dev/version.txt +1 -0
  4. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21/half_orm_dev.egg-info}/PKG-INFO +1 -1
  5. half_orm_dev-1.0.0a20/half_orm_dev/version.txt +0 -1
  6. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/AUTHORS +0 -0
  7. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/LICENSE +0 -0
  8. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/README.md +0 -0
  9. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/__init__.py +0 -0
  10. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/bootstrap_manager.py +0 -0
  11. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/__init__.py +0 -0
  12. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/__init__.py +0 -0
  13. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/apply.py +0 -0
  14. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/bootstrap.py +0 -0
  15. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/check.py +0 -0
  16. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/clone.py +0 -0
  17. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/init.py +0 -0
  18. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/migrate.py +0 -0
  19. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/patch.py +0 -0
  20. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/release.py +0 -0
  21. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/restore.py +0 -0
  22. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/revert_migration.py +0 -0
  23. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/set_git_origin.py +0 -0
  24. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/sync.py +0 -0
  25. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/todo.py +0 -0
  26. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/undo.py +0 -0
  27. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/update.py +0 -0
  28. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/commands/upgrade.py +0 -0
  29. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli/main.py +0 -0
  30. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/cli_extension.py +0 -0
  31. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/database.py +0 -0
  32. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/decorators.py +0 -0
  33. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/file_executor.py +0 -0
  34. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/hgit.py +0 -0
  35. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migration_manager.py +0 -0
  36. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/17/1/00_move_to_hop.py +0 -0
  37. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/17/1/01_txt_to_toml.py +0 -0
  38. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/17/4/00_toml_dict_format.py +0 -0
  39. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/17/4/01_add_bootstrap_table.py +0 -0
  40. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/17/4/02_move_patches_to_subdirs.py +0 -0
  41. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/17/5/01_update_pyproject_dependency.py +0 -0
  42. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/18/0/00_add_async_support.py +0 -0
  43. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/0/18/0/01_update_default_tests.py +0 -0
  44. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/migrations/hop/BREAKING_CHANGES-1.0.0.md +0 -0
  45. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/modules.py +0 -0
  46. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patch_manager.py +0 -0
  47. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patch_validator.py +0 -0
  48. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +0 -0
  49. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +0 -0
  50. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +0 -0
  51. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patches/log +0 -0
  52. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/patches/sql/half_orm_meta.sql +0 -0
  53. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/release_file.py +0 -0
  54. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/release_manager.py +0 -0
  55. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/scripts/repair-metadata.py +0 -0
  56. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/.gitignore +0 -0
  57. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/MANIFEST.in +0 -0
  58. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/README +0 -0
  59. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/conftest_template +0 -0
  60. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/git-hooks/pre-commit +0 -0
  61. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/git-hooks/pre-push +0 -0
  62. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/git-hooks/prepare-commit-msg +0 -0
  63. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/git-hooks/reference-transaction +0 -0
  64. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/init_module_template +0 -0
  65. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/module_template_1 +0 -0
  66. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/module_template_2 +0 -0
  67. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/module_template_3 +0 -0
  68. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/pyproject.toml +0 -0
  69. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/relation_test +0 -0
  70. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/sql_adapter +0 -0
  71. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/templates/warning +0 -0
  72. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev/utils.py +0 -0
  73. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev.egg-info/SOURCES.txt +0 -0
  74. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev.egg-info/dependency_links.txt +0 -0
  75. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev.egg-info/entry_points.txt +0 -0
  76. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev.egg-info/requires.txt +0 -0
  77. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/half_orm_dev.egg-info/top_level.txt +0 -0
  78. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/pyproject.toml +0 -0
  79. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/setup.cfg +0 -0
  80. {half_orm_dev-1.0.0a20 → half_orm_dev-1.0.0a21}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: half_orm_dev
3
- Version: 1.0.0a20
3
+ Version: 1.0.0a21
4
4
  Summary: half_orm development Framework.
5
5
  Author-email: Joël Maïzi <joel.maizi@collorg.org>
6
6
  License-Expression: GPL-3.0-or-later
@@ -491,7 +491,6 @@ class Repo:
491
491
  " Run 'hop migrate' on a development machine first, then deploy."
492
492
  )
493
493
 
494
- self._migration_running = True
495
494
  try:
496
495
  # Create migration manager
497
496
  migration_mgr = MigrationManager(self)
@@ -506,25 +505,31 @@ class Repo:
506
505
 
507
506
  result['migration_needed'] = True
508
507
 
509
- # Migration must be run on ho-prod branch
510
- # If not on ho-prod, switch automatically if working directory is clean
511
508
  current_branch = self.hgit.branch if self.hgit else 'unknown'
512
509
  switched_branch = False
513
510
 
511
+ # Dirty check done ONCE here, before any operation.
512
+ # After this point _migration_running disables further dirty checks:
513
+ # all modifications are the migration's responsibility and will be committed.
514
+ if self.hgit and self.hgit.git_repo.is_dirty(untracked_files=False):
515
+ config_version = self.__config.hop_version if hasattr(self, '_Repo__config') else '0.0.0'
516
+ status = self.hgit.git_repo.git.status('--short')
517
+ raise RepoError(
518
+ f"Repository migration required but working directory has uncommitted changes.\n\n"
519
+ f" Repository version: {config_version}\n"
520
+ f" Installed version: {current_version}\n"
521
+ f" Current branch: {current_branch}\n\n"
522
+ f" Please commit or stash your changes:\n"
523
+ f" git stash\n"
524
+ f" OR\n"
525
+ f" git add . && git commit -m \"your message\"\n"
526
+ f"Dirty files:\n{status}"
527
+ )
528
+
529
+ # From here, all modifications are made by the migration itself.
530
+ self._migration_running = True
531
+
514
532
  if not self.hgit or self.hgit.branch != 'ho-prod':
515
- # Check if working directory is clean
516
- if self.hgit and self.hgit.git_repo.is_dirty(untracked_files=False):
517
- config_version = self.__config.hop_version if hasattr(self, '_Repo__config') else '0.0.0'
518
- raise RepoError(
519
- f"Repository migration required but working directory has uncommitted changes.\n\n"
520
- f" Repository version: {config_version}\n"
521
- f" Installed version: {current_version}\n"
522
- f" Current branch: {current_branch}\n\n"
523
- f" Please commit or stash your changes:\n"
524
- f" git stash\n"
525
- f" OR\n"
526
- f" git add . && git commit -m \"your message\"\n"
527
- )
528
533
 
529
534
  # Working directory is clean, switch to ho-prod
530
535
  try:
@@ -896,17 +901,21 @@ class Repo:
896
901
  git_repo = self.hgit.git_repo
897
902
  current_branch = git_repo.active_branch.name
898
903
 
899
- # Check if working directory is clean
900
- if git_repo.is_dirty(untracked_files=False):
901
- status = git_repo.git.status('--short')
902
- raise RepoError(
903
- f"Working directory has uncommitted changes.\n"
904
- f"Please commit or stash your changes before running this command:\n"
905
- f" git stash\n"
906
- f" OR\n"
907
- f" git add . && git commit -m \"your message\"\n"
908
- f"Dirty files:\n{status}"
909
- )
904
+ # Check if working directory is clean.
905
+ # Skipped during migration: _migration_running means the dirty check
906
+ # was already done once at the start of run_migrations_if_needed(),
907
+ # and all subsequent modifications are committed by the migration itself.
908
+ if not getattr(self, '_migration_running', False):
909
+ if git_repo.is_dirty(untracked_files=False):
910
+ status = git_repo.git.status('--short')
911
+ raise RepoError(
912
+ f"Working directory has uncommitted changes.\n"
913
+ f"Please commit or stash your changes before running this command:\n"
914
+ f" git stash\n"
915
+ f" OR\n"
916
+ f" git add . && git commit -m \"your message\"\n"
917
+ f"Dirty files:\n{status}"
918
+ )
910
919
 
911
920
  # Switch to ho-prod temporarily
912
921
  git_repo.heads['ho-prod'].checkout()
@@ -1391,6 +1400,30 @@ class Repo:
1391
1400
  # step 12: Protect ho-prod from direct commits
1392
1401
  self.install_git_hooks()
1393
1402
 
1403
+ def stage_maintenance_file(self, relative_path: str) -> None:
1404
+ """Stage a file modified by an automated maintenance operation."""
1405
+ if not hasattr(self, '_maintenance_files'):
1406
+ self._maintenance_files = []
1407
+ abs_path = os.path.join(self.__base_dir, relative_path)
1408
+ if os.path.exists(abs_path):
1409
+ self.hgit.git_repo.index.add([relative_path])
1410
+ if relative_path not in self._maintenance_files:
1411
+ self._maintenance_files.append(relative_path)
1412
+
1413
+ def commit_maintenance_files(self, message: str = 'update maintenance files') -> bool:
1414
+ """Commit all staged maintenance files in a single [HOP] commit (skip hooks)."""
1415
+ if not getattr(self, '_maintenance_files', None):
1416
+ return False
1417
+ try:
1418
+ self.hgit.git_repo.index.commit(
1419
+ f'[HOP] {message}',
1420
+ skip_hooks=True,
1421
+ )
1422
+ self._maintenance_files = []
1423
+ return True
1424
+ except Exception:
1425
+ return False
1426
+
1394
1427
  def install_git_hooks(self, force: bool = False) -> dict:
1395
1428
  """
1396
1429
  Install or update Git hooks from templates.
@@ -1467,6 +1500,7 @@ class Repo:
1467
1500
  if missing:
1468
1501
  with gitignore_path.open('a') as f:
1469
1502
  f.write('\n' + '\n'.join(missing) + '\n')
1503
+ self.stage_maintenance_file('.gitignore')
1470
1504
 
1471
1505
  return {
1472
1506
  'installed': any_installed,
@@ -1643,6 +1677,7 @@ class Repo:
1643
1677
  # 1. Check and update Git hooks
1644
1678
  if not dry_run:
1645
1679
  result['hooks'] = self.install_git_hooks()
1680
+ self.commit_maintenance_files('update git hooks and .gitignore')
1646
1681
  else:
1647
1682
  # Dry run: just check if update would be needed
1648
1683
  hooks_source_dir = os.path.join(TEMPLATE_DIRS, 'git-hooks')
@@ -0,0 +1 @@
1
+ 1.0.0-a21
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: half_orm_dev
3
- Version: 1.0.0a20
3
+ Version: 1.0.0a21
4
4
  Summary: half_orm development Framework.
5
5
  Author-email: Joël Maïzi <joel.maizi@collorg.org>
6
6
  License-Expression: GPL-3.0-or-later
@@ -1 +0,0 @@
1
- 1.0.0-a20
File without changes
File without changes