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.
- bl_odoo-0.0.0/LICENSE +21 -0
- bl_odoo-0.0.0/PKG-INFO +203 -0
- bl_odoo-0.0.0/README.md +187 -0
- bl_odoo-0.0.0/bl/__init__.py +1 -0
- bl_odoo-0.0.0/bl/__main__.py +214 -0
- bl_odoo-0.0.0/bl/clean_project.py +201 -0
- bl_odoo-0.0.0/bl/config.py +56 -0
- bl_odoo-0.0.0/bl/editable.py +77 -0
- bl_odoo-0.0.0/bl/freezer.py +78 -0
- bl_odoo-0.0.0/bl/spec_parser.py +246 -0
- bl_odoo-0.0.0/bl/spec_processor.py +892 -0
- bl_odoo-0.0.0/bl/types.py +95 -0
- bl_odoo-0.0.0/bl/utils.py +82 -0
- bl_odoo-0.0.0/bl_odoo.egg-info/PKG-INFO +203 -0
- bl_odoo-0.0.0/bl_odoo.egg-info/SOURCES.txt +34 -0
- bl_odoo-0.0.0/bl_odoo.egg-info/dependency_links.txt +1 -0
- bl_odoo-0.0.0/bl_odoo.egg-info/entry_points.txt +2 -0
- bl_odoo-0.0.0/bl_odoo.egg-info/requires.txt +5 -0
- bl_odoo-0.0.0/bl_odoo.egg-info/top_level.txt +1 -0
- bl_odoo-0.0.0/pyproject.toml +66 -0
- bl_odoo-0.0.0/setup.cfg +4 -0
- bl_odoo-0.0.0/tests/test_clean_project.py +652 -0
- bl_odoo-0.0.0/tests/test_config.py +26 -0
- bl_odoo-0.0.0/tests/test_editable.py +72 -0
- bl_odoo-0.0.0/tests/test_freezer.py +176 -0
- bl_odoo-0.0.0/tests/test_frozen_parser.py +149 -0
- bl_odoo-0.0.0/tests/test_frozen_processor.py +100 -0
- bl_odoo-0.0.0/tests/test_main.py +76 -0
- bl_odoo-0.0.0/tests/test_spec_parser.py +489 -0
- bl_odoo-0.0.0/tests/test_spec_processor_async.py +1168 -0
- bl_odoo-0.0.0/tests/test_spec_processor_helpers.py +119 -0
- bl_odoo-0.0.0/tests/test_spec_processor_integration.py +47 -0
- bl_odoo-0.0.0/tests/test_spec_processor_parsing.py +126 -0
- bl_odoo-0.0.0/tests/test_spec_processor_repo_processor.py +192 -0
- bl_odoo-0.0.0/tests/test_types.py +69 -0
- 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
|
+
[](https://github.com/FranzPoize/bl/actions/workflows/ci-publish.yml) [](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
|
+
|
bl_odoo-0.0.0/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# bl
|
|
2
|
+
[](https://github.com/FranzPoize/bl/actions/workflows/ci-publish.yml) [](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()
|