bl-odoo 0.0.0__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 (36) hide show
  1. bl_odoo-0.0.0/LICENSE +21 -0
  2. bl_odoo-0.0.0/PKG-INFO +203 -0
  3. bl_odoo-0.0.0/README.md +187 -0
  4. bl_odoo-0.0.0/bl/__init__.py +1 -0
  5. bl_odoo-0.0.0/bl/__main__.py +214 -0
  6. bl_odoo-0.0.0/bl/clean_project.py +201 -0
  7. bl_odoo-0.0.0/bl/config.py +56 -0
  8. bl_odoo-0.0.0/bl/editable.py +77 -0
  9. bl_odoo-0.0.0/bl/freezer.py +78 -0
  10. bl_odoo-0.0.0/bl/spec_parser.py +246 -0
  11. bl_odoo-0.0.0/bl/spec_processor.py +892 -0
  12. bl_odoo-0.0.0/bl/types.py +95 -0
  13. bl_odoo-0.0.0/bl/utils.py +82 -0
  14. bl_odoo-0.0.0/bl_odoo.egg-info/PKG-INFO +203 -0
  15. bl_odoo-0.0.0/bl_odoo.egg-info/SOURCES.txt +34 -0
  16. bl_odoo-0.0.0/bl_odoo.egg-info/dependency_links.txt +1 -0
  17. bl_odoo-0.0.0/bl_odoo.egg-info/entry_points.txt +2 -0
  18. bl_odoo-0.0.0/bl_odoo.egg-info/requires.txt +5 -0
  19. bl_odoo-0.0.0/bl_odoo.egg-info/top_level.txt +1 -0
  20. bl_odoo-0.0.0/pyproject.toml +66 -0
  21. bl_odoo-0.0.0/setup.cfg +4 -0
  22. bl_odoo-0.0.0/tests/test_clean_project.py +652 -0
  23. bl_odoo-0.0.0/tests/test_config.py +26 -0
  24. bl_odoo-0.0.0/tests/test_editable.py +72 -0
  25. bl_odoo-0.0.0/tests/test_freezer.py +176 -0
  26. bl_odoo-0.0.0/tests/test_frozen_parser.py +149 -0
  27. bl_odoo-0.0.0/tests/test_frozen_processor.py +100 -0
  28. bl_odoo-0.0.0/tests/test_main.py +76 -0
  29. bl_odoo-0.0.0/tests/test_spec_parser.py +489 -0
  30. bl_odoo-0.0.0/tests/test_spec_processor_async.py +1168 -0
  31. bl_odoo-0.0.0/tests/test_spec_processor_helpers.py +119 -0
  32. bl_odoo-0.0.0/tests/test_spec_processor_integration.py +47 -0
  33. bl_odoo-0.0.0/tests/test_spec_processor_parsing.py +126 -0
  34. bl_odoo-0.0.0/tests/test_spec_processor_repo_processor.py +192 -0
  35. bl_odoo-0.0.0/tests/test_types.py +69 -0
  36. bl_odoo-0.0.0/tests/test_utils.py +100 -0
