mirror of
https://github.com/GayPizzaSpecifications/darwin-apk.git
synced 2025-08-03 21:41:31 +00:00
basic package graph implemented
This commit is contained in:
@ -5,22 +5,10 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ApkIndexDependency: ApkIndexRequirementRef {
|
||||
let name: String
|
||||
let versionSpec: ApkVersionSpecification
|
||||
struct ApkIndexDependency: Hashable {
|
||||
let requirement: ApkRequirement
|
||||
|
||||
init(name: String, version spec: ApkVersionSpecification) {
|
||||
self.name = name
|
||||
self.versionSpec = spec
|
||||
}
|
||||
}
|
||||
|
||||
extension ApkIndexDependency: CustomStringConvertible {
|
||||
var description: String {
|
||||
switch self.versionSpec {
|
||||
case .any: self.name
|
||||
case .conflict: "!\(self.name)"
|
||||
case .constraint(let op, let version): "\(self.name)\(op)\(version)"
|
||||
}
|
||||
init(requirement: ApkRequirement) {
|
||||
self.requirement = requirement
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct ApkIndexInstallIf: ApkIndexRequirementRef {
|
||||
let name: String
|
||||
let versionSpec: ApkVersionSpecification
|
||||
struct ApkIndexInstallIf: Hashable {
|
||||
let requirement: ApkRequirement
|
||||
|
||||
init(name: String, version spec: ApkVersionSpecification) {
|
||||
self.name = name
|
||||
self.versionSpec = spec
|
||||
init(requirement: ApkRequirement) {
|
||||
self.requirement = requirement
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ApkIndexPackage: ApkIndexRequirementRef {
|
||||
struct ApkIndexPackage: Hashable {
|
||||
let indexChecksum: ApkIndexDigest
|
||||
let name: String
|
||||
let version: String
|
||||
@ -74,8 +74,10 @@ extension ApkIndexPackage {
|
||||
case "A":
|
||||
architecture = record.value
|
||||
case "D":
|
||||
do { dependencies = try ApkIndexDependency.extract(record.value) }
|
||||
catch { throw .badValue(key: record.key) }
|
||||
do {
|
||||
dependencies = try record.value.components(separatedBy: " ")
|
||||
.map { .init(requirement: try .init(extract: $0)) }
|
||||
} catch { throw .badValue(key: record.key) }
|
||||
case "C":
|
||||
guard let digest = ApkIndexDigest(decode: record.value) else {
|
||||
throw .badValue(key: record.key)
|
||||
@ -92,11 +94,15 @@ extension ApkIndexPackage {
|
||||
}
|
||||
installedSize = value
|
||||
case "p":
|
||||
do { provides = try ApkIndexProvides.extract(record.value) }
|
||||
catch { throw .badValue(key: record.key) }
|
||||
do {
|
||||
provides = try record.value.components(separatedBy: " ")
|
||||
.map { .init(requirement: try .init(extract: $0)) }
|
||||
} catch { throw .badValue(key: record.key) }
|
||||
case "i":
|
||||
do { installIf = try ApkIndexInstallIf.extract(record.value) }
|
||||
catch { throw .badValue(key: record.key) }
|
||||
do {
|
||||
installIf = try record.value.components(separatedBy: " ")
|
||||
.map { .init(requirement: try .init(extract: $0)) }
|
||||
} catch { throw .badValue(key: record.key) }
|
||||
case "o":
|
||||
origin = record.value
|
||||
case "m":
|
||||
@ -191,13 +197,13 @@ extension ApkIndexPackage: CustomStringConvertible {
|
||||
s += "provider prio: \(providerPrio)\n"
|
||||
}
|
||||
if !self.dependencies.isEmpty {
|
||||
s += "dependencies: - \(self.dependencies.map(String.init).joined(separator: " "))\n"
|
||||
s += "dependencies: - \(self.dependencies.map(\.requirement.description).joined(separator: " "))\n"
|
||||
}
|
||||
if !self.provides.isEmpty {
|
||||
s += "provides: ----- \(self.provides.map { $0.name }.joined(separator: " "))\n"
|
||||
s += "provides: ----- \(self.provides.map(\.name).joined(separator: " "))\n"
|
||||
}
|
||||
if !self.installIf.isEmpty {
|
||||
s += "install if: --- \(self.installIf.map { $0.name }.joined(separator: " "))\n"
|
||||
s += "install if: --- \(self.installIf.map(\.requirement.description).joined(separator: " "))\n"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
struct ApkIndexProvides: ApkIndexRequirementRef {
|
||||
struct ApkIndexProvides: Hashable {
|
||||
let name: String
|
||||
|
||||
init(name: String, version _: ApkVersionSpecification) {
|
||||
self.name = name
|
||||
init(requirement: ApkRequirement) {
|
||||
self.name = requirement.name
|
||||
}
|
||||
}
|
||||
|
@ -3,24 +3,58 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
protocol ApkIndexRequirementRef: Equatable, Hashable {
|
||||
var name: String { get }
|
||||
var invert: Bool { get }
|
||||
struct ApkIndexRequirementRef {
|
||||
private weak var _graph: ApkPackageGraph?
|
||||
|
||||
init(name: String, version spec: ApkVersionSpecification)
|
||||
let packageID: Int
|
||||
let constraint: Constraint
|
||||
|
||||
func satisfied(by other: ApkIndexPackage) -> Bool
|
||||
init(_ graph: ApkPackageGraph, id: Int, constraint: Constraint) {
|
||||
self._graph = graph
|
||||
self.packageID = id
|
||||
self.constraint = constraint
|
||||
}
|
||||
|
||||
var package: ApkIndexPackage {
|
||||
self._graph!.pkgIndex.packages[self.packageID]
|
||||
}
|
||||
|
||||
func satisfied(by other: ApkRequirement) -> Bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
extension ApkIndexRequirementRef: Equatable, Hashable {
|
||||
static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
lhs.packageID == rhs.packageID && lhs.constraint == rhs.constraint
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
self.packageID.hash(into: &hasher)
|
||||
self.constraint.hash(into: &hasher)
|
||||
}
|
||||
}
|
||||
|
||||
extension ApkIndexRequirementRef {
|
||||
var invert: Bool { false }
|
||||
func satisfied(by _: ApkIndexPackage) -> Bool { true }
|
||||
|
||||
static func extract<T: ApkIndexRequirementRef>(_ blob: String) throws(ApkRequirement.ParseError) -> [T] {
|
||||
return try blob.components(separatedBy: " ")
|
||||
.map { token throws(ApkRequirement.ParseError) in
|
||||
let (name, versionSpec) = try ApkRequirement.extract(blob: token)
|
||||
return .init(name: name, version: versionSpec)
|
||||
}
|
||||
enum Constraint: Hashable {
|
||||
case dep(version: ApkVersionSpecification)
|
||||
case provision
|
||||
case installIf(version: ApkVersionSpecification)
|
||||
}
|
||||
}
|
||||
|
||||
extension ApkIndexRequirementRef: CustomStringConvertible {
|
||||
var description: String {
|
||||
guard let package = self._graph?.pkgIndex.packages[self.packageID] else {
|
||||
return String()
|
||||
}
|
||||
return switch self.constraint {
|
||||
case .dep(let version):
|
||||
"dep=\(ApkRequirement(name: package.name, spec: version))"
|
||||
case .provision:
|
||||
"provides=\(package.name)"
|
||||
case .installIf(let version):
|
||||
"installIf=\(ApkRequirement(name: package.name, spec: version))"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ public struct ApkIndexUpdater {
|
||||
|
||||
public init() {
|
||||
self.repositories = [
|
||||
"https://dl-cdn.alpinelinux.org/alpine/v3.21/main",
|
||||
"https://dl-cdn.alpinelinux.org/alpine/edge/community"
|
||||
"https://dl-cdn.alpinelinux.org/alpine/v3.20/main",
|
||||
"https://dl-cdn.alpinelinux.org/alpine/v3.20/community"
|
||||
]
|
||||
// other archs: "armhf", "armv7", "loongarch64", "ppc64le", "riscv64", "s390x", "x86"
|
||||
self.architectures = [ "aarch64", "x86_64" ]
|
||||
self.architectures = [ "aarch64" /*, "x86_64" */ ]
|
||||
}
|
||||
|
||||
public func update() {
|
||||
@ -41,14 +41,23 @@ public struct ApkIndexUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
let index: ApkIndex
|
||||
let graph: ApkPackageGraph
|
||||
do {
|
||||
let tables = try repositories.map { try readIndex(URL(filePath: $0.localName)) }
|
||||
index = ApkIndex.merge(tables)
|
||||
try index.description.write(to: URL(fileURLWithPath: "packages.txt"), atomically: false, encoding: .utf8)
|
||||
graph = ApkPackageGraph(index: ApkIndex.merge(tables))
|
||||
graph.buildGraphNode()
|
||||
|
||||
try graph.pkgIndex.description.write(to: URL(filePath: "packages.txt"), atomically: false, encoding: .utf8)
|
||||
} catch {
|
||||
fatalError(error.localizedDescription)
|
||||
}
|
||||
|
||||
if var out = TextFileWriter(URL(filePath: "shallowIsolates.txt")) {
|
||||
for node in graph.shallowIsolates { print(node, to: &out) }
|
||||
}
|
||||
if var out = TextFileWriter(URL(filePath: "deepIsolates.txt")) {
|
||||
for node in graph.deepIsolates { print(node, to: &out) }
|
||||
}
|
||||
}
|
||||
|
||||
private func readIndex(_ indexURL: URL) throws -> ApkIndex {
|
||||
|
Reference in New Issue
Block a user