half-orm-dev 0.16.0a2__tar.gz → 0.16.0a4__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.16.0a2/half_orm_dev.egg-info → half_orm_dev-0.16.0a4}/PKG-INFO +1 -1
- half_orm_dev-0.16.0a4/half_orm_dev/__init__.py +1 -0
- half_orm_dev-0.16.0a4/half_orm_dev/cli_extension.py +38 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/modules.py +1 -1
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/repo.py +52 -0
- half_orm_dev-0.16.0a4/half_orm_dev/version.txt +1 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4/half_orm_dev.egg-info}/PKG-INFO +1 -1
- half_orm_dev-0.16.0a2/half_orm_dev/__init__.py +0 -0
- half_orm_dev-0.16.0a2/half_orm_dev/cli_extension.py +0 -171
- half_orm_dev-0.16.0a2/half_orm_dev/version.txt +0 -1
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/AUTHORS +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/LICENSE +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/README.md +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/changelog.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/database.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/db_conn.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/hgit.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/hop.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/manifest.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patch.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/log +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/sql/half_orm_meta.sql +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/.gitignore +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/MANIFEST.in +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/Pipfile +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/README +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/base_test +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/init_module_template +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/module_template_1 +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/module_template_2 +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/module_template_3 +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/relation_test +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/setup.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/sql_adapter +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/warning +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/utils.py +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/SOURCES.txt +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/dependency_links.txt +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/requires.txt +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/top_level.txt +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/setup.cfg +0 -0
- {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__all__ = ['cli']
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
CLI extension integration for half-orm-dev
|
|
6
|
+
|
|
7
|
+
Provides the halfORM development tools through the unified half_orm CLI interface.
|
|
8
|
+
Generates/Patches/Synchronizes a hop Python package with a PostgreSQL database.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
from half_orm.cli_utils import create_and_register_extension
|
|
13
|
+
from .cli import create_cli_group
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def add_commands(main_group):
|
|
17
|
+
"""
|
|
18
|
+
Required entry point for halfORM extensions.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
main_group: The main Click group for the half_orm command
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# Create the dev CLI group with all commands
|
|
25
|
+
dev_group = create_cli_group()
|
|
26
|
+
|
|
27
|
+
# Register it as an extension
|
|
28
|
+
@create_and_register_extension(main_group, sys.modules[__name__])
|
|
29
|
+
def dev():
|
|
30
|
+
"""halfORM development tools - project management, patches, and database synchronization"""
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
# Copy all commands from the created group to the registered extension
|
|
34
|
+
for name, command in dev_group.commands.items():
|
|
35
|
+
dev.add_command(command)
|
|
36
|
+
|
|
37
|
+
# Copy the callback from the created group
|
|
38
|
+
dev.callback = dev_group.callback
|
|
@@ -165,7 +165,7 @@ def __get_inheritance_info(rel, package_name):
|
|
|
165
165
|
inheritance_import_list = []
|
|
166
166
|
inherited_classes_aliases_list = []
|
|
167
167
|
for base in rel.__class__.__bases__:
|
|
168
|
-
if base.__name__ != 'Relation':
|
|
168
|
+
if base.__name__ != 'Relation' and hasattr(base, '_t_fqrn'):
|
|
169
169
|
inh_sfqrn = list(base._t_fqrn)
|
|
170
170
|
inh_sfqrn[0] = package_name
|
|
171
171
|
inh_cl_alias = f"{camel_case(inh_sfqrn[1])}{camel_case(inh_sfqrn[2])}"
|
|
@@ -87,16 +87,68 @@ class Config:
|
|
|
87
87
|
|
|
88
88
|
class Repo:
|
|
89
89
|
"""Reads and writes the hop repo conf file.
|
|
90
|
+
|
|
91
|
+
Implements Singleton pattern to ensure only one instance per base directory.
|
|
90
92
|
"""
|
|
93
|
+
|
|
94
|
+
# Singleton storage: base_dir -> instance
|
|
95
|
+
_instances = {}
|
|
96
|
+
|
|
97
|
+
# Instance variables
|
|
91
98
|
__new = False
|
|
92
99
|
__checked: bool = False
|
|
93
100
|
__base_dir: Optional[str] = None
|
|
94
101
|
__config: Optional[Config] = None
|
|
95
102
|
database: Optional[Database] = None
|
|
96
103
|
hgit: Optional[HGit] = None
|
|
104
|
+
|
|
105
|
+
def __new__(cls):
|
|
106
|
+
"""Singleton implementation based on current working directory"""
|
|
107
|
+
# Find the base directory for this context
|
|
108
|
+
base_dir = cls._find_base_dir()
|
|
109
|
+
|
|
110
|
+
# Return existing instance if it exists for this base_dir
|
|
111
|
+
if base_dir in cls._instances:
|
|
112
|
+
return cls._instances[base_dir]
|
|
113
|
+
|
|
114
|
+
# Create new instance
|
|
115
|
+
instance = super().__new__(cls)
|
|
116
|
+
cls._instances[base_dir] = instance
|
|
117
|
+
return instance
|
|
118
|
+
|
|
97
119
|
def __init__(self):
|
|
120
|
+
# Only initialize once per instance
|
|
121
|
+
if hasattr(self, '_initialized'):
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
self._initialized = True
|
|
98
125
|
self.__check()
|
|
99
126
|
|
|
127
|
+
@classmethod
|
|
128
|
+
def _find_base_dir(cls):
|
|
129
|
+
"""Find the base directory for the current context (same logic as __check)"""
|
|
130
|
+
base_dir = os.path.abspath(os.path.curdir)
|
|
131
|
+
while base_dir:
|
|
132
|
+
conf_file = os.path.join(base_dir, '.hop', 'config')
|
|
133
|
+
if os.path.exists(conf_file):
|
|
134
|
+
return base_dir
|
|
135
|
+
par_dir = os.path.split(base_dir)[0]
|
|
136
|
+
if par_dir == base_dir:
|
|
137
|
+
break
|
|
138
|
+
base_dir = par_dir
|
|
139
|
+
return os.path.abspath(os.path.curdir) # fallback to current dir
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def clear_instances(cls):
|
|
143
|
+
"""Clear all singleton instances - useful for testing or cleanup"""
|
|
144
|
+
for instance in cls._instances.values():
|
|
145
|
+
if instance.database and instance.database.model:
|
|
146
|
+
try:
|
|
147
|
+
instance.database.model.disconnect()
|
|
148
|
+
except:
|
|
149
|
+
pass
|
|
150
|
+
cls._instances.clear()
|
|
151
|
+
|
|
100
152
|
@property
|
|
101
153
|
def new(self):
|
|
102
154
|
"Returns if the repo is being created or not."
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.16.0-a4
|
|
File without changes
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
CLI extension integration for half-orm-dev
|
|
6
|
-
|
|
7
|
-
Provides the halfORM development tools through the unified half_orm CLI interface.
|
|
8
|
-
Generates/Patches/Synchronizes a hop Python package with a PostgreSQL database.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import sys
|
|
12
|
-
import click
|
|
13
|
-
from half_orm.cli_utils import create_and_register_extension
|
|
14
|
-
|
|
15
|
-
# Import existing halfORM_dev functionality
|
|
16
|
-
from half_orm_dev.repo import Repo
|
|
17
|
-
from half_orm import utils
|
|
18
|
-
|
|
19
|
-
class Hop:
|
|
20
|
-
"""Sets the options available to the hop command"""
|
|
21
|
-
__available_cmds = []
|
|
22
|
-
__command = None
|
|
23
|
-
|
|
24
|
-
def __init__(self):
|
|
25
|
-
self.__repo: Repo = Repo()
|
|
26
|
-
if not self.repo_checked:
|
|
27
|
-
Hop.__available_cmds = ['new']
|
|
28
|
-
else:
|
|
29
|
-
if not self.__repo.devel:
|
|
30
|
-
# Sync-only mode
|
|
31
|
-
Hop.__available_cmds = ['sync-package']
|
|
32
|
-
else:
|
|
33
|
-
# Full mode - check environment
|
|
34
|
-
if self.__repo.production:
|
|
35
|
-
Hop.__available_cmds = ['upgrade', 'restore']
|
|
36
|
-
else:
|
|
37
|
-
Hop.__available_cmds = ['prepare', 'apply', 'release', 'undo']
|
|
38
|
-
|
|
39
|
-
@property
|
|
40
|
-
def repo_checked(self):
|
|
41
|
-
"""Returns whether we are in a repo or not."""
|
|
42
|
-
return self.__repo.checked
|
|
43
|
-
|
|
44
|
-
@property
|
|
45
|
-
def model(self):
|
|
46
|
-
"""Returns the model (half_orm.model.Model) associated to the repo."""
|
|
47
|
-
return self.__repo.model
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def state(self):
|
|
51
|
-
"""Returns the state of the repo."""
|
|
52
|
-
return self.__repo.state
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def command(self):
|
|
56
|
-
"""The command invoked (click)"""
|
|
57
|
-
return self.__command
|
|
58
|
-
|
|
59
|
-
def add_commands(main_group):
|
|
60
|
-
"""
|
|
61
|
-
Required entry point for halfORM extensions.
|
|
62
|
-
|
|
63
|
-
Args:
|
|
64
|
-
main_group: The main Click group for the half_orm command
|
|
65
|
-
"""
|
|
66
|
-
|
|
67
|
-
# Create hop instance to determine available commands
|
|
68
|
-
hop = Hop()
|
|
69
|
-
|
|
70
|
-
@create_and_register_extension(main_group, sys.modules[__name__])
|
|
71
|
-
def dev():
|
|
72
|
-
"""halfORM development tools - project management, patches, and database synchronization"""
|
|
73
|
-
pass
|
|
74
|
-
|
|
75
|
-
# Define all possible commands
|
|
76
|
-
@click.command()
|
|
77
|
-
@click.argument('package_name')
|
|
78
|
-
@click.option('-d', '--devel', is_flag=True, help="Development mode")
|
|
79
|
-
def new(package_name, devel=False):
|
|
80
|
-
"""Creates a new hop project named <package_name>."""
|
|
81
|
-
hop._Hop__repo.init(package_name, devel)
|
|
82
|
-
|
|
83
|
-
@click.command()
|
|
84
|
-
@click.option(
|
|
85
|
-
'-l', '--level',
|
|
86
|
-
type=click.Choice(['patch', 'minor', 'major']), help="Release level.")
|
|
87
|
-
@click.option('-m', '--message', type=str, help="The git commit message")
|
|
88
|
-
def prepare(level, message=None):
|
|
89
|
-
"""Prepares the next release."""
|
|
90
|
-
hop._Hop__command = 'prepare'
|
|
91
|
-
hop._Hop__repo.prepare_release(level, message)
|
|
92
|
-
sys.exit()
|
|
93
|
-
|
|
94
|
-
@click.command()
|
|
95
|
-
def apply():
|
|
96
|
-
"""Apply the current release."""
|
|
97
|
-
hop._Hop__command = 'apply'
|
|
98
|
-
hop._Hop__repo.apply_release()
|
|
99
|
-
|
|
100
|
-
@click.command()
|
|
101
|
-
@click.option(
|
|
102
|
-
'-d', '--database-only', is_flag=True,
|
|
103
|
-
help='Restore the database to the previous release.')
|
|
104
|
-
def undo(database_only):
|
|
105
|
-
"""Undo the last release."""
|
|
106
|
-
hop._Hop__command = 'undo'
|
|
107
|
-
hop._Hop__repo.undo_release(database_only)
|
|
108
|
-
|
|
109
|
-
@click.command()
|
|
110
|
-
def upgrade():
|
|
111
|
-
"""Apply one or many patches.
|
|
112
|
-
|
|
113
|
-
Switches to hop_main, pulls should check the tags.
|
|
114
|
-
"""
|
|
115
|
-
hop._Hop__command = 'upgrade_prod'
|
|
116
|
-
hop._Hop__repo.upgrade_prod()
|
|
117
|
-
|
|
118
|
-
@click.command()
|
|
119
|
-
@click.argument('release')
|
|
120
|
-
def restore(release):
|
|
121
|
-
"""Restore to release."""
|
|
122
|
-
hop._Hop__repo.restore(release)
|
|
123
|
-
|
|
124
|
-
@click.command()
|
|
125
|
-
@click.option('-p', '--push', is_flag=True, help='Push git repo to origin')
|
|
126
|
-
def release(push=False):
|
|
127
|
-
"""Commit and optionally push the current release."""
|
|
128
|
-
hop._Hop__repo.commit_release(push)
|
|
129
|
-
|
|
130
|
-
@click.command()
|
|
131
|
-
def sync_package():
|
|
132
|
-
"""Synchronize the Python package with the database model."""
|
|
133
|
-
hop._Hop__repo.sync_package()
|
|
134
|
-
|
|
135
|
-
# Map command names to command functions
|
|
136
|
-
all_commands = {
|
|
137
|
-
'new': new,
|
|
138
|
-
'prepare': prepare,
|
|
139
|
-
'apply': apply,
|
|
140
|
-
'undo': undo,
|
|
141
|
-
'release': release,
|
|
142
|
-
'sync-package': sync_package,
|
|
143
|
-
'upgrade': upgrade,
|
|
144
|
-
'restore': restore
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
# 🎯 COMPORTEMENT ADAPTATIF RESTAURÉ
|
|
148
|
-
# Only add commands that are available in the current context
|
|
149
|
-
for cmd_name in hop._Hop__available_cmds:
|
|
150
|
-
if cmd_name in all_commands:
|
|
151
|
-
dev.add_command(all_commands[cmd_name])
|
|
152
|
-
|
|
153
|
-
# Add callback to show state when no subcommand (like original hop)
|
|
154
|
-
original_callback = dev.callback
|
|
155
|
-
|
|
156
|
-
@click.pass_context
|
|
157
|
-
def enhanced_callback(ctx, *args, **kwargs):
|
|
158
|
-
if ctx.invoked_subcommand is None:
|
|
159
|
-
# Show repo state when no subcommand is provided
|
|
160
|
-
if hop.repo_checked:
|
|
161
|
-
click.echo(hop.state)
|
|
162
|
-
else:
|
|
163
|
-
click.echo(hop.state)
|
|
164
|
-
click.echo("\nNot in a hop repository.")
|
|
165
|
-
click.echo(f"Try {utils.Color.bold('half_orm dev new [--devel] <package_name>')} or change directory.\n")
|
|
166
|
-
else:
|
|
167
|
-
# Call original callback if there is one
|
|
168
|
-
if original_callback:
|
|
169
|
-
return original_callback(*args, **kwargs)
|
|
170
|
-
|
|
171
|
-
dev.callback = enhanced_callback
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.16.0-a2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|