half-orm-dev 0.17.0a10__tar.gz → 0.17.0a11__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-0.17.0a10/half_orm_dev.egg-info → half_orm_dev-0.17.0a11}/PKG-INFO +6 -17
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patch_manager.py +93 -3
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/repo.py +9 -12
- half_orm_dev-0.17.0a11/half_orm_dev/templates/pyproject.toml +55 -0
- half_orm_dev-0.17.0a11/half_orm_dev/version.txt +1 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11/half_orm_dev.egg-info}/PKG-INFO +6 -17
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev.egg-info/SOURCES.txt +3 -4
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev.egg-info/top_level.txt +0 -1
- half_orm_dev-0.17.0a11/pyproject.toml +54 -0
- half_orm_dev-0.17.0a11/setup.py +49 -0
- half_orm_dev-0.17.0a10/half_orm_dev/templates/setup.py +0 -81
- half_orm_dev-0.17.0a10/half_orm_dev/version.txt +0 -1
- half_orm_dev-0.17.0a10/setup.py +0 -80
- half_orm_dev-0.17.0a10/tests/__init__.py +0 -0
- half_orm_dev-0.17.0a10/tests/conftest.py +0 -335
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/AUTHORS +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/LICENSE +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/README.md +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/__init__.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/__init__.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/__init__.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/apply.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/check.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/clone.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/init.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/new.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/patch.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/release.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/restore.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/sync.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/todo.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/undo.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/update.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/commands/upgrade.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli/main.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/cli_extension.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/database.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/decorators.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/hgit.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/hop.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/manifest.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/modules.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patch.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patch_validator.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patches/log +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patches/sql/half_orm_meta.sql +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/release_manager.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/.gitignore +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/MANIFEST.in +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/Pipfile +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/README +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/conftest_template +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/git-hooks/pre-commit +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/git-hooks/prepare-commit-msg +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/init_module_template +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/module_template_1 +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/module_template_2 +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/module_template_3 +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/relation_test +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/sql_adapter +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/warning +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/utils.py +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev.egg-info/dependency_links.txt +0 -0
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev.egg-info/requires.txt +1 -1
- {half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/setup.cfg +0 -0
|
@@ -1,42 +1,31 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: half_orm_dev
|
|
3
|
-
Version: 0.17.
|
|
3
|
+
Version: 0.17.0a11
|
|
4
4
|
Summary: half_orm development Framework.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
License: GNU General Public License v3 (GPLv3)
|
|
5
|
+
Author-email: Joël Maïzi <joel.maizi@collorg.org>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/collorg/halfORM_dev
|
|
9
8
|
Keywords: postgres,relation-object mapping
|
|
10
9
|
Classifier: Development Status :: 3 - Alpha
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
12
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.9
|
|
21
19
|
Description-Content-Type: text/markdown
|
|
22
20
|
License-File: LICENSE
|
|
23
21
|
License-File: AUTHORS
|
|
24
22
|
Requires-Dist: GitPython
|
|
25
23
|
Requires-Dist: click
|
|
26
24
|
Requires-Dist: pydash
|
|
27
|
-
Requires-Dist: half_orm<0.18.0,>=0.17.0
|
|
28
25
|
Requires-Dist: pytest
|
|
29
|
-
|
|
30
|
-
Dynamic: author-email
|
|
31
|
-
Dynamic: classifier
|
|
32
|
-
Dynamic: description
|
|
33
|
-
Dynamic: description-content-type
|
|
34
|
-
Dynamic: home-page
|
|
35
|
-
Dynamic: keywords
|
|
36
|
-
Dynamic: license
|
|
26
|
+
Requires-Dist: half_orm<0.18.0,>=0.17.0
|
|
37
27
|
Dynamic: license-file
|
|
38
28
|
Dynamic: requires-dist
|
|
39
|
-
Dynamic: summary
|
|
40
29
|
|
|
41
30
|
# half_orm_dev
|
|
42
31
|
|
|
@@ -15,6 +15,7 @@ import time
|
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
from typing import List, Dict, Optional, Tuple, Any
|
|
17
17
|
from dataclasses import dataclass
|
|
18
|
+
import click
|
|
18
19
|
from git.exc import GitCommandError
|
|
19
20
|
|
|
20
21
|
from half_orm import utils
|
|
@@ -1588,7 +1589,7 @@ class PatchManager:
|
|
|
1588
1589
|
2. Create temporary validation branch from release branch
|
|
1589
1590
|
3. Merge patch into temp branch
|
|
1590
1591
|
4. Run patch apply and verify no modifications
|
|
1591
|
-
5. Run tests (
|
|
1592
|
+
5. Run tests (best-effort if available)
|
|
1592
1593
|
6. Cleanup temp branch
|
|
1593
1594
|
7. Return to original branch
|
|
1594
1595
|
|
|
@@ -1680,8 +1681,8 @@ class PatchManager:
|
|
|
1680
1681
|
f"Failed to run patch apply during validation: {e}"
|
|
1681
1682
|
)
|
|
1682
1683
|
|
|
1683
|
-
# 4. Run tests (
|
|
1684
|
-
|
|
1684
|
+
# 4. Run tests (best-effort)
|
|
1685
|
+
self._run_tests_if_available()
|
|
1685
1686
|
|
|
1686
1687
|
click.echo(f" • {utils.Color.green('✓')} Validation passed!\n")
|
|
1687
1688
|
|
|
@@ -1699,6 +1700,95 @@ class PatchManager:
|
|
|
1699
1700
|
# Cleanup errors are non-critical, just warn
|
|
1700
1701
|
click.echo(f"⚠️ Warning: Failed to cleanup temp branch {temp_branch}: {e}")
|
|
1701
1702
|
|
|
1703
|
+
def _run_tests_if_available(self) -> None:
|
|
1704
|
+
"""
|
|
1705
|
+
Run tests if test configuration is available.
|
|
1706
|
+
|
|
1707
|
+
Detects if the project has test configuration (pytest.ini, pyproject.toml
|
|
1708
|
+
with pytest config, etc.) and runs pytest if available.
|
|
1709
|
+
- If no test config found: skip silently
|
|
1710
|
+
- If tests fail: raise PatchManagerError (BLOCKS workflow)
|
|
1711
|
+
- If tests pass: success message
|
|
1712
|
+
- If pytest not installed: warning but continue
|
|
1713
|
+
|
|
1714
|
+
This ensures code quality by blocking patches with failing tests.
|
|
1715
|
+
|
|
1716
|
+
Raises:
|
|
1717
|
+
PatchManagerError: If tests fail
|
|
1718
|
+
|
|
1719
|
+
Examples:
|
|
1720
|
+
self._run_tests_if_available()
|
|
1721
|
+
# With tests configured and passing → ✓ Tests passed
|
|
1722
|
+
# With tests configured but failing → raises PatchManagerError
|
|
1723
|
+
# Without test config → skips silently
|
|
1724
|
+
"""
|
|
1725
|
+
base_dir = Path(self._repo.base_dir)
|
|
1726
|
+
|
|
1727
|
+
# Check if test configuration exists
|
|
1728
|
+
test_config_files = [
|
|
1729
|
+
base_dir / "pytest.ini",
|
|
1730
|
+
base_dir / "pyproject.toml",
|
|
1731
|
+
base_dir / "setup.cfg",
|
|
1732
|
+
base_dir / "tox.ini"
|
|
1733
|
+
]
|
|
1734
|
+
|
|
1735
|
+
has_test_config = any(f.exists() for f in test_config_files)
|
|
1736
|
+
|
|
1737
|
+
# Also check if tests directory exists
|
|
1738
|
+
tests_dir = base_dir / "tests"
|
|
1739
|
+
has_tests_dir = tests_dir.exists() and tests_dir.is_dir()
|
|
1740
|
+
|
|
1741
|
+
if not has_test_config and not has_tests_dir:
|
|
1742
|
+
# No test config - skip silently (project may not have tests yet)
|
|
1743
|
+
return
|
|
1744
|
+
|
|
1745
|
+
# Try to run pytest
|
|
1746
|
+
try:
|
|
1747
|
+
click.echo(f" • Running tests...")
|
|
1748
|
+
result = subprocess.run(
|
|
1749
|
+
["pytest", "-v", "--tb=short"],
|
|
1750
|
+
cwd=str(base_dir),
|
|
1751
|
+
capture_output=True,
|
|
1752
|
+
text=True
|
|
1753
|
+
# No timeout - user can Ctrl+C if needed
|
|
1754
|
+
# Cleanup (temp branch + lock) is protected by finally blocks
|
|
1755
|
+
)
|
|
1756
|
+
|
|
1757
|
+
if result.returncode == 0:
|
|
1758
|
+
click.echo(f" • {utils.Color.green('✓')} Tests passed")
|
|
1759
|
+
else:
|
|
1760
|
+
# Tests failed - BLOCK the workflow
|
|
1761
|
+
error_msg = f"Tests failed! Cannot close patch with failing tests.\n\n"
|
|
1762
|
+
|
|
1763
|
+
if result.stdout:
|
|
1764
|
+
# Show test output
|
|
1765
|
+
error_msg += "Test output:\n"
|
|
1766
|
+
output_lines = result.stdout.strip().split('\n')
|
|
1767
|
+
# Show last 20 lines to give enough context
|
|
1768
|
+
last_lines = output_lines[-20:] if len(output_lines) > 20 else output_lines
|
|
1769
|
+
for line in last_lines:
|
|
1770
|
+
error_msg += f" {line}\n"
|
|
1771
|
+
|
|
1772
|
+
if result.stderr:
|
|
1773
|
+
error_msg += f"\nErrors:\n{result.stderr}\n"
|
|
1774
|
+
|
|
1775
|
+
error_msg += "\nFix the failing tests before closing the patch."
|
|
1776
|
+
raise PatchManagerError(error_msg)
|
|
1777
|
+
|
|
1778
|
+
except FileNotFoundError:
|
|
1779
|
+
# pytest not installed - warn but don't block
|
|
1780
|
+
click.echo(f" • {utils.Color.yellow('⚠')} pytest not found (install pytest to run tests)")
|
|
1781
|
+
except PatchManagerError:
|
|
1782
|
+
# Re-raise our own exceptions (test failures)
|
|
1783
|
+
raise
|
|
1784
|
+
except Exception as e:
|
|
1785
|
+
# Any other error - warn but don't block (might be environment issue)
|
|
1786
|
+
click.echo(f" • {utils.Color.yellow('⚠')} Failed to run tests: {e} (continuing anyway)")
|
|
1787
|
+
|
|
1788
|
+
# Note: KeyboardInterrupt (Ctrl+C) is not caught here - it inherits from
|
|
1789
|
+
# BaseException, not Exception, so it will propagate up to the decorator
|
|
1790
|
+
# where the lock will be properly released in the finally block
|
|
1791
|
+
|
|
1702
1792
|
def _validate_on_ho_release(self) -> str:
|
|
1703
1793
|
"""
|
|
1704
1794
|
Validate that current branch is ho-release/X.Y.Z.
|
|
@@ -291,15 +291,15 @@ class Repo:
|
|
|
291
291
|
else:
|
|
292
292
|
utils.error(f"ERROR! The path '{self.__base_dir}' already exists!\n", exit_code=1)
|
|
293
293
|
readme = utils.read(os.path.join(TEMPLATE_DIRS, 'README'))
|
|
294
|
-
|
|
294
|
+
pyproject_template = utils.read(os.path.join(TEMPLATE_DIRS, 'pyproject.toml'))
|
|
295
295
|
git_ignore = utils.read(os.path.join(TEMPLATE_DIRS, '.gitignore'))
|
|
296
296
|
pipfile = utils.read(os.path.join(TEMPLATE_DIRS, 'Pipfile'))
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
pyproject = pyproject_template.format(
|
|
299
299
|
dbname=self.__config.name,
|
|
300
300
|
package_name=self.__config.name,
|
|
301
301
|
half_orm_version=half_orm.__version__)
|
|
302
|
-
utils.write(os.path.join(self.__base_dir, '
|
|
302
|
+
utils.write(os.path.join(self.__base_dir, 'pyproject.toml'), pyproject)
|
|
303
303
|
|
|
304
304
|
pipfile = pipfile.format(
|
|
305
305
|
half_orm_version=half_orm.__version__,
|
|
@@ -527,7 +527,7 @@ class Repo:
|
|
|
527
527
|
7. Initialize Database instance (self.database)
|
|
528
528
|
8. Generate Python package structure
|
|
529
529
|
9. Initialize Git repository with ho-prod branch
|
|
530
|
-
10. Generate template files (README, .gitignore,
|
|
530
|
+
10. Generate template files (README, .gitignore, pyproject.toml, Pipfile)
|
|
531
531
|
11. Save model/schema-0.0.0.sql
|
|
532
532
|
|
|
533
533
|
Git-centric Architecture:
|
|
@@ -1303,31 +1303,28 @@ See docs/half_orm_dev.md for complete documentation.
|
|
|
1303
1303
|
Creates standard project files:
|
|
1304
1304
|
- README.md: Project documentation
|
|
1305
1305
|
- .gitignore: Git exclusions
|
|
1306
|
-
-
|
|
1306
|
+
- pyproject.toml: Python packaging (PEP 517/518)
|
|
1307
1307
|
- Pipfile: Dependencies (current template)
|
|
1308
1308
|
|
|
1309
1309
|
Templates read from TEMPLATE_DIRS and formatted with project variables.
|
|
1310
1310
|
|
|
1311
|
-
Note: Future enhancement will migrate to pyproject.toml,
|
|
1312
|
-
but keeping current templates for initial implementation.
|
|
1313
|
-
|
|
1314
1311
|
Examples:
|
|
1315
1312
|
_generate_template_files()
|
|
1316
|
-
# Creates: README.md, .gitignore,
|
|
1313
|
+
# Creates: README.md, .gitignore, pyproject.toml, Pipfile
|
|
1317
1314
|
"""
|
|
1318
1315
|
import half_orm
|
|
1319
1316
|
from half_orm_dev.utils import TEMPLATE_DIRS, hop_version
|
|
1320
1317
|
|
|
1321
1318
|
# Read templates
|
|
1322
1319
|
readme_template = utils.read(os.path.join(TEMPLATE_DIRS, 'README'))
|
|
1323
|
-
|
|
1320
|
+
pyproject_template = utils.read(os.path.join(TEMPLATE_DIRS, 'pyproject.toml'))
|
|
1324
1321
|
git_ignore = utils.read(os.path.join(TEMPLATE_DIRS, '.gitignore'))
|
|
1325
1322
|
pipfile_template = utils.read(os.path.join(TEMPLATE_DIRS, 'Pipfile'))
|
|
1326
1323
|
|
|
1327
1324
|
# Format templates with project variables
|
|
1328
1325
|
package_name = self.__config.name
|
|
1329
1326
|
|
|
1330
|
-
|
|
1327
|
+
pyproject = pyproject_template.format(
|
|
1331
1328
|
dbname=package_name,
|
|
1332
1329
|
package_name=package_name,
|
|
1333
1330
|
half_orm_version=half_orm.__version__
|
|
@@ -1345,7 +1342,7 @@ See docs/half_orm_dev.md for complete documentation.
|
|
|
1345
1342
|
)
|
|
1346
1343
|
|
|
1347
1344
|
# Write files
|
|
1348
|
-
utils.write(os.path.join(self.__base_dir, '
|
|
1345
|
+
utils.write(os.path.join(self.__base_dir, 'pyproject.toml'), pyproject)
|
|
1349
1346
|
utils.write(os.path.join(self.__base_dir, 'Pipfile'), pipfile)
|
|
1350
1347
|
utils.write(os.path.join(self.__base_dir, 'README.md'), readme)
|
|
1351
1348
|
utils.write(os.path.join(self.__base_dir, '.gitignore'), git_ignore)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Package for PostgreSQL {dbname} database.
|
|
2
|
+
# You can edit the following parameters:
|
|
3
|
+
# - version (in {package_name}/version.txt)
|
|
4
|
+
# - authors
|
|
5
|
+
# - license
|
|
6
|
+
# - keywords
|
|
7
|
+
# - description
|
|
8
|
+
|
|
9
|
+
[build-system]
|
|
10
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
11
|
+
build-backend = "setuptools.build_meta"
|
|
12
|
+
|
|
13
|
+
[project]
|
|
14
|
+
name = "{package_name}"
|
|
15
|
+
dynamic = ["version"]
|
|
16
|
+
description = "Package for {dbname} PostgreSQL database"
|
|
17
|
+
readme = "README.md"
|
|
18
|
+
keywords = []
|
|
19
|
+
authors = [
|
|
20
|
+
{{name = "Your Name", email = "your.email@example.com"}}
|
|
21
|
+
]
|
|
22
|
+
license = "MIT"
|
|
23
|
+
classifiers = [
|
|
24
|
+
# How mature is this project? Common values are
|
|
25
|
+
# 3 - Alpha
|
|
26
|
+
# 4 - Beta
|
|
27
|
+
# 5 - Production/Stable
|
|
28
|
+
"Development Status :: 3 - Alpha",
|
|
29
|
+
|
|
30
|
+
# Indicate who your project is intended for
|
|
31
|
+
"Intended Audience :: Developers",
|
|
32
|
+
"Topic :: Software Development :: Build Tools",
|
|
33
|
+
|
|
34
|
+
# Specify the Python versions you support here
|
|
35
|
+
"Programming Language :: Python :: 3.9",
|
|
36
|
+
"Programming Language :: Python :: 3.10",
|
|
37
|
+
"Programming Language :: Python :: 3.11",
|
|
38
|
+
"Programming Language :: Python :: 3.12",
|
|
39
|
+
"Programming Language :: Python :: 3.13",
|
|
40
|
+
"Programming Language :: Python :: 3.14",
|
|
41
|
+
]
|
|
42
|
+
requires-python = ">=3.9"
|
|
43
|
+
dependencies = [
|
|
44
|
+
"half_orm=={half_orm_version}",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = ""
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.packages.find]
|
|
51
|
+
where = ["."]
|
|
52
|
+
exclude = ["contrib", "docs", "tests", "patches", "svg"]
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.dynamic]
|
|
55
|
+
version = {{file = "{package_name}/version.txt"}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.17.0-a11
|
|
@@ -1,42 +1,31 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: half_orm_dev
|
|
3
|
-
Version: 0.17.
|
|
3
|
+
Version: 0.17.0a11
|
|
4
4
|
Summary: half_orm development Framework.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
License: GNU General Public License v3 (GPLv3)
|
|
5
|
+
Author-email: Joël Maïzi <joel.maizi@collorg.org>
|
|
6
|
+
License-Expression: GPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/collorg/halfORM_dev
|
|
9
8
|
Keywords: postgres,relation-object mapping
|
|
10
9
|
Classifier: Development Status :: 3 - Alpha
|
|
11
10
|
Classifier: Intended Audience :: Developers
|
|
12
11
|
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
12
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.9
|
|
21
19
|
Description-Content-Type: text/markdown
|
|
22
20
|
License-File: LICENSE
|
|
23
21
|
License-File: AUTHORS
|
|
24
22
|
Requires-Dist: GitPython
|
|
25
23
|
Requires-Dist: click
|
|
26
24
|
Requires-Dist: pydash
|
|
27
|
-
Requires-Dist: half_orm<0.18.0,>=0.17.0
|
|
28
25
|
Requires-Dist: pytest
|
|
29
|
-
|
|
30
|
-
Dynamic: author-email
|
|
31
|
-
Dynamic: classifier
|
|
32
|
-
Dynamic: description
|
|
33
|
-
Dynamic: description-content-type
|
|
34
|
-
Dynamic: home-page
|
|
35
|
-
Dynamic: keywords
|
|
36
|
-
Dynamic: license
|
|
26
|
+
Requires-Dist: half_orm<0.18.0,>=0.17.0
|
|
37
27
|
Dynamic: license-file
|
|
38
28
|
Dynamic: requires-dist
|
|
39
|
-
Dynamic: summary
|
|
40
29
|
|
|
41
30
|
# half_orm_dev
|
|
42
31
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
AUTHORS
|
|
2
2
|
LICENSE
|
|
3
3
|
README.md
|
|
4
|
+
pyproject.toml
|
|
4
5
|
setup.py
|
|
5
6
|
half_orm_dev/__init__.py
|
|
6
7
|
half_orm_dev/cli_extension.py
|
|
@@ -52,11 +53,9 @@ half_orm_dev/templates/init_module_template
|
|
|
52
53
|
half_orm_dev/templates/module_template_1
|
|
53
54
|
half_orm_dev/templates/module_template_2
|
|
54
55
|
half_orm_dev/templates/module_template_3
|
|
56
|
+
half_orm_dev/templates/pyproject.toml
|
|
55
57
|
half_orm_dev/templates/relation_test
|
|
56
|
-
half_orm_dev/templates/setup.py
|
|
57
58
|
half_orm_dev/templates/sql_adapter
|
|
58
59
|
half_orm_dev/templates/warning
|
|
59
60
|
half_orm_dev/templates/git-hooks/pre-commit
|
|
60
|
-
half_orm_dev/templates/git-hooks/prepare-commit-msg
|
|
61
|
-
tests/__init__.py
|
|
62
|
-
tests/conftest.py
|
|
61
|
+
half_orm_dev/templates/git-hooks/prepare-commit-msg
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "half_orm_dev"
|
|
7
|
+
dynamic = ["version", "dependencies"]
|
|
8
|
+
description = "half_orm development Framework."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
keywords = ["postgres", "relation-object mapping"]
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Joël Maïzi", email = "joel.maizi@collorg.org"}
|
|
13
|
+
]
|
|
14
|
+
license = "GPL-3.0-or-later"
|
|
15
|
+
classifiers = [
|
|
16
|
+
# How mature is this project? Common values are
|
|
17
|
+
# 3 - Alpha
|
|
18
|
+
# 4 - Beta
|
|
19
|
+
# 5 - Production/Stable
|
|
20
|
+
"Development Status :: 3 - Alpha",
|
|
21
|
+
|
|
22
|
+
# Indicate who your project is intended for
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"Topic :: Software Development :: Build Tools",
|
|
25
|
+
|
|
26
|
+
# Specify the Python versions you support here
|
|
27
|
+
"Programming Language :: Python :: 3.9",
|
|
28
|
+
"Programming Language :: Python :: 3.10",
|
|
29
|
+
"Programming Language :: Python :: 3.11",
|
|
30
|
+
"Programming Language :: Python :: 3.12",
|
|
31
|
+
"Programming Language :: Python :: 3.13",
|
|
32
|
+
"Programming Language :: Python :: 3.14",
|
|
33
|
+
]
|
|
34
|
+
requires-python = ">=3.9"
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://github.com/collorg/halfORM_dev"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.packages.find]
|
|
40
|
+
where = ["."]
|
|
41
|
+
include = ["half_orm_dev*"]
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.package-data]
|
|
44
|
+
half_orm_dev = [
|
|
45
|
+
"templates/*",
|
|
46
|
+
"templates/git-hooks/*",
|
|
47
|
+
"templates/.gitignore",
|
|
48
|
+
"db_patch_system/*",
|
|
49
|
+
"patches/**/*",
|
|
50
|
+
"version.txt"
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.dynamic]
|
|
54
|
+
version = {file = "half_orm_dev/version.txt"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#-*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Minimal setup.py for dynamic half_orm dependency calculation.
|
|
4
|
+
|
|
5
|
+
Most configuration is in pyproject.toml. This file exists only to add
|
|
6
|
+
the dynamically calculated half_orm version constraint.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from setuptools import setup
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_half_orm_version_constraint():
|
|
15
|
+
"""
|
|
16
|
+
Calculate half_orm version constraint from half_orm_dev version.
|
|
17
|
+
|
|
18
|
+
For version X.Y.Z[-xxx], returns: half_orm>=X.Y.0,<X.(Y+1).0
|
|
19
|
+
"""
|
|
20
|
+
version_file = Path(__file__).parent / "half_orm_dev" / "version.txt"
|
|
21
|
+
version_text = version_file.read_text(encoding="utf-8").strip()
|
|
22
|
+
|
|
23
|
+
# Parse version with regex to handle X.Y.Z[-suffix]
|
|
24
|
+
match = re.match(r'^(\d+)\.(\d+)\.(\d+)(?:-.*)?$', version_text)
|
|
25
|
+
|
|
26
|
+
if not match:
|
|
27
|
+
raise ValueError(f"Invalid version format in version.txt: {version_text}")
|
|
28
|
+
|
|
29
|
+
major, minor, patch = match.groups()
|
|
30
|
+
major, minor = int(major), int(minor)
|
|
31
|
+
|
|
32
|
+
# Generate constraint: half_orm>=X.Y.0,<X.(Y+1).0
|
|
33
|
+
min_version = f"{major}.{minor}.0"
|
|
34
|
+
max_version = f"{major}.{minor + 1}.0"
|
|
35
|
+
|
|
36
|
+
return f"half_orm>={min_version},<{max_version}"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Call setup with all dependencies (including dynamic half_orm constraint)
|
|
40
|
+
# All other configuration is in pyproject.toml
|
|
41
|
+
setup(
|
|
42
|
+
install_requires=[
|
|
43
|
+
"GitPython",
|
|
44
|
+
"click",
|
|
45
|
+
"pydash",
|
|
46
|
+
"pytest",
|
|
47
|
+
get_half_orm_version_constraint(),
|
|
48
|
+
]
|
|
49
|
+
)
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"""Package for PostgreSQL {dbname} database.
|
|
2
|
-
You can edit the following parameters:
|
|
3
|
-
- version
|
|
4
|
-
- author
|
|
5
|
-
- author_email
|
|
6
|
-
- license
|
|
7
|
-
- keywords
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from setuptools import setup, find_packages
|
|
11
|
-
from codecs import open
|
|
12
|
-
from os import path
|
|
13
|
-
import re
|
|
14
|
-
import half_orm
|
|
15
|
-
|
|
16
|
-
PWD = path.abspath(path.dirname(__file__))
|
|
17
|
-
|
|
18
|
-
def get_long_description():
|
|
19
|
-
"""
|
|
20
|
-
Return the README.
|
|
21
|
-
"""
|
|
22
|
-
with open("README.md", encoding="utf8") as f:
|
|
23
|
-
return f.read()
|
|
24
|
-
|
|
25
|
-
def get_version(package):
|
|
26
|
-
"""
|
|
27
|
-
Return package version as listed in `__version__` in `init.py`.
|
|
28
|
-
"""
|
|
29
|
-
with open(path.join(package, "version.txt")) as f:
|
|
30
|
-
return f.read()
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
package_name='{package_name}'
|
|
34
|
-
|
|
35
|
-
setup(
|
|
36
|
-
name=package_name,
|
|
37
|
-
|
|
38
|
-
version=get_version(package_name),
|
|
39
|
-
|
|
40
|
-
description='Package for {dbname} PG',
|
|
41
|
-
long_description=get_long_description(),
|
|
42
|
-
long_description_content_type='text/markdown',
|
|
43
|
-
url='',
|
|
44
|
-
|
|
45
|
-
author='',
|
|
46
|
-
author_email='',
|
|
47
|
-
license='',
|
|
48
|
-
|
|
49
|
-
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
50
|
-
classifiers=[
|
|
51
|
-
# How mature is this project? Common values are
|
|
52
|
-
# 3 - Alpha
|
|
53
|
-
# 4 - Beta
|
|
54
|
-
# 5 - Production/Stable
|
|
55
|
-
'Development Status :: 3 - Alpha',
|
|
56
|
-
|
|
57
|
-
# Indicate who your project is intended for
|
|
58
|
-
'Intended Audience :: Developers',
|
|
59
|
-
'Topic :: Software Development :: Build Tools',
|
|
60
|
-
|
|
61
|
-
# Pick your license as you wish (should match "license" above)
|
|
62
|
-
'License :: OSI Approved :: MIT License',
|
|
63
|
-
|
|
64
|
-
# Specify the Python versions you support here. In particular, ensure
|
|
65
|
-
# that you indicate whether you support Python 2, Python 3 or both.
|
|
66
|
-
'Programming Language :: Python :: 3.6',
|
|
67
|
-
'Programming Language :: Python :: 3.7',
|
|
68
|
-
'Programming Language :: Python :: 3.8',
|
|
69
|
-
'Programming Language :: Python :: 3.9',
|
|
70
|
-
'Programming Language :: Python :: 3.10',
|
|
71
|
-
],
|
|
72
|
-
|
|
73
|
-
keywords='',
|
|
74
|
-
|
|
75
|
-
packages=find_packages(exclude=['contrib', 'docs', 'tests', 'patches', 'svg']),
|
|
76
|
-
|
|
77
|
-
install_requires=[
|
|
78
|
-
'half_orm=={half_orm_version}'
|
|
79
|
-
],
|
|
80
|
-
|
|
81
|
-
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.17.0-a10
|
half_orm_dev-0.17.0a10/setup.py
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
#-*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import codecs
|
|
5
|
-
import re
|
|
6
|
-
from setuptools import setup, find_packages
|
|
7
|
-
|
|
8
|
-
def read(name):
|
|
9
|
-
return codecs.open(
|
|
10
|
-
os.path.join(os.path.dirname(__file__), name), "r", "utf-8").read()
|
|
11
|
-
|
|
12
|
-
def get_half_orm_version_constraint():
|
|
13
|
-
"""
|
|
14
|
-
Calculate half_orm version constraint from half_orm_dev version.
|
|
15
|
-
|
|
16
|
-
For version X.Y.Z[-xxx], returns: half_orm>=X.Y.0,<X.(Y+1).0
|
|
17
|
-
"""
|
|
18
|
-
version_text = read('half_orm_dev/version.txt').strip()
|
|
19
|
-
|
|
20
|
-
# Parse version with regex to handle X.Y.Z[-suffix]
|
|
21
|
-
match = re.match(r'^(\d+)\.(\d+)\.(\d+)(?:-.*)?$', version_text)
|
|
22
|
-
|
|
23
|
-
if not match:
|
|
24
|
-
raise ValueError(f"Invalid version format in version.txt: {version_text}")
|
|
25
|
-
|
|
26
|
-
major, minor, patch = match.groups()
|
|
27
|
-
major, minor = int(major), int(minor)
|
|
28
|
-
|
|
29
|
-
# Generate constraint: half_orm>=X.Y.0,<X.(Y+1).0
|
|
30
|
-
min_version = f"{major}.{minor}.0"
|
|
31
|
-
max_version = f"{major}.{minor + 1}.0"
|
|
32
|
-
|
|
33
|
-
return f"half_orm>={min_version},<{max_version}"
|
|
34
|
-
|
|
35
|
-
setup(
|
|
36
|
-
name='half_orm_dev',
|
|
37
|
-
version=read('half_orm_dev/version.txt').strip(),
|
|
38
|
-
description="half_orm development Framework.",
|
|
39
|
-
long_description=read('README.md'),
|
|
40
|
-
keywords='postgres, relation-object mapping',
|
|
41
|
-
author='Joël Maïzi',
|
|
42
|
-
author_email='joel.maizi@collorg.org',
|
|
43
|
-
url='https://github.com/collorg/halfORM_dev',
|
|
44
|
-
license='GNU General Public License v3 (GPLv3)',
|
|
45
|
-
packages=find_packages(),
|
|
46
|
-
package_data={'half_orm_dev': [
|
|
47
|
-
'templates/*', 'templates/git-hooks/*', 'templates/.gitignore', 'db_patch_system/*', 'patches/**/*', 'version.txt']},
|
|
48
|
-
install_requires=[
|
|
49
|
-
'GitPython',
|
|
50
|
-
'click',
|
|
51
|
-
'pydash',
|
|
52
|
-
get_half_orm_version_constraint(),
|
|
53
|
-
'pytest'
|
|
54
|
-
],
|
|
55
|
-
classifiers=[
|
|
56
|
-
# How mature is this project? Common values are
|
|
57
|
-
# 3 - Alpha
|
|
58
|
-
# 4 - Beta
|
|
59
|
-
# 5 - Production/Stable
|
|
60
|
-
'Development Status :: 3 - Alpha',
|
|
61
|
-
|
|
62
|
-
# Indicate who your project is intended for
|
|
63
|
-
'Intended Audience :: Developers',
|
|
64
|
-
'Topic :: Software Development :: Build Tools',
|
|
65
|
-
|
|
66
|
-
# Pick your license as you wish (should match "license" above)
|
|
67
|
-
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
|
68
|
-
|
|
69
|
-
# Specify the Python versions you support here. In particular, ensure
|
|
70
|
-
# that you indicate whether you support Python 2, Python 3 or both.
|
|
71
|
-
'Programming Language :: Python :: 3.8',
|
|
72
|
-
'Programming Language :: Python :: 3.9',
|
|
73
|
-
'Programming Language :: Python :: 3.10',
|
|
74
|
-
'Programming Language :: Python :: 3.11',
|
|
75
|
-
'Programming Language :: Python :: 3.12',
|
|
76
|
-
'Programming Language :: Python :: 3.13',
|
|
77
|
-
'Programming Language :: Python :: 3.14',
|
|
78
|
-
],
|
|
79
|
-
long_description_content_type = "text/markdown"
|
|
80
|
-
)
|
|
File without changes
|
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Shared pytest fixtures for half_orm_dev tests.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import pytest
|
|
6
|
-
import tempfile
|
|
7
|
-
import shutil
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from unittest.mock import Mock, patch
|
|
10
|
-
from half_orm_dev.database import Database
|
|
11
|
-
from half_orm_dev.repo import Repo
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@pytest.fixture
|
|
15
|
-
def temp_repo():
|
|
16
|
-
"""
|
|
17
|
-
Create temporary directory structure for testing.
|
|
18
|
-
"""
|
|
19
|
-
temp_dir = tempfile.mkdtemp()
|
|
20
|
-
patches_dir = Path(temp_dir) / "Patches"
|
|
21
|
-
patches_dir.mkdir()
|
|
22
|
-
|
|
23
|
-
# Create releases/ directory with candidates file (for new workflow)
|
|
24
|
-
releases_dir = Path(temp_dir) / "releases"
|
|
25
|
-
releases_dir.mkdir(exist_ok=True)
|
|
26
|
-
candidates_file = releases_dir / "0.17.0-candidates.txt"
|
|
27
|
-
candidates_file.write_text("", encoding='utf-8') # Empty file initially
|
|
28
|
-
|
|
29
|
-
repo = Mock()
|
|
30
|
-
repo.base_dir = temp_dir
|
|
31
|
-
repo.devel = True
|
|
32
|
-
repo.name = "test_database"
|
|
33
|
-
repo.git_origin = "https://github.com/test/repo.git"
|
|
34
|
-
|
|
35
|
-
# Create default HGit mock with tag methods
|
|
36
|
-
mock_hgit = Mock()
|
|
37
|
-
mock_hgit.fetch_tags = Mock()
|
|
38
|
-
mock_hgit.tag_exists = Mock(return_value=False)
|
|
39
|
-
mock_hgit.create_tag = Mock()
|
|
40
|
-
mock_hgit.push_tag = Mock()
|
|
41
|
-
repo.hgit = mock_hgit
|
|
42
|
-
|
|
43
|
-
yield repo, temp_dir, patches_dir
|
|
44
|
-
|
|
45
|
-
shutil.rmtree(temp_dir)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@pytest.fixture
|
|
49
|
-
def patch_manager(temp_repo):
|
|
50
|
-
"""
|
|
51
|
-
Create PatchManager instance with temporary repo.
|
|
52
|
-
|
|
53
|
-
The repo.hgit already has default tag mocks configured in temp_repo fixture.
|
|
54
|
-
Tests can override repo.hgit if needed, but should use mock_hgit_complete fixture.
|
|
55
|
-
"""
|
|
56
|
-
from half_orm_dev.patch_manager import PatchManager
|
|
57
|
-
|
|
58
|
-
repo, temp_dir, patches_dir = temp_repo
|
|
59
|
-
repo.restore_database_from_schema = Repo.restore_database_from_schema.__get__(repo, type(repo))
|
|
60
|
-
mock_get_version = Mock(return_value=(16, 1))
|
|
61
|
-
repo.database.get_postgres_version = mock_get_version
|
|
62
|
-
patch_mgr = PatchManager(repo)
|
|
63
|
-
return patch_mgr, repo, temp_dir, patches_dir
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@pytest.fixture
|
|
67
|
-
def mock_hgit_complete():
|
|
68
|
-
"""
|
|
69
|
-
Create complete mock HGit for create_patch workflow tests.
|
|
70
|
-
|
|
71
|
-
Provides all necessary mocks for successful patch creation workflow:
|
|
72
|
-
- Branch validation (on ho-release/X.Y.Z) - NEW workflow
|
|
73
|
-
- Repository clean check
|
|
74
|
-
- Remote configuration check
|
|
75
|
-
- Remote fetch operations
|
|
76
|
-
- Branch synchronization check
|
|
77
|
-
- Tag availability check
|
|
78
|
-
- Git operations (checkout, add, commit, tag, push)
|
|
79
|
-
- Branch operations (create, delete, checkout)
|
|
80
|
-
"""
|
|
81
|
-
mock_hgit = Mock()
|
|
82
|
-
|
|
83
|
-
# Branch and repo state - NEW: use ho-release/X.Y.Z instead of ho-prod
|
|
84
|
-
mock_hgit.branch = "ho-release/0.17.0"
|
|
85
|
-
mock_hgit.repos_is_clean.return_value = True
|
|
86
|
-
mock_hgit.has_remote.return_value = True
|
|
87
|
-
|
|
88
|
-
# Branch synchronization check
|
|
89
|
-
# Returns (is_synced, status) tuple
|
|
90
|
-
mock_hgit.is_branch_synced.return_value = (True, "synced")
|
|
91
|
-
|
|
92
|
-
# Fetch operations
|
|
93
|
-
mock_hgit.fetch_from_origin.return_value = None
|
|
94
|
-
mock_hgit.fetch_tags.return_value = None
|
|
95
|
-
|
|
96
|
-
# Tag operations
|
|
97
|
-
mock_hgit.tag_exists.return_value = False # No existing tags
|
|
98
|
-
mock_hgit.create_tag.return_value = None
|
|
99
|
-
mock_hgit.push_tag.return_value = None
|
|
100
|
-
mock_hgit.delete_local_tag.return_value = None
|
|
101
|
-
|
|
102
|
-
# Branch operations
|
|
103
|
-
mock_hgit.checkout.return_value = None
|
|
104
|
-
mock_hgit.delete_local_branch.return_value = None
|
|
105
|
-
mock_hgit.push_branch.return_value = None
|
|
106
|
-
|
|
107
|
-
# Git proxy methods
|
|
108
|
-
mock_hgit.add.return_value = None
|
|
109
|
-
mock_hgit.commit.return_value = None
|
|
110
|
-
|
|
111
|
-
# Git repo access for reset operations
|
|
112
|
-
mock_git_repo = Mock()
|
|
113
|
-
mock_git_repo.git.reset.return_value = None
|
|
114
|
-
mock_hgit._HGit__git_repo = mock_git_repo
|
|
115
|
-
|
|
116
|
-
return mock_hgit
|
|
117
|
-
|
|
118
|
-
@pytest.fixture
|
|
119
|
-
def sample_patch_files():
|
|
120
|
-
"""
|
|
121
|
-
Provide sample patch file contents for testing.
|
|
122
|
-
"""
|
|
123
|
-
return {
|
|
124
|
-
'01_create_table.sql': 'CREATE TABLE users (id SERIAL PRIMARY KEY);',
|
|
125
|
-
'02_add_indexes.sql': 'CREATE INDEX idx_users_id ON users(id);',
|
|
126
|
-
'migrate.py': 'print("Running migration")',
|
|
127
|
-
'cleanup.py': 'print("Cleanup complete")',
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
@pytest.fixture
|
|
132
|
-
def mock_database():
|
|
133
|
-
"""
|
|
134
|
-
Mock database connection for testing.
|
|
135
|
-
|
|
136
|
-
Provides a mock database connection object that can be used
|
|
137
|
-
to test SQL execution without requiring a real database.
|
|
138
|
-
|
|
139
|
-
Returns:
|
|
140
|
-
Mock: Mock database connection with execute_query method
|
|
141
|
-
"""
|
|
142
|
-
mock_db = Mock()
|
|
143
|
-
mock_db.execute_query = Mock()
|
|
144
|
-
mock_db.execute = Mock()
|
|
145
|
-
mock_db.cursor = Mock()
|
|
146
|
-
|
|
147
|
-
return mock_db
|
|
148
|
-
|
|
149
|
-
@pytest.fixture
|
|
150
|
-
def mock_database_for_schema_generation():
|
|
151
|
-
"""
|
|
152
|
-
Create complete Database mock for _generate_schema_sql() testing.
|
|
153
|
-
|
|
154
|
-
Provides a mock with all necessary attributes and methods for schema
|
|
155
|
-
generation tests, including mangled private attributes.
|
|
156
|
-
|
|
157
|
-
Returns:
|
|
158
|
-
Mock: Configured Database mock with:
|
|
159
|
-
- _Database__name: Database name (mangled private attribute)
|
|
160
|
-
- _collect_connection_params(): Returns connection parameters
|
|
161
|
-
- _get_connection_params(): Returns connection parameters
|
|
162
|
-
- _execute_pg_command(): Mock for pg_dump execution
|
|
163
|
-
|
|
164
|
-
Example:
|
|
165
|
-
def test_something(self, mock_database_for_schema_generation, tmp_path):
|
|
166
|
-
database = mock_database_for_schema_generation
|
|
167
|
-
model_dir = tmp_path / "model"
|
|
168
|
-
model_dir.mkdir()
|
|
169
|
-
|
|
170
|
-
result = Database._generate_schema_sql(database, "1.0.0", model_dir)
|
|
171
|
-
"""
|
|
172
|
-
mock_db = Mock(spec=Database)
|
|
173
|
-
|
|
174
|
-
# Set mangled private attribute for database name
|
|
175
|
-
mock_db._Database__name = "test_db"
|
|
176
|
-
|
|
177
|
-
# Mock connection parameter methods
|
|
178
|
-
connection_params = {
|
|
179
|
-
'user': 'test_user',
|
|
180
|
-
'password': 'test_pass',
|
|
181
|
-
'host': 'localhost',
|
|
182
|
-
'port': 5432,
|
|
183
|
-
'production': False
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
mock_db._collect_connection_params = Mock(return_value=connection_params)
|
|
187
|
-
mock_db._get_connection_params = Mock(return_value=connection_params)
|
|
188
|
-
|
|
189
|
-
# Mock pg_dump execution
|
|
190
|
-
mock_db._execute_pg_command = Mock()
|
|
191
|
-
|
|
192
|
-
return mock_db
|
|
193
|
-
|
|
194
|
-
"""
|
|
195
|
-
Additional fixtures for ReleaseManager tests.
|
|
196
|
-
Add these to tests/conftest.py
|
|
197
|
-
"""
|
|
198
|
-
|
|
199
|
-
@pytest.fixture
|
|
200
|
-
def mock_release_manager_basic(tmp_path):
|
|
201
|
-
"""
|
|
202
|
-
Create basic ReleaseManager with minimal mocks.
|
|
203
|
-
|
|
204
|
-
Provides:
|
|
205
|
-
- ReleaseManager instance
|
|
206
|
-
- Mock repo with base_dir
|
|
207
|
-
- Temporary releases/ directory
|
|
208
|
-
|
|
209
|
-
Returns:
|
|
210
|
-
Tuple of (release_mgr, mock_repo, tmp_path)
|
|
211
|
-
"""
|
|
212
|
-
from unittest.mock import Mock
|
|
213
|
-
from half_orm_dev.release_manager import ReleaseManager
|
|
214
|
-
|
|
215
|
-
mock_repo = Mock()
|
|
216
|
-
mock_repo.base_dir = str(tmp_path)
|
|
217
|
-
|
|
218
|
-
# Create releases/ directory
|
|
219
|
-
releases_dir = tmp_path / "releases"
|
|
220
|
-
releases_dir.mkdir(exist_ok=True)
|
|
221
|
-
|
|
222
|
-
release_mgr = ReleaseManager(mock_repo)
|
|
223
|
-
|
|
224
|
-
return release_mgr, mock_repo, tmp_path
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
@pytest.fixture
|
|
228
|
-
def mock_release_manager_with_hgit(mock_release_manager_basic):
|
|
229
|
-
"""
|
|
230
|
-
Create ReleaseManager with fully mocked HGit.
|
|
231
|
-
|
|
232
|
-
Provides:
|
|
233
|
-
- ReleaseManager instance
|
|
234
|
-
- Mock repo with HGit configured
|
|
235
|
-
- HGit mocked for all Git operations
|
|
236
|
-
- Default "happy path" configuration
|
|
237
|
-
|
|
238
|
-
Returns:
|
|
239
|
-
Tuple of (release_mgr, mock_repo, mock_hgit, tmp_path)
|
|
240
|
-
"""
|
|
241
|
-
from unittest.mock import Mock
|
|
242
|
-
|
|
243
|
-
release_mgr, mock_repo, tmp_path = mock_release_manager_basic
|
|
244
|
-
|
|
245
|
-
# Mock HGit with all required methods
|
|
246
|
-
mock_hgit = Mock()
|
|
247
|
-
|
|
248
|
-
# Branch and repo state
|
|
249
|
-
mock_hgit.branch = "ho-prod"
|
|
250
|
-
mock_hgit.repos_is_clean.return_value = True
|
|
251
|
-
|
|
252
|
-
# Fetch and sync
|
|
253
|
-
mock_hgit.fetch_from_origin.return_value = None
|
|
254
|
-
mock_hgit.is_branch_synced.return_value = (True, "synced")
|
|
255
|
-
mock_hgit.pull.return_value = None
|
|
256
|
-
|
|
257
|
-
# Git operations
|
|
258
|
-
mock_hgit.add.return_value = None
|
|
259
|
-
mock_hgit.commit.return_value = None
|
|
260
|
-
mock_hgit.push.return_value = None
|
|
261
|
-
|
|
262
|
-
mock_repo.hgit = mock_hgit
|
|
263
|
-
|
|
264
|
-
return release_mgr, mock_repo, mock_hgit, tmp_path
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
@pytest.fixture
|
|
268
|
-
def mock_release_manager_with_production(mock_release_manager_with_hgit):
|
|
269
|
-
"""
|
|
270
|
-
Create ReleaseManager with production version mocking.
|
|
271
|
-
|
|
272
|
-
Provides:
|
|
273
|
-
- Everything from mock_release_manager_with_hgit
|
|
274
|
-
- Mock _get_production_version() to return "1.3.5"
|
|
275
|
-
- Mock model/schema.sql symlink (for tests that directly test _get_production_version)
|
|
276
|
-
- Default production version: 1.3.5
|
|
277
|
-
|
|
278
|
-
Returns:
|
|
279
|
-
Tuple of (release_mgr, mock_repo, mock_hgit, tmp_path, prod_version)
|
|
280
|
-
"""
|
|
281
|
-
from unittest.mock import Mock, patch
|
|
282
|
-
|
|
283
|
-
release_mgr, mock_repo, mock_hgit, tmp_path = mock_release_manager_with_hgit
|
|
284
|
-
|
|
285
|
-
# Create model/ directory with schema files (for tests that test _get_production_version directly)
|
|
286
|
-
model_dir = tmp_path / "model"
|
|
287
|
-
model_dir.mkdir()
|
|
288
|
-
|
|
289
|
-
# Create versioned schema file
|
|
290
|
-
prod_version = "1.3.5"
|
|
291
|
-
schema_file = model_dir / f"schema-{prod_version}.sql"
|
|
292
|
-
schema_file.write_text("-- Schema version 1.3.5")
|
|
293
|
-
|
|
294
|
-
# Create symlink schema.sql -> schema-1.3.5.sql
|
|
295
|
-
schema_symlink = model_dir / "schema.sql"
|
|
296
|
-
schema_symlink.symlink_to(f"schema-{prod_version}.sql")
|
|
297
|
-
|
|
298
|
-
# Mock database last_release_s
|
|
299
|
-
mock_database = Mock()
|
|
300
|
-
mock_database.last_release_s = prod_version
|
|
301
|
-
mock_repo.database = mock_database
|
|
302
|
-
|
|
303
|
-
# CRITICAL: Mock _get_production_version() to avoid reading symlink in most tests
|
|
304
|
-
# This allows tests to focus on workflow without setting up full file structure
|
|
305
|
-
release_mgr._get_production_version = Mock(return_value=prod_version)
|
|
306
|
-
|
|
307
|
-
return release_mgr, mock_repo, mock_hgit, tmp_path, prod_version
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
@pytest.fixture
|
|
311
|
-
def sample_release_files(tmp_path):
|
|
312
|
-
"""
|
|
313
|
-
Create sample release files in releases/ directory.
|
|
314
|
-
|
|
315
|
-
Creates:
|
|
316
|
-
- releases/1.3.4.txt (production)
|
|
317
|
-
- releases/1.3.5-rc2.txt (rc)
|
|
318
|
-
- releases/1.4.0-stage.txt (stage)
|
|
319
|
-
|
|
320
|
-
Returns:
|
|
321
|
-
Tuple of (releases_dir, dict of created files)
|
|
322
|
-
"""
|
|
323
|
-
releases_dir = tmp_path / "releases"
|
|
324
|
-
releases_dir.mkdir(exist_ok=True)
|
|
325
|
-
|
|
326
|
-
files = {
|
|
327
|
-
'1.3.4.txt': '',
|
|
328
|
-
'1.3.5-rc2.txt': '',
|
|
329
|
-
'1.4.0-stage.txt': '',
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
for filename, content in files.items():
|
|
333
|
-
(releases_dir / filename).write_text(content)
|
|
334
|
-
|
|
335
|
-
return releases_dir, files
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/patches/sql/half_orm_meta.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/git-hooks/pre-commit
RENAMED
|
File without changes
|
|
File without changes
|
{half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev/templates/init_module_template
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
|
{half_orm_dev-0.17.0a10 → half_orm_dev-0.17.0a11}/half_orm_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|