Exemplo n.º 1
0
    def package(self):
        """Package pypi module with 'self.name'"""
        if not self.version and not self.source_folder:
            return runez.abort(
                "Need either source_folder or version in order to package",
                fatal=(True, []))

        if not self.version:
            setup_py = os.path.join(self.source_folder, "setup.py")
            if not os.path.isfile(setup_py):
                return runez.abort("No setup.py in %s",
                                   short(self.source_folder),
                                   fatal=(True, []))
            self.version = system.run_python(setup_py,
                                             "--version",
                                             dryrun=False,
                                             fatal=False,
                                             package_name=self.name)
            if not self.version:
                return runez.abort("Could not determine version from %s",
                                   short(setup_py),
                                   fatal=(True, []))

        self.pip_wheel()

        self.refresh_entry_points()
        runez.ensure_folder(self.dist_folder, folder=True)
        template = "{name}" if self.source_folder else "{name}-{version}"
        self.packaged = []
        self.effective_package(template)
Exemplo n.º 2
0
 def represented(self):
     """
     :return str: Human readable representation of these settings
     """
     if not self.contents:
         return "    - %s: # empty" % short(self.path)
     result = ["    - %s:" % short(self.path)]
     add_representation(result, self.contents, indent="      ")
     return "\n".join(result)
Exemplo n.º 3
0
 def get_definition(self, key):
     """
     :param str key: Key to look up
     :return Definition|None: Definition corresponding to 'key' in this settings file, if any
     """
     if not key:
         return None
     if "." in key:
         prefix, _, leaf = key.rpartition(".")
         definition = self.get_definition(prefix)
         if not definition:
             return None
         if isinstance(definition.value, dict):
             value = definition.value.get(leaf)
             if value is not None:
                 return Definition(value, self, key)
             return None
         if definition.value is not None:
             LOG.debug("'%s' is of type %s (not a dict) in '%s'", prefix,
                       type(definition.value), short(self.path))
         return None
     value = self.contents.get(key)
     if value is not None:
         return Definition(value, self, key)
     return None
Exemplo n.º 4
0
def test_custom_settings():
    s = pickley.settings.Settings(sample_path("custom"))
    s.load_config()

    assert str(s) == "[4] base: %s" % short(s.base.path)
    assert str(s.defaults) == "defaults"
    assert str(s.base) == "base: %s" % short(s.base.path)
    assert s.get_definition("") is None
    assert s.resolved_definition("") is None
    assert s.resolved_value("foo") is None

    p = s.base.full_path("foo/bar")
    assert s.base.relative_path(p) == "foo/bar"

    d = s.resolved_definition("delivery", package_name="dict_sample")
    assert str(d) == "config.json:delivery.copy"

    assert s.resolved_value("delivery", package_name="tox") == "venv"
    assert s.resolved_value("delivery", package_name="virtualenv") == "wrap"

    assert s.resolved_value("packager",
                            package_name="tox") == system.VENV_PACKAGER
    assert s.resolved_value("packager", package_name="virtualenv") == "pex"

    assert s.resolved_packages("bundle:dev") == ["tox", "twine"]
    assert s.get_value("bundle.dev") == ["tox", "twine"]
    assert s.get_value("bundle.dev2") == ["tox", "twine", "pipenv"]

    old_width = pickley.settings.REPRESENTATION_WIDTH
    pickley.settings.REPRESENTATION_WIDTH = 40
    actual = s.represented(include_defaults=False).replace(
        short(s.base.path), "{base}")
    assert actual == EXPECTED_REPRESENTATION.strip()
    pickley.settings.REPRESENTATION_WIDTH = old_width

    s.cli.contents["packager"] = "copy"
    d = s.resolved_definition("packager")
    assert d.value == "copy"
    assert d.source is s.cli
    d = s.get_definition("packager")
    assert d.value == "copy"
    assert d.source is s.cli

    assert s.install_timeout == 2
    assert s.version_check_seconds == 60
Exemplo n.º 5
0
 def sanity_check(self, args):
     """
     :param str args: Args to run as sanity-check against all packaged exes, example: "--version"
     """
     if args:
         for path in self.executables:
             output = runez.run(path, args)
             print("Sanity check: %s %s -> %s" %
                   (short(path), args, output))
