def do_lock( project: Project, strategy: str = "all", tracked_names: Optional[Iterable[str]] = None, requirements: Optional[List[Requirement]] = None, ) -> Dict[str, Candidate]: """Performs the locking process and update lockfile. :param project: the project instance :param strategy: update stratege: reuse/eager/all :param tracked_names: required when using eager strategy :param requirements: An optional dictionary of requirements, read from pyproject if not given. """ check_project_file(project) # TODO: multiple dependency definitions for the same package. provider = project.get_provider(strategy, tracked_names) if not requirements: requirements = [ r for deps in project.all_dependencies.values() for r in deps.values() ] with stream.open_spinner(title="Resolving dependencies", spinner="dots") as spin, stream.logging("lock"): reporter = project.get_reporter(requirements, tracked_names, spin) resolver = project.core.resolver_class(provider, reporter) mapping, dependencies, summaries = resolve( resolver, requirements, project.environment.python_requires) data = format_lockfile(mapping, dependencies, summaries) spin.succeed("Resolution success") project.write_lockfile(data) return mapping
def do_lock( project: Project, strategy: str = "all", tracked_names: Optional[Iterable[str]] = None, requirements: Optional[List[Requirement]] = None, ) -> Dict[str, Candidate]: """Performs the locking process and update lockfile. :param project: the project instance :param strategy: update strategy: reuse/eager/all :param tracked_names: required when using eager strategy :param requirements: An optional dictionary of requirements, read from pyproject if not given. """ check_project_file(project) # TODO: multiple dependency definitions for the same package. provider = project.get_provider(strategy, tracked_names) if not requirements: requirements = [ r for deps in project.all_dependencies.values() for r in deps.values() ] resolve_max_rounds = int(project.config["strategy.resolve_max_rounds"]) ui = project.core.ui with ui.logging("lock"): # The context managers are nested to ensure the spinner is stopped before # any message is thrown to the output. with ui.open_spinner(title="Resolving dependencies", spinner="dots") as spin: reporter = project.get_reporter(requirements, tracked_names, spin) resolver = project.core.resolver_class(provider, reporter) try: mapping, dependencies, summaries = resolve( resolver, requirements, project.environment.python_requires, resolve_max_rounds, ) except ResolutionTooDeep: spin.fail(f"{termui.Emoji.LOCK} Lock failed") ui.echo( "The dependency resolution exceeds the maximum loop depth of " f"{resolve_max_rounds}, there may be some circular dependencies " "in your project. Try to solve them or increase the " f"{termui.green('`strategy.resolve_max_rounds`')} config.", err=True, ) raise except ResolutionImpossible as err: spin.fail(f"{termui.Emoji.LOCK} Lock failed") ui.echo(format_resolution_impossible(err), err=True) raise else: data = format_lockfile(mapping, dependencies, summaries) spin.succeed(f"{termui.Emoji.LOCK} Lock successful") project.write_lockfile(data) return mapping
def do_lock( project: Project, strategy: str = "all", tracked_names: Iterable[str] | None = None, requirements: list[Requirement] | None = None, dry_run: bool = False, refresh: bool = False, ) -> dict[str, Candidate]: """Performs the locking process and update lockfile.""" check_project_file(project) if refresh: locked_repo = project.locked_repository repo = project.get_repository() mapping: dict[str, Candidate] = {} dependencies: dict[str, list[Requirement]] = {} with project.core.ui.open_spinner("Re-calculating hashes..."): for key, candidate in locked_repo.packages.items(): reqs, python_requires, summary = locked_repo.candidate_info[key] candidate.hashes = repo.get_hashes(candidate) candidate.summary = summary candidate.requires_python = python_requires ident = cast(str, key[0]) mapping[ident] = candidate dependencies[ident] = list(map(parse_requirement, reqs)) lockfile = format_lockfile(project, mapping, dependencies) project.write_lockfile(lockfile) return mapping # TODO: multiple dependency definitions for the same package. provider = project.get_provider(strategy, tracked_names) if not requirements: requirements = [ r for deps in project.all_dependencies.values() for r in deps.values() ] resolve_max_rounds = int(project.config["strategy.resolve_max_rounds"]) ui = project.core.ui with ui.logging("lock"): # The context managers are nested to ensure the spinner is stopped before # any message is thrown to the output. with ui.open_spinner(title="Resolving dependencies", spinner="dots") as spin: reporter = project.get_reporter(requirements, tracked_names, spin) resolver: Resolver = project.core.resolver_class(provider, reporter) signals.pre_lock.send(project, requirements=requirements, dry_run=dry_run) try: mapping, dependencies = resolve( resolver, requirements, project.environment.python_requires, resolve_max_rounds, ) except ResolutionTooDeep: spin.fail(f"{termui.Emoji.LOCK} Lock failed") ui.echo( "The dependency resolution exceeds the maximum loop depth of " f"{resolve_max_rounds}, there may be some circular dependencies " "in your project. Try to solve them or increase the " f"{termui.green('`strategy.resolve_max_rounds`')} config.", err=True, ) raise except ResolutionImpossible as err: spin.fail(f"{termui.Emoji.LOCK} Lock failed") ui.echo(format_resolution_impossible(err), err=True) raise ResolutionImpossible("Unable to find a resolution") from None else: data = format_lockfile(project, mapping, dependencies) spin.succeed(f"{termui.Emoji.LOCK} Lock successful") signals.post_lock.send(project, resolution=mapping, dry_run=dry_run) project.write_lockfile(data, write=not dry_run) return mapping