Exemplo n.º 1
0
def hook_alchemy_genproject(task, args):
    script_path = os.path.join(dragon.ALCHEMY_HOME, "scripts", "genproject",
                               "genproject.py")
    subscript_name = task.name.replace("gen", "")

    if "-h" in args or "--help" in args:
        dragon.exec_cmd("%s %s -h" % (script_path, subscript_name))
        dragon.LOGW(
            "Note: The -b option and dump_xml file are automatically given.")
        raise dragon.TaskExit()

    dump_xml = dragon.gen_alchemy_dump_xml()
    cmd_args = [
        script_path, subscript_name, "-b",
        "'-p %s-%s -A'" % (dragon.PRODUCT, dragon.VARIANT), dump_xml,
        " ".join(args)
    ]
    dragon.exec_cmd(" ".join(cmd_args))
Exemplo n.º 2
0
def get_json_config(json_file="product_config.json", additional_paths=None):
    search_paths = [
        os.path.join(dragon.OUT_DIR),
        os.path.join(dragon.WORKSPACE_DIR,"products",
            dragon.PRODUCT, dragon.VARIANT, "config"),
        os.path.join(dragon.WORKSPACE_DIR,"products",
            dragon.PRODUCT),
        ]
    if isinstance(additional_paths, list):
        search_paths.extend(additional_paths)

    try:
        cfp = ConfigFileParser(json_file, search_paths)
    except IOError:
        dragon.LOGW("%s file not found", json_file)
        cfp = None
    except ValueError as ex:
        raise dragon.TaskError(ex.message)
    return cfp
Exemplo n.º 3
0
def relative_symlink(src, dest):
    if dragon.WORKSPACE_DIR in dragon.OUT_DIR:
        for _file_check in [src, dest]:
            if dragon.WORKSPACE_DIR not in os.path.realpath(_file_check):
                raise IOError("'%s' is not part of the workspace." %
                        _file_check)
    else:
        for _file_check in [src, dest]:
            if dragon.WORKSPACE_DIR not in os.path.realpath(_file_check):
                dragon.LOGW("'%s' is not part of the workspace." %
                        _file_check)

    if os.path.lexists(dest):
        if not os.path.islink(dest):
            raise IOError("'%s' should not be a regular file/directory" % dest)
        dragon.exec_cmd("rm -f %s" % dest)
    makedirs(os.path.dirname(dest))
    dragon.exec_cmd("ln -fs %s %s" %
            (os.path.relpath(src, os.path.dirname(dest)), dest))
Exemplo n.º 4
0
def _hook_alchemy_genproject_android(task, args, abi):
    script_path = os.path.join(dragon.ALCHEMY_HOME, 'scripts', 'genproject',
                               'genproject.py')
    subscript_name = task.name.replace('gen', '')

    if '-h' in args or '--help' in args:
        dragon.exec_cmd('{} {} -h'.format(script_path, subscript_name))
        dragon.LOGW(
            'Note: The -b option and dump_xml file are automatically given.')
        raise dragon.TaskExit()

    dragon.exec_cmd(cmd='./build.sh -p {}-{} --abis {} -A dump-xml'.format(
        dragon.PRODUCT, dragon.VARIANT, abi))
    dump_xml = os.path.join(dragon.OUT_DIR, abi, 'alchemy-database.xml')
    cmd_args = [
        script_path, subscript_name, '-b',
        "'-p {}-{} --abis {} -A'".format(dragon.PRODUCT, dragon.VARIANT,
                                         abi), dump_xml, ' '.join(args)
    ]
    dragon.exec_cmd(' '.join(cmd_args))
