Skip to content

Commit 51ee991

Browse files
committed
overhaul package repo encoding, enable indexing them by creation date
1 parent 0474dfd commit 51ee991

15 files changed

+473
-47
lines changed

Sources/GitHubAPI/GitHub.Repo.License.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ extension GitHub.Repo.License:JSONObjectDecodable
3232
public
3333
init(json:JSON.ObjectDecoder<CodingKey>) throws
3434
{
35-
self.init(id: try json[.id].decode(),
36-
name: try json[.name].decode())
35+
self.init(id: try json[.id].decode(), name: try json[.name].decode())
3736
}
3837
}

Sources/SwiftinitPages/Surfaces/Editions/Swiftinit.TagsPage.swift

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -92,28 +92,28 @@ extension Swiftinit.TagsPage:Swiftinit.ApplicationPage
9292

9393
main[.section, { $0.class = "details" }]
9494
{
95-
if let repo:Unidoc.PackageMetadata.Repo = self.package.repo
95+
if let repo:Unidoc.PackageRepo = self.package.repo
9696
{
9797
$0[.h2] = "Package Repository"
9898

9999
$0[.dl]
100100
{
101-
switch repo
101+
switch repo.origin
102102
{
103-
case .github(let repo):
103+
case .github(let origin):
104104
let now:UnixInstant = .now()
105105

106106
$0[.dt] = "Provider"
107107
$0[.dd]
108108
{
109109
$0[.a]
110110
{
111-
$0.href = "https://github.com/\(repo.owner.login)/\(repo.name)"
111+
$0.href = origin.https
112112
$0.target = "_blank"
113113
} = "GitHub"
114114
}
115115

116-
if let license:GitHub.Repo.License = repo.license
116+
if let license:Unidoc.PackageLicense = repo.license
117117
{
118118
$0[.dt] = "License"
119119
$0[.dd] = license.name
@@ -125,10 +125,10 @@ extension Swiftinit.TagsPage:Swiftinit.ApplicationPage
125125
}
126126

127127
$0[.dt] = "Owner"
128-
$0[.dd] = repo.owner
128+
$0[.dd] = origin.owner
129129

130130
$0[.dt] = "Watchers"
131-
$0[.dd] = "\(repo.watchers)"
131+
$0[.dd] = "\(origin.watchers)"
132132

133133
$0[.dt] = "Forks"
134134
$0[.dd] = "\(repo.forks)"
@@ -137,23 +137,21 @@ extension Swiftinit.TagsPage:Swiftinit.ApplicationPage
137137
$0[.dd] = "\(repo.stars)"
138138

139139
$0[.dt] = "Archived?"
140-
$0[.dd] = repo.archived ? "yes" : "no"
140+
$0[.dd] = origin.archived ? "yes" : "no"
141141

142-
if let created:Timestamp.Components = .init(iso8601: repo.created)
143-
{
144-
let created:Timestamp.Date = created.date
142+
let created:UnixInstant = .millisecond(repo.created.value)
143+
let updated:UnixInstant = .millisecond(repo.updated.value)
145144

145+
if let created:Timestamp.Date = created.timestamp?.date
146+
{
146147
$0[.dt] = "Created"
147148
$0[.dd] = "\(created.month(.en)) \(created.day), \(created.year)"
148149
}
149-
if let updated:Timestamp.Components = .init(iso8601: repo.updated),
150-
let updated:UnixInstant = .init(utc: updated)
151-
{
152-
let age:Age = .init(now - updated)
153150

154-
$0[.dt] = "Last Pushed"
155-
$0[.dd] = "\(age)"
156-
}
151+
let age:Age = .init(now - updated)
152+
153+
$0[.dt] = "Last Pushed"
154+
$0[.dd] = "\(age)"
157155
}
158156
}
159157
}

Sources/SwiftinitPages/Surfaces/Editions/Unidoc.PackageStatus (ext).swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extension Unidoc.PackageStatus
77
init?(from output:borrowing Unidoc.PackageQuery.Output)
88
{
99
guard
10-
let repo:Unidoc.PackageMetadata.Repo = output.package.repo,
10+
let repo:Unidoc.PackageRepo = output.package.repo,
1111
let release:Unidoc.PackageQuery.Tag = output.releases.first,
1212
let release:Edition = .init(from: release)
1313
else
@@ -17,7 +17,7 @@ extension Unidoc.PackageStatus
1717

1818
self.init(
1919
coordinate: output.package.id,
20-
repo: "https://\(repo.origin)",
20+
repo: repo.origin.https,
2121
release: release,
2222
prerelease: output.prereleases.first.flatMap(Edition.init(from:)))
2323
}

Sources/SwiftinitServer/Endpoints/Interactive/Swiftinit.PackageIndexTagEndpoint.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ extension Swiftinit.PackageIndexTagEndpoint:RestrictedEndpoint
4343
}
4444

4545
guard
46-
case .github(let repo) = package.repo
46+
case .github(let origin) = package.repo?.origin
4747
else
4848
{
4949
return .notFound("Not a GitHub repository")
@@ -52,8 +52,8 @@ extension Swiftinit.PackageIndexTagEndpoint:RestrictedEndpoint
5252
let response:GitHubPlugin.TagResponse = try await github.api.connect
5353
{
5454
try await $0.inspect(tag: self.tag,
55-
owner: repo.owner.login,
56-
repo: repo.name,
55+
owner: origin.owner,
56+
repo: origin.name,
5757
pat: github.plugin.pat)
5858
}
5959

Sources/SwiftinitServer/Plugins/GitHubPlugin.RepoMonitor.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,25 @@ extension GitHubPlugin.RepoMonitor:GitHubCrawler
3535

3636
for var package:Unidoc.PackageMetadata in stale
3737
{
38-
guard case .github(let old) = package.repo
38+
guard
39+
let old:Unidoc.PackageRepo = package.repo
3940
else
4041
{
41-
fatalError("unreachable: non-GitHub package was marked as stale!")
42+
fatalError("unreachable: repoless package was marked as stale!")
43+
}
44+
45+
let origin:Unidoc.PackageRepo.GitHubOrigin
46+
switch old.origin
47+
{
48+
case .github(let github): origin = github
4249
}
4350

4451
let response:GitHubPlugin.RepoMonitorResponse = try await connection.crawl(
45-
owner: old.owner.login,
46-
repo: old.name,
52+
owner: origin.owner,
53+
repo: origin.name,
4754
pat: self.pat)
4855

49-
package.repo = .github(response.repo)
56+
package.repo = try .github(response.repo)
5057
package.crawled = .now()
5158

5259
switch try await server.db.packages.update(metadata: package, with: session)
@@ -60,7 +67,7 @@ extension GitHubPlugin.RepoMonitor:GitHubCrawler
6067
// record contains a timestamp.
6168
server.atomics.reposCrawled.wrappingIncrement(ordering: .relaxed)
6269
}
63-
if response.repo != old
70+
if package.repo != old
6471
{
6572
server.atomics.reposUpdated.wrappingIncrement(ordering: .relaxed)
6673
}
@@ -112,8 +119,7 @@ extension GitHubPlugin.RepoMonitor:GitHubCrawler
112119
{
113120
let activity:UnidocDatabase.RepoFeed.Activity = .init(discovered: .now(),
114121
package: package.symbol,
115-
refname: interesting,
116-
origin: .github(response.repo.owner.login, response.repo.name))
122+
refname: interesting)
117123

118124
try await server.db.repoFeed.push(activity, with: session)
119125
}

Sources/SwiftinitServer/Plugins/GitHubPlugin.RepoTelescope.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ extension GitHubPlugin.RepoTelescope:GitHubCrawler
6868
{
6969
let symbol:Symbol.Package = "\(repo.owner.login).\(repo.name)"
7070
switch try await server.db.unidoc.index(package: symbol,
71-
repo: .github(repo),
71+
repo: try .github(repo),
7272
mode: .automatic,
7373
with: session)
7474
{

Sources/UnidocDB/Activity/UnidocDatabase.RepoFeed.Activity.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,15 @@ extension UnidocDatabase.RepoFeed
1616
let package:Symbol.Package
1717
public
1818
let refname:String
19-
public
20-
let origin:Unidoc.PackageMetadata.Repo.Origin
2119

2220
@inlinable public
2321
init(discovered id:BSON.Millisecond,
2422
package:Symbol.Package,
25-
refname:String,
26-
origin:Unidoc.PackageMetadata.Repo.Origin)
23+
refname:String)
2724
{
2825
self.id = id
2926
self.package = package
3027
self.refname = refname
31-
self.origin = origin
3228
}
3329
}
3430
}
@@ -41,6 +37,8 @@ extension UnidocDatabase.RepoFeed.Activity:MongoMasterCodingModel
4137

