def handle(self): from poetry.layouts import layout layout_ = layout('standard') path = Path.cwd() / Path(self.argument('path')) name = self.option('name') if not name: name = path.name if path.exists(): if list(path.glob('*')): # Directory is not empty. Aborting. raise RuntimeError( 'Destination <fg=yellow;bg=red>{}</> ' 'exists and is not empty'.format( path ) ) readme_format = 'rst' layout_ = layout_(name, '0.1.0', readme_format=readme_format) layout_.create(path) self.line( 'Created package <info>{}</> in <fg=blue>{}</>' .format(name, path.relative_to(Path.cwd())) )
def handle(self): from poetry.core.semver import parse_constraint from poetry.core.vcs.git import GitConfig from poetry.layouts import layout from poetry.utils._compat import Path from poetry.utils.env import SystemEnv, InterpreterLookup if self.option("src"): layout_ = layout("src") else: layout_ = layout("standard") path = Path.cwd() / Path(self.argument("path")) name = self.option("name") if not name: name = path.name if path.exists(): if list(path.glob("*")): # Directory is not empty. Aborting. raise RuntimeError("Destination <fg=yellow>{}</> " "exists and is not empty".format(path)) readme_format = "rst" config = GitConfig() author = None if config.get("user.name"): author = config["user.name"] author_email = config.get("user.email") if author_email: author += " <{}>".format(author_email) executable, py_minor, py_patch = InterpreterLookup.find() current_env = SystemEnv(executable) default_python = "^{}".format(".".join( str(v) for v in current_env.version_info[:2])) dev_dependencies = {} python_constraint = parse_constraint(default_python) if parse_constraint("<3.5").allows_any(python_constraint): dev_dependencies["pytest"] = "^4.6" if parse_constraint(">=3.5").allows_all(python_constraint): dev_dependencies["pytest"] = "^5.2" layout_ = layout_( name, "0.1.0", author=author, readme_format=readme_format, python=default_python, dev_dependencies=dev_dependencies, ) layout_.create(path) self.line("Created package <info>{}</> in <fg=blue>{}</>".format( module_name(name), path.relative_to(Path.cwd())))
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.utils.env import SystemEnv from poetry.vcs.git import GitConfig if self.option("src"): layout_ = layout("src") else: layout_ = layout("standard") path = Path.cwd() / Path(self.argument("path")) name = self.option("name") if not name: name = path.name if path.exists(): if list(path.glob("*")): # Directory is not empty. Aborting. raise RuntimeError( "Destination <fg=yellow>{}</> " "exists and is not empty".format(path) ) readme_format = "rst" config = GitConfig() author = None if config.get("user.name"): author = config["user.name"] author_email = config.get("user.email") if author_email: author += " <{}>".format(author_email) current_env = SystemEnv(Path(sys.executable)) default_python = "^{}".format( ".".join(str(v) for v in current_env.version_info[:2]) ) layout_ = layout_( name, "0.1.0", author=author, readme_format=readme_format, python=default_python, ) layout_.create(path) self.line( "Created package <info>{}</> in <fg=blue>{}</>".format( name, path.relative_to(Path.cwd()) ) )
def test_get_cached_archive_for_link(config, mocker): chef = Chef( config, MockEnv( version_info=(3, 8, 3), marker_env={ "interpreter_name": "cpython", "interpreter_version": "3.8.3" }, supported_tags=[ Tag("cp38", "cp38", "macosx_10_15_x86_64"), Tag("py3", "none", "any"), ], ), ) cwd = Path.cwd() / ".pypoetrycache" mocker.patch.object( chef, "get_cached_archives_for_link", return_value=[ Link(f"file:///{cwd}demo-0.1.0-py2.py3-none-any"), Link(f"file:///{cwd}demo-0.1.0.tar.gz"), Link(f"file:///{cwd}demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl"), Link(f"file:///{cwd}demo-0.1.0-cp37-cp37-macosx_10_15_x86_64.whl"), ], ) archive = chef.get_cached_archive_for_link( Link("https://files.python-poetry.org/demo-0.1.0.tar.gz")) assert Link(f"file:///{cwd}demo-0.1.0-cp38-cp38-macosx_10_15_x86_64.whl" ) == archive
def poetry(self): from poetry.factory import Factory from poetry.utils._compat import Path if self._poetry is not None: return self._poetry self._poetry = Factory().create_poetry(Path.cwd()) return self._poetry
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.vcs.git import GitConfig if self.option('src'): layout_ = layout('src') else: layout_ = layout('standard') path = Path.cwd() / Path(self.argument('path')) name = self.option('name') if not name: name = path.name if path.exists(): if list(path.glob('*')): # Directory is not empty. Aborting. raise RuntimeError( 'Destination <fg=yellow>{}</> ' 'exists and is not empty'.format( path ) ) readme_format = 'rst' config = GitConfig() author = None if config.get('user.name'): author = config['user.name'] author_email = config.get('user.email') if author_email: author += ' <{}>'.format(author_email) layout_ = layout_(name, '0.1.0', author=author, readme_format=readme_format) layout_.create(path) self.line( 'Created package <info>{}</> in <fg=blue>{}</>' .format(name, path.relative_to(Path.cwd())) )
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.vcs.git import GitConfig if self.option("src"): layout_ = layout("src") else: layout_ = layout("standard") path = Path.cwd() / Path(self.argument("path")) name = self.option("name") if not name: name = path.name if path.exists(): if list(path.glob("*")): # Directory is not empty. Aborting. raise RuntimeError( "Destination <fg=yellow>{}</> " "exists and is not empty".format(path) ) readme_format = "rst" config = GitConfig() author = None if config.get("user.name"): author = config["user.name"] author_email = config.get("user.email") if author_email: author += " <{}>".format(author_email) layout_ = layout_(name, "0.1.0", author=author, readme_format=readme_format) layout_.create(path) self.line( "Created package <info>{}</> in <fg=blue>{}</>".format( name, path.relative_to(Path.cwd()) ) )
def get(cls, reload=False, cwd=None): # type: (IO, bool) -> Env if cls._env is not None and not reload: return cls._env # Check if we are inside a virtualenv or not in_venv = (os.environ.get("VIRTUAL_ENV") is not None or hasattr(sys, "real_prefix") or (hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix)) if not in_venv: # Checking if a local virtualenv exists if cwd and (cwd / ".venv").exists(): venv = cwd / ".venv" return VirtualEnv(Path(venv)) config = Config.create("config.toml") create_venv = config.setting("settings.virtualenvs.create", True) if not create_venv: return SystemEnv(Path(sys.prefix)) venv_path = config.setting("settings.virtualenvs.path") if venv_path is None: venv_path = Path(CACHE_DIR) / "virtualenvs" else: venv_path = Path(venv_path) if cwd is None: cwd = Path.cwd() name = cwd.name name = "{}-py{}".format( name, ".".join([str(v) for v in sys.version_info[:2]])) venv = venv_path / name if not venv.exists(): return SystemEnv(Path(sys.prefix)) return VirtualEnv(venv) if os.environ.get("VIRTUAL_ENV") is not None: prefix = Path(os.environ["VIRTUAL_ENV"]) base_prefix = None else: prefix = Path(sys.prefix) base_prefix = cls.get_base_prefix() return VirtualEnv(prefix, base_prefix)
def get_vcs(directory): # type: (Path) -> Git working_dir = Path.cwd() os.chdir(str(directory.resolve())) try: git_dir = decode( subprocess.check_output(["git", "rev-parse", "--show-toplevel"], stderr=subprocess.STDOUT)).strip() vcs = Git(Path(git_dir)) except (subprocess.CalledProcessError, OSError): vcs = None finally: os.chdir(str(working_dir)) return vcs
def handle(self): # Load poetry config and display errors, if any poetry_file = Poetry.locate(Path.cwd()) config = TomlFile(str(poetry_file)).read()["tool"]["poetry"] check_result = Poetry.check(config, strict=True) if not check_result["errors"] and not check_result["warnings"]: self.info("All set!") return 0 for error in check_result["errors"]: self.line("<error>Error: {}</error>".format(error)) for error in check_result["warnings"]: self.line("<warning>Warning: {}</warning>".format(error)) return 1
def handle(self): # Load poetry config and display errors, if any poetry_file = Factory.locate(Path.cwd()) config = PyProjectTOML(poetry_file).poetry_config check_result = Factory.validate(config, strict=True) if not check_result["errors"] and not check_result["warnings"]: self.info("All set!") return 0 for error in check_result["errors"]: self.line("<error>Error: {}</error>".format(error)) for error in check_result["warnings"]: self.line("<warning>Warning: {}</warning>".format(error)) return 1
def test_get_cache_directory_for_link(config): chef = Chef( config, MockEnv(marker_env={ "interpreter_name": "cpython", "interpreter_version": "3.8.3" }), ) cwd = Path.cwd() / ".pypoetrycache" directory = chef.get_cache_directory_for_link( Link("https://files.python-poetry.org/poetry-1.1.0.tar.gz")) expected = Path( f"{cwd}/artifacts/ba/63/13/283a3b3b7f95f05e9e6f84182d276f7bb0951d5b0cc24422b33f7a4648" ) assert expected == directory
def main(print_content_hash: bool) -> None: """Merge the lock file of a Poetry project. This is a tool for resolving merge conflicts in the lock file of Poetry, a packaging and dependency manager for Python. If the merge conflicts cannot be resolved by this tool, you can use the --print-content-hash option to compute the content hash for the metadata.content-hash entry, and resolve the conflicts manually. \f Args: print_content_hash: Print the content hash. """ poetry = Factory().create_poetry(Path.cwd()) if print_content_hash: click.echo(poetry.locker._content_hash) else: merge_lock(poetry)
def create(cls, io, name=None, cwd=None): # type: (...) -> Venv if "VIRTUAL_ENV" not in os.environ: # Not in a virtualenv # Checking if we need to create one # First we check if there is a .venv # at the root of the project. if cwd and (cwd / ".venv").exists(): venv = cwd / ".venv" else: config = Config.create("config.toml") create_venv = config.setting("settings.virtualenvs.create") root_venv = config.setting("settings.virtualenvs.in-project") venv_path = config.setting("settings.virtualenvs.path") if root_venv: if not cwd: raise RuntimeError( "Unable to determine the project's directory" ) venv_path = cwd / ".venv" elif venv_path is None: venv_path = Path(CACHE_DIR) / "virtualenvs" else: venv_path = Path(venv_path) if not name: name = Path.cwd().name name = "{}-py{}".format( name, ".".join([str(v) for v in sys.version_info[:2]]) ) if root_venv: venv = venv_path else: venv = venv_path / name if not venv.exists(): if create_venv is False: io.writeln( "<fg=black;bg=yellow>" "Skipping virtualenv creation, " "as specified in config file." "</>" ) return cls() io.writeln( "Creating virtualenv <info>{}</> in {}".format( name, str(venv_path) ) ) cls.build(str(venv)) else: if io.is_very_verbose(): io.writeln( "Virtualenv <info>{}</> already exists.".format(name) ) os.environ["VIRTUAL_ENV"] = str(venv) # venv detection: # stdlib venv may symlink sys.executable, so we can't use realpath. # but others can symlink *to* the venv Python, # so we can't just use sys.executable. # So we just check every item in the symlink tree (generally <= 3) p = os.path.normcase(sys.executable) paths = [p] while os.path.islink(p): p = os.path.normcase(os.path.join(os.path.dirname(p), os.readlink(p))) paths.append(p) p_venv = os.path.normcase(os.environ["VIRTUAL_ENV"]) if any(p.startswith(p_venv) for p in paths): # Running properly in the virtualenv, don't need to do anything return cls() venv = os.environ["VIRTUAL_ENV"] return cls(venv)
def create(cls, io, name=None, cwd=None): # type: (...) -> Venv if 'VIRTUAL_ENV' not in os.environ: # Not in a virtualenv # Checking if we need to create one # First we check if there is a .venv # at the root of the project. if cwd and (cwd / '.venv').exists(): venv = cwd / '.venv' else: config = Config.create('config.toml') create_venv = config.setting('settings.virtualenvs.create') root_venv = config.setting('settings.virtualenvs.in-project') venv_path = config.setting('settings.virtualenvs.path') if root_venv: if not cwd: raise RuntimeError('Unbale to determine the project\'s directory') venv_path = (cwd / '.venv') elif venv_path is None: venv_path = Path(CACHE_DIR) / 'virtualenvs' else: venv_path = Path(venv_path) if not name: name = Path.cwd().name name = '{}-py{}'.format( name, '.'.join([str(v) for v in sys.version_info[:2]]) ) if root_venv: venv = venv_path else: venv = venv_path / name if not venv.exists(): if create_venv is False: io.writeln( '<fg=black;bg=yellow>' 'Skipping virtualenv creation, ' 'as specified in config file.' '</>' ) return cls() io.writeln( 'Creating virtualenv <info>{}</> in {}'.format( name, str(venv_path) ) ) cls.build(str(venv)) else: if io.is_very_verbose(): io.writeln( 'Virtualenv <info>{}</> already exists.'.format(name) ) os.environ['VIRTUAL_ENV'] = str(venv) # venv detection: # stdlib venv may symlink sys.executable, so we can't use realpath. # but others can symlink *to* the venv Python, # so we can't just use sys.executable. # So we just check every item in the symlink tree (generally <= 3) p = os.path.normcase(sys.executable) paths = [p] while os.path.islink(p): p = os.path.normcase( os.path.join(os.path.dirname(p), os.readlink(p))) paths.append(p) p_venv = os.path.normcase(os.environ['VIRTUAL_ENV']) if any(p.startswith(p_venv) for p in paths): # Running properly in the virtualenv, don't need to do anything return cls() venv = os.environ['VIRTUAL_ENV'] return cls(venv)
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.utils.env import SystemEnv from poetry.core.vcs.git import GitConfig if (Path.cwd() / "pyproject.toml").exists(): self.line("<error>A pyproject.toml file already exists.</error>") return 1 vcs_config = GitConfig() self.line("") self.line( "This command will guide you through creating your <info>pyproject.toml</> config." ) self.line("") name = self.option("name") if not name: name = Path.cwd().name.lower() question = self.create_question( "Package name [<comment>{}</comment>]: ".format(name), default=name) name = self.ask(question) version = "0.1.0" question = self.create_question( "Version [<comment>{}</comment>]: ".format(version), default=version) version = self.ask(question) description = self.option("description") or "" question = self.create_question( "Description [<comment>{}</comment>]: ".format(description), default=description, ) description = self.ask(question) author = self.option("author") if not author and vcs_config and vcs_config.get("user.name"): author = vcs_config["user.name"] author_email = vcs_config.get("user.email") if author_email: author += " <{}>".format(author_email) question = self.create_question( "Author [<comment>{}</comment>, n to skip]: ".format(author), default=author) question.set_validator(lambda v: self._validate_author(v, author)) author = self.ask(question) if not author: authors = [] else: authors = [author] license = self.option("license") or "" question = self.create_question( "License [<comment>{}</comment>]: ".format(license), default=license) question.set_validator(self._validate_license) license = self.ask(question) python = self.option("python") if not python: current_env = SystemEnv(Path(sys.executable)) default_python = "^{}".format(".".join( str(v) for v in current_env.version_info[:2])) question = self.create_question( "Compatible Python versions [<comment>{}</comment>]: ".format( default_python), default=default_python, ) python = self.ask(question) self.line("") requirements = {} question = "Would you like to define your main dependencies interactively?" help_message = ( "You can specify a package in the following forms:\n" " - A single name (<b>requests</b>)\n" " - A name and a constraint (<b>requests@^2.23.0</b>)\n" " - A git url (<b>git+https://github.com/python-poetry/poetry.git</b>)\n" " - A git url with a revision (<b>git+https://github.com/python-poetry/poetry.git#develop</b>)\n" " - A file path (<b>../my-package/my-package.whl</b>)\n" " - A directory (<b>../my-package/</b>)\n" " - A url (<b>https://example.com/packages/my-package-0.1.0.tar.gz</b>)\n" ) help_displayed = False if self.confirm(question, True): self.line(help_message) help_displayed = True requirements = self._format_requirements( self._determine_requirements(self.option("dependency"))) self.line("") dev_requirements = {} question = ( "Would you like to define your development dependencies interactively?" ) if self.confirm(question, True): if not help_displayed: self.line(help_message) dev_requirements = self._format_requirements( self._determine_requirements(self.option("dev-dependency"))) self.line("") layout_ = layout("standard")( name, version, description=description, author=authors[0] if authors else None, license=license, python=python, dependencies=requirements, dev_dependencies=dev_requirements, ) content = layout_.generate_poetry_content() if self.io.is_interactive(): self.line("<info>Generated file</info>") self.line("") self.line(content) self.line("") if not self.confirm("Do you confirm generation?", True): self.line("<error>Command aborted</error>") return 1 with (Path.cwd() / "pyproject.toml").open("w", encoding="utf-8") as f: f.write(content)
def _parse_requirements( self, requirements): # type: (List[str]) -> List[Dict[str, str]] from poetry.puzzle.provider import Provider result = [] try: cwd = self.poetry.file.parent except RuntimeError: cwd = Path.cwd() for requirement in requirements: requirement = requirement.strip() extras = [] extras_m = re.search(r"\[([\w\d,-_]+)\]$", requirement) if extras_m: extras = [e.strip() for e in extras_m.group(1).split(",")] requirement, _ = requirement.split("[") url_parsed = urlparse.urlparse(requirement) if url_parsed.scheme and url_parsed.netloc: # Url if url_parsed.scheme in ["git+https", "git+ssh"]: from poetry.core.vcs.git import Git from poetry.core.vcs.git import ParsedUrl parsed = ParsedUrl.parse(requirement) url = Git.normalize_url(requirement) pair = OrderedDict([("name", parsed.name), ("git", url.url)]) if parsed.rev: pair["rev"] = url.revision if extras: pair["extras"] = extras package = Provider.get_package_from_vcs( "git", url.url, reference=pair.get("rev")) pair["name"] = package.name result.append(pair) continue elif url_parsed.scheme in ["http", "https"]: package = Provider.get_package_from_url(requirement) pair = OrderedDict([("name", package.name), ("url", package.source_url)]) if extras: pair["extras"] = extras result.append(pair) continue elif (os.path.sep in requirement or "/" in requirement) and cwd.joinpath(requirement).exists(): path = cwd.joinpath(requirement) if path.is_file(): package = Provider.get_package_from_file(path.resolve()) else: package = Provider.get_package_from_directory(path) result.append( OrderedDict([ ("name", package.name), ("path", path.relative_to(cwd).as_posix()), ] + ([("extras", extras)] if extras else []))) continue pair = re.sub("^([^@=: ]+)(?:@|==|(?<![<>~!])=|:| )(.*)$", "\\1 \\2", requirement) pair = pair.strip() require = OrderedDict() if " " in pair: name, version = pair.split(" ", 2) extras_m = re.search(r"\[([\w\d,-_]+)\]$", name) if extras_m: extras = [e.strip() for e in extras_m.group(1).split(",")] name, _ = name.split("[") require["name"] = name if version != "latest": require["version"] = version else: m = re.match(r"^([^><=!: ]+)((?:>=|<=|>|<|!=|~=|~|\^).*)$", requirement.strip()) if m: name, constraint = m.group(1), m.group(2) extras_m = re.search(r"\[([\w\d,-_]+)\]$", name) if extras_m: extras = [ e.strip() for e in extras_m.group(1).split(",") ] name, _ = name.split("[") require["name"] = name require["version"] = constraint else: extras_m = re.search(r"\[([\w\d,-_]+)\]$", pair) if extras_m: extras = [ e.strip() for e in extras_m.group(1).split(",") ] pair, _ = pair.split("[") require["name"] = pair if extras: require["extras"] = extras result.append(require) return result
def handle(self): from poetry.config.file_config_source import FileConfigSource from poetry.locations import CONFIG_DIR from poetry.utils._compat import Path from poetry.utils._compat import basestring from poetry.utils.toml_file import TomlFile config = Factory.create_config(self.io) config_file = TomlFile(Path(CONFIG_DIR) / "config.toml") try: local_config_file = TomlFile(self.poetry.file.parent / "poetry.toml") if local_config_file.exists(): config.merge(local_config_file.read()) except RuntimeError: local_config_file = TomlFile(Path.cwd() / "poetry.toml") if self.option("local"): config.set_config_source(FileConfigSource(local_config_file)) if not config_file.exists(): config_file.path.parent.mkdir(parents=True, exist_ok=True) config_file.touch(mode=0o0600) if self.option("list"): self._list_configuration(config.all(), config.raw()) return 0 setting_key = self.argument("key") if not setting_key: return 0 if self.argument("value") and self.option("unset"): raise RuntimeError( "You can not combine a setting value with --unset") # show the value if no value is provided if not self.argument("value") and not self.option("unset"): m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key")) if m: if not m.group(1): value = {} if config.get("repositories") is not None: value = config.get("repositories") else: repo = config.get("repositories.{}".format(m.group(1))) if repo is None: raise ValueError( "There is no {} repository defined".format( m.group(1))) value = repo self.line(str(value)) else: values = self.unique_config_values if setting_key not in values: raise ValueError( "There is no {} setting.".format(setting_key)) value = config.get(setting_key) if not isinstance(value, basestring): value = json.dumps(value) self.line(value) return 0 values = self.argument("value") unique_config_values = self.unique_config_values if setting_key in unique_config_values: if self.option("unset"): return config.config_source.remove_property(setting_key) return self._handle_single_value( config.config_source, setting_key, unique_config_values[setting_key], values, ) # handle repositories m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key")) if m: if not m.group(1): raise ValueError( "You cannot remove the [repositories] section") if self.option("unset"): repo = config.get("repositories.{}".format(m.group(1))) if repo is None: raise ValueError( "There is no {} repository defined".format(m.group(1))) config.config_source.remove_property("repositories.{}".format( m.group(1))) return 0 if len(values) == 1: url = values[0] config.config_source.add_property( "repositories.{}.url".format(m.group(1)), url) return 0 raise ValueError( "You must pass the url. " "Example: poetry config repositories.foo https://bar.com") # handle auth m = re.match(r"^(http-basic|pypi-token)\.(.+)", self.argument("key")) if m: if self.option("unset"): keyring_repository_password_del(config, m.group(2)) config.auth_config_source.remove_property("{}.{}".format( m.group(1), m.group(2))) return 0 if m.group(1) == "http-basic": if len(values) == 1: username = values[0] # Only username, so we prompt for password password = self.secret("Password:"******"Expected one or two arguments " "(username, password), got {}".format( len(values))) else: username = values[0] password = values[1] property_value = dict(username=username) try: keyring_repository_password_set(m.group(2), username, password) except RuntimeError: property_value.update(password=password) config.auth_config_source.add_property( "{}.{}".format(m.group(1), m.group(2)), property_value) elif m.group(1) == "pypi-token": if len(values) != 1: raise ValueError( "Expected only one argument (token), got {}".format( len(values))) token = values[0] config.auth_config_source.add_property( "{}.{}".format(m.group(1), m.group(2)), token) return 0 # handle certs m = re.match(r"(?:certificates)\.([^.]+)\.(cert|client-cert)", self.argument("key")) if m: if self.option("unset"): config.auth_config_source.remove_property( "certificates.{}.{}".format(m.group(1), m.group(2))) return 0 if len(values) == 1: config.auth_config_source.add_property( "certificates.{}.{}".format(m.group(1), m.group(2)), values[0]) else: raise ValueError("You must pass exactly 1 value") return 0 raise ValueError("Setting {} does not exist".format( self.argument("key")))
def package(): p = ProjectPackage("root", "1.0") p.root_dir = Path.cwd() return p
def create_venv(cls, io, name=None, cwd=None): # type: (IO, bool, Path) -> Env if cls._env is not None: return cls._env env = cls.get(cwd=cwd) if env.is_venv(): # Already inside a virtualenv. return env config = Config.create("config.toml") create_venv = config.setting("settings.virtualenvs.create") root_venv = config.setting("settings.virtualenvs.in-project") venv_path = config.setting("settings.virtualenvs.path") if root_venv: if not cwd: raise RuntimeError( "Unable to determine the project's directory") venv_path = cwd / ".venv" elif venv_path is None: venv_path = Path(CACHE_DIR) / "virtualenvs" else: venv_path = Path(venv_path) if not name: if not cwd: cwd = Path.cwd() name = cwd.name name = "{}-py{}".format( name, ".".join([str(v) for v in sys.version_info[:2]])) if root_venv: venv = venv_path else: venv = venv_path / name if not venv.exists(): if create_venv is False: io.writeln("<fg=black;bg=yellow>" "Skipping virtualenv creation, " "as specified in config file." "</>") return SystemEnv(Path(sys.prefix)) io.writeln("Creating virtualenv <info>{}</> in {}".format( name, str(venv_path))) cls.build_venv(str(venv)) else: if io.is_very_verbose(): io.writeln( "Virtualenv <info>{}</> already exists.".format(name)) # venv detection: # stdlib venv may symlink sys.executable, so we can't use realpath. # but others can symlink *to* the venv Python, # so we can't just use sys.executable. # So we just check every item in the symlink tree (generally <= 3) p = os.path.normcase(sys.executable) paths = [p] while os.path.islink(p): p = os.path.normcase( os.path.join(os.path.dirname(p), os.readlink(p))) paths.append(p) p_venv = os.path.normcase(str(venv)) if any(p.startswith(p_venv) for p in paths): # Running properly in the virtualenv, don't need to do anything return SystemEnv(Path(sys.prefix), cls.get_base_prefix()) return VirtualEnv(venv)
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.utils.env import Env from poetry.vcs.git import GitConfig if (Path.cwd() / "pyproject.toml").exists(): self.error("A pyproject.toml file already exists.") return 1 vcs_config = GitConfig() self.line([ "", "This command will guide you through creating your <info>pyproject.toml</> config.", "", ]) name = self.option("name") if not name: name = Path.cwd().name.lower() question = self.create_question( "Package name [<comment>{}</comment>]: ".format(name), default=name) name = self.ask(question) version = "0.1.0" question = self.create_question( "Version [<comment>{}</comment>]: ".format(version), default=version) version = self.ask(question) description = self.option("description") or "" question = self.create_question( "Description [<comment>{}</comment>]: ".format(description), default=description, ) description = self.ask(question) author = self.option("author") if not author and vcs_config and vcs_config.get("user.name"): author = vcs_config["user.name"] author_email = vcs_config.get("user.email") if author_email: author += " <{}>".format(author_email) question = self.create_question( "Author [<comment>{}</comment>, n to skip]: ".format(author), default=author) question.validator = lambda v: self._validate_author(v, author) author = self.ask(question) if not author: authors = [] else: authors = [author] license = self.option("license") or "" question = self.create_question( "License [<comment>{}</comment>]: ".format(license), default=license) question.validator = self._validate_license license = self.ask(question) current_env = Env.get() default_python = "^{}".format(".".join( str(v) for v in current_env.version_info[:2])) question = self.create_question( "Compatible Python versions [<comment>{}</comment>]: ".format( default_python), default=default_python, ) python = self.ask(question) self.line("") requirements = {} question = ("Would you like to define your dependencies" " (require) interactively?") if self.confirm(question, True): requirements = self._format_requirements( self._determine_requirements(self.option("dependency"))) dev_requirements = {} question = ("Would you like to define your dev dependencies" " (require-dev) interactively") if self.confirm(question, True): dev_requirements = self._format_requirements( self._determine_requirements(self.option("dev-dependency"))) layout_ = layout("standard")( name, version, description=description, author=authors[0] if authors else None, license=license, python=python, dependencies=requirements, dev_dependencies=dev_requirements, ) content = layout_.generate_poetry_content() if self.input.is_interactive(): self.line("<info>Generated file</info>") self.line(["", content, ""]) if not self.confirm("Do you confirm generation?", True): self.line("<error>Command aborted</error>") return 1 with (Path.cwd() / "pyproject.toml").open("w") as f: f.write(content)
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.vcs.git import GitConfig if (Path.cwd() / "pyproject.toml").exists(): self.error("A pyproject.toml file already exists.") return 1 vcs_config = GitConfig() self.line( [ "", "This command will guide you through creating your <info>pyproject.toml</> config.", "", ] ) name = self.option("name") if not name: name = Path.cwd().name.lower() question = self.create_question( "Package name [<comment>{}</comment>]: ".format(name), default=name ) name = self.ask(question) version = "0.1.0" question = self.create_question( "Version [<comment>{}</comment>]: ".format(version), default=version ) version = self.ask(question) description = self.option("description") or "" question = self.create_question( "Description [<comment>{}</comment>]: ".format(description), default=description, ) description = self.ask(question) author = self.option("author") if not author and vcs_config and vcs_config.get("user.name"): author = vcs_config["user.name"] author_email = vcs_config.get("user.email") if author_email: author += " <{}>".format(author_email) question = self.create_question( "Author [<comment>{}</comment>, n to skip]: ".format(author), default=author ) question.validator = lambda v: self._validate_author(v, author) author = self.ask(question) if not author: authors = [] else: authors = [author] license = self.option("license") or "" question = self.create_question( "License [<comment>{}</comment>]: ".format(license), default=license ) question.validator = self._validate_license license = self.ask(question) question = self.create_question("Compatible Python versions [*]: ", default="*") python = self.ask(question) self.line("") requirements = {} question = "Would you like to define your dependencies" " (require) interactively?" if self.confirm(question, True): requirements = self._format_requirements( self._determine_requirements(self.option("dependency")) ) dev_requirements = {} question = "Would you like to define your dev dependencies" " (require-dev) interactively" if self.confirm(question, True): dev_requirements = self._format_requirements( self._determine_requirements(self.option("dev-dependency")) ) layout_ = layout("standard")( name, version, description=description, author=authors[0] if authors else None, license=license, python=python, dependencies=requirements, dev_dependencies=dev_requirements, ) content = layout_.generate_poetry_content() if self.input.is_interactive(): self.line("<info>Generated file</info>") self.line(["", content, ""]) if not self.confirm("Do you confirm generation?", True): self.line("<error>Command aborted</error>") return 1 with (Path.cwd() / "pyproject.toml").open("w") as f: f.write(content)
def __init__(self): self._lock = TOMLFile(Path.cwd().joinpath("poetry.lock")) self._locked = True self._content_hash = self._get_content_hash()
def handle(self): from poetry.layouts import layout from poetry.utils._compat import Path from poetry.vcs.git import GitConfig if (Path.cwd() / 'pyproject.toml').exists(): self.error('A pyproject.toml file already exists.') return 1 vcs_config = GitConfig() self.line([ '', 'This command will guide you through creating your <info>poetry.toml</> config.', '' ]) name = self.option('name') if not name: name = Path.cwd().name.lower() question = self.create_question( 'Package name [<comment>{}</comment>]: '.format(name), default=name ) name = self.ask(question) version = '0.1.0' question = self.create_question( 'Version [<comment>{}</comment>]: '.format(version), default=version ) version = self.ask(question) description = self.option('description') or '' question = self.create_question( 'Description [<comment>{}</comment>]: '.format(description), default=description ) description = self.ask(question) author = self.option('author') if not author and vcs_config and vcs_config.get('user.name'): author = vcs_config['user.name'] author_email = vcs_config.get('user.email') if author_email: author += ' <{}>'.format(author_email) question = self.create_question( 'Author [<comment>{}</comment>, n to skip]: '.format(author), default=author ) question.validator = lambda v: self._validate_author(v, author) author = self.ask(question) if not author: authors = [] else: authors = [author] license = self.option('license') or '' question = self.create_question( 'License [<comment>{}</comment>]: '.format(license), default=license ) license = self.ask(question) question = self.create_question( 'Compatible Python versions [*]: ', default='*' ) python = self.ask(question) self.line('') requirements = [] question = 'Would you like to define your dependencies' \ ' (require) interactively?' if self.confirm(question, True): requirements = self._format_requirements( self._determine_requirements(self.option('dependency')) ) dev_requirements = [] question = 'Would you like to define your dev dependencies' \ ' (require-dev) interactively' if self.confirm(question, True): dev_requirements = self._format_requirements( self._determine_requirements(self.option('dev-dependency')) ) layout_ = layout('standard')( name, version, description=description, author=authors[0] if authors else None, license=license, python=python, dependencies=requirements, dev_dependencies=dev_requirements ) content = layout_.generate_poetry_content() if self.input.is_interactive(): self.line('<info>Generated file</info>') self.line(['', content, '']) if not self.confirm('Do you confirm generation?', True): self.line('<error>Command aborted</error>') return 1 with (Path.cwd() / 'pyproject.toml').open('w') as f: f.write(content)