|
|
#!/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
|