4238
case package = "P"
4339
case refname = "G"
40+
41+
@available(*, unavailable)
4442
case origin = "O"
4543
}
4644
}
@@ -53,7 +51,6 @@ extension UnidocDatabase.RepoFeed.Activity:BSONDocumentEncodable
5351

5452
bson[.package] = self.package
5553
bson[.refname] = self.refname
56-
bson[.origin] = self.origin
5754
}
5855
}
5956
extension UnidocDatabase.RepoFeed.Activity:BSONDocumentDecodable
@@ -63,7 +60,6 @@ extension UnidocDatabase.RepoFeed.Activity:BSONDocumentDecodable
6360
{
6461
self.init(discovered: try bson[.id].decode(),
6562
package: try bson[.package].decode(),
66-
refname: try bson[.refname].decode(),
67-
origin: try bson[.origin].decode())
63+
refname: try bson[.refname].decode())
6864
}
6965
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import BSON
2+
import MongoQL
3+
4+
extension Unidoc
5+
{
6+
@frozen public
7+
struct PackageLicense:Equatable, Sendable
8+
{
9+
public
10+
let spdx:String
11+
public
12+
let name:String
13+
14+
@inlinable public
15+
init(spdx:String, name:String)
16+
{
17+
self.spdx = spdx
18+
self.name = name
19+
}
20+
}
21+
}
22+
extension Unidoc.PackageLicense:MongoMasterCodingModel
23+
{
24+
@frozen public
25+
enum CodingKey:String, Sendable
26+
{
27+
case spdx = "I"
28+
case name = "N"
29+
}
30+
}
31+
extension Unidoc.PackageLicense:BSONDocumentEncodable
32+
{
33+
public
34+
func encode(to bson:inout BSON.DocumentEncoder<CodingKey>)
35+
{
36+
bson[.spdx] = self.spdx
37+
bson[.name] = self.name
38+
}
39+
}
40+
extension Unidoc.PackageLicense:BSONDocumentDecodable
41+
{
42+
@inlinable public
43+
init(bson:BSON.DocumentDecoder<CodingKey, some RandomAccessCollection<UInt8>>) throws
44+
{
45+
self.init(spdx: try bson[.spdx].decode(), name: try bson[.name].decode())
46+
}
47+
}

