示例#1
0
文件: build.py 项目: equinor/komodo
def pip_install(pkg,
                ver,
                pkgpath,
                data,
                prefix,
                dlprefix,
                pip="pip",
                *args,
                **kwargs):
    ver = strip_version(ver)
    if ver == LATEST_PACKAGE_ALIAS:
        ver = latest_pypi_version(pkg)
    cmd = [
        pip,
        "install {}=={}".format(pkg, strip_version(ver)),
        "--root {}".format(kwargs["fakeroot"]),
        "--prefix {}".format(prefix),
        "--no-index",
        "--no-deps",
        "--ignore-installed",
        "--cache-dir {}".format(dlprefix),
        "--find-links {}".format(dlprefix),
        kwargs.get("makeopts", ""),
    ]

    print('Installing {} ({}) from pip'.format(pkg, ver))
    shell(cmd)
示例#2
0
def grab(path, filename=None, version=None, protocol=None, pip='pip'):
    # guess protocol if it's obvious from the url (usually is)
    if protocol is None:
        protocol = path.split(':')[0]

    if protocol in ('http', 'https', 'ftp'):
        shell('wget --quiet {} -O {}'.format(path, filename))
    elif protocol in ('git'):
        shell("git clone "
              "-b {version} "
              "-q --recursive "
              "-- {path} {filename}"
              "".format(
                  version=strip_version(version),
                  path=path,
                  filename=filename,
              ))

    elif protocol in ('nfs', 'fs-ln'):
        shell('cp --recursive --symbolic-link {} {}'.format(path, filename))

    elif protocol in ('fs-cp'):
        shell('cp --recursive {} {}'.format(path, filename))

    elif protocol in ('rsync'):
        shell('rsync -a {}/ {}'.format(path, filename))
    else:
        raise NotImplementedError('Unknown protocol {}'.format(protocol))
示例#3
0
文件: cli.py 项目: equinor/komodo
def _main(args):
    args.prefix = os.path.abspath(args.prefix)

    data = Data(extra_data_dirs=args.extra_data_dirs)

    if args.download or (not args.build and not args.install):
        git_hashes = fetch(args.pkgs,
                           args.repo,
                           outdir=args.cache,
                           pip=args.pip)

    if args.download and not args.build:
        sys.exit(0)

    # append root to the temporary build dir, as we want a named root/
    # directory as the distribution root, organised under the distribution name
    # (release)
    tmp_prefix = os.path.join(os.path.join(args.prefix), args.release, "root")
    fakeroot = os.path.abspath(args.release)
    if args.build or not args.install:
        make(
            args.pkgs,
            args.repo,
            data,
            prefix=tmp_prefix,
            dlprefix=args.cache,
            builddir=args.tmp,
            jobs=args.jobs,
            cmk=args.cmake,
            pip=args.pip,
            virtualenv=args.virtualenv,
            fakeroot=fakeroot,
        )
        shell("mv {} {}".format(args.release + tmp_prefix, args.release))
        shell("rmdir -p --ignore-fail-on-non-empty {}".format(
            os.path.dirname(args.release + tmp_prefix)))

    if args.build and not args.install:
        sys.exit(0)

    # create the enable script
    for tmpl, target in [("enable.in", "enable"),
                         ("enable.csh.in", "enable.csh")]:
        # TODO should args.release be release_path?
        with open("{}/{}".format(args.release, target), "w") as f:
            f.write(
                shell([
                    "m4 {}".format(data.get("enable.m4")),
                    "-D komodo_prefix={}".format(tmp_prefix),
                    "-D komodo_pyver={}".format(args.pyver),
                    "-D komodo_release={}".format(args.release),
                    data.get(tmpl),
                ]).decode("utf-8"))

    with open(args.locations_config) as defs, open(
            os.path.join(args.release, "local"), "w") as local_activator, open(
                os.path.join(args.release, "local.csh"),
                "w") as local_csh_activator:
        defs = yml.safe_load(defs)
        local.write_local_activators(data, defs, local_activator,
                                     local_csh_activator)

    releasedoc = os.path.join(args.release, args.release)
    with open(releasedoc, "w") as y:
        release = {}
        for pkg, ver in args.pkgs.items():
            entry = args.repo[pkg][ver]
            maintainer = args.repo[pkg][ver]["maintainer"]
            if ver == LATEST_PACKAGE_ALIAS:
                ver = latest_pypi_version(entry.get("pypi_package_name", pkg))
            elif args.repo[pkg][ver].get("fetch") == "git":
                ver = git_hashes[pkg]
            release[pkg] = {
                "version": ver,
                "maintainer": maintainer,
            }
        yml.dump(release, y, default_flow_style=False)

    if args.dry_run:
        return

    print("Installing {} to {}".format(args.release, args.prefix))
    install_root = os.path.join(args.prefix, args.release, "root")

    shell("{1} {0} .{0} {0}".format(args.release, args.renamer))
    shell("rsync -a .{} {}".format(args.release, args.prefix), sudo=args.sudo)

    if os.path.exists("{1}/{0}".format(args.release, args.prefix)):
        shell(
            "{2} {0} {0}.delete {1}/{0}".format(args.release, args.prefix,
                                                args.renamer),
            sudo=args.sudo,
        )

    shell(
        "{2} .{0} {0} {1}/.{0}".format(args.release, args.prefix,
                                       args.renamer),
        sudo=args.sudo,
    )
    shell("rm -rf {1}/{0}.delete".format(args.release, args.prefix),
          sudo=args.sudo)

    if args.tmp:
        # Allows e.g. pip to use this folder as tmpfolder, instead of in some
        # cases falling back to /tmp, which is undesired when building on nfs.
        os.environ["TMPDIR"] = args.tmp

    print('Fixup #! in pip-provided packages if bin exist')
    release_path = os.path.join(args.prefix, args.release)
    release_root = os.path.join(release_path, "root")
    for pkg, ver in args.pkgs.items():
        current = args.repo[pkg][ver]
        if current["make"] != "pip":
            continue

        package_name = current.get("pypi_package_name", pkg)
        if ver == LATEST_PACKAGE_ALIAS:
            ver = latest_pypi_version(package_name)
        shell_input = [
            args.pip,
            "install {}=={}".format(package_name, strip_version(ver)),
            "--prefix",
            release_root,
            "--no-index",
            "--no-deps",
            "--ignore-installed",
            "--cache-dir {}".format(args.cache),
            "--find-links {}".format(args.cache),
        ]
        shell_input.append(current.get("makeopts"))

        print(shell(shell_input, sudo=args.sudo))

    fixup_python_shebangs(args.prefix, args.release)

    switch.create_activator_switch(data, args.prefix, args.release)

    # run any post-install scripts on the release
    if args.postinst:
        shell([args.postinst, release_path])

    print("running", "find {} -name '*.pyc' -delete".format(release_root))
    shell("find {} -name '*.pyc' -delete".format(release_root))

    print("Setting permissions",
          [data.get("set_permissions.sh"), release_path])
    shell([data.get("set_permissions.sh"), release_path])
