Ejemplo n.º 1
0
 def test_default_exists_dev_exists_dev_only(self):
     with temp_chdir() as d:
         file1 = os.path.join(d, 'requirements.txt')
         file2 = os.path.join(d, 'requirementss.txt')
         create_file(file1)
         create_file(file2)
         assert get_requirements_file(d, dev=True) == file2
Ejemplo n.º 2
0
def uninstall(packages, env_name, global_uninstall, dev, quiet, yes):
    """If the option --env is supplied, the uninstall will be applied using
    that named virtual env. Unless the option --global is selected, the
    uninstall will only affect the current user. Of course, this will have
    no effect if a virtual env is in use. The desired name of the admin
    user can be set with the `_DEFAULT_ADMIN_` environment variable.

    With no packages selected, this will uninstall using a `requirements.txt`
    or a dev version of that in the current directory.
    """
    if not packages:
        reqs = get_requirements_file(os.getcwd(), dev=dev)
        if not reqs:
            click.echo('Unable to locate a requirements file.')
            sys.exit(1)

        packages = ['-r', reqs]

    # Windows' `runas` allows only a single argument for the
    # command so we catch this case and turn our command into
    # a string later.
    windows_admin_command = None

    if yes:  # no cov
        packages = ['-y', *packages]

    if env_name:
        venv_dir = os.path.join(VENV_DIR, env_name)
        if not os.path.exists(venv_dir):
            click.echo('Virtual env named `{}` does not exist.'.format(env_name))
            sys.exit(1)

        with venv(venv_dir):
            command = [get_proper_pip(), 'uninstall', *packages] + (['-q'] if quiet else [])
            result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)
    else:
        command = [get_proper_pip(), 'uninstall'] + (['-q'] if quiet else [])

        if not venv_active() and global_uninstall:  # no cov
            if ON_WINDOWS:
                windows_admin_command = get_admin_command()
            else:
                command = get_admin_command() + command

        command.extend(packages)

        if windows_admin_command:  # no cov
            command = windows_admin_command + [' '.join(command)]

        result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)

    sys.exit(result.returncode)
