Skip to content

Commit

Permalink
improvement: Add a separate API to retrieve the projects in a reposit…
Browse files Browse the repository at this point in the history
…ory in topological order such that most Slap commands that do not care about the order do not have the overhead of inspecting the project dependencies and sorting the projects.
  • Loading branch information
NiklasRosenstein committed Apr 8, 2022
1 parent fa584be commit 5f75071
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 12 deletions.
9 changes: 9 additions & 0 deletions .changelog/_unreleased.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@ id = "bd6e203d-1a23-4f59-a521-ba83866e9eb7"
type = "improvement"
description = "Allow unrecognized keys in `ChangelogConfig`"
author = "@NiklasRosenstein"

[[entries]]
id = "bec1a134-1576-46c8-8159-f52090d42c35"
type = "improvement"
description = "Add a separate API to retrieve the projects in a repository in topological order such that most Slap commands that do not care about the order do not have the overhead of inspecting the project dependencies and sorting the projects."
author = "@NiklasRosenstein"
issues = [
"https://github.com/NiklasRosenstein/slam/issues/50",
]
12 changes: 7 additions & 5 deletions src/slap/ext/application/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ def activate(self, app: Application, config: None) -> None:
app.cleo.add(self)

def handle(self) -> int:
projects = self.app.repository.get_projects_ordered()

self.line(f'Repository <s>"{self.app.repository.directory}"</s>')
self.line(f' vcs: <opt>{self.app.repository.vcs()}</opt>')
self.line(f' host: <opt>{self.app.repository.host()}</opt>')
self.line(f' projects: <opt>{[p.id for p in self.app.repository.projects()]}</opt>')
self.line(f' projects: <opt>{[p.id for p in projects]}</opt>')

for project in self.app.repository.projects():
for project in projects:
if not project.is_python_project: continue
packages_list = project.packages()
packages = (
Expand All @@ -39,10 +41,10 @@ def handle(self) -> int:
self.line(f' readme: <opt>{project.handler().get_readme(project)}</opt>')
self.line(f' handler: <opt>{project.handler()}</opt>')

inter_deps = project.get_interdependencies(self.app.repository.projects())
inter_deps = project.get_interdependencies(projects)
if inter_deps:
projects = ", ".join(f"<opt>{p.dist_name()}</opt>" for p in inter_deps)
self.line(f' depends on: {projects}')
project_names = ", ".join(f"<opt>{p.dist_name()}</opt>" for p in inter_deps)
self.line(f' depends on: {project_names}')

deps = project.dependencies()
self.line(f' dependencies:')
Expand Down
2 changes: 1 addition & 1 deletion src/slap/ext/application/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def handle(self) -> int:
assert len(projects) == 1, projects
project_dependencies = self._get_project_dependencies(projects[0])
else:
projects = self.app.repository.projects()
projects = self.app.repository.get_projects_ordered()
project_dependencies = []

extras = {x.strip() for x in (self.option("extras") or self.option("only-extras") or '').split(',') if x.strip()}
Expand Down
2 changes: 1 addition & 1 deletion src/slap/ext/application/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def handle(self) -> int:
num_projects = 0
num_skipped = 0

for project in self.app.repository.projects():
for project in self.app.repository.get_projects_ordered():
if not project.is_python_project:
continue

Expand Down
2 changes: 1 addition & 1 deletion src/slap/ext/project_handlers/poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def get_dependency_location_key_sequence(
return ['tool', 'poetry'] + locator, value


def convert_poetry_dependencies(dependencies: dict[str, str] | list[str]) -> list[str]:
def convert_poetry_dependencies(dependencies: dict[str, str | t.Any] | list[str]) -> list[str]:
from poetry.core.packages.dependency import Dependency # type: ignore[import]

if isinstance(dependencies, list):
Expand Down
15 changes: 11 additions & 4 deletions src/slap/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,23 @@ def _get_repository_handler(self) -> RepositoryHandlerPlugin | None:
def _get_projects(self) -> list[Project]:
""" Returns the projects provided by the project handler, but sorted in topological order. """

from nr.util.digraph import DiGraph
from nr.util.digraph.algorithm.topological_sort import topological_sort

handler = self._handler()
if not handler:
return []

projects = sorted(handler.get_projects(self), key=lambda p: p.id)
return sorted(handler.get_projects(self), key=lambda p: p.id)

def get_projects_ordered(self) -> list[Project]:
""" Return a topological ordering of the projects. """

from nr.util.digraph import DiGraph
from nr.util.digraph.algorithm.topological_sort import topological_sort
from slap.project import Project

graph: DiGraph[Project, None, None] = DiGraph()
projects = self.projects()
for project in projects:
assert isinstance(project, Project)
graph.add_node(project, None)
for dep in project.get_interdependencies(projects):
graph.add_node(dep, None)
Expand Down

0 comments on commit 5f75071

Please sign in to comment.