示例#4
0
def fetch(pkgs, repo, outdir=".", pip="pip", git="git"):
    missingpkg = [pkg for pkg in pkgs if pkg not in repo]
    missingver = [
        pkg for pkg, ver in pkgs.items()
        if pkg in repo and ver not in repo[pkg]
    ]

    if missingpkg:
        eprint('Packages requested, but not found in the repository:')
        eprint('missingpkg: {}'.format(','.join(missingpkg)))

    for pkg in missingver:
        eprint('missingver: missing version for {}: {} requested, found: {}'.
               format(pkg, pkgs[pkg], ','.join(repo[pkg].keys())))

    if missingpkg or missingver:
        return

    if outdir and not os.path.exists(outdir):
        os.mkdir(outdir)

    pypi_packages = []

    with pushd(outdir):
        for pkg, ver in pkgs.items():

            current = repo[pkg][ver]
            if "pypi_package_name" in current and current["make"] != "pip":
                raise ValueError(
                    "pypi_package_name is only valid when building with pip")

            url = current.get("source")
            protocol = current.get("fetch")
            pkg_alias = current.get("pypi_package_name", pkg)
            name = "{} ({}): {}".format(pkg_alias, ver, url)
            pkgname = "{}-{}".format(pkg_alias, ver)

            if url is None and protocol is None:
                package_folder = os.path.abspath(pkgname)
                print('Nothing to fetch for {}, but created folder {}'.format(
                    pkgname, package_folder))
                os.mkdir(pkgname)
                continue

            dst = pkgname

            spliturl = url.split('?')[0].split('.')
            ext = spliturl[-1]

            if len(spliturl) > 1 and spliturl[-2] == 'tar':
                ext = 'tar.{}'.format(spliturl[-1])

            if ext in [
                    'rpm', 'tar', 'gz', 'tgz', 'tar.gz', 'tar.bz2', 'tar.xz'
            ]:
                dst = '{}.{}'.format(dst, ext)

            if url == "pypi":
                print("Defering download of {}".format(name))
                pypi_packages.append(normalize_filename(strip_version(dst)))
                continue

            print('Downloading {}'.format(name))
            grab(url,
                 filename=dst,
                 version=ver,
                 protocol=protocol,
                 pip=pip,
                 git=git)

            if ext in ['tgz', 'tar.gz', 'tar.bz2', 'tar.xz']:
                print('Extracting {} ...'.format(dst))
                topdir = shell(
                    ' tar -xvf {}'.format(dst)).decode("utf-8").split()[0]
                normalised_dir = topdir.split('/')[0]

                if not os.path.exists(pkgname):
                    print('Creating symlink {} -> {}'.format(
                        normalised_dir, pkgname))
                    os.symlink(normalised_dir, pkgname)

        print('Downloading {} pypi packages'.format(len(pypi_packages)))
        shell([
            pip, 'download', '--no-deps', '--dest .', " ".join(pypi_packages)
        ])