-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLoadedRepository.swift
160 lines (131 loc) · 4.99 KB
/
LoadedRepository.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import Foundation
enum LoadedRepositoryError: Error {
case invalidURL(String)
case invalidLinkedRepositoryURL(String)
case invalidAcceptedRedirectionURL(String)
case missingDescriptorID(pahkat_Descriptor)
case missingVersion(pahkat_Release, Descriptor)
case missingAgentName
case missingAgentVersion
}
class LoadedRepository: Hashable, Equatable {
static func == (lhs: LoadedRepository, rhs: LoadedRepository) -> Bool {
lhs.index.url.absoluteString == rhs.index.url.absoluteString
}
static func <(lhs: LoadedRepository, rhs: LoadedRepository) -> Bool {
return lhs.index.url.absoluteString < rhs.index.url.absoluteString
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.index.url)
}
struct Index: Hashable, Equatable {
struct Agent: Hashable, Equatable {
let name: String
let version: String
let url: URL?
}
let url: URL
let landingURL: URL?
let channels: Set<String>
let defaultChannel: String?
let name: [String: String]
let description: [String: String]
let linkedRepositories: [URL]
let acceptedRedirections: [URL]
let agent: Agent
}
struct Meta: Hashable, Equatable {
let channel: String?
}
private let rawPackages: Packageable
let index: Index
let meta: Meta
var packages: RefMap<String, Package> { rawPackages.packages }
var descriptors: RefMap<String, Descriptor> { rawPackages.descriptors }
static func from(protobuf: Pahkat_LoadedRepository) throws -> LoadedRepository {
let packagesFbs = pahkat_Packages.getRootAsPackages(bb: ByteBuffer(data: protobuf.packagesFbs))
let rawPackages = Packages(packagesFbs)
let meta = Meta(
channel: protobuf.meta.channel == "" ? nil : protobuf.meta.channel
)
let i = protobuf.index
guard let url = URL(string: i.url) else {
throw LoadedRepositoryError.invalidURL(i.url)
}
let landingURL = URL(string: i.landingURL)
let channels = Set(i.channels)
let defaultChannel = i.defaultChannel == "" ? nil : i.defaultChannel
let linkedRepositories: [URL] = try i.linkedRepositories.map {
guard let url = URL(string: $0) else {
throw LoadedRepositoryError.invalidLinkedRepositoryURL($0)
}
return url
}
let acceptedRedirections: [URL] = try i.acceptedRedirections.map {
guard let url = URL(string: $0) else {
throw LoadedRepositoryError.invalidAcceptedRedirectionURL($0)
}
return url
}
guard let agentName = i.agent.name == "" ? nil : i.agent.name else {
throw LoadedRepositoryError.missingAgentName
}
guard let agentVersion = i.agent.version == "" ? nil : i.agent.version else {
throw LoadedRepositoryError.missingAgentVersion
}
let agent = Index.Agent(name: agentName, version: agentVersion, url: URL(string: i.agent.url))
let index = Index(
url: url,
landingURL: landingURL,
channels: channels,
defaultChannel: defaultChannel,
name: i.name,
description: i.description_p,
linkedRepositories: linkedRepositories,
acceptedRedirections: acceptedRedirections,
agent: agent)
return LoadedRepository(
index: index,
meta: meta,
packages: rawPackages)
}
public init<T: Packageable>(index: Index, meta: Meta, packages: T) {
self.index = index
self.meta = meta
self.rawPackages = packages
}
}
extension LoadedRepository.Index {
var nativeName: String {
return self.name["en"] ?? "<unknown repo name>"
}
var nativeDescription: String {
return self.name["en"] ?? "<unknown repo desc>"
}
}
extension LoadedRepository {
func packageKey(for descriptor: Descriptor) -> PackageKey {
return PackageKey(repositoryURL: self.index.url, id: descriptor.id)
}
func release(for key: PackageKey) -> Release? {
if (key.repositoryURL != self.index.url) {
return nil
}
guard let descriptor = self.descriptors[key.id] else {
return nil
}
return descriptor.release.first(where: { release in
if release.macosTarget == nil { return false }
var channel: String? = release.channel
if channel == "" {
channel = nil
}
// Check if repo channel is not null
if let repoChannel = self.meta.channel {
// If this package's channel is null or repo channel is equal, it's valid
return channel == nil || repoChannel == channel
}
return channel == nil
})
}
}