Skip to content
Closed
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
17 changes: 16 additions & 1 deletion docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ update the constraint, for example `^2.3`. You can do this using the `add` comma
* `--dry-run` : Outputs the operations but will not execute anything (implicitly enables --verbose).
* `--no-dev` : Do not install dev dependencies.
* `--lock` : Do not perform install (only update the lockfile).
* `--editable`: "Add as dependency in editable mode. Only permissible for non path or VCS dependencies!"

## add

Expand Down Expand Up @@ -230,7 +231,13 @@ poetry add ../my-package/dist/my-package-0.1.0.tar.gz
poetry add ../my-package/dist/my_package-0.1.0.whl
```

If you want the dependency to be installed in editable mode you can specify it in the `pyproject.toml` file. It means that changes in the local directory will be reflected directly in environment.
If you want the dependency to be installed in editable mode you can pass the `--editable` flag or specify it in the `pyproject.toml` file. It means that changes in the local directory will be reflected directly in environment.

```bash
poetry add --editable ../my/path
```

or

```toml
[tool.poetry.dependencies]
Expand All @@ -242,6 +249,14 @@ my-package = {path = "../my/path", develop = true}
Before poetry 1.1 path dependencies were installed in editable mode by default. You should always set the `develop` attribute explicit,
to make sure the behavior is the same for all poetry versions.

!!!note

We are working on resolving the inconsistency in the naming of the `--editable` flag and the `develop` attribute. In future the `develop` attribute will be deprecated!

!!!note

Currently passing the `--editable` flag with a non path or VCS dependency will result in a nonintuitive runtime error. We are currently working on providing a better error message.

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

Expand Down
8 changes: 8 additions & 0 deletions poetry/console/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class AddCommand(InstallerCommand, InitCommand):
"Output the operations but do not execute anything (implicitly enables --verbose).",
),
option("lock", None, "Do not perform operations (only update the lockfile)."),
option(
"editable",
None,
"Add as dependency in editable mode. Will cause command to fail for non path or VCS dependencies!",
),
]
help = (
"The add command adds required packages to your <comment>pyproject.toml</> and installs them.\n\n"
Expand Down Expand Up @@ -146,6 +151,9 @@ def handle(self):
if self.option("source"):
constraint["source"] = self.option("source")

if self.option("editable"):
constraint["develop"] = True

if len(constraint) == 1 and "version" in constraint:
constraint = constraint["version"]

Expand Down
91 changes: 91 additions & 0 deletions tests/console/commands/test_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,61 @@ def test_add_with_lock(app, repo, tester):
assert content_hash != app.poetry.locker.lock_data["metadata"]["content-hash"]


def test_add_with_editable_fails_for_schema_without_develop(app, repo, tester):
repo.add_package(get_package("cachy", "0.2.0"))

with pytest.raises(RuntimeError) as e:
tester.execute("cachy --editable")
# TODO: Provide better error message.
# `Develop` attribute is only supported by directory
# https://github.com/python-poetry/poetry-core/blob/master/poetry/core/packages/directory_dependency.py
# and vcs https://github.com/python-poetry/poetry-core/blob/master/poetry/core/packages/directory_dependency.py
# dependencies. There should be an explicit error message raised, stating that `develop` is
# inappropriate for other source types.
assert """\
The Poetry configuration is invalid:
- [dependencies.cachy] {'version': '^0.2.0', 'develop': True} is not valid under any of the given schemas
""" in str(
e.value
)


def test_add_with_editable(app, repo, tester, mocker):
p = mocker.patch("poetry.utils._compat.Path.cwd")
p.return_value = Path(__file__).parent

repo.add_package(get_package("pendulum", "1.4.4"))
repo.add_package(get_package("cleo", "0.6.5"))

path = "../git/github.com/demo/demo"
tester.execute("{} --editable".format(path))

expected = """\

Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 2 installs, 0 updates, 0 removals

• Installing pendulum (1.4.4)
• Installing demo (0.1.2 {})
""".format(
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)

assert expected == tester.io.fetch_output()

content = app.poetry.file.read()["tool"]["poetry"]

assert "demo" in content["dependencies"]
assert content["dependencies"]["demo"] == {
"path": "../git/github.com/demo/demo",
"develop": True,
}


def test_add_no_constraint_old_installer(app, repo, installer, old_tester):
repo.add_package(get_package("cachy", "0.1.0"))
repo.add_package(get_package("cachy", "0.2.0"))
Expand Down Expand Up @@ -1653,3 +1708,39 @@ def test_dry_run_restore_original_content(app, repo, installer, tester):
tester.execute("cachy --dry-run")

assert original_content == app.poetry.file.read()


def test_add_with_editable_old_installer(app, repo, old_tester, mocker):
p = mocker.patch("poetry.utils._compat.Path.cwd")
p.return_value = Path(__file__).parent

repo.add_package(get_package("pendulum", "1.4.4"))
repo.add_package(get_package("cleo", "0.6.5"))

path = "../git/github.com/demo/demo"
old_tester.execute("{} --editable".format(path))

expected = """\

Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 2 installs, 0 updates, 0 removals

- Installing pendulum (1.4.4)
- Installing demo (0.1.2 {})
""".format(
app.poetry.file.parent.joinpath(path).resolve().as_posix()
)

assert expected == old_tester.io.fetch_output()

content = app.poetry.file.read()["tool"]["poetry"]

assert "demo" in content["dependencies"]
assert content["dependencies"]["demo"] == {
"path": "../git/github.com/demo/demo",
"develop": True,
}