Remade dependency graph example to test suite, package venv support
This commit is contained in:
@@ -1,28 +1,36 @@
|
||||
from os.path import basename, dirname, join
|
||||
|
||||
from ..cli import (resolve_circular_references, # type: ignore
|
||||
show_unresolved_dependencies)
|
||||
from ..config import FileConfig # type: ignore
|
||||
from ..language import MakeDataConfig # type: ignore
|
||||
from ..project_graph import ProjectGraph # type: ignore
|
||||
from ..shell import failure, pretty_debug, success # type: ignore
|
||||
from icmtoolchain.cli import resolve_circular_references
|
||||
from icmtoolchain.config import FileConfig
|
||||
from icmtoolchain.language import MakeDataConfig
|
||||
from icmtoolchain.project_graph import ProjectGraph
|
||||
from icmtoolchain.utils import RuntimeCodeError
|
||||
|
||||
|
||||
def pretty_print_order(graph: ProjectGraph):
|
||||
return ' -> '.join([basename(edge.project.directory) \
|
||||
if isinstance(edge.project, FileConfig) \
|
||||
else str(edge) for edge in graph.traverse_dependencies()])
|
||||
RESOLVED_DEPENDENCY_ORDER = [
|
||||
"8-multi-reference",
|
||||
"4-circular-dependency",
|
||||
"7-simple-reference",
|
||||
"3-cross-reference",
|
||||
"2-circular-reference",
|
||||
"6-multi-dependency",
|
||||
"5-simple-dependency",
|
||||
"1-master-project"
|
||||
]
|
||||
|
||||
master_project_path = join(dirname(__file__), "1-master-project")
|
||||
master_project = MakeDataConfig.of(master_project_path)
|
||||
if master_project:
|
||||
graph = ProjectGraph(master_project)
|
||||
graph.collect_dependencies(master_project)
|
||||
success(f"Got {len(graph.values())} nodes of {basename(master_project_path)!r} dependencies")
|
||||
unresolved_artifacts = graph.resolve_dependencies()
|
||||
show_unresolved_dependencies(unresolved_artifacts)
|
||||
pretty_debug(f"Currently order (excluding affected projects): {pretty_print_order(graph)}")
|
||||
resolve_circular_references(graph)
|
||||
success(f"Order: {pretty_print_order(graph)}")
|
||||
else:
|
||||
failure("No such project.")
|
||||
if not master_project:
|
||||
raise RuntimeCodeError(1, "No such project.")
|
||||
graph = ProjectGraph(master_project)
|
||||
graph.collect_dependencies(master_project)
|
||||
if len(graph) != len(RESOLVED_DEPENDENCY_ORDER):
|
||||
raise RuntimeCodeError(2, f"Graph dependencies length mismatch: {len(RESOLVED_DEPENDENCY_ORDER)} != {len(graph)}.")
|
||||
graph.resolve_dependencies()
|
||||
if not resolve_circular_references(graph):
|
||||
raise RuntimeCodeError(3, "Expected circular dependencies, but nothing was found.")
|
||||
resolved_dependencies = []
|
||||
for dependency in graph.traverse_dependencies():
|
||||
assert isinstance(dependency.project, FileConfig)
|
||||
resolved_dependencies.append(basename(dependency.project.directory))
|
||||
if resolved_dependencies != RESOLVED_DEPENDENCY_ORDER:
|
||||
raise RuntimeCodeError(4, f"Traversed dependencies sorting mismatch: {' -> '.join(resolved_dependencies)}.")
|
||||
|
||||
@@ -45,3 +45,6 @@ build-backend = "pdm.backend"
|
||||
|
||||
[tool.pdm]
|
||||
distribution = true
|
||||
|
||||
[tool.pdm.build]
|
||||
package-dir = "src"
|
||||
|
||||
@@ -70,8 +70,7 @@ def resolve_circular_references(graph: ProjectGraph) -> bool:
|
||||
if any(unused_edges):
|
||||
repr_unused_edges = [f"{edge}" for edge in unused_edges]
|
||||
failure(f"Following dependencies have been removed as there is no further connection in them to other projects: {', '.join(repr_unused_edges)}!")
|
||||
from .utils import RuntimeCodeError
|
||||
raise RuntimeCodeError(255, "Cannot build a project with unresolved dependencies!")
|
||||
raise RuntimeError("Cannot build a project with unresolved dependencies!")
|
||||
return True
|
||||
|
||||
def execute_task(callable: 'NamedCallable') -> None:
|
||||
@@ -355,20 +354,20 @@ def run_cli_test():
|
||||
def run_example_test(name: str):
|
||||
examples_directory = join(dirname(__file__), "..", "..", "examples")
|
||||
if not isdir(examples_directory):
|
||||
failure("Examples directory is not available.")
|
||||
return
|
||||
raise RuntimeError("Examples directory is not available.")
|
||||
example_executable = join(examples_directory, name, "__main__.py")
|
||||
if not isfile(example_executable):
|
||||
failure(f"No such example {name!r}. It should be one of: {', '.join(listdir(examples_directory))}.")
|
||||
return
|
||||
raise RuntimeError(f"No such example {name!r}. It should be one of: {', '.join(listdir(examples_directory))}.")
|
||||
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
example_name = f"{__name__[:__name__.rindex('.')]}.examples.{name}"
|
||||
example_spec = spec_from_file_location(example_name, example_executable)
|
||||
assert example_spec
|
||||
if not example_spec:
|
||||
raise RuntimeError(f"Cannot obtain example {name!r} spec.")
|
||||
example_module = module_from_spec(example_spec)
|
||||
sys.modules[example_name] = example_module
|
||||
assert example_spec.loader
|
||||
if not example_spec.loader:
|
||||
raise RuntimeError(f"Cannot obtain example {name!r} module loader.")
|
||||
example_spec.loader.exec_module(example_module)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user