Exemplo n.º 6
0
def uninstall_existing(target, fatal=True):
    """
    :param str target: Path to executable to auto-uninstall if needed
    :param bool|None fatal: Abort execution on failure if True
    :return int: 1 if successfully uninstalled, 0 if nothing to do, -1 if failed
    """
    handler = find_uninstaller(target)
    if handler:
        return handler(target, fatal=fatal)

    return runez.abort("Can't automatically uninstall %s", short(target), fatal=(fatal, -1))
Exemplo n.º 7
0
    def install(self, force=False):
        """
        :param bool force: If True, re-install even if package is already installed
        """
        try:
            self.internal_install(force=force)

        except SoftLockException as e:
            LOG.error("%s is currently being installed by another process" %
                      self.name)
            runez.abort("If that is incorrect, please delete %s.lock",
                        short(e.folder))
Exemplo n.º 8
0
def add_representation(result, data, indent=""):
    """
    :param list result: Where to add lines representing 'data'
    :param dict|list|str data: Data to represent
    :param str indent: Indentation to use
    """
    if not data:
        return
    if isinstance(data, list):
        for item in data:
            result.append("%s- %s" % (indent, short(item)))
        return
    if isinstance(data, dict):
        for key, value in sorted(data.items()):
            if isinstance(value, list):
                brief = runez.represented_args(value, separator=", ")
                if len(brief) < REPRESENTATION_WIDTH:
                    result.append("%s%s: [%s]" % (indent, short(key), brief))
                    continue
            if isinstance(value, (dict, list)):
                result.append("%s%s:" % (indent, short(key)))
                add_representation(result, value, indent="  %s" % indent)
            else:
                result.append("%s%s: %s" % (indent, short(key), short(value)))
        return
    result.append("%s- %s" % (indent, short(data)))
Exemplo n.º 9
0
def test_package(cli):
    pickley = system.SETTINGS.base.full_path("dist", "pickley", "bin",
                                             "pickley")
    expected_version = system.run_python(os.path.join(PROJECT, "setup.py"),
                                         "--version")

    # Package pickley as venv
    cli.expect_success(["package", "-d", "dist", PROJECT],
                       "Packaged %s successfully" % short(PROJECT))

    # Verify that it packaged OK, and is relocatable
    assert runez.is_executable(pickley)
    assert run_program(pickley, "--version") == expected_version
    assert runez.first_line(pickley).startswith("#!/usr/bin/env python")
Exemplo n.º 10
0
def main(ctx, debug, dryrun, base, index, config, python, delivery, packager):
    """
    Package manager for python CLIs
    """
    if any(opt in sys.argv
           for opt in ctx.help_option_names):  # pragma: no cover
        return

    if dryrun:
        debug = True

    if base:
        base = runez.resolved_path(base)
        if not os.path.exists(base):
            sys.exit("Can't use %s as base: folder does not exist" %
                     short(base))
        system.SETTINGS.set_base(base)

    if not dryrun and ctx.invoked_subcommand in AUDITED:
        file_location = system.SETTINGS.meta.full_path("audit.log")

    else:
        file_location = None

    runez.log.setup(
        debug=debug,
        dryrun=dryrun,
        greetings=":: {argv}",
        console_format="%(levelname)s %(message)s" if debug else "%(message)s",
        console_level=logging.WARNING,
        console_stream=sys.stderr,
        file_format=
        "%(asctime)s %(timezone)s [%(process)d] %(context)s%(levelname)s - %(message)s",
        file_level=logging.DEBUG,
        file_location=file_location,
        locations=None,
        rotate="size:500k",
        rotate_count=1,
    )
    runez.log.silence("pip")

    # Disable logging.config, as pip tries to get smart and configure all logging...
    logging.config.dictConfig = lambda x: None

    system.SETTINGS.load_config(config=config,
                                delivery=delivery,
                                index=index,
                                packager=packager)
    system.DESIRED_PYTHON = python