Sources/UnidocDB/Packages/Unidoc.PackageMetadata.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension Unidoc
4040
///
4141
/// Currently only GitHub repos are supported.
4242
public
43-
var repo:Repo?
43+
var repo:PackageRepo?
4444

4545
/// When this package *record* was last crawled. This is different from the time when
4646
/// the package itself was last updated.
@@ -53,7 +53,7 @@ extension Unidoc
5353
hidden:Bool = false,
5454
realm:Unidoc.Realm? = nil,
5555
realmAligning:Bool = false,
56-
repo:Repo? = nil,
56+
repo:PackageRepo? = nil,
5757
crawled:BSON.Millisecond = 0)
5858
{
5959
self.id = id
@@ -76,7 +76,10 @@ extension Unidoc.PackageMetadata:MongoMasterCodingModel
7676
case hidden = "H"
7777
case realm = "r"
7878
case realmAligning = "A"
79-
case repo = "R"
79+
80+
case repo = "G"
81+
case repoLegacy = "R"
82+
8083
case crawled = "T"
8184
}
8285
}
@@ -106,5 +109,15 @@ extension Unidoc.PackageMetadata:BSONDocumentDecodable
106109
realmAligning: try bson[.realmAligning]?.decode() ?? false,
107110
repo: try bson[.repo]?.decode(),
108111
crawled: try bson[.crawled]?.decode() ?? 0)
112+
113+
if case nil = self.repo,
114+
let legacy:Repo = try bson[.repoLegacy]?.decode()
115+
{
116+
switch legacy
117+
{
118+
case .github(let repo):
119+
self.repo = try .github(repo)
120+
}
121+
}
109122
}
110123
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Symbols
2+
3+
extension Unidoc.PackageRepo
4+
{
5+
@frozen public
6+
enum AnyOrigin:Equatable, Sendable
7+
{
8+
case github(GitHubOrigin)
9+
}
10+
}
11+
extension Unidoc.PackageRepo.AnyOrigin
12+
{
13+
@inlinable public
14+
var https:String
15+
{
16+
switch self
17+
{
18+
case .github(let self): self.https
19+
}
20+
}
21+
22+
@inlinable public
23+
func blob(refname:String, file:Symbol.File) -> String
24+
{
25+
switch self
26+
{
27+
case .github(let self): "\(self.https)/blob/\(refname)/\(file)"
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)