Files
darwin-apk/Sources/apk/Graph/ApkPackageGraph.swift

65 lines
2.0 KiB
Swift

/*
* darwin-apk © 2024 Gay Pizza Specifications
* SPDX-License-Identifier: Apache-2.0
*/
class ApkPackageGraph {
let pkgIndex: ApkIndex
private var _nodes = [ApkPackageGraphNode]()
var nodes: [ApkPackageGraphNode] { self._nodes }
var shallowIsolates: [ApkPackageGraphNode] { self._nodes.filter(\.parents.isEmpty) }
var deepIsolates: [ApkPackageGraphNode] { self._nodes.filter(\.children.isEmpty) }
init(index: ApkIndex) {
self.pkgIndex = index
}
func buildGraphNode() {
var provides = [String: Int]()
for (idx, package) in self.pkgIndex.packages.enumerated() {
provides[package.name] = idx
for provision in package.provides {
provides[provision.name] = idx
}
}
for package in pkgIndex.packages {
self._nodes.append(.init(
package: package,
children: package.dependencies.compactMap { dependency in
guard let id = provides[dependency.requirement.name] else {
return nil
}
return .init(self, id: id, constraint: .dep(version: dependency.requirement.versionSpec))
} + package.provides.compactMap { provision in
guard let id = provides[provision.name] else {
return nil
}
return .init(self, id: id, constraint: .provision)
} + package.installIf.compactMap { installIf in
guard let id = provides[installIf.requirement.name] else {
return nil
}
return .init(self, id: id, constraint: .installIf(version: installIf.requirement.versionSpec ))
}
))
}
var reverseDependencies = [ApkIndexRequirementRef: [ApkIndexRequirementRef]]()
for (index, node) in self._nodes.enumerated() {
for child in node.children {
reverseDependencies[child, default: []].append(
.init(self, id: index, constraint: child.constraint)
)
}
}
for (ref, parents) in reverseDependencies {
self._nodes[ref.packageID].parents = parents
}
}
}