Exemplo n.º 5
0
def setup_globals(options):
    os.environ["LANG"] = "C"

    # Setup product/variant
    dragon.PRODUCT = options.product
    dragon.VARIANT = options.variant
    dragon.PRODUCT_DIR = options.product_dir
    dragon.VARIANT_DIR = options.variant_dir

    if not dragon.PARROT_BUILD_PROP_PRODUCT:
        dragon.PARROT_BUILD_PROP_PRODUCT = dragon.PRODUCT
    if not dragon.PARROT_BUILD_PROP_VARIANT:
        dragon.PARROT_BUILD_PROP_VARIANT = dragon.VARIANT

    # Initialize default build properties, can be overwritten by product configuration
    if options.build_id:
        dragon.PARROT_BUILD_PROP_UID = options.build_id

    if not dragon.PARROT_BUILD_PROP_VERSION and not dragon.PARROT_BUILD_PROP_UID:
        # Use the version indicated in next-version if available
        next_version_file = None
        if dragon.PRODUCT_DIR:
            next_version_file = os.path.join(dragon.PRODUCT_DIR,
                                             "next-version")
        if next_version_file and os.path.exists(next_version_file):
            with open(next_version_file, "r") as fd:
                dragon.PARROT_BUILD_PROP_VERSION = fd.read().strip("\n")
        else:
            dragon.PARROT_BUILD_PROP_VERSION = "0.0.0"

    if not dragon.PARROT_BUILD_PROP_VERSION:
        # Remove part before version num
        _match = dragon.version_match(dragon.PARROT_BUILD_PROP_UID,
                                      prefix=True,
                                      suffix=True)
        if _match:
            # Recover the UID part with possible details (MAJOR.MINOR.RELEASE[-specification])
            (_uid, _version) = _match
            _version = _uid[_uid.find(_version):]
        else:
            _version = "0.0.0"
            dragon.LOGW("Unable to extract version from UID (%s)." %
                        dragon.PARROT_BUILD_PROP_UID)
        dragon.PARROT_BUILD_PROP_VERSION = _version

    if not dragon.PARROT_BUILD_PROP_UID:
        dragon.PARROT_BUILD_PROP_UID = "%s-%s-%s-%s" % (
            dragon.PARROT_BUILD_PROP_PRODUCT,
            dragon.PARROT_BUILD_PROP_VARIANT, dragon.PARROT_BUILD_PROP_VERSION,
            datetime.datetime.now().strftime("%Y%m%d-%H%M"))

    # Setup directories
    if not dragon.OUT_ROOT_DIR:
        dragon.OUT_ROOT_DIR = os.path.join(dragon.WORKSPACE_DIR, "out")
    if not dragon.OUT_DIR:
        dragon.OUT_DIR = dragon.get_out_dir(dragon.PRODUCT, dragon.VARIANT)
    dragon.BUILD_DIR = os.path.join(dragon.OUT_DIR, "build")
    dragon.STAGING_DIR = os.path.join(dragon.OUT_DIR, "staging")
    dragon.FINAL_DIR = os.path.join(dragon.OUT_DIR, "final")
    dragon.IMAGES_DIR = os.path.join(dragon.OUT_DIR, "images")

    # Directory where alchemy is (and re-export it in environment)
    if not dragon.ALCHEMY_HOME:
        dragon.ALCHEMY_HOME = os.path.join(dragon.WORKSPACE_DIR, "build",
                                           "alchemy")
    if not os.path.isdir(dragon.ALCHEMY_HOME):
        logging.warning("Alchemy not found at '%s'", dragon.ALCHEMY_HOME)
    os.environ["ALCHEMY_HOME"] = dragon.ALCHEMY_HOME

    # Directory where police is (and re-export it in environment)
    if not dragon.POLICE_HOME:
        dragon.POLICE_HOME = os.path.join(dragon.WORKSPACE_DIR, "build",
                                          "police")
    if not os.path.isdir(dragon.POLICE_HOME) and options.police:
        logging.warning("Police not found at '%s'", dragon.POLICE_HOME)
    os.environ["POLICE_HOME"] = dragon.POLICE_HOME
    dragon.POLICE_OUT_DIR = os.path.join(dragon.OUT_DIR, "police")
    dragon.POLICE_SPY_LOG = os.path.join(dragon.POLICE_OUT_DIR,
                                         "police-spy.log")
    dragon.POLICE_PROCESS_LOG = os.path.join(dragon.POLICE_OUT_DIR,
                                             "police-process.log")

    # Setup spy if needed
    if options.police and not options.police_no_spy:
        setup_police_spy()
