-
Notifications
You must be signed in to change notification settings - Fork 0
/
o-multiverse
executable file
·384 lines (334 loc) · 13.1 KB
/
o-multiverse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
#!/usr/bin/env bash
set -Eeuo pipefail
trap cleanup SIGINT SIGTERM ERR EXIT
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-v] [-b <branches>] [-e <repos>] [--vscode] [--reset-config]
Setup the repositories for an Odoo Multiverse environment.
Run this command from the directory you want to contain all Odoo versions.
This will clone all necessary repositories and create folders per branch using git worktrees. The final structure would look like this:
<multiverse-folder>
├── .worktree-source
│ ├── odoo (bare)
│ ├── enterprise (bare)
│ ├── design-themes (bare)
│ └── documentation (bare)
├── 15.0
│ └── ...
├── 16.0
│ └── ...
├── 17.0
│ ├── odoo (17.0)
│ ├── enterprise (17.0)
│ ├── design-themes (17.0)
│ ├── documentation (17.0)
│ ├── internal (symlink to ../internal)
│ ├── upgrade (symlink to ../upgrade)
│ ├── upgrade-util (symlink to ../upgrade-util)
│ └── pyproject.toml
├── ...
│ └── ...
├── internal (master)
├── upgrade (master)
└── upgrade-util (master)
Options:
-h, --help Print this help and exit.
-v, --verbose Print script debug info.
-b <branches>, --branches <branches>
Specify which Odoo branches you want to add
(comma-separated).
(default: 15.0,16.0,17.0,saas-17.2,saas-17.4,master)
-e <repos>, --exclude <repos>
Specify which repositories to exclude
(comma-separated). Repositories included by default:
- odoo
- enterprise
- design-themes
- documentation
- internal
- upgrade
- upgrade-util
--vscode Copy tools and debug configuration for VS Code.
--reset-config Reset the existing configuration files to use the most
recent one.
EOF
exit
}
cleanup() {
trap - SIGINT SIGTERM ERR EXIT
}
# shellcheck disable=SC2034
setup_formatting() {
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
NOFORMAT="\033[0m"
# Bold
B="\033[1m" B_END="\033[22m"
# Italic
I="\033[3m" I_END="\033[23m"
# Underline
U="\033[4m" U_END="\033[24m"
# Colors (_BG = Background, BR_ = Bright)
BLACK="\033[30m" BLACK_BG="\033[40m" BR_BLACK="\033[90m" BR_BLACK_BG="\033[100m"
RED="\033[31m" RED_BG="\033[41m" BR_RED="\033[91m" BR_RED_BG="\033[101m"
GREEN="\033[32m" GREEN_BG="\033[42m" BR_GREEN="\033[92m" BR_GREEN_BG="\033[102m"
YELLOW="\033[33m" YELLOW_BG="\033[43m" BR_YELLOW="\033[93m" BR_YELLOW_BG="\033[103m"
BLUE="\033[34m" BLUE_BG="\033[44m" BR_BLUE="\033[94m" BR_BLUE_BG="\033[104m"
MAGENTA="\033[35m" MAGENTA_BG="\033[45m" BR_MAGENTA="\033[95m" BR_MAGENTA_BG="\033[105m"
CYAN="\033[36m" CYAN_BG="\033[46m" BR_CYAN="\033[96m" BR_CYAN_BG="\033[106m"
WHITE="\033[37m" WHITE_BG="\033[47m" BR_WHITE="\033[97m" BR_WHITE_BG="\033[107m"
DEFAULT="\033[39m" DEFAULT_BG="\033[49m"
else
NOFORMAT="" B="" B_END="" I="" I_END="" U="" U_END=""
BLACK="" BLACK_BG="" BR_BLACK="" BR_BLACK_BG=""
RED="" RED_BG="" BR_RED="" BR_RED_BG=""
GREEN="" GREEN_BG="" BR_GREEN="" BR_GREEN_BG=""
YELLOW="" YELLOW_BG="" BR_YELLOW="" BR_YELLOW_BG=""
BLUE="" BLUE_BG="" BR_BLUE="" BR_BLUE_BG=""
MAGENTA="" MAGENTA_BG="" BR_MAGENTA="" BR_MAGENTA_BG=""
CYAN="" CYAN_BG="" BR_CYAN="" BR_CYAN_BG=""
WHITE="" WHITE_BG="" BR_WHITE="" BR_WHITE_BG=""
DEFAULT="" DEFAULT_BG=""
fi
}
msg() {
echo >&2 -e "${1-}"
}
die() {
local msg=$1
local code=${2-1}
msg "$msg"
exit "$code"
}
parse_params() {
branches=("15.0" "16.0" "17.0" "saas-17.2" "saas-17.4" "master")
exclude=("___DUMMY___")
vscode=false
reset_config=false
while :; do
case "${1-}" in
-h | --help) usage ;;
-v | --verbose) set -x ;;
--no-color) NO_COLOR=1 ;;
-b | --branches)
IFS=',' read -ra branches <<< "${2-}"
shift
;;
-e | --exclude)
IFS=',' read -ra exclude <<< "${2-}"
shift
;;
--vscode) vscode=true ;;
--reset-config) reset_config=true ;;
-?*) die "Unknown option: $1" ;;
*) break ;;
esac
shift
done
return 0
}
parse_params "$@"
setup_formatting
# The root directory where the multiverse is set up
worktrees_root_dir="$(pwd)"
# The directory acting as a root for each Odoo-related source repository
worktree_source_dir=".worktree-source"
# The directory to clone each bare repository's files in
bare_dir=".bare"
msg "🟣 ${MAGENTA}${B}Odoo Multiverse${NOFORMAT}\n"
msg "🗄️ ${WHITE}${B}Setting up source repositories${NOFORMAT}\n"
if [ -d "$worktree_source_dir" ]; then
msg "${BR_BLACK}The worktree source directory ${U}$(pwd)/$worktree_source_dir${U_END} already exists.${NOFORMAT}\n"
else
msg "Creating worktree source directory ${U}$(pwd)/$worktree_source_dir${U_END} ...\n"
mkdir "$worktree_source_dir"
fi
pushd "$worktree_source_dir" > /dev/null
# Repositories where we need to check out each specified branch
multibranch_repos=("odoo" "enterprise" "design-themes" "documentation")
# Repositories where we only check out the default branch and symlink it
unibranch_repos=("upgrade" "upgrade-util" "internal")
# Remove excluded repositories
for repo in "${exclude[@]}"; do
if [[ " ${multibranch_repos[*]} " == *" $repo "* ]]; then
multibranch_repos=("${multibranch_repos[@]/$repo}")
fi
if [[ " ${unibranch_repos[*]} " == *" $repo "* ]]; then
unibranch_repos=("${unibranch_repos[@]/$repo}")
fi
done
# Clone all multibranch repositories as bare ones to create worktrees off later
for repo in "${multibranch_repos[@]}"; do
if [ -z "$repo" ]; then
continue
fi
if [ -d "$repo" ]; then
msg "${BR_BLACK}Source directory for repository ${B}$repo${B_END} already exists at ${U}$(pwd)/$repo${NOFORMAT}"
else
msg "Creating source directory for repository ${B}$repo${B_END} at ${U}$(pwd)/$repo${U_END} ..."
mkdir "$repo"
fi
pushd "$repo" > /dev/null
repo_url="git@github.com:odoo/$repo.git"
dev_repo_url="git@github.com:odoo-dev/$repo.git"
if [ -d "$bare_dir" ]; then
msg "${BR_BLACK}Bare repository ${B}$repo${B_END} already exists at ${U}$(pwd)/$bare_dir${NOFORMAT}"
else
msg "Cloning bare repository ${B}$repo${B_END} to ${U}$(pwd)/$bare_dir${U_END} ..."
git clone --bare "$repo_url" "$bare_dir"
pushd "$bare_dir" > /dev/null
msg "Adjusting origin fetch locations ..."
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
# Add odoo-dev remote for odoo, enterprise and design-themes
if [[ "$repo" != "documentation" ]]; then
msg "Adding 'odoo-dev' remote as 'dev' ..."
git remote add "dev" "$dev_repo_url"
git remote set-url --push "origin" "you_should_not_push_on_this_repository"
fi
popd > /dev/null
msg "Setting .git file contents ..."
echo "gitdir: ./$bare_dir" > .git
msg "Fetching all branches ..."
git fetch
fi
msg "Pruning non-existing worktrees ...\n"
git worktree prune
popd > /dev/null
done
popd > /dev/null
# Clone all unibranch repositories
for repo in "${unibranch_repos[@]}"; do
if [ -z "$repo" ]; then
continue
fi
if [ -d "$repo" ]; then
msg "${BR_BLACK}Repository ${B}$repo${B_END} already exists at ${U}$(pwd)/$repo${NOFORMAT}"
else
repo_url="git@github.com:odoo/$repo.git"
msg "Cloning repository ${B}$repo${B_END} to ${U}$(pwd)/$repo${U_END} ..."
git clone "$repo_url" "$repo"
fi
done
# Add a git worktree for each branch
for branch in "${branches[@]}"; do
if [ -z "$branch" ]; then
continue
fi
msg "\n🌳 ${WHITE}${B}Setting up worktrees for branch ${U}$branch${NOFORMAT}\n"
mkdir -p "$branch"
pushd "$branch" > /dev/null
for repo in "${multibranch_repos[@]}"; do
if [ -z "$repo" ]; then
continue
fi
if [ -d "$repo" ]; then
msg "${BR_BLACK}Worktree for repository ${B}$repo${B_END} and branch ${B}$branch${B_END} already exists at ${U}$(pwd)/$repo${NOFORMAT}"
else
msg "${DEFAULT}Adding a worktree for repository ${B}$repo${B_END} and branch ${B}$branch${B_END} at ${U}$(pwd)/$repo${U_END} ...${BR_BLACK}"
pushd "../$worktree_source_dir/$repo" > /dev/null
git worktree add "../../$branch/$repo" "$branch"
pushd "../../$branch/$repo" > /dev/null
git branch --set-upstream-to "origin/$branch"
# Make the worktree links relative (so they also work in a Docker container)
# sed -i "s@$worktrees_root_dir@../..@g" .git
# worktree_dir=$(sed "s/gitdir: //g" '.git')
# pushd "$worktree_dir" > /dev/null
# sed -i "s@$worktrees_root_dir@../../../../..@g" gitdir
# popd > /dev/null
popd > /dev/null
popd > /dev/null
fi
done
for repo in "${unibranch_repos[@]}"; do
if [ -z "$repo" ]; then
continue
fi
if [ -d "$repo" ]; then
msg "${BR_BLACK}Linked repository ${B}$repo${B_END} for branch ${B}$branch${B_END} already exists at ${U}$(pwd)/$repo${NOFORMAT}"
else
msg "${DEFAULT}Linking repository ${B}$repo${B_END} for branch ${B}$branch${B_END} at ${U}$(pwd)/$repo${U_END} ..."
ln -s "../$repo" "$repo"
fi
done
if $reset_config; then
msg "Overwriting existing configuration files ..."
fi
if [ ! -f pyproject.toml ] || $reset_config ; then
# Copy Ruff config
cp -f "$script_dir/multiverse-config/pyproject.toml" .
fi
if [ ! -f requirements.txt ] || $reset_config ; then
# Copy extra Python dependencies
cp -f "$script_dir/multiverse-config/requirements.txt" .
fi
if $vscode && { [ ! -d .vscode ] || $reset_config; }; then
# Copy VSCode config
cp -fr "$script_dir/multiverse-config/.vscode" .
fi
# Set up Python environment and install dependencies
if $reset_config && [ -d .venv ]; then
msg "${DEFAULT}Resetting Python environment for branch ${B}$branch${B_END} and installing dependencies ...${BR_BLACK}"
rm -rf .venv
python3 -m venv .venv
elif [ -d .venv ]; then
msg "${DEFAULT}Python environment for branch ${B}$branch${B_END} already exists. Updating dependencies ...${BR_BLACK}"
else
msg "${DEFAULT}Setting up Python environment for branch ${B}$branch${B_END} and installing dependencies ...${BR_BLACK}"
python3 -m venv .venv
fi
msg " ${BR_BLACK}${I}This could take a while ...${I_END}\n"
source .venv/bin/activate
if [ -d odoo ]; then
pip install -q -r odoo/requirements.txt
fi
if [ -d documentation ]; then
pip install -q -r documentation/requirements.txt
fi
pip install -q -r requirements.txt
# Set up Javascript tooling in odoo repository
if [ -d odoo ]; then
pushd odoo > /dev/null
js_tooling_dir="addons/web/tooling"
if [ -f .eslintrc.json ] || [ -f jsconfig.json ]; then
msg "${DEFAULT}Javascript tooling for repository ${B}odoo${B_END} in branch ${B}$branch${B_END} already exists. Updating rules and dependencies ...${BR_BLACK}"
else
msg "${DEFAULT}Setting up Javascript tooling for repository ${B}odoo${B_END} in branch ${B}$branch${B_END} and installing dependencies ...${BR_BLACK}"
fi
cp -f "$js_tooling_dir/_eslintignore" .eslintignore
cp -f "$js_tooling_dir/_eslintrc.json" .eslintrc.json
if [ "$branch" = "15.0" ] || [ "$branch" = "16.0" ]; then
cp -f "$js_tooling_dir/_prettierignore" .prettierignore
cp -f "$js_tooling_dir/_prettierrc.json" .prettierrc.json
else
cp -f "$js_tooling_dir/_jsconfig.json" jsconfig.json
fi
cp -f "$js_tooling_dir/_package.json" package.json
npm install --silent
popd > /dev/null
fi
# Set up Javascript tooling in enterprise repository
if [ -d enterprise ]; then
pushd enterprise > /dev/null
js_tooling_dir="../odoo/addons/web/tooling"
if [ -f .eslintrc.json ] || [ -f jsconfig.json ]; then
msg "${DEFAULT}Javascript tooling for repository ${B}enterprise${B_END} in branch ${B}$branch${B_END} already exists. Updating rules and dependencies ...${BR_BLACK}"
else
msg "${DEFAULT}Setting up Javascript tooling for repository ${B}enterprise${B_END} in branch ${B}$branch${B_END} and installing dependencies ...${BR_BLACK}"
fi
cp -f "$js_tooling_dir/_eslintignore" .eslintignore
cp -f "$js_tooling_dir/_eslintrc.json" .eslintrc.json
if [ "$branch" = "15.0" ] || [ "$branch" = "16.0" ]; then
cp -f "$js_tooling_dir/_prettierignore" .prettierignore
cp -f "$js_tooling_dir/_prettierrc.json" .prettierrc.json
else
cp -f "$js_tooling_dir/_jsconfig.json" jsconfig.json
sed -i "s@addons/@../odoo/addons/@g" jsconfig.json
fi
cp -f "$js_tooling_dir/_package.json" package.json
cp -f ../odoo/package-lock.json package-lock.json
cp -af ../odoo/node_modules node_modules
popd > /dev/null
fi
popd > /dev/null
done
msg "${NOFORMAT}\n💪 ${B}Great!${B_END} You're now ready to work on multiple versions of Odoo."