def handle(self, project: Project, options: argparse.Namespace) -> None: sections: list[str] = list(options.sections) if options.pyproject: options.hashes = False sections = translate_sections( project, options.default, options.dev, options.sections or (), ) requirements: dict[str, Requirement] = {} packages: Iterable[Requirement] | Iterable[Candidate] for section in sections: requirements.update(project.get_dependencies(section)) if options.pyproject: packages = requirements.values() else: project.core.ui.echo( "The exported requirements file is no longer cross-platform. " "Using it on other platforms may cause unexpected result.", fg="yellow", err=True, ) candidates = resolve_candidates_from_lockfile( project, requirements.values()) packages = candidates.values() content = FORMATS[options.format].export(project, packages, options) # type: ignore if options.output: Path(options.output).write_text(content) else: project.core.ui.echo(content)
def do_sync( project: Project, sections: Sequence[str] = (), dev: bool = False, default: bool = True, dry_run: bool = False, clean: Optional[bool] = None, tracked_names: Optional[Sequence[str]] = None, ) -> None: """Synchronize project""" if not project.lockfile_file.exists(): raise ProjectError("Lock file does not exist, nothing to sync") clean = default if clean is None else clean if tracked_names and dry_run: candidates = { name: c for name, c in project.get_locked_candidates("__all__").items() if name in tracked_names } else: candidates = {} sections = translate_sections(project, default, dev, sections or ()) valid_sections = list(project.iter_sections()) for section in sections: if section not in valid_sections: raise PdmUsageError( f"Section {termui.green(repr(section))} doesn't exist " "in the pyproject.toml") candidates.update(project.get_locked_candidates(section)) handler = project.core.synchronizer_class(candidates, project.environment, clean, dry_run) handler.synchronize()
def do_sync( project: Project, *, sections: Sequence[str] = (), dev: bool = True, default: bool = True, dry_run: bool = False, clean: bool = False, requirements: list[Requirement] | None = None, tracked_names: Sequence[str] | None = None, no_editable: bool = False, no_self: bool = False, ) -> None: """Synchronize project""" if requirements is None: if not project.lockfile_file.exists(): raise ProjectError("Lock file does not exist, nothing to sync") elif not project.is_lockfile_compatible(): project.core.ui.echo( "Lock file version is not compatible with PDM, " "install may fail, please regenerate the pdm.lock", err=True, ) elif not project.is_lockfile_hash_match(): project.core.ui.echo( "Lock file hash doesn't match pyproject.toml, packages may be outdated", err=True, ) sections = translate_sections(project, default, dev, sections or ()) requirements = [] for section in sections: requirements.extend(project.get_dependencies(section).values()) candidates = resolve_candidates_from_lockfile(project, requirements) if tracked_names and dry_run: candidates = { name: c for name, c in candidates.items() if name in tracked_names } handler = project.core.synchronizer_class( candidates, project.environment, clean, dry_run, no_editable=no_editable, install_self=not no_self and "default" in sections and bool(project.meta.name), ) handler.synchronize()
def handle(self, project: Project, options: argparse.Namespace) -> None: candidates = {} sections = list(options.sections) if options.pyproject: options.hashes = False sections = translate_sections( project, options.default, compatible_dev_flag(project, options.dev), options.sections or (), ) for section in sections: if options.pyproject: candidates.update(project.get_dependencies(section)) else: candidates.update(project.get_locked_candidates(section)) candidates.pop(project.meta.name and project.meta.project_name, None) content = FORMATS[options.format].export(project, candidates.values(), options) if options.output: Path(options.output).write_text(content) else: project.core.ui.echo(content)
def do_update( project: Project, dev: bool = False, sections: Sequence[str] = (), default: bool = True, strategy: str = "reuse", save: str = "compatible", unconstrained: bool = False, top: bool = False, dry_run: bool = False, packages: Sequence[str] = (), ) -> None: """Update specified packages or all packages""" check_project_file(project) if len(packages) > 0 and (top or len(sections) > 1 or not default): raise PdmUsageError( "packages argument can't be used together with multiple -s or " "--no-default and --top.") all_dependencies = project.all_dependencies updated_deps = {} if not packages: sections = translate_sections(project, default, dev, sections or ()) for section in sections: updated_deps.update(all_dependencies[section]) else: section = sections[0] if sections else ("dev" if dev else "default") dependencies = all_dependencies[section] for name in packages: matched_name = next( filter( lambda k: safe_name(strip_extras(k)[0]).lower() == safe_name(name).lower(), dependencies.keys(), ), None, ) if not matched_name: raise ProjectError( "{} does not exist in {} {}dependencies.".format( termui.green(name, bold=True), section, "dev-" if dev else "")) updated_deps[matched_name] = dependencies[matched_name] project.core.ui.echo("Updating packages: {}.".format(", ".join( termui.green(v, bold=True) for v in updated_deps))) if unconstrained: for _, dep in updated_deps.items(): dep.specifier = get_specifier("") reqs = [r for deps in all_dependencies.values() for r in deps.values()] resolved = do_lock( project, strategy if top or packages else "all", updated_deps.keys(), reqs, dry_run=dry_run, ) do_sync( project, sections=sections, dev=dev, default=default, clean=False, dry_run=dry_run, tracked_names=updated_deps.keys() if top else None, ) if unconstrained and not dry_run: # Need to update version constraints save_version_specifiers(updated_deps, resolved, save) project.add_dependencies(updated_deps, section, dev) lockfile = project.lockfile project.write_lockfile(lockfile, False)
def test_prod_should_not_be_with_dev(project): setup_dependencies(project) with pytest.raises(PdmUsageError): cli_utils.translate_sections(project, True, False, ("test", ))
def test_dependency_group_selection(project, args, golden): setup_dependencies(project) target = cli_utils.translate_sections(project, *args) assert sorted(golden) == sorted(target)