Exemplo n.º 6
0
def generate_release_archive(release_id, additional_files=None,
        product_config="product_config.json", warn_on_overwrite=False,
        previous_manifest=None):

    # Disable police while generating the archive
    os.environ["POLICE_HOOK_DISABLED"] = "1"

    # Init final directories and sources
    release_dir = os.path.join(dragon.OUT_DIR, "release-" + release_id)
    release_config_dir = os.path.join(release_dir, "config")

    # Create base list of files for release
    archive_content = [
        {
            "src": os.path.join(dragon.OUT_DIR,
                "symbols-%s-%s.tar" % (dragon.PRODUCT, dragon.VARIANT)),
            "dest": os.path.join(release_dir, "symbols.tar"),
        },
        {
            "src": os.path.join(dragon.OUT_DIR,
                "sdk-%s-%s.tar.gz" % (dragon.PRODUCT, dragon.VARIANT)),
            "dest": os.path.join(release_dir, "sdk.tar.gz"),
        },
        {
            "src": os.path.join(dragon.OUT_DIR, "images"),
            "dest": os.path.join(release_dir, "images"),
        },
        {
            "src": os.path.join(dragon.OUT_DIR, "staging", "etc", "build.prop"),
            "dest": os.path.join(release_dir, "build.prop"),
        },
        {
            "src": os.path.join(dragon.OUT_DIR, "build", "linux", ".config"),
            "dest": os.path.join(release_config_dir, "linux.config"),
            "mandatory": False
        },
        {
            "src": os.path.join(dragon.OUT_DIR, "global.config"),
            "dest": os.path.join(release_config_dir, "global.config"),
        },
        {
            "src": os.path.join(dragon.WORKSPACE_DIR, "build", "dragon_build",
                "pinst_wrapper.py"),
            "dest": os.path.join(release_dir, "pinst_wrapper.py"),
        },
        {
            "src": os.path.join(dragon.OUT_DIR, "police"),
            "dest": os.path.join(release_dir, "police"),
            "mandatory": False
        },
        {
            "src": os.path.join(dragon.OUT_DIR, "oss-packages"),
            "dest": os.path.join(release_dir, "oss-packages"),
            "mandatory": False
        },
    ]

    release_manifest = "release.xml"
    if not previous_manifest:
        previous_manifest = release_manifest

    cfp = get_json_config(product_config)
    release_section = None
    if cfp:
        release_section = cfp.get_section("release")
    # As this section is optional, we add it only if present
    if release_section:
        json_filepath = cfp.get_config_filepath()
        archive_content.append({
            "src": json_filepath,
            "dest": os.path.join(release_dir, "product_config.json")
            })
        # Export current variables as environment to be used with json
        for _envvar in ["PARROT_BUILD_PROP_GROUP", "PARROT_BUILD_PROP_PROJECT",
                "PARROT_BUILD_PROP_PRODUCT", "PARROT_BUILD_PROP_VARIANT",
                "PARROT_BUILD_PROP_REGION", "PARROT_BUILD_PROP_UID",
                "PARROT_BUILD_PROP_VERSION", "WORKSPACE_DIR", "OUT_DIR" ]:
            os.environ[_envvar] = getattr(dragon, _envvar)

        json_add_files = release_section.get("additional_files", [])
        release_manifest = release_section.get("manifest_name",
                release_manifest)
        # In case of a previous manifest with different name
        # between two versions (It serves only for changelog)
        previous_manifest = release_section.get("previous_manifest",
                release_manifest)
        for _elem in json_add_files:
            archive_content.append({
                "src": os.path.expandvars(_elem["src"]),
                "dest": os.path.join(
                    release_dir, os.path.expandvars(_elem["dest"])),
                "mandatory":_elem.get("mandatory", True),
            })
        warn_on_overwrite = release_section.get("warn_on_overwrite", False)
    # For files provided by function calling
    if isinstance(additional_files, list):
        archive_content.extend(additional_files)

    for _elem in archive_content:
        src = _elem["src"]
        dest = _elem["dest"]
        # Optional field
        mandatory = _elem.get("mandatory", True)
        if os.path.exists(dest):
            if warn_on_overwrite:
                dragon.LOGW("%s will be overwritten.", dest)
            os.unlink(dest)
        # This function already do the parent dirname creation when needed
        if os.path.exists(src):
            relative_symlink(src, dest)
        else:
            if mandatory and not dragon.OPTIONS.dryrun:
                raise dragon.TaskError("%s file is absent. Cannot generate release." % src)

    # Normally it is also found in final/etc but in case the product does not
    # have this feature because of the task being overloaded.
    gen_manifest_xml(os.path.join(release_dir, "manifest.xml"))
    # Too bad if absent
    # Can raise error on first release, where no previous manifest is found
    try:
        dragon.exec_cmd("repo diffmanifest --full --graph --no-color "
                "+:{previous_xml_name} {xml_name} > {output}".format(
                    output=os.path.join(release_dir, "changelog.txt"),
                    xml_name=release_manifest,
                    previous_xml_name=previous_manifest)
                )
    except:
        pass

    # Generate md5sum file
    dragon.exec_dir_cmd(dirpath=release_dir, cmd="md5sum $(find -follow -type f) > md5sum.txt")

    # Archive the release
    dragon.exec_cmd("tar -C %s -hcf %s.tar ." % (release_dir, release_dir))

    # Re-enable police while generating the archive
    del os.environ["POLICE_HOOK_DISABLED"]

    # Do not move in workspace if output dir is somewhere else (jenkins for example)
    if dragon.OUT_DIR.startswith(dragon.WORKSPACE_DIR):
        dragon.exec_cmd("mv -f %s.tar %s " % (release_dir,
                os.path.join(dragon.WORKSPACE_DIR, "%s.tar" % dragon.PARROT_BUILD_PROP_UID)))