Nicolas JEUDY
2 years ago
30 changed files with 2178 additions and 17 deletions
-
44Dockerfile
-
144bin/addons
-
165bin/autoaggregate
-
52bin/config-generate
-
75bin/direxec
-
15bin/log
-
11bin/pot
-
18bin/preparedb
-
18custom/build.d/100-repos-aggregate
-
18custom/build.d/110-addons-link
-
30custom/build.d/200-dependencies
-
31custom/build.d/300-fontconfig
-
51custom/build.d/400-clean
-
10custom/build.d/500-compile
-
21custom/build.d/900-dependencies-cleanup
-
8custom/dependencies/apt.txt
-
3custom/dependencies/apt_build.txt
-
0custom/dependencies/gem.txt
-
0custom/dependencies/npm.txt
-
43custom/dependencies/pip.txt
-
164custom/src/addons.yaml
-
20custom/src/private/.editorconfig
-
884custom/src/repos.yaml
-
38custom/ssh/cloudron_git.rsa
-
1custom/ssh/cloudron_git.rsa.pub
-
7custom/ssh/config
-
14custom/ssh/known_hosts
-
173lib/doodbalib/__init__.py
-
119lib/doodbalib/installer.py
-
18start.sh
@ -0,0 +1,144 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import print_function |
|||
|
|||
import ast |
|||
import os |
|||
import sys |
|||
from argparse import ArgumentParser |
|||
from subprocess import check_call |
|||
|
|||
from doodbalib import ( |
|||
CORE, |
|||
ENTERPRISE, |
|||
MANIFESTS, |
|||
PRIVATE, |
|||
SRC_DIR, |
|||
AddonsConfigError, |
|||
addons_config, |
|||
logger, |
|||
) |
|||
|
|||
# Exit codes |
|||
EXIT_NO_ADDONS = 0x4 |
|||
|
|||
# Define CLI options |
|||
parser = ArgumentParser(description="Install addons in current environment") |
|||
parser.add_argument( |
|||
"action", |
|||
choices=("init", "update", "list"), |
|||
help="What to do with the matched addons.", |
|||
) |
|||
parser.add_argument( |
|||
"-c", "--core", action="store_true", help="Use all Odoo core addons" |
|||
) |
|||
parser.add_argument( |
|||
"-d", |
|||
"--dependencies", |
|||
action="store_true", |
|||
help="Use only dependencies of selected addons", |
|||
) |
|||
parser.add_argument("-e", "--extra", action="store_true", help="Use all extra addons") |
|||
parser.add_argument( |
|||
"-f", |
|||
"--fullpath", |
|||
action="store_true", |
|||
help="Print addon's full path, only useful with list mode", |
|||
) |
|||
parser.add_argument( |
|||
"-i", "--installable", action="store_true", help="Include only installable addons" |
|||
) |
|||
parser.add_argument( |
|||
"-n", "--enterprise", action="store_true", help="Use all enterprise addons" |
|||
) |
|||
parser.add_argument( |
|||
"-p", "--private", action="store_true", help="Use all private addons" |
|||
) |
|||
parser.add_argument( |
|||
"-s", |
|||
"--separator", |
|||
type=str, |
|||
default=",", |
|||
help="String that separates addons only useful with list mode", |
|||
) |
|||
parser.add_argument( |
|||
"-t", |
|||
"--test", |
|||
action="store_true", |
|||
help="Run unit tests for these addons, usually combined with update", |
|||
) |
|||
parser.add_argument( |
|||
"-x", |
|||
"--explicit", |
|||
action="store_true", |
|||
help="Fail if any addon is explicitly declared but not found", |
|||
) |
|||
parser.add_argument( |
|||
"-w", |
|||
"--with", |
|||
action="append", |
|||
dest="with_", |
|||
default=[], |
|||
help="Addons to include always.", |
|||
) |
|||
parser.add_argument( |
|||
"-W", "--without", action="append", default=[], help="Addons to exclude always." |
|||
) |
|||
|
|||
# Generate the matching addons set |
|||
args = parser.parse_args() |
|||
dependencies = {"base"} |
|||
addons = set(args.with_) |
|||
without = set(args.without) |
|||
if addons & without: |
|||
sys.exit("Cannot include and exclude the same addon!") |
|||
if args.dependencies and args.fullpath: |
|||
sys.exit("Unsupported combination of --dependencies and --fullpath") |
|||
try: |
|||
for addon, repo in addons_config(strict=args.explicit): |
|||
if addon in without: |
|||
continue |
|||
core_ok = args.core and repo == CORE |
|||
enterprise_ok = args.enterprise and repo == ENTERPRISE |
|||
extra_ok = args.extra and repo not in {CORE, ENTERPRISE, PRIVATE} |
|||
private_ok = args.private and repo == PRIVATE |
|||
manual_ok = addon in addons |
|||
if private_ok or core_ok or extra_ok or enterprise_ok or manual_ok: |
|||
addon_path = os.path.join(SRC_DIR, repo, addon) |
|||
manifest = {} |
|||
for manifest_name in MANIFESTS: |
|||
try: |
|||
manifest_path = os.path.join(addon_path, manifest_name) |
|||
with open(manifest_path, "r") as code: |
|||
manifest = ast.literal_eval(code.read()) |
|||
break |
|||
except IOError: |
|||
continue |
|||
if args.installable and not manifest.get("installable", True): |
|||
continue |
|||
dependencies.update(manifest.get("depends", [])) |
|||
if args.fullpath and args.action == "list": |
|||
addon = addon_path |
|||
addons.add(addon) |
|||
except AddonsConfigError as error: |
|||
sys.exit(error.message) |
|||
# Use dependencies instead, if requested |
|||
if args.dependencies: |
|||
addons = dependencies - addons |
|||
addons -= without |
|||
|
|||
# Do the required action |
|||
if not addons: |
|||
print("No addons found", file=sys.stderr) |
|||
sys.exit(EXIT_NO_ADDONS) |
|||
addons = args.separator.join(sorted(addons)) |
|||
if args.action == "list": |
|||
print(addons) |
|||
else: |
|||
command = ["odoo", "--stop-after-init", "--{}".format(args.action), addons] |
|||
if args.test: |
|||
command += ["--test-enable", "--workers", "0"] |
|||
if os.environ.get("PGDATABASE"): |
|||
command += ["--db-filter", u"^{}$".format(os.environ.get("PGDATABASE"))] |
|||
logger.info("Executing %s", " ".join(command)) |
|||
check_call(command) |
@ -0,0 +1,165 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
import os |
|||
import sys |
|||
from multiprocessing import cpu_count |
|||
from subprocess import check_call |
|||
|
|||
import yaml |
|||
from doodbalib import ( |
|||
ADDONS_YAML, |
|||
AUTO_REPOS_YAML, |
|||
CORE, |
|||
ODOO_DIR, |
|||
PRIVATE, |
|||
REPOS_YAML, |
|||
SRC_DIR, |
|||
logger, |
|||
) |
|||
|
|||
# if the umask matches the `chmod -R u+rwX,g+rX-w,o= /opt/odoo` command the build is faster as we don't need to fix as |
|||
# many permissions after auto aggregation |
|||
UMASK = os.environ.get("UMASK") or "0027" |
|||
UID = int(os.environ.get("UID") or -1) |
|||
GID = int(os.environ.get("GID") or -1) |
|||
DEFAULT_REPO_PATTERN = os.environ.get("DEFAULT_REPO_PATTERN") |
|||
DEFAULT_REPO_PATTERN_ODOO = os.environ.get("DEFAULT_REPO_PATTERN_ODOO") |
|||
log_level = os.environ.get("LOG_LEVEL", "INFO") |
|||
|
|||
|
|||
def aggregate(config): |
|||
"""Execute git aggregator to pull git code. |
|||
|
|||
:param str config: |
|||
Path where to find the ``repos.yaml`` file. |
|||
""" |
|||
logger.info("Running gitaggregate with %s", config) |
|||
|
|||
def pre_exec_umask(): |
|||
# Download git code with the specified umask, if set, otherwise use "0027" |
|||
os.umask(int(UMASK, 8)) |
|||
|
|||
pre_execs = [pre_exec_umask] |
|||
|
|||
def pre_exec(): |
|||
for _exec in pre_execs: |
|||
try: |
|||
_exec() |
|||
except Exception as e: |
|||
logger.error("Error in %s: %s" % (_exec, e)) |
|||
logger.exception(e) |
|||
raise |
|||
|
|||
if ~GID: |
|||
|
|||
def pre_exec_gid(): |
|||
# execute git with GID |
|||
os.setgid(GID) |
|||
|
|||
pre_execs.append(pre_exec_gid) |
|||
|
|||
if ~UID: |
|||
|
|||
def pre_exec_uid(): |
|||
# execute git with UID |
|||
os.setuid(UID) |
|||
# set odoo home directory |
|||
# (git checks if user has a config in $HOME, and we cannot read /root as odoo user) |
|||
os.environ["HOME"] = "/home/odoo" |
|||
|
|||
pre_execs.append(pre_exec_uid) |
|||
|
|||
check_call( |
|||
[ |
|||
"gitaggregate", |
|||
"--expand-env", |
|||
"--config", |
|||
config, |
|||
"--log-level", |
|||
log_level, |
|||
"--jobs", |
|||
str(cpu_count() or 1), |
|||
"aggregate", |
|||
], |
|||
cwd=SRC_DIR, |
|||
stderr=sys.stderr, |
|||
stdout=sys.stdout, |
|||
preexec_fn=pre_exec, |
|||
) |
|||
|
|||
|
|||
def origin_for( |
|||
folder, |
|||
default_repo_pattern=DEFAULT_REPO_PATTERN, |
|||
odoo_repo_pattern=DEFAULT_REPO_PATTERN_ODOO, |
|||
): |
|||
"""Guess the default git origin for that folder. |
|||
|
|||
:param str folder: |
|||
Normally an absolute path to an expected git repo, whose name should |
|||
match the git repository where it comes from, using the env-supplied |
|||
pattern. |
|||
""" |
|||
base = os.path.basename(folder) |
|||
pattern = default_repo_pattern |
|||
if base == "odoo": |
|||
pattern = odoo_repo_pattern |
|||
return pattern.format(base) |
|||
|
|||
|
|||
def missing_repos_config(): |
|||
"""Find the undefined repositories and return their default configuration. |
|||
|
|||
:return dict: |
|||
git-aggregator-ready configuration dict for undefined repositories. |
|||
""" |
|||
defined, expected = set(), {ODOO_DIR} |
|||
# Find the repositories defined by hand |
|||
try: |
|||
with open(REPOS_YAML) as yaml_file: |
|||
for doc in yaml.safe_load_all(yaml_file): |
|||
for repo in doc: |
|||
defined.add(os.path.abspath(os.path.join(SRC_DIR, repo))) |
|||
except (IOError, AttributeError): |
|||
logger.debug("No repositories defined by hand") |
|||
addons_env = {} |
|||
# Find the repositories that should be present |
|||
try: |
|||
with open(ADDONS_YAML) as yaml_file: |
|||
for doc in yaml.safe_load_all(yaml_file): |
|||
env = dict(os.environ, **doc.get("ENV", {})) |
|||
for repo in doc: |
|||
if repo in {PRIVATE, "ONLY", "ENV"}: |
|||
continue |
|||
if repo == CORE: |
|||
repo_path = ODOO_DIR |
|||
else: |
|||
repo_path = os.path.abspath(os.path.join(SRC_DIR, repo)) |
|||
if not os.path.exists(repo_path) or os.path.isdir( |
|||
os.path.join(repo_path, ".git") |
|||
): |
|||
expected.add(repo_path) |
|||
addons_env[repo_path] = env |
|||
except (IOError, AttributeError): |
|||
logger.debug("No addons are expected to be present") |
|||
# Find the undefined repositories and generate a config for them |
|||
missing = expected - defined |
|||
config = {} |
|||
for repo_path in missing: |
|||
env = addons_env.get(repo_path, os.environ) |
|||
depth = env["DEPTH_DEFAULT"] |
|||
origin_version = "origin %s" % env["ODOO_VERSION"] |
|||
config[repo_path] = { |
|||
"defaults": {"depth": depth}, |
|||
"merges": [origin_version], |
|||
"remotes": { |
|||
"origin": origin_for( |
|||
repo_path, |
|||
env["DEFAULT_REPO_PATTERN"], |
|||
env["DEFAULT_REPO_PATTERN_ODOO"], |
|||
) |
|||
}, |
|||
"target": origin_version, |
|||
} |
|||
logger.debug("Generated missing repos config %r", config) |
|||
return config |
@ -0,0 +1,52 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
"""Generate Odoo server configuration from templates""" |
|||
|
|||
import os |
|||
from contextlib import closing |
|||
from string import Template |
|||
|
|||
from doodbalib import logger |
|||
|
|||
try: |
|||
# Python 2, where io.StringIO fails because it is unicode-only |
|||
from StringIO import StringIO |
|||
except ImportError: |
|||
from io import StringIO |
|||
|
|||
try: |
|||
from configparser import RawConfigParser |
|||
|
|||
parser = RawConfigParser(strict=False) |
|||
except ImportError: |
|||
# Python 2, where strict=True doesn't exist |
|||
from ConfigParser import RawConfigParser |
|||
|
|||
parser = RawConfigParser() |
|||
|
|||
ODOO_VERSION = os.environ.get("ODOO_VERSION") |
|||
TARGET_FILE = os.environ.get("ODOO_RC", "/opt/odoo/auto/odoo.conf") |
|||
CONFIG_DIRS = ("/opt/odoo/common/conf.d", "/opt/odoo/custom/conf.d") |
|||
CONFIG_FILES = [] |
|||
|
|||
# Read all configuraiton files found in those folders |
|||
logger.info("Merging found configuration files in %s", TARGET_FILE) |
|||
for dir_ in CONFIG_DIRS: |
|||
try: |
|||
for file_ in sorted(os.listdir(dir_)): |
|||
parser.read(os.path.join(dir_, file_)) |
|||
except OSError: # TODO Use FileNotFoundError when we drop python 2 |
|||
continue |
|||
|
|||
# Write it to a memory string object |
|||
with closing(StringIO()) as resultfp: |
|||
parser.write(resultfp) |
|||
resultfp.seek(0) |
|||
# Obtain the config string |
|||
result = resultfp.read() |
|||
# Expand environment variables found within |
|||
result = Template(result).substitute(os.environ) |
|||
logger.debug("Resulting configuration:\n%s", result) |
|||
# Write it to destination |
|||
with open(TARGET_FILE, "w") as targetfp: |
|||
targetfp.write(result) |
@ -0,0 +1,75 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
import os |
|||
import subprocess |
|||
import sys |
|||
from logging import DEBUG, INFO, WARNING |
|||
|
|||
from doodbalib import logger, which |
|||
|
|||
# Call this file linked from another file called `build` or `entrypoint` |
|||
mode = os.path.basename(__file__) |
|||
|
|||
dir_odoo = "/opt/odoo" |
|||
dir_common = os.path.join(dir_odoo, "common", "%s.d" % mode) |
|||
dir_custom = os.path.join(dir_odoo, "custom", "%s.d" % mode) |
|||
|
|||
# Find scripts |
|||
files = [(d, dir_common) for d in os.listdir(dir_common)] |
|||
try: |
|||
files += [(d, dir_custom) for d in os.listdir(dir_custom)] |
|||
except OSError: |
|||
pass |
|||
|
|||
# Run scripts |
|||
for executable, folder in sorted(files): |
|||
command = os.path.join(folder, executable) |
|||
if os.access(command, os.X_OK): |
|||
logger.debug("Executing %s", command) |
|||
subprocess.check_call(command) |
|||
|
|||
# Allow to omit 1st command and default to `odoo` |
|||
extra_command = sys.argv[1:] |
|||
if extra_command: |
|||
if extra_command[0] == "shell" or extra_command[0].startswith("-"): |
|||
extra_command.insert(0, "odoo") |
|||
# Set the DB creation language, if needed |
|||
if extra_command[0] in {"odoo", "/usr/local/bin/odoo"}: |
|||
if os.environ.get("INITIAL_LANG"): |
|||
from psycopg2 import OperationalError, connect |
|||
|
|||
try: |
|||
connection = connect(dbname=os.environ.get("PGDATABASE")) |
|||
connection.close() |
|||
except OperationalError: |
|||
# No DB exists, set initial language |
|||
extra_command += ["--load-language", os.environ["INITIAL_LANG"]] |
|||
if os.environ.get("PTVSD_ENABLE") == "1": |
|||
# Warn deprecation |
|||
logger.log( |
|||
WARNING, |
|||
"ptvsd has beed deprecated for python debugging. " |
|||
"Please use debugpy (see https://github.com/Tecnativa/doodba#debugpy)", |
|||
) |
|||
# See `python -m ptvsd -h` to understand this |
|||
extra_command[0] = os.path.realpath(which(extra_command[0])) |
|||
extra_command = ( |
|||
["python", "-m", "ptvsd"] |
|||
+ os.environ.get("PTVSD_ARGS", "").split() |
|||
+ extra_command |
|||
) |
|||
elif os.environ["DEBUGPY_ENABLE"] == "1": |
|||
# See `python -m debugpy -h` to understand this |
|||
extra_command[0] = os.path.realpath(which(extra_command[0])) |
|||
extra_command = ( |
|||
["python", "-m", "debugpy"] |
|||
+ os.environ["DEBUGPY_ARGS"].split() |
|||
+ extra_command |
|||
) |
|||
logger.log( |
|||
DEBUG if extra_command[0] == "/qa/insider" else INFO, |
|||
"Executing %s", |
|||
" ".join(extra_command), |
|||
) |
|||
os.execvp(extra_command[0], extra_command) |
@ -0,0 +1,15 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
from __future__ import unicode_literals |
|||
|
|||
import argparse |
|||
import logging |
|||
|
|||
from doodbalib import LOG_LEVELS, logger |
|||
|
|||
parser = argparse.ArgumentParser(description="Easy logging for scripts") |
|||
parser.add_argument("level", choices=LOG_LEVELS) |
|||
parser.add_argument("message", nargs="+") |
|||
arguments = parser.parse_args() |
|||
|
|||
logger.log(getattr(logging, arguments.level), " ".join(arguments.message)) |
@ -0,0 +1,11 @@ |
|||
#!/bin/bash |
|||
# Shortcut to run Odoo in unit testing mode |
|||
set -e |
|||
addons=$1 |
|||
shift |
|||
log INFO Executing Odoo in i18n export mode for addons $addons |
|||
# HACK Odoo needs a *.po file to guess the output format |
|||
ln -sf /dev/stdout /tmp/stdout.po |
|||
set -x |
|||
exec odoo --stop-after-init -d "$PGDATABASE" --i18n-export /tmp/stdout.po \ |
|||
--modules "$addons" --update "$addons" --workers 0 "$@" |
@ -0,0 +1,18 @@ |
|||
#!/usr/bin/env python |
|||
# -*- coding: utf-8 -*- |
|||
# Script to prepare the database with initial data |
|||
|
|||
import click |
|||
import click_odoo |
|||
|
|||
|
|||
@click.command() |
|||
@click_odoo.env_options(default_log_level="info", database_must_exist=True) |
|||
def main(env): |
|||
"""Set report.url in the database to be pointing at localhost.""" |
|||
env["ir.config_parameter"].set_param("report.url", "http://localhost:8069") |
|||
env.cr.commit() |
|||
|
|||
|
|||
if __name__ == "__main__": |
|||
main() |
@ -0,0 +1,18 @@ |
|||
#!/bin/bash |
|||
set -e |
|||
|
|||
# make sure odoo has a user.name configured, as merges would not succeed otherwise |
|||
# (even if GIT_AUTHOR_NAME and EMAIL are set and should be used, it seems gitaggregate is not passing them to git) |
|||
su --shell="$SHELL" odoo -c 'git config user.name 1>/dev/null || git config --global user.name "'"$GIT_AUTHOR_NAME"'"' |
|||
|
|||
# copy ssh directory to odoo user as well (gitaggregate may also be run as odoo user) |
|||
if [[ ! -e ~odoo/.ssh ]] ; then |
|||
cp -a /opt/odoo/custom/ssh ~odoo/.ssh |
|||
fi |
|||
|
|||
if [ "$AGGREGATE" != true ]; then |
|||
log WARNING Not aggregating code repositories |
|||
exit 0 |
|||
fi |
|||
|
|||
exec autoaggregate |
@ -0,0 +1,18 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
import os |
|||
from glob import iglob |
|||
|
|||
from doodbalib import ADDONS_DIR, ADDONS_YAML, SRC_DIR, addons_config, logger |
|||
|
|||
logger.info("Linking all addons from %s in %s", ADDONS_YAML, ADDONS_DIR) |
|||
|
|||
# Remove all links in addons dir |
|||
for link in iglob(os.path.join(ADDONS_DIR, "*")): |
|||
os.remove(link) |
|||
# Add new links |
|||
for addon, repo in addons_config(): |
|||
src = os.path.relpath(os.path.join(SRC_DIR, repo, addon), ADDONS_DIR) |
|||
dst = os.path.join(ADDONS_DIR, addon) |
|||
os.symlink(src, dst) |
|||
logger.debug("Linked %s in %s", src, dst) |
@ -0,0 +1,30 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 LasLabs Inc. |
|||
|
|||
from glob import glob |
|||
from os.path import basename, join, splitext |
|||
|
|||
from doodbalib import CUSTOM_DIR, FILE_APT_BUILD, SRC_DIR |
|||
from doodbalib.installer import INSTALLERS, install, logger |
|||
|
|||
# Build dependencies installed before any others |
|||
install("apt", FILE_APT_BUILD) |
|||
|
|||
for name in INSTALLERS: |
|||
req_files = [] |
|||
# Normal dependency installation |
|||
req_files.append(join(CUSTOM_DIR, "dependencies", "%s.txt" % name)) |
|||
for req_file in req_files: |
|||
install(name, req_file) |
|||
|
|||
# Sorted dependencies installation |
|||
dep_files = sorted(glob(join(CUSTOM_DIR, "dependencies", "[0-9]*-*"))) |
|||
for dep_file in dep_files: |
|||
root, ext = splitext(basename(dep_file)) |
|||
# Get the installer (xxx-installer[-description][.ext]) |
|||
installer = root.split("-", 2)[1] |
|||
if installer not in INSTALLERS: |
|||
logger.error("Unknown installer: %s", installer) |
|||
raise Exception |
|||
install(installer, dep_file) |
@ -0,0 +1,31 @@ |
|||
#!/bin/bash |
|||
set -e |
|||
|
|||
mkdir -p ~cloudron/.config/fontconfig/conf.d |
|||
cat <<END > ~odoo/.config/fontconfig/conf.d/100-doodba.conf |
|||
<?xml version="1.0"?> |
|||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd"> |
|||
<!-- Odoo default fonts, generated by Doodba --> |
|||
<fontconfig> |
|||
<alias> |
|||
<family>monospace</family> |
|||
<prefer> |
|||
<family>$FONT_MONO</family> |
|||
</prefer> |
|||
</alias> |
|||
<alias> |
|||
<family>sans-serif</family> |
|||
<prefer> |
|||
<family>$FONT_SANS</family> |
|||
</prefer> |
|||
</alias> |
|||
<alias> |
|||
<family>serif</family> |
|||
<prefer> |
|||
<family>$FONT_SERIF</family> |
|||
</prefer> |
|||
</alias> |
|||
</fontconfig> |
|||
END |
|||
|
|||
chown cloudron:cloudron ~cloudron/.config |
@ -0,0 +1,51 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
import os |
|||
import shutil |
|||
import sys |
|||
|
|||
from doodbalib import CLEAN, ODOO_DIR, PRIVATE_DIR, SRC_DIR, addons_config, logger |
|||
|
|||
if not CLEAN: |
|||
logger.warning("Not cleaning garbage") |
|||
sys.exit() |
|||
|
|||
# Get the enabled paths |
|||
repos_addons = {} |
|||
for addon, repo in addons_config(filtered=False): |
|||
repo_path = os.path.realpath(os.path.join(SRC_DIR, repo)) |
|||
repos_addons.setdefault(repo_path, set()) |
|||
repos_addons[repo_path].add(addon) |
|||
logger.debug("Addon paths enabled: %s", repos_addons) |
|||
|
|||
# Traverse src dir and remove anything not explicitly enabled |
|||
for directory, subdirectories, subfiles in os.walk(SRC_DIR): |
|||
logger.debug("Checking for cleanup directory %s", directory) |
|||
# Skip main src directory |
|||
if directory == SRC_DIR: |
|||
continue |
|||
# Always skip private/* |
|||
if directory == PRIVATE_DIR: |
|||
subdirectories[:] = [] |
|||
continue |
|||
# Inside the odoo dir, skip all but addons dir |
|||
if directory == ODOO_DIR: |
|||
subdirectories[:] = ["addons"] |
|||
continue |
|||
try: |
|||
# Get addons enalbed in current directory |
|||
enabled_addons = repos_addons[directory] |
|||
except KeyError: |
|||
# This isn't a repo; is there anything inside to preserve? |
|||
directory += os.path.sep |
|||
if any(repo.startswith(directory) for repo in repos_addons): |
|||
# Then, let's walk in; we'll remove later if needed |
|||
continue |
|||
else: |
|||
# This is an addons repo; do not walk into the enabled ones |
|||
for addon in enabled_addons: |
|||
subdirectories.remove(addon) |
|||
continue |
|||
# Remove every other directory |
|||
logger.info("Removing directory %s", directory) |
|||
shutil.rmtree(directory) |
@ -0,0 +1,10 @@ |
|||
#!/bin/bash |
|||
set -e |
|||
|
|||
if [ "$COMPILE" != true ]; then |
|||
log WARNING Not compiling Python code |
|||
exit 0 |
|||
fi |
|||
|
|||
log INFO Compiling all Python code in /opt/odoo |
|||
python -m compileall -q /opt/odoo |
@ -0,0 +1,21 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 LasLabs Inc. |
|||
|
|||
import os |
|||
|
|||
from doodbalib import CUSTOM_DIR, FILE_APT_BUILD |
|||
from doodbalib.installer import INSTALLERS |
|||
|
|||
# Build-time dependencies must be removed when finishing build |
|||
if os.path.isfile(FILE_APT_BUILD): |
|||
installer = INSTALLERS["apt"](FILE_APT_BUILD) |
|||
installer.remove() |
|||
installer.cleanup() |
|||
|
|||
|
|||
# Clean up garbage generated by respective package managers |
|||
for name, class_ in INSTALLERS.items(): |
|||
req_file = os.path.join(CUSTOM_DIR, "dependencies", "%s.txt" % name) |
|||
if os.path.isfile(req_file): |
|||
class_(req_file).cleanup() |
@ -0,0 +1,8 @@ |
|||
python3-pandas |
|||
cups |
|||
libcups2-dev |
|||
python3-dev |
|||
build-essential |
|||
libcairo2-dev |
|||
pkg-config |
|||
xmlsec1 |
@ -0,0 +1,3 @@ |
|||
libldap2-dev |
|||
libssl-dev |
|||
libsasl2-dev |
@ -0,0 +1,43 @@ |
|||
git+https://github.com/OCA/openupgradelib.git@master |
|||
unicodecsv |
|||
unidecode |
|||
py3o.template |
|||
PyPDF2 |
|||
py3o.formats |
|||
zeep |
|||
parse-accept-language |
|||
pyquerystring |
|||
cerberus==1.3.2 |
|||
apispec>=4.0.0 |
|||
marshmallow |
|||
marshmallow-objects>=2.0.0 |
|||
cachetools |
|||
boto |
|||
pycups |
|||
bravado_core |
|||
facebook_business |
|||
python-telegram-bot |
|||
swagger_spec_validator |
|||
viberbot |
|||
PyMuPDF==1.16.14 |
|||
factur-x |
|||
regex |
|||
dateparser |
|||
pycairo |
|||
rocketchat_API |
|||
ovh |
|||
weboob |
|||
payplug |
|||
qrcode |
|||
markdownify |
|||
requests_oauthlib |
|||
pyocclient |
|||
cryptography>=2.3 |
|||
jwcrypto==0.5.0 |
|||
freezegun |
|||
pysaml2 |
|||
formio-data |
|||
pysaml2 |
|||
odoo_test_helper |
|||
python-jose |
|||
click-odoo-contrib |
@ -0,0 +1,164 @@ |
|||
sale-workflow: |
|||
- "*" |
|||
openupgrade: |
|||
- "openupgrade_framework" |
|||
- "openupgrade_scripts" |
|||
partner-contact: |
|||
- "*" |
|||
server-ux: |
|||
- "*" |
|||
bank-payment: |
|||
- "*" |
|||
account-financial-tools: |
|||
- "account_*" |
|||
- "base_*" |
|||
community-data-files: |
|||
- "*" |
|||
hr: |
|||
- "*" |
|||
l10n-france: |
|||
- "*" |
|||
l10n-switzerland: |
|||
- "*" |
|||
product-attribute: |
|||
- "*" |
|||
project: |
|||
- "*" |
|||
project-reporting: |
|||
- "*" |
|||
web: |
|||
- "*" |
|||
website: |
|||
- "*" |
|||
mis-builder: |
|||
- "*" |
|||
operating-unit: |
|||
- "*" |
|||
connector: |
|||
- "*" |
|||
purchase-workflow: |
|||
- "*" |
|||
server-env: |
|||
- "*" |
|||
odoo-theme: |
|||
- "*" |
|||
report-engine: |
|||
- "*" |
|||
formio: |
|||
- "*" |
|||
# learning_addons: |
|||
# - "*" |
|||
muk-web: |
|||
- "*" |
|||
rest-framework: |
|||
- "*" |
|||
server-auth: |
|||
- "*" |
|||
server-tools: |
|||
- "*" |
|||
wms: |
|||
- "*" |
|||
stock-logistics-warehouse: |
|||
- "*" |
|||
contract: |
|||
- "*" |
|||
field-service: |
|||
- "*" |
|||
queue: |
|||
- "*" |
|||
commission: |
|||
- "*" |
|||
pms: |
|||
- "*" |
|||
dms: |
|||
- "*" |
|||
social: |
|||
- "*" |
|||
pos: |
|||
- "*" |
|||
product-configurator: |
|||
- "*" |
|||
stock-logistics-workflow: |
|||
- "*" |
|||
account-financial-reporting: |
|||
- "*" |
|||
bank-statement-import: |
|||
- "*" |
|||
account-reconcile: |
|||
- "*" |
|||
manufacture: |
|||
- "*" |
|||
multi-company: |
|||
- "*" |
|||
account-analytic: |
|||
- "*" |
|||
stock-logistics-reporting: |
|||
- "*" |
|||
account-invoice-reporting: |
|||
- "*" |
|||
sale-reporting: |
|||
- "*" |
|||
account-closing: |
|||
- "*" |
|||
account-payment: |
|||
- "*" |
|||
edi: |
|||
- "*" |
|||
timesheet: |
|||
- "*" |
|||
odoo-pim: |
|||
- "*" |
|||
delivery-carrier: |
|||
- "*" |
|||
storage: |
|||
- "*" |
|||
product-variant: |
|||
- "*" |
|||
e-commerce: |
|||
- "*" |
|||
hr-expense: |
|||
- "*" |
|||
crm: |
|||
- "*" |
|||
maintenance: |
|||
- "*" |
|||
connector-telephony: |
|||
- "*" |
|||
server-backend: |
|||
- "*" |
|||
intrastat-extrastat: |
|||
- "*" |
|||
brand: |
|||
- "*" |
|||
hr-holidays: |
|||
- "*" |
|||
server-brand: |
|||
- "*" |
|||
report-print-send: |
|||
- "*" |
|||
calendar: |
|||
- "*" |
|||
credit-control: |
|||
- "*" |
|||
# myc-extra-addons: |
|||
# - "*" |
|||
account-invoicing: |
|||
- "*" |
|||
sync-addons: |
|||
- "*" |
|||
vertical-cooperative: |
|||
- "*" |
|||
# nj-addons: |
|||
# - "*" |
|||
vertical-association: |
|||
- "*" |
|||
account-move-import: |
|||
- "*" |
|||
galicea-addons: |
|||
- "*" |
|||
straga-main: |
|||
- "*" |
|||
odoo-usability: |
|||
- "*" |
|||
odoo-py3o-report-templates: |
|||
- "*" |
@ -0,0 +1,20 @@ |
|||
# Configuration for known file extensions |
|||
[*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}] |
|||
charset = utf-8 |
|||
end_of_line = lf |
|||
indent_size = 4 |
|||
indent_style = space |
|||
insert_final_newline = true |
|||
trim_trailing_whitespace = true |
|||
|
|||
[*.{json,yml,yaml,rst,md}] |
|||
indent_size = 2 |
|||
|
|||
# Do not configure editor for libs and autogenerated content |
|||
[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}] |
|||
charset = unset |
|||
end_of_line = unset |
|||
indent_size = unset |
|||
indent_style = unset |
|||
insert_final_newline = false |
|||
trim_trailing_whitespace = false |
@ -0,0 +1,884 @@ |
|||
./sale-workflow: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/OCA/sale-workflow.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./partner-contact: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/partner-contact.git |
|||
# myc: ssh://git@git.myceliandre.fr:5022/OCA/partner-contact.git |
|||
target: oca 14.0 |
|||
merges: |
|||
#- myc 14.0_partner_favorite |
|||
- oca 14.0 |
|||
./server-ux: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/server-ux.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./bank-payment: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/bank-payment.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/820/head |
|||
- oca refs/pull/822/head |
|||
#- oca refs/pull/831/head |
|||
#- oca refs/pull/858/head |
|||
./account-financial-tools: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/account-financial-tools.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/1087/head |
|||
- oca refs/pull/1236/head |
|||
./community-data-files: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/community-data-files.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./hr: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/hr.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./l10n-switzerland: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/l10n-switzerland.git |
|||
target: oca 12.0 |
|||
merges: |
|||
- oca 12.0 |
|||
./l10n-france: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/l10n-france.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/257/head |
|||
- oca refs/pull/321/head |
|||
./product-attribute: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/product-attribute.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./project: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/project.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./project-reporting: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/project-reporting.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/44/head |
|||
./website: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/website.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./web: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/web.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./mis-builder: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/mis-builder.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./operating-unit: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/operating-unit.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./connector: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/connector.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./delivery-carrier: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/OCA/delivery-carrier.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./purchase-workflow: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/OCA/purchase-workflow.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./server-env: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/OCA/server-env.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./odoo-theme: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
myc: https://git.myceliandre.fr/Myceliandre/odoo_theme.git |
|||
target: myc 14.0 |
|||
merges: |
|||
- myc 14.0 |
|||
./report-engine: |
|||
defaults: |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/reporting-engine.git |
|||
target: oca 14.0 |
|||
merges: |
|||
#- oca refs/pull/445/head |
|||
#- oca refs/pull/506/head |
|||
#- oca refs/pull/526/head |
|||
#- oca refs/pull/502/head |
|||
# report_py3o PR |
|||
#- oca refs/pull/445/head |
|||
- oca 14.0 |
|||
./formio: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/novacode-nl/odoo-formio.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
# ./learning_addons: |
|||
# defaults: |
|||
# # Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# # You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# # for a sane value of 100 commits) |
|||
# depth: $DEPTH_DEFAULT |
|||
# remotes: |
|||
# origin: ssh://git@git.myceliandre.fr:5022/Myceliandre/odoo_learning_addons.git |
|||
# target: origin 14.0 |
|||
# merges: |
|||
# - origin 14.0 |
|||
./muk-web: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/muk-it/muk_web.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./rest-framework: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/rest-framework.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./server-auth: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/server-auth.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./server-tools: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/server-tools.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./wms: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/wms.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./stock-logistics-warehouse: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/stock-logistics-warehouse.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./contract: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/contract.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./field-service: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/field-service.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./queue: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/queue.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./commission: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/commission.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./pms: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/pms.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./dms: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/dms.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./social: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/social.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./pos: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/pos.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./product-configurator: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/product-configurator.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./stock-logistics-workflow: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/stock-logistics-workflow.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./account-financial-reporting: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/account-financial-reporting.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./bank-statement-import: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/bank-statement-import.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/396/head |
|||
- oca refs/pull/417/head |
|||
- oca refs/pull/423/head |
|||
./account-reconcile: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/account-reconcile.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/361/head |
|||
- oca refs/pull/382/head |
|||
- oca refs/pull/402/head |
|||
- oca refs/pull/412/head |
|||
./manufacture: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/manufacture.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./multi-company: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/multi-company.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./account-analytic: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/account-analytic.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./stock-logistics-reporting: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/stock-logistics-reporting.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./account-invoice-reporting: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/account-invoice-reporting.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./account-invoicing: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/account-invoicing.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./sale-reporting: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/sale-reporting.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./account-closing: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/account-closing.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/155/head |
|||
- oca refs/pull/174/head |
|||
./account-payment: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/account-payment.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./edi: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: 200 |
|||
remotes: |
|||
oca: https://github.com/OCA/edi.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
- oca refs/pull/326/head |
|||
#- oca refs/pull/334/head |
|||
- oca refs/pull/454/head |
|||
./timesheet: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/timesheet.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./odoo-pim: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/odoo-pim.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./storage: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/storage.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./product-variant: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/product-variant.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./e-commerce: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/e-commerce.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./hr-expense: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/hr-expense.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./crm: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/crm.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./maintenance: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/maintenance.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./connector-telephony: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/connector-telephony.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./server-backend: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/server-backend.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./intrastat-extrastat: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/intrastat-extrastat.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./brand: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/brand.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./hr-holidays: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/hr-holidays.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./server-brand: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/server-brand.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./report-print-send: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/report-print-send.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./calendar: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/calendar.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
./credit-control: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
oca: https://github.com/OCA/credit-control.git |
|||
target: oca 14.0 |
|||
merges: |
|||
- oca 14.0 |
|||
# ./myc-extra-addons: |
|||
# defaults: |
|||
# depth: $DEPTH_DEFAULT |
|||
# remotes: |
|||
# myc: ssh://git@git.myceliandre.fr:5022/njeudy/myc-extra-addons.git |
|||
# target: myc 14.0 |
|||
# merges: |
|||
# - myc 14.0 |
|||
./sync-addons: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/itpp-labs/sync-addons.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./vertical-cooperative: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://git.myceliandre.fr/njeudy/vertical-cooperative.git |
|||
target: origin 14.0-MIG-INITIAL |
|||
merges: |
|||
- origin 14.0-MIG-INITIAL |
|||
# ./nj-addons: |
|||
# defaults: |
|||
# depth: $DEPTH_DEFAULT |
|||
# remotes: |
|||
# origin: ssh://git@git.myceliandre.fr:5022/nj.0k.io/nj-addons.git |
|||
# target: origin 14.0 |
|||
# merges: |
|||
# - origin 14.0 |
|||
./vertical-association: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/OCA/vertical-association.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./account-move-import: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/akretion/account-move-import.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./galicea-addons: |
|||
defaults: |
|||
# Shallow repositories ($DEPTH_DEFAULT=1) are faster & thinner |
|||
# You may need a bigger depth when merging PRs (use $DEPTH_MERGE |
|||
# for a sane value of 100 commits) |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://git.myceliandre.fr/Myceliandre/galicea-odoo-addons-ecosystem.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./openupgrade: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/OCA/OpenUpgrade.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./straga-main: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/straga/odoo_vik_main.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./odoo-usability: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/akretion/odoo-usability.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
|||
./odoo-py3o-report-templates: |
|||
defaults: |
|||
depth: $DEPTH_DEFAULT |
|||
remotes: |
|||
origin: https://github.com/akretion/odoo-py3o-report-templates.git |
|||
target: origin 14.0 |
|||
merges: |
|||
- origin 14.0 |
@ -0,0 +1,38 @@ |
|||
-----BEGIN OPENSSH PRIVATE KEY----- |
|||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn |
|||
NhAAAAAwEAAQAAAYEAxTkiUEpg2rhVAbvImkk2BAKIB13kCg2IyNuiUtPwKWBt4gyDzQwS |
|||
r9+lhDcTb41UmQFn0++dBCveRkTTafY+d23aWSHf+vfM470CSzdwothHIukNnPyRvWAwhO |
|||
Z7X51evA2hYuUvdeZex0Rqrwdxu1vrpCsPwHxiEAMm5Adc8ybqEiKBkoRv20PKas1WEl/m |
|||
RpSTadGUZVh0fJFp9gRFKmZMqXWm81hB5MpKL4OBd/APhRZfqNT0WOTIBHFKySjAqNi4H8 |
|||
eUW3voi/ivSMTCv1MyybzSEHRLS8fzDa9zJ6uXp6/SOVSNyIT8oNqBBOG0Bk0w2y9E32lR |
|||
tnqmugVU40CSoIwf9LyCy3pSdqM1mM+sXTsd/tqY4Vo/H1m6U+zjEX1/9pLYbS0uDbdCAv |
|||
ChoxQg+HtCZ74wX2c+yFrVcDqqHNOqCbbPdjSNrdCFVdZtx2A2AuqALFnXskc1lJ4VTOsJ |
|||
Fr5QoAmLGRYN0lvqzNVUwI/BklmIYOgi8cvXf4PxAAAFkItx43GLceNxAAAAB3NzaC1yc2 |
|||
EAAAGBAMU5IlBKYNq4VQG7yJpJNgQCiAdd5AoNiMjbolLT8ClgbeIMg80MEq/fpYQ3E2+N |
|||
VJkBZ9PvnQQr3kZE02n2Pndt2lkh3/r3zOO9Aks3cKLYRyLpDZz8kb1gMITme1+dXrwNoW |
|||
LlL3XmXsdEaq8Hcbtb66QrD8B8YhADJuQHXPMm6hIigZKEb9tDymrNVhJf5kaUk2nRlGVY |
|||
dHyRafYERSpmTKl1pvNYQeTKSi+DgXfwD4UWX6jU9FjkyARxSskowKjYuB/HlFt76Iv4r0 |
|||
jEwr9TMsm80hB0S0vH8w2vcyerl6ev0jlUjciE/KDagQThtAZNMNsvRN9pUbZ6proFVONA |
|||
kqCMH/S8gst6UnajNZjPrF07Hf7amOFaPx9ZulPs4xF9f/aS2G0tLg23QgLwoaMUIPh7Qm |
|||
e+MF9nPsha1XA6qhzTqgm2z3Y0ja3QhVXWbcdgNgLqgCxZ17JHNZSeFUzrCRa+UKAJixkW |
|||
DdJb6szVVMCPwZJZiGDoIvHL13+D8QAAAAMBAAEAAAGAAxi7jjEsxiJgy08sfieqHnP/uM |
|||
Xjn7jIrgaszMohGjU2ZHc31o9a98H2MlY/CuBYNLLN84jumTMrIUVRYHeKUYu7Au1CPAmK |
|||
AQVltNKhBR2KOGUaXp2kmCmbeWq5Ay5QX3mDUC8zCJHeaRiM6ESgp4Vw9LnsXGRXkdLK2I |
|||
e5EORKhpBeInPL4dB1rCmfMViqH++TRPUSdGjoI1CRLliw0VKb34lGXsnC9xmqAob5EG4H |
|||
gFpylA8L6x1kepVgzDnEjYf9DEHwapmBrqFzamItaVX0/tCbz9Z+pJKPwbQUNiI685vpto |
|||
y+1N3ebPlQWIYVMe8nNJk5sHU1fHSvwaUy7LHC7rQS5M8+rPk9uJ6Gn4IzrMT+krUXhLQ7 |
|||
ty8MeA2MJfkZPh2hewp+oBInocNrQY/YoEIG+GymWl5bWd14Oq1aD3c6kiQx4wFbS+UQ8v |
|||
K24PwXQMp44Js8tu8VzW8PkJDS0tWIBbj6vb3VLnLzPSi96RXcUwGNtB5nIkgKbdt1AAAA |
|||
wQDarcaxa7NIz5MkRgLhWNUPSZRh9upUnck6Ul7JnMYeVkNTm6u17V5sl1qj6Tk+EhZvHL |
|||
5pwMra8XtCDq5rtQuG6d7SQp0aB1uQEXioIkSzazaMO2KRxSJsLjXpSwPQn6dcrwEpDafX |
|||
1bgTocYA+fg54qv0F1luBOojv5XaUYY/6Qh0avdVohP00uS5vnNCSrFR4K/VB2Xgi3F0Io |
|||
dm7gdGwN/VCXpkydW3o8x/ka1vWQhAWdhfcd4ZNu10tya3m1wAAADBAPveoaaPPK0k4v5B |
|||
5TMXlnz939H7i+iwBx3cDgZNRX8c1nnhb+rjy/JQV0N01v6CUmAR4NgRe4SrCb7HgRcvAd |
|||
Ac2uYzT3f5/F3Gj/zETGM1cCrMox64BPqIPkMrQVtq58AdclJqqiqvbYYl5oycbkKd2CcF |
|||
dhMh5GAI2RTDMcxQzcM5EBGh9vWxUtCosNBsGMRm8jvUXg8fpNIduf6B+qU3pNen6otPPt |
|||
ydGZStR+iAkf4p8ny0OJQ+lTPMfimzvwAAAMEAyHUXp/60l7g6A1s5lOgvnUwJYlVk5MRl |
|||
QEfdAHVbIhqM+Vig4po1nk2zVf+VKtZe6JIalcrelHydohMgFIsMsfFOn/lhjuL+yUaeb9 |
|||
ud0aJmP7MPOcf2uFv5iqN87Q893OHdkoZSak2SHWQm/Sho3tHKaM7OdQwOiwJqnzyPc8Dg |
|||
YD/JJWsqzNRCQ9BL7zuaf1+0gb5lBJGw95kBDg7rOuKQXdk7uWxQCZPXj3/xO2kk0t/cTa |
|||
cgHT4D/mOucfRPAAAAFm5qZXVkeUBERVNLVE9QLU1MUk5HOEQBAgME |
|||
-----END OPENSSH PRIVATE KEY----- |
@ -0,0 +1 @@ |
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDFOSJQSmDauFUBu8iaSTYEAogHXeQKDYjI26JS0/ApYG3iDIPNDBKv36WENxNvjVSZAWfT750EK95GRNNp9j53bdpZId/698zjvQJLN3Ci2Eci6Q2c/JG9YDCE5ntfnV68DaFi5S915l7HRGqvB3G7W+ukKw/AfGIQAybkB1zzJuoSIoGShG/bQ8pqzVYSX+ZGlJNp0ZRlWHR8kWn2BEUqZkypdabzWEHkykovg4F38A+FFl+o1PRY5MgEcUrJKMCo2Lgfx5Rbe+iL+K9IxMK/UzLJvNIQdEtLx/MNr3Mnq5enr9I5VI3IhPyg2oEE4bQGTTDbL0TfaVG2eqa6BVTjQJKgjB/0vILLelJ2ozWYz6xdOx3+2pjhWj8fWbpT7OMRfX/2kthtLS4Nt0IC8KGjFCD4e0JnvjBfZz7IWtVwOqoc06oJts92NI2t0IVV1m3HYDYC6oAsWdeyRzWUnhVM6wkWvlCgCYsZFg3SW+rM1VTAj8GSWYhg6CLxy9d/g/E= njeudy@DESKTOP-MLRNG8D |
@ -0,0 +1,7 @@ |
|||
# See syntax in https://www.ssh.com/ssh/config/ and `man ssh_config` |
|||
Host * |
|||
IgnoreUnknown UseKeychain |
|||
UseKeychain yes |
|||
IdentityFile /root/.ssh/cloudron_git.rsa |
|||
PubkeyAcceptedKeyTypes=+ssh-dss |
|||
AddKeysToAgent yes |
@ -0,0 +1,14 @@ |
|||
# Use `ssh-keyscan` to fill this file and ensure remote git hosts ssh keys |
|||
|
|||
# bitbucket.org:22 SSH-2.0-conker_1.0.298-8c5a6f7 app-126 |
|||
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw== |
|||
|
|||
# github.com:22 SSH-2.0-libssh-0.7.0 |
|||
github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== |
|||
|
|||
# gitlab.com:22 SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2 |
|||
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 |
|||
# gitlab.com:22 SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2 |
|||
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= |
|||
# gitlab.com:22 SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2 |
|||
gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf |
@ -0,0 +1,173 @@ |
|||
# -*- coding: utf-8 -*- |
|||
import logging |
|||
import os |
|||
from glob import glob |
|||
from pprint import pformat |
|||
from subprocess import check_output |
|||
|
|||
import yaml |
|||
|
|||
# Constants needed in scripts |
|||
CUSTOM_DIR = "/app/code/custom" |
|||
AUTO_DIR = "/app/code/auto" |
|||
ADDONS_DIR = os.path.join(AUTO_DIR, "addons") |
|||
SRC_DIR = os.path.join(CUSTOM_DIR, "src") |
|||
|
|||
ADDONS_YAML = os.path.join(SRC_DIR, "addons") |
|||
if os.path.isfile("%s.yaml" % ADDONS_YAML): |
|||
ADDONS_YAML = "%s.yaml" % ADDONS_YAML |
|||
else: |
|||
ADDONS_YAML = "%s.yml" % ADDONS_YAML |
|||
|
|||
REPOS_YAML = os.path.join(SRC_DIR, "repos") |
|||
if os.path.isfile("%s.yaml" % REPOS_YAML): |
|||
REPOS_YAML = "%s.yaml" % REPOS_YAML |
|||
else: |
|||
REPOS_YAML = "%s.yml" % REPOS_YAML |
|||
|
|||
AUTO_REPOS_YAML = os.path.join(AUTO_DIR, "repos") |
|||
if os.path.isfile("%s.yml" % AUTO_REPOS_YAML): |
|||
AUTO_REPOS_YAML = "%s.yml" % AUTO_REPOS_YAML |
|||
else: |
|||
AUTO_REPOS_YAML = "%s.yaml" % AUTO_REPOS_YAML |
|||
|
|||
CLEAN = os.environ.get("CLEAN") == "true" |
|||
LOG_LEVELS = frozenset({"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}) |
|||
FILE_APT_BUILD = os.path.join(CUSTOM_DIR, "dependencies", "apt_build.txt") |
|||
PRIVATE = "private" |
|||
CORE = "odoo/addons" |
|||
ENTERPRISE = "enterprise" |
|||
PRIVATE_DIR = os.path.join(SRC_DIR, PRIVATE) |
|||
CORE_DIR = os.path.join(SRC_DIR, CORE) |
|||
ODOO_DIR = os.path.join(SRC_DIR, "odoo") |
|||
ODOO_VERSION = os.environ["ODOO_VERSION"] |
|||
MANIFESTS = ("__manifest__.py", "__openerp__.py") |
|||
|
|||
# Customize logging for build |
|||
logger = logging.getLogger("doodba") |
|||
log_handler = logging.StreamHandler() |
|||
log_formatter = logging.Formatter("%(name)s %(levelname)s: %(message)s") |
|||
log_handler.setFormatter(log_formatter) |
|||
logger.addHandler(log_handler) |
|||
_log_level = os.environ.get("LOG_LEVEL", "") |
|||
if _log_level.isdigit(): |
|||
_log_level = int(_log_level) |
|||
elif _log_level in LOG_LEVELS: |
|||
_log_level = getattr(logging, _log_level) |
|||
else: |
|||
if _log_level: |
|||
logger.warning("Wrong value in $LOG_LEVEL, falling back to INFO") |
|||
_log_level = logging.INFO |
|||
logger.setLevel(_log_level) |
|||
|
|||
|
|||
class AddonsConfigError(Exception): |
|||
def __init__(self, message, *args): |
|||
super(AddonsConfigError, self).__init__(message, *args) |
|||
self.message = message |
|||
|
|||
|
|||
def addons_config(filtered=True, strict=False): |
|||
"""Yield addon name and path from ``ADDONS_YAML``. |
|||
|
|||
:param bool filtered: |
|||
Use ``False`` to include all addon definitions. Use ``True`` (default) |
|||
to include only those matched by ``ONLY`` clauses, if any. |
|||
|
|||
:param bool strict: |
|||
Use ``True`` to raise an exception if any declared addon is not found. |
|||
|
|||
:return Iterator[str, str]: |
|||
A generator that yields ``(addon, repo)`` pairs. |
|||
""" |
|||
config = dict() |
|||
missing_glob = set() |
|||
missing_manifest = set() |
|||
all_globs = {} |
|||
try: |
|||
with open(ADDONS_YAML) as addons_file: |
|||
for doc in yaml.safe_load_all(addons_file): |
|||
# Skip sections with ONLY and that don't match |
|||
only = doc.pop("ONLY", {}) |
|||
if not filtered: |
|||
doc.setdefault(CORE, ["*"]) |
|||
doc.setdefault(PRIVATE, ["*"]) |
|||
elif any( |
|||
os.environ.get(key) not in values for key, values in only.items() |
|||
): |
|||
logger.debug("Skipping section with ONLY %s", only) |
|||
continue |
|||
# Flatten all sections in a single dict |
|||
for repo, partial_globs in doc.items(): |
|||
if repo == "ENV": |
|||
continue |
|||
logger.debug("Processing %s repo", repo) |
|||
all_globs.setdefault(repo, set()) |
|||
all_globs[repo].update(partial_globs) |
|||
except IOError: |
|||
logger.debug("Could not find addons configuration yaml.") |
|||
# Add default values for special sections |
|||
for repo in (CORE, PRIVATE): |
|||
all_globs.setdefault(repo, {"*"}) |
|||
logger.debug("Merged addons definition before expanding: %r", all_globs) |
|||
# Expand all globs and store config |
|||
for repo, partial_globs in all_globs.items(): |
|||
for partial_glob in partial_globs: |
|||
logger.debug("Expanding in repo %s glob %s", repo, partial_glob) |
|||
full_glob = os.path.join(SRC_DIR, repo, partial_glob) |
|||
found = glob(full_glob) |
|||
if not found: |
|||
# Projects without private addons should never fail |
|||
if (repo, partial_glob) != (PRIVATE, "*"): |
|||
missing_glob.add(full_glob) |
|||
logger.debug("Skipping unexpandable glob '%s'", full_glob) |
|||
continue |
|||
for addon in found: |
|||
if not os.path.isdir(addon): |
|||
continue |
|||
manifests = (os.path.join(addon, m) for m in MANIFESTS) |
|||
if not any(os.path.isfile(m) for m in manifests): |
|||
missing_manifest.add(addon) |
|||
logger.debug( |
|||
"Skipping '%s' as it is not a valid Odoo " "module", addon |
|||
) |
|||
continue |
|||
logger.debug("Registering addon %s", addon) |
|||
addon = os.path.basename(addon) |
|||
config.setdefault(addon, set()) |
|||
config[addon].add(repo) |
|||
# Fail now if running in strict mode |
|||
if strict: |
|||
error = [] |
|||
if missing_glob: |
|||
error += ["Addons not found:", pformat(missing_glob)] |
|||
if missing_manifest: |
|||
error += ["Addons without manifest:", pformat(missing_manifest)] |
|||
if error: |
|||
raise AddonsConfigError("\n".join(error), missing_glob, missing_manifest) |
|||
logger.debug("Resulting configuration after expanding: %r", config) |
|||
for addon, repos in config.items(): |
|||
# Private addons are most important |
|||
if PRIVATE in repos: |
|||
yield addon, PRIVATE |
|||
continue |
|||
# Odoo core addons are least important |
|||
if repos == {CORE}: |
|||
yield addon, CORE |
|||
continue |
|||
repos.discard(CORE) |
|||
# Other addons fall in between |
|||
if filtered and len(repos) != 1: |
|||
raise AddonsConfigError( |
|||
u"Addon {} defined in several repos {}".format(addon, repos) |
|||
) |
|||
for repo in repos: |
|||
yield addon, repo |
|||
|
|||
|
|||
try: |
|||
from shutil import which |
|||
except ImportError: |
|||
# Custom which implementation for Python 2 |
|||
def which(binary): |
|||
return check_output(["which", binary]).strip() |
@ -0,0 +1,119 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from collections import OrderedDict |
|||
from os.path import exists |
|||
from subprocess import check_call |
|||
|
|||
from doodbalib import logger |
|||
|
|||
|
|||
class Installer(object): |
|||
"""Base class to install packages with some package system.""" |
|||
|
|||
_cleanup_commands = [] |
|||
_install_command = None |
|||
_remove_command = None |
|||
|
|||
def __init__(self, file_path): |
|||
self.file_path = file_path |
|||
self._requirements = self.requirements() |
|||
|
|||
def _run_command(self, command): |
|||
logger.info("Executing: %s", command) |
|||
return check_call(command, shell=isinstance(command, str)) |
|||
|
|||
def cleanup(self): |
|||
"""Remove cache and other garbage produced by the installer engine.""" |
|||
for command in self._cleanup_commands: |
|||
self._run_command(command) |
|||
|
|||
def install(self): |
|||
"""Install the requirements from the given file.""" |
|||
if self._requirements: |
|||
return not self._run_command(self._install_command + self._requirements) |
|||
else: |
|||
logger.info("No installable requirements found in %s", self.file_path) |
|||
return False |
|||
|
|||
def remove(self): |
|||
"""Uninstall the requirements from the given file.""" |
|||
if not self._remove_command: |
|||
return |
|||
if self._requirements: |
|||
self._run_command(self._remove_command + self._requirements) |
|||
else: |
|||
logger.info("No removable requirements found in %s", self.file_path) |
|||
|
|||
def requirements(self): |
|||
"""Get a list of requirements from the given file.""" |
|||
requirements = [] |
|||
try: |
|||
with open(self.file_path, "r") as fh: |
|||
for line in fh: |
|||
line = line.strip() |
|||
if not line or line.startswith("#"): |
|||
continue |
|||
requirements += line.split() |
|||
except IOError: |
|||
# No requirements file |
|||
pass |
|||
return requirements |
|||
|
|||
|
|||
class AptInstaller(Installer): |
|||
_cleanup_commands = [["apt-get", "-y", "autoremove"], "rm -Rf /var/lib/apt/lists/*"] |
|||
_install_command = [ |
|||
"apt-get", |
|||
"-o", |
|||
"Dpkg::Options::=--force-confdef", |
|||
"-o", |
|||
"Dpkg::Options::=--force-confold", |
|||
"-y", |
|||
"--no-install-recommends", |
|||
"install", |
|||
] |
|||
_remove_command = ["apt-get", "purge", "-y"] |
|||
|
|||
def _dirty(self): |
|||
return exists("/var/lib/apt/lists/lock") |
|||
|
|||
def cleanup(self): |
|||
if self._dirty(): |
|||
super(AptInstaller, self).cleanup() |
|||
|
|||
def install(self): |
|||
if not self._dirty() and self._requirements: |
|||
self._run_command(["apt-get", "update"]) |
|||
return super(AptInstaller, self).install() |
|||
|
|||
|
|||
class GemInstaller(Installer): |
|||
_cleanup_commands = ["rm -Rf ~/.gem /var/lib/gems/*/cache/"] |
|||
_install_command = ["gem", "install", "--no-document", "--no-update-sources"] |
|||
|
|||
|
|||
class NpmInstaller(Installer): |
|||
_cleanup_commands = ["rm -Rf ~/.npm /tmp/*"] |
|||
_install_command = ["npm", "install", "-g"] |
|||
|
|||
|
|||
class PipInstaller(Installer): |
|||
_install_command = ["pip", "install", "--no-cache-dir", "-r"] |
|||
|
|||
def requirements(self): |
|||
"""Pip will use its ``--requirements`` feature.""" |
|||
return [self.file_path] if exists(self.file_path) else [] |
|||
|
|||
|
|||
INSTALLERS = OrderedDict( |
|||
[ |
|||
("apt", AptInstaller), |
|||
("gem", GemInstaller), |
|||
("npm", NpmInstaller), |
|||
("pip", PipInstaller), |
|||
] |
|||
) |
|||
|
|||
|
|||
def install(installer, file_path): |
|||
"""Perform a given type of installation from a given file.""" |
|||
return INSTALLERS[installer](file_path).install() |
Write
Preview
Loading…
Cancel
Save
Reference in new issue