Ejemplo n.º 3
0
def test(package, local, path, cov, merge, test_args, cov_args, global_exe,
         no_detect):
    """Runs tests using `pytest`, optionally checking coverage.

    The path is derived in the following order:

    \b
    1. The optional argument, which should be the name of a package
       that was installed via `hatch install -l` or `pip install -e`.
    2. The --local flag.
    3. The option --path, which can be a relative or absolute path.
    4. The current directory.

    If the path points to a package, it should have a `tests` directory.

    If a project is detected but there is no dedicated virtual env, it
    will be created and any dev requirements will be installed in it.

    \b
    $ git clone https://github.com/ofek/privy && cd privy
    $ hatch test -c
    ========================= test session starts ==========================
    platform linux -- Python 3.5.2, pytest-3.2.1, py-1.4.34, pluggy-0.4.0
    rootdir: /home/ofek/privy, inifile:
    plugins: xdist-1.20.0, mock-1.6.2, httpbin-0.0.7, forked-0.2, cov-2.5.1
    collected 10 items

    \b
    tests/test_privy.py ..........

    \b
    ====================== 10 passed in 4.34 seconds =======================

    \b
    Tests completed, checking coverage...

    \b
    Name                  Stmts   Miss Branch BrPart  Cover   Missing
    -----------------------------------------------------------------
    privy/__init__.py         1      0      0      0   100%
    privy/core.py            30      0      0      0   100%
    privy/utils.py           13      0      4      0   100%
    tests/__init__.py         0      0      0      0   100%
    tests/test_privy.py      57      0      0      0   100%
    -----------------------------------------------------------------
    TOTAL                   101      0      4      0   100%
    """
    if package:
        echo_waiting('Locating package...')
        path = get_editable_package_location(package)
        if not path:
            echo_failure('`{}` is not an editable package.'.format(package))
            sys.exit(1)
    elif local:
        echo_waiting('Locating package...')
        name, path = get_editable_package_location()
        if not name:
            if path is None:
                echo_failure('There are no local packages available.')
                sys.exit(1)
            else:
                echo_failure(
                    'There are multiple local packages available. Select '
                    'one with the optional argument.')
                sys.exit(1)
        echo_info('Package `{}` has been selected.'.format(name))
    elif path:
        possible_path = resolve_path(path)
        if not possible_path:
            echo_failure('Directory `{}` does not exist.'.format(path))
            sys.exit(1)
        path = possible_path
    else:
        path = os.getcwd()

    python_cmd = [sys.executable if global_exe else get_proper_python(), '-m']
    command = python_cmd.copy()

    if cov:
        command.extend(['coverage', 'run'])
        command.extend(cov_args.split() if cov_args is not None else (
            ['--parallel-mode'] if merge else []))
        command.append('-m')

    command.append('pytest')
    command.extend(test_args.split())

    try:  # no cov
        sys.stdout.fileno()
        testing = False
    except io.UnsupportedOperation:  # no cov
        testing = True

    # For testing we need to pipe because Click changes stdio streams.
    stdout = sys.stdout if not testing else subprocess.PIPE
    stderr = sys.stderr if not testing else subprocess.PIPE

    venv_dir = None
    if not (package
            or local) and not venv_active() and not no_detect and is_project():
        venv_dir = os.path.join(path, get_venv_folder())
        if not is_venv(venv_dir):
            echo_info('A project has been detected!')
            echo_waiting('Creating a dedicated virtual env... ', nl=False)
            create_venv(venv_dir)
            echo_success('complete!')

            with venv(venv_dir):
                echo_waiting('Installing this project in the virtual env...')
                install_packages(['-e', '.'])
                click.echo()

                echo_waiting('Ensuring pytest and coverage are available...')
                install_packages(['pytest', 'coverage'])
                click.echo()

                dev_requirements = get_requirements_file(path, dev=True)
                if dev_requirements:
                    echo_waiting(
                        'Installing test dependencies in the virtual env...')
                    install_packages(['-r', dev_requirements])
                    click.echo()

    with chdir(path):
        echo_waiting('Testing...')
        output = b''

        if venv_dir:
            with venv(venv_dir):
                test_result = subprocess.run(command,
                                             stdout=stdout,
                                             stderr=stderr,
                                             shell=NEED_SUBPROCESS_SHELL)
        else:
            test_result = subprocess.run(command,
                                         stdout=stdout,
                                         stderr=stderr,
                                         shell=NEED_SUBPROCESS_SHELL)
        output += test_result.stdout or b''
        output += test_result.stderr or b''

        if cov:
            echo_waiting('\nTests completed, checking coverage...\n')

            if merge:
                if venv_dir:
                    with venv(venv_dir):
                        result = subprocess.run(
                            python_cmd + ['coverage', 'combine', '--append'],
                            stdout=stdout,
                            stderr=stderr,
                            shell=NEED_SUBPROCESS_SHELL)
                else:
                    result = subprocess.run(
                        python_cmd + ['coverage', 'combine', '--append'],
                        stdout=stdout,
                        stderr=stderr,
                        shell=NEED_SUBPROCESS_SHELL)
                output += result.stdout or b''
                output += result.stderr or b''

            if venv_dir:
                with venv(venv_dir):
                    result = subprocess.run(
                        python_cmd + ['coverage', 'report', '--show-missing'],
                        stdout=stdout,
                        stderr=stderr,
                        shell=NEED_SUBPROCESS_SHELL)
            else:
                result = subprocess.run(
                    python_cmd + ['coverage', 'report', '--show-missing'],
                    stdout=stdout,
                    stderr=stderr,
                    shell=NEED_SUBPROCESS_SHELL)
            output += result.stdout or b''
            output += result.stderr or b''

    if testing:  # no cov
        click.echo(output.decode())

    sys.exit(test_result.returncode)
