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.
Files changed (45) hide show
  1. {half_orm_dev-0.16.0a2/half_orm_dev.egg-info → half_orm_dev-0.16.0a4}/PKG-INFO +1 -1
  2. half_orm_dev-0.16.0a4/half_orm_dev/__init__.py +1 -0
  3. half_orm_dev-0.16.0a4/half_orm_dev/cli_extension.py +38 -0
  4. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/modules.py +1 -1
  5. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/repo.py +52 -0
  6. half_orm_dev-0.16.0a4/half_orm_dev/version.txt +1 -0
  7. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4/half_orm_dev.egg-info}/PKG-INFO +1 -1
  8. half_orm_dev-0.16.0a2/half_orm_dev/__init__.py +0 -0
  9. half_orm_dev-0.16.0a2/half_orm_dev/cli_extension.py +0 -171
  10. half_orm_dev-0.16.0a2/half_orm_dev/version.txt +0 -1
  11. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/AUTHORS +0 -0
  12. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/LICENSE +0 -0
  13. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/README.md +0 -0
  14. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/changelog.py +0 -0
  15. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/database.py +0 -0
  16. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/db_conn.py +0 -0
  17. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/hgit.py +0 -0
  18. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/hop.py +0 -0
  19. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/manifest.py +0 -0
  20. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patch.py +0 -0
  21. {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
  22. {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
  23. {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
  24. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/log +0 -0
  25. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/patches/sql/half_orm_meta.sql +0 -0
  26. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/.gitignore +0 -0
  27. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/MANIFEST.in +0 -0
  28. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/Pipfile +0 -0
  29. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/README +0 -0
  30. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/base_test +0 -0
  31. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/init_module_template +0 -0
  32. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/module_template_1 +0 -0
  33. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/module_template_2 +0 -0
  34. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/module_template_3 +0 -0
  35. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/relation_test +0 -0
  36. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/setup.py +0 -0
  37. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/sql_adapter +0 -0
  38. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/templates/warning +0 -0
  39. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev/utils.py +0 -0
  40. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/SOURCES.txt +0 -0
  41. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/dependency_links.txt +0 -0
  42. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/requires.txt +0 -0
  43. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/half_orm_dev.egg-info/top_level.txt +0 -0
  44. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/setup.cfg +0 -0
  45. {half_orm_dev-0.16.0a2 → half_orm_dev-0.16.0a4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: half_orm_dev
3
- Version: 0.16.0a2
3
+ Version: 0.16.0a4
4
4
  Summary: half_orm development Framework.
5
5
  Home-page: https://github.com/collorg/halfORM_dev
6
6
  Author: Joël Maïzi
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: half_orm_dev
3
- Version: 0.16.0a2
3
+ Version: 0.16.0a4
4
4
  Summary: half_orm development Framework.
5
5
  Home-page: https://github.com/collorg/halfORM_dev
6
6
  Author: Joël Maïzi
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