bl_odoo-0.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
bl_odoo-0.0.0/PKG-INFO ADDED
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: bl-odoo
3
+ Version: 0.0.0
4
+ Summary: A command-line tool for managing Odoo dependencies.
5
+ Author-email: Your Name <your.email@example.com>
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: copier
11
+ Requires-Dist: rich
12
+ Requires-Dist: ruamel-yaml>=0.19.1
13
+ Requires-Dist: typer
14
+ Requires-Dist: xdg-base-dirs>=6.0.2
15
+ Dynamic: license-file
16
+
17
+ # bl
18
+ [![CI](https://github.com/FranzPoize/bl/actions/workflows/ci-publish.yml/badge.svg)](https://github.com/FranzPoize/bl/actions/workflows/ci-publish.yml) [![codecov](https://codecov.io/github/FranzPoize/bl/graph/badge.svg?token=JWD4KU0PEN)](https://codecov.io/github/FranzPoize/bl)
19
+
20
+ ## Why BL
21
+
22
+ Because `ak` is a bit slow and I was tired of waiting around
23
+
24
+ ## Install
25
+
26
+ `pipx install bl-odoo`
27
+
28
+ ## Usage
29
+
30
+ For all those command `bl` will try to look in the current directory. If it does find the spec file
31
+ it will try to look in the child `odoo` directory. (i.e. you can launch `bl` in the root of you project)
32
+ You can also override the default paths and verbosity with:
33
+
34
+ - `-c/--config`: path to the project spec file (default: `spec.yaml`)
35
+ - `-z/--frozen`: path to the frozen spec file (default: `frozen.yaml`)
36
+ - `-o/--config-override`: path to an override config to extend the project specification
37
+ - `-j/--concurrency`: number of concurrent tasks (default: `28`)
38
+ - `-b/--use-bindfs`: use bindfs instead of creating symlinks (requires `user_allow_other` in `/etc/fuse.conf`)
39
+ - `-w/--workdir`: working directory, defaults to the directory of `--config`
40
+ - `--log-level`: one of `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` (default: `WARNING`)
41
+
42
+ ### Build
43
+
44
+ ```bash
45
+ bl build [-c PATH_TO_SPEC] [-z PATH_TO_FROZEN] [-o CONFIG_OVERRIDE] [-j CONCURRENCY] [-b/--use-bindfs] [-w WORKDIR] [--log-level LEVEL]
46
+ ```
47
+
48
+ #### What does it do
49
+ It does what ak build does
50
+
51
+ #### Params
52
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
53
+ * `PATH_TO_FROZEN` path to your frozen spec (default: `frozen.yaml`)
54
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
55
+ * `CONCURRENCY` number of module clone simultaneously (default: `28`)
56
+ * `--use-bindfs` use bindfs instead of creating symlinks (requires `user_allow_other` in `/etc/fuse.conf`)
57
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
58
+ * `LEVEL` log level (see `--log-level` above)
59
+
60
+ #### How it looks
61
+ <img width="1683" height="756" alt="bl_build" src="https://github.com/user-attachments/assets/22fc1565-3a54-4f57-9b85-a11263b9b536" />
62
+
63
+ ### Freeze
64
+
65
+ ```bash
66
+ bl freeze [-c PATH_TO_SPEC] [-z PATH_TO_FROZEN] [-o CONFIG_OVERRIDE] [-j CONCURRENCY] [-w WORKDIR] [--log-level LEVEL]
67
+ ```
68
+
69
+ #### What does it do
70
+ It does what ak freeze does
71
+
72
+ #### Params
73
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
74
+ * `PATH_TO_FROZEN` path to your frozen spec (default: `frozen.yaml`)
75
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
76
+ * `CONCURRENCY` number of module clone simultaneously (default: `28`)
77
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
78
+ * `LEVEL` log level (see `--log-level` above)
79
+
80
+ ### Diff
81
+
82
+ ```bash
83
+ bl diff [-c PATH_TO_SPEC] [-z PATH_TO_FROZEN] [-o CONFIG_OVERRIDE] [-j CONCURRENCY] [-w WORKDIR] [--log-level LEVEL]
84
+ ```
85
+
86
+ #### What does it do
87
+ Shows diff for all dirty repos in the project.
88
+
89
+ #### Params
90
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
91
+ * `PATH_TO_FROZEN` path to your frozen spec (default: `frozen.yaml`)
92
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
93
+ * `CONCURRENCY` number of module clone simultaneously (default: `28`)
94
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
95
+ * `LEVEL` log level (see `--log-level` above)
96
+
97
+ ### Clean
98
+
99
+ ```bash
100
+ bl clean [-c PATH_TO_SPEC] [-o CONFIG_OVERRIDE] [-w WORKDIR] [--log-level LEVEL] [--remove] [--unlink] [--force] [--dry-run]
101
+ ```
102
+
103
+ #### What does it do
104
+ By default it scans all repos in the spec for dirty git state and resets them with `git reset --hard`.
105
+
106
+ #### Params
107
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
108
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
109
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
110
+ * `LEVEL` log level (see `--log-level` above)
111
+ * `--remove` delete `src` and `external-src` directories
112
+ * `--unlink` also clean the links directory
113
+ * `--force` remove confirmation prompts
114
+ * `--dry-run` just output what it would do
115
+
116
+ ### Init
117
+
118
+ ```bash
119
+ bl init [DESTINATION]
120
+ ```
121
+
122
+ #### What does it do
123
+ Initializes a new project from the [docky-odoo-template-shared](https://github.com/akretion/docky-odoo-template-shared) template using [Copier](https://copier.readthedocs.io/).
124
+
125
+ #### Params
126
+ * `DESTINATION` destination directory (default: current directory)
127
+
128
+ ## Odoo is taking a really long time to clone
129
+
130
+ Yes !
131
+
132
+ You can add a locales entry to your odoo repo in `spec.yaml` like so:
133
+ ```yaml
134
+ odoo:
135
+ modules:
136
+ - account
137
+ ...
138
+ remotes:
139
+ odoo: https://github.com/odoo/odoo
140
+ merges:
141
+ - odoo 14.0
142
+ locales:
143
+ - fr
144
+ - en
145
+ ```
146
+ It will only download the french and english translation instead of all of them
147
+ - without locales: 849MB and 40 seconds fresh build
148
+ - with locales fr, en: 169MB and 27 seconds fresh build
149
+
150
+ ⚠️ WARNING: you must list all the odoo modules you need if you use the locales property
151
+
152
+ ## I have warnings about patch globs
153
+
154
+ There is a new property to handle `git am <patch_glob>` (the old one still works but I hope to remove it at some point)
155
+
156
+ Before:
157
+ ```yaml
158
+ folder_name:
159
+ modules:
160
+ ...
161
+ remotes:
162
+ ...
163
+ merges:
164
+ ...
165
+ shell_command_after:
166
+ - git am ../../patches/patch_folder/*
167
+ ```
168
+ After:
169
+ ```yaml
170
+ folder_name:
171
+ modules:
172
+ ...
173
+ remotes:
174
+ ...
175
+ merges:
176
+ ...
177
+ patch_globs:
178
+ - ../../patches/patch_folder/*
179
+ ```
180
+
181
+
182
+ ## Benchmarks
183
+
184
+ ### Ak benchmarks
185
+ #### Fresh install
186
+ <img width="1462" height="347" alt="ak_bench_cold" src="https://github.com/user-attachments/assets/e29cd3d9-831c-43c1-8f29-e040ebee5740" />
187
+
188
+ #### Already cloned once
189
+ <img width="1419" height="356" alt="ak_bench_hot" src="https://github.com/user-attachments/assets/47b5756e-efe1-4272-82b7-e160f73af1be" />
190
+
191
+ ### Bl benchmarks
192
+ #### Fresh install
193
+ <img width="1335" height="343" alt="bl_bench_cold" src="https://github.com/user-attachments/assets/a64ba1c4-17bd-4017-acfd-5749df505f50" />
194
+
195
+ #### Already cloned once
196
+ <img width="1373" height="342" alt="bl_bench_hot" src="https://github.com/user-attachments/assets/b11e60c2-368b-496c-bc88-f5a765f44bfe" />
197
+
198
+ ### Results
199
+ |Type| AK | BL |
200
+ |----|----|----|
201
+ |Cold| ~100s | 2 - 10x faster |
202
+ |Hot| 3-20s | 2 - 10x faster |
203
+
@@ -0,0 +1,187 @@
1
+ # bl
2
+ [![CI](https://github.com/FranzPoize/bl/actions/workflows/ci-publish.yml/badge.svg)](https://github.com/FranzPoize/bl/actions/workflows/ci-publish.yml) [![codecov](https://codecov.io/github/FranzPoize/bl/graph/badge.svg?token=JWD4KU0PEN)](https://codecov.io/github/FranzPoize/bl)
3
+
4
+ ## Why BL
5
+
6
+ Because `ak` is a bit slow and I was tired of waiting around
7
+
8
+ ## Install
9
+
10
+ `pipx install bl-odoo`
11
+
12
+ ## Usage
13
+
14
+ For all those command `bl` will try to look in the current directory. If it does find the spec file
15
+ it will try to look in the child `odoo` directory. (i.e. you can launch `bl` in the root of you project)
16
+ You can also override the default paths and verbosity with:
17
+
18
+ - `-c/--config`: path to the project spec file (default: `spec.yaml`)
19
+ - `-z/--frozen`: path to the frozen spec file (default: `frozen.yaml`)
20
+ - `-o/--config-override`: path to an override config to extend the project specification
21
+ - `-j/--concurrency`: number of concurrent tasks (default: `28`)
22
+ - `-b/--use-bindfs`: use bindfs instead of creating symlinks (requires `user_allow_other` in `/etc/fuse.conf`)
23
+ - `-w/--workdir`: working directory, defaults to the directory of `--config`
24
+ - `--log-level`: one of `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` (default: `WARNING`)
25
+
26
+ ### Build
27
+
28
+ ```bash
29
+ bl build [-c PATH_TO_SPEC] [-z PATH_TO_FROZEN] [-o CONFIG_OVERRIDE] [-j CONCURRENCY] [-b/--use-bindfs] [-w WORKDIR] [--log-level LEVEL]
30
+ ```
31
+
32
+ #### What does it do
33
+ It does what ak build does
34
+
35
+ #### Params
36
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
37
+ * `PATH_TO_FROZEN` path to your frozen spec (default: `frozen.yaml`)
38
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
39
+ * `CONCURRENCY` number of module clone simultaneously (default: `28`)
40
+ * `--use-bindfs` use bindfs instead of creating symlinks (requires `user_allow_other` in `/etc/fuse.conf`)
41
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
42
+ * `LEVEL` log level (see `--log-level` above)
43
+
44
+ #### How it looks
45
+ <img width="1683" height="756" alt="bl_build" src="https://github.com/user-attachments/assets/22fc1565-3a54-4f57-9b85-a11263b9b536" />
46
+
47
+ ### Freeze
48
+
49
+ ```bash
50
+ bl freeze [-c PATH_TO_SPEC] [-z PATH_TO_FROZEN] [-o CONFIG_OVERRIDE] [-j CONCURRENCY] [-w WORKDIR] [--log-level LEVEL]
51
+ ```
52
+
53
+ #### What does it do
54
+ It does what ak freeze does
55
+
56
+ #### Params
57
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
58
+ * `PATH_TO_FROZEN` path to your frozen spec (default: `frozen.yaml`)
59
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
60
+ * `CONCURRENCY` number of module clone simultaneously (default: `28`)
61
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
62
+ * `LEVEL` log level (see `--log-level` above)
63
+
64
+ ### Diff
65
+
66
+ ```bash
67
+ bl diff [-c PATH_TO_SPEC] [-z PATH_TO_FROZEN] [-o CONFIG_OVERRIDE] [-j CONCURRENCY] [-w WORKDIR] [--log-level LEVEL]
68
+ ```
69
+
70
+ #### What does it do
71
+ Shows diff for all dirty repos in the project.
72
+
73
+ #### Params
74
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
75
+ * `PATH_TO_FROZEN` path to your frozen spec (default: `frozen.yaml`)
76
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
77
+ * `CONCURRENCY` number of module clone simultaneously (default: `28`)
78
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
79
+ * `LEVEL` log level (see `--log-level` above)
80
+
81
+ ### Clean
82
+
83
+ ```bash
84
+ bl clean [-c PATH_TO_SPEC] [-o CONFIG_OVERRIDE] [-w WORKDIR] [--log-level LEVEL] [--remove] [--unlink] [--force] [--dry-run]
85
+ ```
86
+
87
+ #### What does it do
88
+ By default it scans all repos in the spec for dirty git state and resets them with `git reset --hard`.
89
+
90
+ #### Params
91
+ * `PATH_TO_SPEC` path to your spec (default: `spec.yaml`)
92
+ * `CONFIG_OVERRIDE` path to an override config to extend the project specification
93
+ * `WORKDIR` working directory; if omitted, the directory containing `spec.yaml`
94
+ * `LEVEL` log level (see `--log-level` above)
95
+ * `--remove` delete `src` and `external-src` directories
96
+ * `--unlink` also clean the links directory
97
+ * `--force` remove confirmation prompts
98
+ * `--dry-run` just output what it would do
99
+
100
+ ### Init
101
+
102
+ ```bash
103
+ bl init [DESTINATION]
104
+ ```
105
+
106
+ #### What does it do
107
+ Initializes a new project from the [docky-odoo-template-shared](https://github.com/akretion/docky-odoo-template-shared) template using [Copier](https://copier.readthedocs.io/).
108
+
109
+ #### Params
110
+ * `DESTINATION` destination directory (default: current directory)
111
+
112
+ ## Odoo is taking a really long time to clone
113
+
114
+ Yes !
115
+
116
+ You can add a locales entry to your odoo repo in `spec.yaml` like so:
117
+ ```yaml
118
+ odoo:
119
+ modules:
120
+ - account
121
+ ...
122
+ remotes:
123
+ odoo: https://github.com/odoo/odoo
124
+ merges:
125
+ - odoo 14.0
126
+ locales:
127
+ - fr
128
+ - en
129
+ ```
130
+ It will only download the french and english translation instead of all of them
131
+ - without locales: 849MB and 40 seconds fresh build
132
+ - with locales fr, en: 169MB and 27 seconds fresh build
133
+
134
+ ⚠️ WARNING: you must list all the odoo modules you need if you use the locales property
135
+
136
+ ## I have warnings about patch globs
137
+
138
+ There is a new property to handle `git am <patch_glob>` (the old one still works but I hope to remove it at some point)
139
+
140
+ Before:
141
+ ```yaml
142
+ folder_name:
143
+ modules:
144
+ ...
145
+ remotes:
146
+ ...
147
+ merges:
148
+ ...
149
+ shell_command_after:
150
+ - git am ../../patches/patch_folder/*
151
+ ```
152
+ After:
153
+ ```yaml
154
+ folder_name:
155
+ modules:
156
+ ...
157
+ remotes:
158
+ ...
159
+ merges:
160
+ ...
161
+ patch_globs:
162
+ - ../../patches/patch_folder/*
163
+ ```
164
+
165
+
166
+ ## Benchmarks
167
+
168
+ ### Ak benchmarks
169
+ #### Fresh install
170
+ <img width="1462" height="347" alt="ak_bench_cold" src="https://github.com/user-attachments/assets/e29cd3d9-831c-43c1-8f29-e040ebee5740" />
171
+
172
+ #### Already cloned once
173
+ <img width="1419" height="356" alt="ak_bench_hot" src="https://github.com/user-attachments/assets/47b5756e-efe1-4272-82b7-e160f73af1be" />
174
+
175
+ ### Bl benchmarks
176
+ #### Fresh install
177
+ <img width="1335" height="343" alt="bl_bench_cold" src="https://github.com/user-attachments/assets/a64ba1c4-17bd-4017-acfd-5749df505f50" />
178
+
179
+ #### Already cloned once
180
+ <img width="1373" height="342" alt="bl_bench_hot" src="https://github.com/user-attachments/assets/b11e60c2-368b-496c-bc88-f5a765f44bfe" />
181
+
182
+ ### Results
183
+ |Type| AK | BL |
184
+ |----|----|----|
185
+ |Cold| ~100s | 2 - 10x faster |
186
+ |Hot| 3-20s | 2 - 10x faster |
187
+
@@ -0,0 +1 @@
1
+ __version__ = "0.4.0"
@@ -0,0 +1,214 @@
1
+ import argparse
2
+ import asyncio
3
+ import atexit
4
+ import json
5
+ import logging
6
+ import logging.handlers
7
+ import queue
8
+ import subprocess
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ from copier import run_copy
13
+ from plumbum.lib import captured_stdout
14
+ from rich.console import Console
15
+
16
+ import bl
17
+ from bl.clean_project import clean_project, show_diffs
18
+ from bl.editable import make_editable
19
+ from bl.freezer import freeze_project
20
+ from bl.spec_parser import load_spec_file
21
+ from bl.spec_processor import process_project
22
+
23
+ err_console = Console(stderr=True)
24
+ out_console = Console()
25
+
26
+
27
+ class RichConsoleHandler(logging.Handler):
28
+ def __init__(self, level=logging.NOTSET):
29
+ super().__init__(level)
30
+ self._console = out_console
31
+ self._err_console = err_console
32
+
33
+ def emit(self, record: logging.LogRecord) -> None:
34
+ try:
35
+ msg = self.format(record)
36
+ level = record.levelno
37
+ if level >= logging.CRITICAL:
38
+ level_style = "bold red"
39
+ elif level >= logging.ERROR:
40
+ level_style = "red"
41
+ elif level >= logging.WARNING:
42
+ level_style = "yellow"
43
+ elif level >= logging.INFO:
44
+ level_style = "cyan"
45
+ else:
46
+ level_style = "dim"
47
+
48
+ message = f"[{level_style}]{record.levelname}[/]: {msg}"
49
+ if level >= logging.ERROR or level >= logging.DEBUG:
50
+ self._err_console.print(message)
51
+ else:
52
+ self._console.print(message)
53
+ if record.exc_info:
54
+ self._console.print_exception()
55
+ except Exception:
56
+ self.handleError(record)
57
+
58
+
59
+ que = queue.Queue(-1)
60
+ queue_handler = logging.handlers.QueueHandler(que)
61
+ listener = logging.handlers.QueueListener(que, RichConsoleHandler())
62
+
63
+
64
+ def check_last_version() -> bool:
65
+ ret = subprocess.run(["which", "pip"], capture_output=True)
66
+ ok = ret.returncode == 0
67
+ pip_target = ret.stdout.decode().strip()
68
+
69
+ pip_call = subprocess.run(["pip", "index", "versions", "--json", "bl-odoo"], capture_output=True)
70
+ pip_index_ok = pip_call.returncode == 0
71
+ pip_return_value = pip_call.stdout.decode().strip()
72
+
73
+ json_pip_index = json.loads(pip_return_value)
74
+ bl_last_version = json_pip_index["versions"][0]
75
+ c_maj, c_min, c_patch = bl.__version__.split(".")
76
+ l_maj, l_min, l_patch = bl_last_version.split(".")
77
+
78
+ if c_maj < l_maj or c_min < l_min or c_patch < l_patch:
79
+ msg = (
80
+ "[red]Watch out ![/] There is a new bl version you should update "
81
+ + f"(Yours is {bl.__version__} != Last is {bl_last_version})"
82
+ )
83
+ border_msg = "[red]" + "#" * (len(msg) - len("[red][/]")) + "[/]"
84
+ out_console.print(f"{border_msg}\n{msg}\n{border_msg}\n\n")
85
+
86
+
87
+ def setup_logging(log_level: str) -> None:
88
+ level = getattr(logging, log_level, logging.WARNING)
89
+ root_logger = logging.getLogger()
90
+ root_logger.handlers.clear()
91
+ root_logger.setLevel(level)
92
+ queue_handler.setFormatter(logging.Formatter("%(message)s"))
93
+ root_logger.addHandler(queue_handler)
94
+ listener.start()
95
+
96
+
97
+ @atexit.register
98
+ def stop_logging():
99
+ listener.stop()
100
+
101
+
102
+ def run():
103
+ parser = argparse.ArgumentParser(
104
+ description="Process a project specification.", formatter_class=argparse.ArgumentDefaultsHelpFormatter
105
+ )
106
+
107
+ parent_parser = argparse.ArgumentParser(add_help=False)
108
+ parent_parser.add_argument(
109
+ "-c", "--config", type=Path, help="Path to the project specification file.", default="spec.yaml"
110
+ )
111
+ parent_parser.add_argument(
112
+ "-N",
113
+ "--no-check-version",
114
+ action="store_true",
115
+ help="Disable last version check",
116
+ )
117
+ parent_parser.add_argument("-z", "--frozen", type=Path, help="Path to the frozen specification file.")
118
+ parent_parser.add_argument(
119
+ "-o",
120
+ "--config-override",
121
+ type=Path,
122
+ action="append",
123
+ help="Path to an override config to extend the project specification. "
124
+ "Can be used multiple times, applied in order.",
125
+ )
126
+ parent_parser.add_argument("-j", "--concurrency", type=int, default=28, help="Number of concurrent tasks.")
127
+ parent_parser.add_argument(
128
+ "-b",
129
+ "--use-bindfs",
130
+ action="store_true",
131
+ help="Use bindfs instead of creating symlinks (must have user_allow_other in /etc/fuse.conf).",
132
+ )
133
+ parent_parser.add_argument("-w", "--workdir", type=Path, help="Working directory. Defaults to config directory.")
134
+ parent_parser.add_argument(
135
+ "--log-level",
136
+ type=str.upper,
137
+ choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
138
+ default="WARNING",
139
+ help="Logging level.",
140
+ )
141
+
142
+ sub = parser.add_subparsers(help="subcommand help", dest="command")
143
+ sub.add_parser("build", parents=[parent_parser], help="build help")
144
+ sub.add_parser("freeze", parents=[parent_parser], help="freeze help")
145
+ sub.add_parser("diff", parents=[parent_parser], help="Show diff for all dirty repos")
146
+ edit_parser = sub.add_parser("edit", parents=[parent_parser], help="Make a repo editable")
147
+ edit_parser.add_argument("repository_name", type=Path)
148
+ init_parser = sub.add_parser("init", parents=[parent_parser], help="Initialize a project from a template")
149
+ init_parser.add_argument("destination", type=Path, nargs="?", default=Path("."), help="Destination directory")
150
+ clean_parser = sub.add_parser("clean", parents=[parent_parser], help="Clean src and external-src in workdir")
151
+ clean_parser.add_argument(
152
+ "--remove",
153
+ action="store_true",
154
+ help="Delete src and external-src.",
155
+ )
156
+ clean_parser.add_argument(
157
+ "--unlink",
158
+ action="store_true",
159
+ help="Clean the links directory.",
160
+ )
161
+ clean_parser.add_argument(
162
+ "--force",
163
+ action="store_true",
164
+ help="Remove confirmation prompts.",
165
+ )
166
+ clean_parser.add_argument(
167
+ "--dry-run",
168
+ action="store_true",
169
+ help="Just output dirty repo.",
170
+ )
171
+
172
+ args = parser.parse_args()
173
+
174
+ level_name = args.log_level
175
+ setup_logging(level_name)
176
+
177
+ if not args.no_check_version:
178
+ check_last_version()
179
+
180
+ if args.command == "init":
181
+ run_copy("https://github.com/akretion/docky-odoo-template-shared", args.destination)
182
+ sys.exit(0)
183
+
184
+ project_spec = load_spec_file(args.config, args.frozen, args.workdir, args.config_override)
185
+ if project_spec is None:
186
+ sys.exit(1)
187
+
188
+ try:
189
+ if args.command == "freeze":
190
+ asyncio.run(freeze_project(project_spec, args.frozen, concurrency=args.concurrency))
191
+ elif args.command == "build":
192
+ asyncio.run(process_project(project_spec, concurrency=args.concurrency, use_bindfs=args.use_bindfs))
193
+ elif args.command == "diff":
194
+ asyncio.run(show_diffs(project_spec))
195
+ elif args.command == "edit":
196
+ asyncio.run(make_editable(args.repository_name, args.config, args.workdir))
197
+ elif args.command == "clean":
198
+ ret = asyncio.run(
199
+ clean_project(
200
+ project_spec,
201
+ remove=args.remove,
202
+ unlink=args.unlink,
203
+ force=args.force,
204
+ dry_run=args.dry_run,
205
+ )
206
+ )
207
+ if ret != 0:
208
+ sys.exit(1)
209
+ except Exception:
210
+ sys.exit(1)
211
+
212
+
213
+ if __name__ == "__main__":
214
+ run()