def test_config_username(): with temp_chdir() as d: runner = CliRunner() runner.invoke(hatch, ['init', PACKAGE_NAME, '--basic', '-ne']) runner.invoke(hatch, ['build']) with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypi_username'] = USERNAME save_settings(settings) with env_vars(ENV_VARS): result = runner.invoke(hatch, ['release', '-p', 'dist', '-t']) assert result.exit_code == 0
def test_pyname_multiple(): with temp_chdir() as d: runner = CliRunner() with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypaths']['pyname1'] = 'pypath1' settings['pypaths']['pyname2'] = 'pypath2' save_settings(settings) result = runner.invoke(hatch, ['shed', '-p', 'pyname1,pyname2']) assert load_settings()['pypaths'] == {} assert result.exit_code == 0 assert 'Successfully removed Python path named `pyname1`.' in result.output assert 'Successfully removed Python path named `pyname2`.' in result.output
def test_python(): with temp_chdir() as d: runner = CliRunner() runner.invoke(hatch, ['init', 'ok', '--basic']) with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypaths']['python'] = sys.executable save_settings(settings) result = runner.invoke(hatch, ['build', '-py', 'python', '-pp', 'Delphi']) files = os.listdir(os.path.join(d, 'dist')) assert result.exit_code == 0 assert matching_file(r'.*\.whl$', files) assert len(files) == 2
def test_username_env(): with temp_chdir() as d: runner = CliRunner() runner.invoke(hatch, ['init', PACKAGE_NAME, '--basic', '-ne']) runner.invoke(hatch, ['build']) os.chdir(os.path.join(d, 'dist')) with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypi_username'] = '' save_settings(settings) extra_env_vars = {'TWINE_USERNAME': USERNAME, **ENV_VARS} with env_vars(extra_env_vars): result = runner.invoke(hatch, ['release', '-t']) assert result.exit_code == 0
def test_build_option(): with temp_chdir() as d: runner = CliRunner() runner.invoke(hatch, ['init', 'ok', '--basic']) init_file = os.path.join(d, 'ok', '__init__.py') with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['semver']['build'] = 'rc' save_settings(settings) result = runner.invoke(hatch, ['grow', 'build', '--build', 'nightly']) contents = read_file(init_file) assert result.exit_code == 0 assert contents == "__version__ = '0.0.1+nightly.1'\n" assert 'Updated {}'.format(init_file) in result.output assert '0.0.1 -> 0.0.1+nightly.1' in result.output
def test_config_username_empty(): with temp_chdir() as d: runner = CliRunner() runner.invoke(hatch, ['init', PACKAGE_NAME, '--basic']) runner.invoke(hatch, ['build']) with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypi_username'] = '' save_settings(settings) with env_vars(ENV_VARS): result = runner.invoke(hatch, ['release', '-p', 'dist', '-t']) assert result.exit_code == 1 assert ( 'A username must be supplied via -u/--username or ' 'in {} as pypi_username.'.format(SETTINGS_FILE)) in result.output
def test_success_missing_key(): with temp_chdir() as d: runner = CliRunner() with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings.pop('pypaths') save_settings(settings) result = runner.invoke(hatch, ['pypath', 'name', 'path']) settings = load_settings() assert settings['pypaths']['name'] == 'path' assert list(settings.keys())[-1] != 'pypaths' assert result.exit_code == 0 assert 'Settings were successfully updated to include `pypaths` entry.' in result.output assert 'Successfully saved Python `name` located at `path`.' in result.output
def test_update(): with temp_chdir() as d: runner = CliRunner() with temp_move_path(SETTINGS_FILE, d): new_settings = copy_default_settings() new_settings.pop('email') new_settings['new setting'] = '' save_settings(new_settings) assert load_settings() == new_settings result = runner.invoke(hatch, ['config', '-u']) updated_settings = load_settings() assert result.exit_code == 0 assert 'Settings were successfully updated.' in result.output assert 'email' in updated_settings assert 'new setting' in updated_settings
def test_pyname(): with temp_chdir() as d: runner = CliRunner() env_name = get_new_venv_name() venv_dir = os.path.join(VENV_DIR, env_name) try: with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypaths']['python'] = sys.executable save_settings(settings) result = runner.invoke(hatch, ['env', env_name, '-py', 'python']) assert os.path.exists(venv_dir) finally: remove_path(venv_dir) assert result.exit_code == 0 assert 'Successfully saved virtual env `{}` to `{}`.'.format( env_name, venv_dir) in result.output
def config(update_settings, restore): """Locates, updates, or restores the config file. \b $ hatch config Settings location: /home/ofek/.local/share/hatch/settings.json """ if update_settings: try: user_settings = load_settings() updated_settings = copy_default_settings() updated_settings.update(user_settings) save_settings(updated_settings) echo_success('Settings were successfully updated.') except FileNotFoundError: restore = True if restore: restore_settings() echo_success('Settings were successfully restored.') echo_success('Settings location: ' + SETTINGS_FILE)
def test_pyname(): with temp_chdir() as d: runner = CliRunner() env_name = get_new_venv_name() venv_dir = os.path.join(VENV_DIR, env_name) try: with temp_move_path(SETTINGS_FILE, d): settings = copy_default_settings() settings['pypaths']['python'] = sys.executable save_settings(settings) result = runner.invoke(hatch, ['init', 'ok', '-py', 'python']) venv_dir = os.path.join(d, 'venv') global_version = get_python_version() wait_until(is_venv, venv_dir) with venv(venv_dir): assert get_python_version() == global_version finally: remove_path(venv_dir) assert result.exit_code == 0
def test_extras(): with temp_chdir() as d: runner = CliRunner() test_dir = os.path.join(d, 'a', 'b') test_file1 = os.path.join(test_dir, 'file1.txt') test_file2 = os.path.join(d, 'x', 'y', 'file2.txt') test_glob = '{}{}*'.format(os.path.join(d, 'x'), os.path.sep) fake_file = os.path.join(test_dir, 'file.py') create_file(test_file1) create_file(test_file2) with temp_move_path(SETTINGS_FILE, d): new_settings = copy_default_settings() new_settings['extras'] = [test_dir, test_file1, test_glob, fake_file] save_settings(new_settings) runner.invoke(hatch, ['init', 'ok', '--basic']) assert os.path.exists(os.path.join(d, 'b', 'file1.txt')) assert os.path.exists(os.path.join(d, 'file1.txt')) assert os.path.exists(os.path.join(d, 'y', 'file2.txt')) assert not os.path.exists(os.path.join(d, 'file2.txt')) assert not os.path.exists(os.path.join(d, 'file.py'))
def pypath(name, path, show): """Names an absolute path to a Python executable. You can also modify these in the config file entry `pypaths`. Hatch can then use these paths by name when creating virtual envs, building packages, etc. \b $ hatch pypath -l There are no saved Python paths. Add one via `hatch pypath NAME PATH`. $ hatch pypath py2 /usr/bin/python Successfully saved Python `py2` located at `/usr/bin/python`. $ hatch pypath py3 /usr/bin/python3 Successfully saved Python `py3` located at `/usr/bin/python3`. $ hatch pypath -l py2 -> /usr/bin/python py3 -> /usr/bin/python3 """ try: settings = load_settings() except FileNotFoundError: echo_failure( 'Unable to locate config file. Try `hatch config --restore`.') sys.exit(1) if 'pypaths' not in settings: updated_settings = copy_default_settings() updated_settings.update(settings) settings = updated_settings echo_success( 'Settings were successfully updated to include `pypaths` entry.') settings['pypaths'][name] = path save_settings(settings) echo_success('Successfully saved Python `{}` located at `{}`.'.format( name, path))
def python(version, name, head): # no cov if not conda_available(): echo_failure( 'Conda is unavailable. You can install it by doing `hatch conda`.') sys.exit(1) exe_name = 'py{}'.format(name or version) + ('.exe' if ON_WINDOWS else '') name = name or version path = os.path.join(get_python_dir(), name) command = [ 'conda', 'create', '--yes', '-p', path, 'python={}'.format(version) ] if os.path.exists(path): echo_failure('The path `{}` already exists.'.format(path)) sys.exit(1) settings = load_settings(lazy=True) if 'pypaths' not in settings: updated_settings = copy_default_settings() updated_settings.update(settings) settings = updated_settings echo_success( 'Settings were successfully updated to include `pypaths` entry.') old_path = settings['pypaths'].get(name) if old_path: echo_failure('The Python path `{}` already points to `{}`.'.format( name, old_path)) sys.exit(1) echo_waiting('Installing Python {}...'.format(version)) try: subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except subprocess.CalledProcessError as e: echo_failure('The installation was seemingly unsuccessful.') click.echo(e.stdout) click.echo(e.stderr) sys.exit(e.returncode) conda_path = get_conda_new_exe_path(path) python_path = resolve_path(shutil.which('python', path=conda_path)) settings['pypaths'][name] = python_path save_settings(settings) echo_success('Successfully saved Python `{}` located at `{}`.'.format( name, python_path)) if head is not None: add_to_path = userpath.prepend if head else userpath.append success = add_to_path(conda_path, app_name='Hatch') shutil.copy(python_path, os.path.join(os.path.dirname(python_path), exe_name)) if success: echo_info( 'Please restart your shell for PATH changes to take effect.') else: echo_warning( 'It appears that we were unable to modify PATH. Please ' 'do so using the following: ', nl=False) echo_info(conda_path)
def shed(ctx, pyname, env_name): """Removes named Python paths or virtual environments. \b $ hatch pypath -l py2 -> /usr/bin/python py3 -> /usr/bin/python3 invalid -> :\/: $ hatch env -ll Virtual environments found in /home/ofek/.virtualenvs: \b duplicate -> Version: 3.5.2 Implementation: CPython fast -> Version: 3.5.3 Implementation: PyPy my-app -> Version: 3.5.2 Implementation: CPython old -> Version: 2.7.12 Implementation: CPython $ hatch shed -p invalid -e duplicate/old Successfully removed Python path named `invalid`. Successfully removed virtual env named `duplicate`. Successfully removed virtual env named `old`. """ if not (pyname or env_name): click.echo(ctx.get_help()) return if pyname: try: settings = load_settings() except FileNotFoundError: echo_failure( 'Unable to locate config file. Try `hatch config --restore`.') sys.exit(1) for pyname in pyname.split('/'): pypath = settings.get('pypaths', {}).pop(pyname, None) if pypath is not None: save_settings(settings) echo_success( 'Successfully removed Python path named `{}`.'.format( pyname)) else: echo_warning( 'Python path named `{}` already does not exist.'.format( pyname)) if env_name: for env_name in env_name.split('/'): venv_dir = os.path.join(get_venv_dir(), env_name) if os.path.exists(venv_dir): remove_path(venv_dir) echo_success( 'Successfully removed virtual env named `{}`.'.format( env_name)) else: echo_warning( 'Virtual env named `{}` already does not exist.'.format( env_name))