Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
5.5 kB · 185 lines
Python
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186import collectionsimport dataclassesimport functoolsimport jsonimport pathlibimport subprocess
import yaml
class DataclassEncoder(json.JSONEncoder): def default(self, it): if dataclasses.is_dataclass(it): return dataclasses.asdict(it) return super().default(it)
@dataclasses.dataclassclass Project: name: str description: str | None project_path: str repo_path: str | None
def __hash__(self) -> int: return hash(self.name)
@classmethod def from_yaml(cls, path: pathlib.Path): data = yaml.safe_load(path.open()) return cls( name=data["identifier"], description=data["description"], project_path=data["projectpath"], repo_path=data["repopath"] )
def get_git_commit(path: pathlib.Path): return subprocess.check_output(["git", "-C", path, "rev-parse", "--short", "HEAD"]).decode().strip()
def validate_unique(projects: list[Project], attr: str): seen = set() for item in projects: attr_value = getattr(item, attr) if attr_value in seen: raise Exception(f"Duplicate {attr}: {attr_value}") seen.add(attr_value)
THIRD_PARTY = { "third-party/appstream": "appstream-qt", "third-party/cmark": "cmark", "third-party/gpgme": "gpgme", "third-party/kdsoap": "kdsoap", "third-party/libaccounts-qt": "accounts-qt", "third-party/libgpg-error": "libgpg-error", "third-party/libquotient": "libquotient", "third-party/packagekit-qt": "packagekit-qt", "third-party/poppler": "poppler", "third-party/qcoro": "qcoro", "third-party/qmltermwidget": "qmltermwidget", "third-party/qtkeychain": "qtkeychain", "third-party/signond": "signond", "third-party/taglib": "taglib", "third-party/wayland-protocols": "wayland-protocols", "third-party/wayland": "wayland", "third-party/zxing-cpp": "zxing-cpp",}
IGNORE = { "kdesupport/phonon-directshow", "kdesupport/phonon-mmf", "kdesupport/phonon-mplayer", "kdesupport/phonon-quicktime", "kdesupport/phonon-waveout", "kdesupport/phonon-xine"}
WARNED = set()
@dataclasses.dataclassclass KDERepoMetadata: version: str projects: list[Project] dep_graph: dict[Project, set[Project]]
@functools.cached_property def projects_by_name(self): return {p.name: p for p in self.projects}
@functools.cached_property def projects_by_path(self): return {p.project_path: p for p in self.projects}
def try_lookup_package(self, path): if path in IGNORE: return None project = self.projects_by_path.get(path) if project is None and path not in WARNED: WARNED.add(path) print(f"Warning: unknown project {path}") return project
@classmethod def from_repo_metadata_checkout(cls, repo_metadata: pathlib.Path, unstable=False): projects = [ Project.from_yaml(metadata_file) for metadata_file in repo_metadata.glob("projects-invent/**/metadata.yaml") ] + [ Project(id, None, project_path, None) for project_path, id in THIRD_PARTY.items() ]
validate_unique(projects, "name") validate_unique(projects, "project_path")
self = cls( version=get_git_commit(repo_metadata), projects=projects, dep_graph={}, )
dep_graph = collections.defaultdict(set)
if unstable: spec_name = "dependency-data-kf6-qt6" else: spec_name = "dependency-data-stable-kf6-qt6"
spec_path = repo_metadata / "dependencies" / spec_name for line in spec_path.open(): line = line.strip() if line.startswith("#"): continue if not line: continue
dependent, dependency = line.split(": ")
dependent = self.try_lookup_package(dependent) if dependent is None: continue
dependency = self.try_lookup_package(dependency) if dependency is None: continue
dep_graph[dependent].add(dependency)
self.dep_graph = dep_graph
return self
def write_json(self, root: pathlib.Path): root.mkdir(parents=True, exist_ok=True)
with (root / "projects.json").open("w") as fd: json.dump(self.projects_by_name, fd, cls=DataclassEncoder, sort_keys=True, indent=2)
with (root / "dependencies.json").open("w") as fd: deps = {k.name: sorted(dep.name for dep in v) for k, v in self.dep_graph.items()} json.dump({"version": self.version, "dependencies": deps}, fd, cls=DataclassEncoder, sort_keys=True, indent=2)
@classmethod def from_json(cls, root: pathlib.Path): projects = [ Project(**v) for v in json.load((root / "projects.json").open()).values() ]
deps = json.load((root / "dependencies.json").open()) self = cls( version=deps["version"], projects=projects, dep_graph={}, )
dep_graph = collections.defaultdict(set) for dependent, dependencies in deps["dependencies"].items(): for dependency in dependencies: dep_graph[self.projects_by_name[dependent]].add(self.projects_by_name[dependency])
self.dep_graph = dep_graph return self