Ejemplo n.º 4
0
 def test_default_not_exists_dev_exists(self):
     with temp_chdir() as d:
         file = os.path.join(d, 'dev-requirements.txt')
         create_file(file)
         assert get_requirements_file(d) == file
Ejemplo n.º 5
0
 def test_default_not_exists(self):
     with temp_chdir() as d:
         assert get_requirements_file(d) is None
Ejemplo n.º 6
0
def update(packages, env_name, eager, all_packages, infra, global_install,
           force, dev, as_module, self, quiet):
    """If the option --env is supplied, the update will be applied using
    that named virtual env. Unless the option --global is selected, the
    update will only affect the current user. Of course, this will have
    no effect if a virtual env is in use. The desired name of the admin
    user can be set with the `_DEFAULT_ADMIN_` environment variable.

    When performing a global update, your system may use an older version
    of pip that is incompatible with some features such as --eager. To
    force the use of these features, use --force.

    With no packages nor options selected, this will update packages by
    looking for a `requirements.txt` or a dev version of that in the current
    directory.

    To update this tool, use the --self flag. After the update, you may want
    to press Enter. All other methods of updating will ignore `hatch`. See:
    https://github.com/pypa/pip/issues/1299
    """
    command = ['install', '--upgrade'] + (['-q'] if quiet else [])
    if not global_install or force:  # no cov
        command.extend(['--upgrade-strategy', 'eager' if eager else 'only-if-needed'])

    infra_packages = ['pip', 'setuptools', 'wheel']
    temp_dir = None

    # Windows' `runas` allows only a single argument for the
    # command so we catch this case and turn our command into
    # a string later.
    windows_admin_command = None

    if self:  # no cov
        as_module = True

    if env_name:
        venv_dir = os.path.join(VENV_DIR, env_name)
        if not os.path.exists(venv_dir):
            click.echo('Virtual env named `{}` does not exist.'.format(env_name))
            sys.exit(1)

        with venv(venv_dir):
            executable = (
                [sys.executable if self else get_proper_python(), '-m', 'pip']
                if as_module or (infra and ON_WINDOWS)
                else [get_proper_pip()]
            )
            command = executable + command
            if all_packages:
                installed_packages = infra_packages if infra else get_installed_packages()
            else:
                installed_packages = None
    else:
        venv_dir = None
        executable = (
            [sys.executable if self else get_proper_python(), '-m', 'pip']
            if as_module or (infra and ON_WINDOWS)
            else [get_proper_pip()]
        )
        command = executable + command
        if all_packages:
            installed_packages = infra_packages if infra else get_installed_packages()
        else:
            installed_packages = None

        if not venv_active():  # no cov
            if global_install:
                if ON_WINDOWS:
                    windows_admin_command = get_admin_command()
                else:
                    command = get_admin_command() + command
            else:
                command.append('--user')

    if self:  # no cov
        command.append('hatch')
        if venv_dir:
            with venv(venv_dir):
                subprocess.Popen(command, shell=NEED_SUBPROCESS_SHELL)
        else:
            subprocess.Popen(command, shell=NEED_SUBPROCESS_SHELL)
        sys.exit()
    elif infra:
        command.extend(infra_packages)
    elif all_packages:
        installed_packages = [
            package for package in installed_packages
            if package not in infra_packages and package != 'hatch'
        ]
        if not installed_packages:
            click.echo('No packages installed.')
            sys.exit(1)
        command.extend(installed_packages)
    elif packages:
        packages = [package for package in packages if package != 'hatch']
        if not packages:
            click.echo('No packages to install.')
            sys.exit(1)
        command.extend(packages)

    # When https://github.com/pypa/pipfile is finalized, we'll use it.
    else:
        reqs = get_requirements_file(os.getcwd(), dev=dev)
        if not reqs:
            click.echo('Unable to locate a requirements file.')
            sys.exit(1)

        with open(reqs, 'r') as f:
            lines = f.readlines()

        matches = []
        for line in lines:
            match = re.match(r'^[^=<>]+', line.lstrip())
            if match and match.group(0) == 'hatch':
                matches.append(line)

        if matches:
            for line in matches:
                lines.remove(line)

            temp_dir = TemporaryDirectory()
            reqs = os.path.join(temp_dir.name, basepath(reqs))

            with open(reqs, 'w') as f:
                f.writelines(lines)

        command.extend(['-r', reqs])

    if windows_admin_command:  # no cov
        command = windows_admin_command + [' '.join(command)]

    if venv_dir:
        with venv(venv_dir):
            result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)
    else:
        result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)

    if temp_dir is not None:
        temp_dir.cleanup()

    sys.exit(result.returncode)
