Skip to content

Commit

Permalink
Merge pull request #591 from pdm-project/deprecate/section-option
Browse files Browse the repository at this point in the history
  • Loading branch information
frostming authored Aug 9, 2021
2 parents 4b070a7 + 3d4f511 commit 39189bb
Show file tree
Hide file tree
Showing 26 changed files with 248 additions and 180 deletions.
2 changes: 1 addition & 1 deletion docs/docs/pyproject/pep621.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ tests = [
To install a group of optional dependencies:

```bash
$ pdm install -s socks
$ pdm install -G socks
```

`-s` option can be given multiple times to include more than one group.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/usage/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ commands =
[testenv:lint]
deps = pdm
commands =
pdm install -s lint
pdm install -G lint
flake8 src/
```

Expand Down
40 changes: 20 additions & 20 deletions docs/docs/usage/dependency.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ $ pdm add requests
`pdm add` can be followed by one or several dependencies, and the dependency specification is described in
[PEP 508](https://www.python.org/dev/peps/pep-0508/).

PDM also allows extra dependency groups by providing `-s/--section <name>` option, and those dependencies will go to
PDM also allows extra dependency groups by providing `-G/--group <name>` option, and those dependencies will go to
`[project.optional-dependencies.<name>]` table in the project file, respectively.

After that, dependencies and sub-dependencies will be resolved properly and installed for you, you can view `pdm.lock` to see
Expand All @@ -53,7 +53,7 @@ Local packages can be installed in [editable mode](https://pip.pypa.io/en/stable

_New in 1.5.0_

PDM also supports defining groups of dependencies that are useful for development. They can be classified as different sections,
PDM also supports defining groups of dependencies that are useful for development,
e.g. some for testing and others for linting. We usually don't want these dependencies appear in the distribution's metadata
so using `optional-dependencies` is probably not a good idea. We can define them as development dependencies:

Expand All @@ -68,7 +68,7 @@ This will result in a pyproject.toml as following:
test = ["pytest"]
```

For backward-compatibility, if `-s/--section` is not given, dependencies will go to `dev` group under `[tool.pdm.dev-dependencies]` by default.
For backward-compatibility, if `-G/--group` is not given, dependencies will go to `dev` group under `[tool.pdm.dev-dependencies]` by default.

!!! NOTE
The same group name MUST NOT appear in both `[tool.pdm.dev-dependencies]` and `[project.optional-dependencies]` .
Expand Down Expand Up @@ -97,26 +97,26 @@ To update the specified package(s):
$ pdm update requests
```

To update multiple sections of dependencies:
To update multiple groups of dependencies:

```console
$ pdm update -s security -s http
$ pdm update -G security -G http
```

To update a given package in the specified section:
To update a given package in the specified group:

```console
$ pdm update -s security cryptography
$ pdm update -G security cryptography
```

If the section is not given, PDM will search for the requirement in the default dependencies set and raises an error if none is found.
If the group is not given, PDM will search for the requirement in the default dependencies set and raises an error if none is found.

To update packages in development dependencies:

```console
# Update all default + dev-dependencies
$ pdm update -d
# Update a package in the specified section of dev-dependencies
# Update a package in the specified group of dev-dependencies
$ pdm update -ds test pytest
```

Expand All @@ -136,10 +136,10 @@ To remove existing dependencies from project file and the library directory:
```console
# Remove requests from the default dependencies
$ pdm remove requests
# Remove h11 from the 'web' section of optional-dependencies
$ pdm remove -s web h11
# Remove pytest-cov from the `test` section of dev-dependencies
$ pdm remove -ds test pytest-cov
# Remove h11 from the 'web' group of optional-dependencies
$ pdm remove -G web h11
# Remove pytest-cov from the `test` group of dev-dependencies
$ pdm remove -dG test pytest-cov
```

## Install the packages pinned in lock file
Expand Down Expand Up @@ -170,15 +170,15 @@ dev2 = ["mkdocs"]
| Command | What it does | Comments |
| ------------------------------- | ------------------------------------------------------------------------ | ------------------------- |
| `pdm install` | install prod and dev deps (no optional) | |
| `pdm install -s extra1` | install prod deps, dev deps, and "extra1" optional section | |
| `pdm install -s dev1` | install prod deps and only "dev1" dev section | |
| `pdm install -s:all` | install prod deps, dev deps and "extra1", "extra2" optional sections | |
| `pdm install -s extra1 -s dev1` | install prod deps, "extra1" optional section and only "dev1" dev section | |
| `pdm install -G extra1` | install prod deps, dev deps, and "extra1" optional group | |
| `pdm install -G dev1` | install prod deps and only "dev1" dev group | |
| `pdm install -G:all` | install prod deps, dev deps and "extra1", "extra2" optional groups | |
| `pdm install -G extra1 -G dev1` | install prod deps, "extra1" optional group and only "dev1" dev group | |
| `pdm install --prod` | install prod only | |
| `pdm install --prod -s extra1` | install prod deps and "extra1" optional | |
| `pdm install --prod -s dev1` | Fail, `--prod` can't be given with dev dependencies | Leave the `--prod` option |
| `pdm install --prod -G extra1` | install prod deps and "extra1" optional | |
| `pdm install --prod -G dev1` | Fail, `--prod` can't be given with dev dependencies | Leave the `--prod` option |

**All** development dependencies are included as long as `--prod` is not passed and `-s` doesn't specify any dev sections.
**All** development dependencies are included as long as `--prod` is not passed and `-G` doesn't specify any dev groups.

Besides, if you don't want the root project to be installed, add `--no-self` option, and `--no-editable` can be used when you want all packages to be installed in non-editable versions. With `--no-editable` turn on, you can safely archive the whole `__pypackages__` and copy it to the target environment for deployment.

Expand Down
1 change: 1 addition & 0 deletions news/591.removal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate `-s/--section` option in favor of `-G/--group`.
80 changes: 40 additions & 40 deletions pdm/cli/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
merge_dictionary,
save_version_specifiers,
set_env_in_reg,
translate_sections,
translate_groups,
)
from pdm.exceptions import NoPythonVersion, PdmUsageError, ProjectError
from pdm.formats import FORMATS
Expand Down Expand Up @@ -121,7 +121,7 @@ def resolve_candidates_from_lockfile(
def do_sync(
project: Project,
*,
sections: Sequence[str] = (),
groups: Sequence[str] = (),
dev: bool = True,
default: bool = True,
dry_run: bool = False,
Expand All @@ -146,10 +146,10 @@ def do_sync(
"Lock file hash doesn't match pyproject.toml, packages may be outdated",
err=True,
)
sections = translate_sections(project, default, dev, sections or ())
groups = translate_groups(project, default, dev, groups or ())
requirements = []
for section in sections:
requirements.extend(project.get_dependencies(section).values())
for group in groups:
requirements.extend(project.get_dependencies(group).values())
candidates = resolve_candidates_from_lockfile(project, requirements)
if tracked_names and dry_run:
candidates = {
Expand All @@ -162,7 +162,7 @@ def do_sync(
clean,
dry_run,
no_editable=no_editable,
install_self=not no_self and "default" in sections and bool(project.meta.name),
install_self=not no_self and "default" in groups and bool(project.meta.name),
use_install_cache=project.config["feature.install_cache"],
)
handler.synchronize()
Expand All @@ -171,7 +171,7 @@ def do_sync(
def do_add(
project: Project,
dev: bool = False,
section: str | None = None,
group: str | None = None,
sync: bool = True,
save: str = "compatible",
strategy: str = "reuse",
Expand All @@ -185,8 +185,8 @@ def do_add(
check_project_file(project)
if not editables and not packages:
raise PdmUsageError("Must specify at least one package or editable package.")
if not section:
section = "dev" if dev else "default"
if not group:
group = "dev" if dev else "default"
tracked_names: set[str] = set()
requirements: dict[str, Requirement] = {}
for r in [parse_requirement(line, True) for line in editables] + [
Expand All @@ -196,29 +196,29 @@ def do_add(
tracked_names.add(key)
requirements[key] = r
project.core.ui.echo(
f"Adding packages to {section} {'dev-' if dev else ''}dependencies: "
f"Adding packages to {group} {'dev-' if dev else ''}dependencies: "
+ ", ".join(termui.green(key or "", bold=True) for key in requirements)
)
all_dependencies = project.all_dependencies
section_deps = all_dependencies.setdefault(section, {})
group_deps = all_dependencies.setdefault(group, {})
if unconstrained:
for req in section_deps.values():
for req in group_deps.values():
req.specifier = get_specifier("")
section_deps.update(requirements)
group_deps.update(requirements)
reqs = [r for deps in all_dependencies.values() for r in deps.values()]
resolved = do_lock(project, strategy, tracked_names, reqs)

# Update dependency specifiers and lockfile hash.
deps_to_update = section_deps if unconstrained else requirements
save_version_specifiers({section: deps_to_update}, resolved, save)
project.add_dependencies(deps_to_update, section, dev)
deps_to_update = group_deps if unconstrained else requirements
save_version_specifiers({group: deps_to_update}, resolved, save)
project.add_dependencies(deps_to_update, group, dev)
lockfile = project.lockfile
project.write_lockfile(lockfile, False)

if sync:
do_sync(
project,
sections=(section,),
groups=(group,),
default=False,
no_editable=no_editable,
no_self=no_self,
Expand All @@ -229,7 +229,7 @@ def do_update(
project: Project,
*,
dev: bool | None = None,
sections: Sequence[str] = (),
groups: Sequence[str] = (),
default: bool = True,
strategy: str = "reuse",
save: str = "compatible",
Expand All @@ -242,21 +242,21 @@ def do_update(
) -> None:
"""Update specified packages or all packages"""
check_project_file(project)
if len(packages) > 0 and (top or len(sections) > 1 or not default):
if len(packages) > 0 and (top or len(groups) > 1 or not default):
raise PdmUsageError(
"packages argument can't be used together with multiple -s or "
"packages argument can't be used together with multiple -G or "
"--no-default and --top."
)
all_dependencies = project.all_dependencies
updated_deps: dict[str, dict[str, Requirement]] = defaultdict(dict)
install_dev = True if dev is None else dev
if not packages:
sections = translate_sections(project, default, install_dev, sections or ())
for section in sections:
updated_deps[section] = all_dependencies[section]
groups = translate_groups(project, default, install_dev, groups or ())
for group in groups:
updated_deps[group] = all_dependencies[group]
else:
section = sections[0] if sections else ("dev" if dev else "default")
dependencies = all_dependencies[section]
group = groups[0] if groups else ("dev" if dev else "default")
dependencies = all_dependencies[group]
for name in packages:
matched_name = next(
filter(
Expand All @@ -269,10 +269,10 @@ def do_update(
if not matched_name:
raise ProjectError(
"{} does not exist in {} {}dependencies.".format(
termui.green(name, bold=True), section, "dev-" if dev else ""
termui.green(name, bold=True), group, "dev-" if dev else ""
)
)
updated_deps[section][matched_name] = dependencies[matched_name]
updated_deps[group][matched_name] = dependencies[matched_name]
project.core.ui.echo(
"Updating packages: {}.".format(
", ".join(
Expand All @@ -295,7 +295,7 @@ def do_update(
)
do_sync(
project,
sections=sections,
groups=groups,
dev=install_dev,
default=default,
clean=False,
Expand All @@ -308,16 +308,16 @@ def do_update(
if unconstrained and not dry_run:
# Need to update version constraints
save_version_specifiers(updated_deps, resolved, save)
for section, deps in updated_deps.items():
project.add_dependencies(deps, section, dev or False)
for group, deps in updated_deps.items():
project.add_dependencies(deps, group, dev or False)
lockfile = project.lockfile
project.write_lockfile(lockfile, False)


def do_remove(
project: Project,
dev: bool = False,
section: str | None = None,
group: str | None = None,
sync: bool = True,
packages: Sequence[str] = (),
no_editable: bool = False,
Expand All @@ -327,14 +327,14 @@ def do_remove(
check_project_file(project)
if not packages:
raise PdmUsageError("Must specify at least one package to remove.")
if not section:
section = "dev" if dev else "default"
if section not in list(project.iter_sections()):
raise ProjectError(f"No-exist section {section}")
if not group:
group = "dev" if dev else "default"
if group not in list(project.iter_groups()):
raise ProjectError(f"No-exist group {group}")

deps = project.get_pyproject_dependencies(section, dev)
deps = project.get_pyproject_dependencies(group, dev)
project.core.ui.echo(
f"Removing packages from {section} {'dev-' if dev else ''}dependencies: "
f"Removing packages from {group} {'dev-' if dev else ''}dependencies: "
+ ", ".join(str(termui.green(name, bold=True)) for name in packages)
)
for name in packages:
Expand All @@ -345,7 +345,7 @@ def do_remove(
if not matched_indexes:
raise ProjectError(
"{} does not exist in {} dependencies.".format(
termui.green(name, bold=True), section
termui.green(name, bold=True), group
)
)
for i in matched_indexes:
Expand All @@ -356,7 +356,7 @@ def do_remove(
if sync:
do_sync(
project,
sections=(section,),
groups=(group,),
default=False,
clean=True,
no_editable=no_editable,
Expand Down Expand Up @@ -545,7 +545,7 @@ def do_import(
else:
key = format
if options is None:
options = Namespace(dev=False, section=None)
options = Namespace(dev=False, group=None)
project_data, settings = FORMATS[key].convert(project, filename, options)
pyproject = project.pyproject or atoml.document()

Expand Down
15 changes: 13 additions & 2 deletions pdm/cli/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pdm.cli import actions
from pdm.cli.commands.base import BaseCommand
from pdm.cli.options import (
deprecated,
install_group,
packages_group,
save_strategy_group,
Expand All @@ -24,7 +25,17 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None:
help="Add packages into dev dependencies",
)
parser.add_argument(
"-s", "--section", help="Specify target section to add into"
"-s",
"--section",
dest="group",
help="(DEPRECATED) Alias of `-G/--group`",
type=deprecated(
"`-s/--section` is deprecated in favor of `-G/--groups` "
"and will be removed in the next minor release."
),
)
parser.add_argument(
"-G", "--group", help="Specify the target dependency group to add into"
)
parser.add_argument(
"-u",
Expand All @@ -51,7 +62,7 @@ def handle(self, project: Project, options: argparse.Namespace) -> None:
actions.do_add(
project,
dev=options.dev,
section=options.section,
group=options.group,
sync=options.sync,
save=options.save_strategy or project.config["strategy.save"],
strategy=options.update_strategy or project.config["strategy.update"],
Expand Down
Loading

0 comments on commit 39189bb

Please sign in to comment.