Exemplo n.º 11
0
def package(build, dist, symlink, relocatable, sanity_check, folder):
    """
    Package a project from source checkout
    """
    build = runez.resolved_path(build)
    dist = runez.resolved_path(dist)
    folder = runez.resolved_path(folder)

    system.SETTINGS.meta = meta_folder(build)

    if not os.path.isdir(folder):
        sys.exit("Folder %s does not exist" % short(folder))

    setup_py = os.path.join(folder, "setup.py")
    if not os.path.exists(setup_py):
        sys.exit("No setup.py in %s" % short(folder))

    with runez.CurrentFolder(folder):
        # Some setup.py's assume their working folder is the folder where they're in
        name = system.run_python(setup_py, "--name", fatal=False, dryrun=False)
        if not name:
            sys.exit("Could not determine package name from %s" %
                     short(setup_py))

    runez.Anchored.add(folder)
    p = PACKAGERS.resolved(name)
    p.build_folder = build
    p.dist_folder = dist
    p.relocatable = relocatable
    p.source_folder = folder
    p.package()
    p.create_symlinks(symlink)
    p.sanity_check(sanity_check)
    print("Packaged %s successfully, produced: %s" %
          (short(folder), runez.represented_args(p.executables)))
    runez.Anchored.pop(folder)
Exemplo n.º 12
0
def test_bogus_install(cli):
    cli.expect_failure("-b foo/bar settings",
                       "Can't use foo/bar as base: folder does not exist")

    cli.expect_failure("auto-upgrade foo", "not currently installed")
    cli.expect_failure("package foo/bar", "Folder", "does not exist")
    cli.expect_failure(["package", cli.context], "No setup.py")
    runez.touch(os.path.join(cli.context, "setup.py"))
    cli.expect_failure(["package", cli.context],
                       "Could not determine package name")

    cli.expect_success("-b{base} check",
                       "No packages installed",
                       base=cli.context)
    cli.expect_success("-b{base} list",
                       "No packages installed",
                       base=cli.context)

    cli.expect_success("settings -d", "base: %s" % short(cli.context))
Exemplo n.º 13
0
 def represented(self, include_defaults=True):
     """
     :param bool include_defaults: When True, include representation of defaults as well
     :return str: Human readable representation of these settings
     """
     result = [
         "settings:",
         "  base: %s" % short(self.base.path),
     ]
     if self.index:
         result.append("  index: %s" % self.index)
     result.append("")
     result.append("  config:")
     result.append(self.cli.represented())
     for child in self.children:
         result.append(child.represented())
     if include_defaults:
         result.append(self.defaults.represented())
     return "\n".join(result).strip()
Exemplo n.º 14
0
    def install(self, target, source):
        """
        :param str target: Full path of executable to deliver (<base>/<entry_point>)
        :param str source: Path to original executable being delivered (.pickley/<package>/...)
        """
        runez.delete(target, logger=None)
        if runez.DRYRUN:
            LOG.debug("Would %s %s (source: %s)", self.implementation_name,
                      short(target), short(source))
            return

        if not os.path.exists(source):
            runez.abort("Can't %s, source %s does not exist",
                        self.implementation_name, short(source))

        try:
            LOG.debug("Delivering %s %s -> %s", self.implementation_name,
                      short(target), short(source))
            self._install(target, source)

        except Exception as e:
            runez.abort("Failed %s %s: %s", self.implementation_name,
                        short(target), e)
Exemplo n.º 15
0
def settings(diagnostics):
    """
    Show settings
    """
    if diagnostics:
        prefix = getattr(sys, "prefix", None)
        real_prefix = getattr(sys, "real_prefix", None)
        print("python         : %s" %
              short(system.target_python(desired=system.INVOKER, fatal=None),
                    meta=False))
        print("sys.executable : %s" % short(sys.executable, meta=False))
        print("sys.prefix     : %s" % short(prefix, meta=False))
        if real_prefix:
            print("sys.real_prefix: %s" % short(real_prefix, meta=False))
        if not system.SETTINGS.meta.path.startswith(
                system.PICKLEY_PROGRAM_PATH):
            print("pickley        : %s" %
                  short(system.PICKLEY_PROGRAM_PATH, meta=False))
        print("meta           : %s" %
              short(system.SETTINGS.meta.path, meta=False))
        print("")

    print(system.SETTINGS.represented())
Exemplo n.º 16
0
def test_settings(cli):
    cli.expect_success("settings -d", "settings:",
                       "base: %s" % short(system.SETTINGS.base.path))
Exemplo n.º 17
0
 def __repr__(self):
     return short(self.path)
Exemplo n.º 18
0
 def __repr__(self):
     return "%s:%s" % (short(self.source), self.key)
Exemplo n.º 19
0
def move(source, destination):
    """
    Copy file or folder, relocate venvs accordingly (if any)
    """
    system.move(source, destination)
    print("Moved %s -> %s" % (short(source), short(destination)))