Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the add and init commands #1221

Merged
merged 5 commits into from
Jul 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
- Added the ability to specify packages on a per-format basis.
- Added support for custom urls in metadata.
- Full environment markers are now supported for dependencies via the `markers` property.
- Added the ability to specify git dependencies directly in `add`, it no longer requires the `--git` option.
- Added the ability to specify path dependencies directly in `add`, it no longer requires the `--path` option.
- Added the ability to add git and path dependencies via the `init` command.

### Changed

Expand All @@ -24,6 +27,9 @@
- The `debug:resolve` command has been renamed to `debug resolve`.
- The `self:update` command has been renamed to `self update`.
- Changed the way virtualenvs are stored (names now depend on the project's path).
- The `--git` option of the `add` command has been removed.
- The `--path` option of the `add` command has been removed.
- The `add` command will now automatically select the latest prerelease if only prereleases are available.

### Fixed

Expand Down
45 changes: 38 additions & 7 deletions docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,36 +182,67 @@ poetry will choose a suitable one based on the available package versions.
poetry add requests pendulum
```

You also can specify a constraint when adding a package, like so:

```bash
poetry add pendulum@^2.0.5
poetry add "pendulum>=2.0.5"
```

If you try to add a package that is already present, you will get an error.
However, if you specify a constraint, like above, the dependency will be updated
by using the specified constraint. If you want to get the latest version of an already
present dependency you can use the special `latest` constraint:

```bash
poetry add pendulum@latest
```

You can also add `git` dependencies:

```bash
poetry add pendulum --git https://github.com/sdispater/pendulum.git
poetry add git+https://github.com/sdispater/pendulum.git
```

If you need to checkout a specific branch, tag or revision,
you can specify it when using `add`:

```bash
poetry add git+https://github.com/sdispater/pendulum.git@develop
poetry add git+https://github.com/sdispater/pendulum.git@2.0.5
```

or make them point to a local directory or file:

```bash
poetry add my-package --path ../my-package/
poetry add my-package --path ../my-package/dist/my-package-0.1.0.tar.gz
poetry add my-package --path ../my-package/dist/my_package-0.1.0.whl
poetry add ./my-package/
poetry add ../my-package/dist/my-package-0.1.0.tar.gz
poetry add ../my-package/dist/my_package-0.1.0.whl
```

Path dependencies pointing to a local directory will be installed in editable mode (i.e. setuptools "develop mode").
It means that changes in the local directory will be reflected directly in environment.

If you don't want the dependency to be installed in editable mode you can specify it in the `pyproject.toml` file:

```
```toml
[tool.poetry.dependencies]
my-package = {path = "../my/path", develop = false}
```

If the package(s) you want to install provide extras, you can specify them
when adding the package:

```bash
poetry add requests[security,socks]
poetry add "requests[security,socks]~=2.22.0"
poetry add "git+https://github.com/pallets/flask.git@1.1.1[dotenv,dev]"
```

### Options

* `--dev (-D)`: Add package as development dependency.
* `--git`: The url of the Git repository.
* `--path`: The path to a dependency.
* `--extras (-E)`: Extras to activate for the dependency.
* `--optional` : Add as an optional dependency.
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose).

Expand Down
51 changes: 19 additions & 32 deletions poetry/console/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ class AddCommand(EnvCommand, InitCommand):
arguments = [argument("name", "Packages to add.", multiple=True)]
options = [
option("dev", "D", "Add package as development dependency."),
option("git", None, "The url of the Git repository.", flag=False),
option("path", None, "The path to a dependency.", flag=False),
option(
"extras",
"E",
Expand Down Expand Up @@ -58,17 +56,11 @@ def handle(self):
packages = self.argument("name")
is_dev = self.option("dev")

if (self.option("git") or self.option("path") or self.option("extras")) and len(
packages
) > 1:
if self.option("extras") and len(packages) > 1:
raise ValueError(
"You can only specify one package "
"when using the --git or --path options"
"You can only specify one package " "when using the --extras option"
)

if self.option("git") and self.option("path"):
raise RuntimeError("--git and --path cannot be used at the same time")

section = "dependencies"
if is_dev:
section = "dev-dependencies"
Expand All @@ -83,32 +75,27 @@ def handle(self):
for name in packages:
for key in poetry_content[section]:
if key.lower() == name.lower():
pair = self._parse_requirements([name])[0]
if "git" in pair or pair.get("version") == "latest":
continue

raise ValueError("Package {} is already present".format(name))

if self.option("git") or self.option("path"):
requirements = {packages[0]: ""}
else:
requirements = self._determine_requirements(
packages, allow_prereleases=self.option("allow-prereleases")
)
requirements = self._format_requirements(requirements)
requirements = self._determine_requirements(
packages, allow_prereleases=self.option("allow-prereleases")
)

# validate requirements format
for constraint in requirements.values():
parse_constraint(constraint)
for _constraint in requirements:
if "version" in _constraint:
# Validate version constraint
parse_constraint(_constraint["version"])

for name, _constraint in requirements.items():
constraint = inline_table()
constraint["version"] = _constraint

if self.option("git"):
del constraint["version"]

constraint["git"] = self.option("git")
elif self.option("path"):
del constraint["version"]
for name, value in _constraint.items():
if name == "name":
continue

constraint["path"] = self.option("path")
constraint[name] = value

if self.option("optional"):
constraint["optional"] = True
Expand All @@ -135,7 +122,7 @@ def handle(self):
if len(constraint) == 1 and "version" in constraint:
constraint = constraint["version"]

poetry_content[section][name] = constraint
poetry_content[section][_constraint["name"]] = constraint

# Write new content
self.poetry.file.write(content)
Expand All @@ -152,7 +139,7 @@ def handle(self):

installer.dry_run(self.option("dry-run"))
installer.update(True)
installer.whitelist(requirements)
installer.whitelist([r["name"] for r in requirements])

try:
status = installer.run()
Expand Down
Loading