Ejemplo n.º 7
0
def uninstall(packages, no_detect, env_name, global_uninstall, admin, dev, quiet, yes):
    """If the option --env is supplied, the uninstall will be applied using
    that named virtual env. Unless the option --global is selected, the
    uninstall will only affect the current user. Of course, this will have
    no effect if a virtual env is in use. The desired name of the admin
    user can be set with the `_DEFAULT_ADMIN_` environment variable.

    With no packages selected, this will uninstall using a `requirements.txt`
    or a dev version of that in the current directory.

    If no --env is chosen, this will attempt to detect a project and use its
    virtual env before resorting to the default pip. No project detection
    will occur if a virtual env is active.
    """
    if not packages:
        reqs = get_requirements_file(os.getcwd(), dev=dev)
        if not reqs:
            echo_failure('Unable to locate a requirements file.')
            sys.exit(1)

        packages = ['-r', reqs]

    # Windows' `runas` allows only a single argument for the
    # command so we catch this case and turn our command into
    # a string later.
    windows_admin_command = None

    if yes:  # no cov
        packages = ['-y', *packages]

    if env_name:
        venv_dir = os.path.join(VENV_DIR, env_name)
        if not os.path.exists(venv_dir):
            echo_failure('Virtual env named `{}` does not exist.'.format(env_name))
            sys.exit(1)

        with venv(venv_dir):
            command = [get_proper_pip(), 'uninstall', *packages] + (['-q'] if quiet else [])
            echo_waiting('Uninstalling in virtual env `{}`...'.format(env_name))
            result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)
    elif not venv_active() and not no_detect and os.path.isfile(os.path.join(os.getcwd(), 'setup.py')):
        venv_dir = os.path.join(os.getcwd(), 'venv')
        if not is_venv(venv_dir):
            echo_info('A project has been detected!')
            echo_waiting('Creating a dedicated virtual env... ', nl=False)
            create_venv(venv_dir)
            echo_success('complete!')

            with venv(venv_dir):
                echo_waiting('Installing this project in the virtual env... ', nl=False)
                install_packages(['-q', '-e', '.'])
                echo_success('complete!')

            echo_warning('New virtual envs have nothing to uninstall, exiting...')
            sys.exit(2)

        with venv(venv_dir):
            command = [get_proper_pip(), 'uninstall', *packages] + (['-q'] if quiet else [])
            echo_waiting('Uninstalling for this project...')
            result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)
    else:
        command = [get_proper_pip(), 'uninstall'] + (['-q'] if quiet else [])

        if not venv_active() and global_uninstall:  # no cov
            if not admin:
                if ON_WINDOWS:
                    windows_admin_command = get_admin_command()
                else:
                    command = get_admin_command() + command

        command.extend(packages)

        if windows_admin_command:  # no cov
            command = windows_admin_command + [' '.join(command)]

        echo_waiting('Uninstalling...')
        result = subprocess.run(command, shell=NEED_SUBPROCESS_SHELL)

    sys.exit(result.returncode)