You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

144 lines
4.2 KiB

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