Skip to content

Commit 32c5641

Browse files
committed
adopt Swift ArgumentParser in unidoc-preview
1 parent 6fe48ca commit 32c5641

File tree

7 files changed

+95
-96
lines changed

7 files changed

+95
-96
lines changed

Package.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ let package:Package = .init(
137137

138138
.executableTarget(name: "unidoc-preview",
139139
dependencies: [
140-
.target(name: "ArgumentParsing"),
140+
.target(name: "System_ArgumentParser"),
141141
.target(name: "UnidocServer"),
142142
]),
143143

@@ -359,12 +359,12 @@ let package:Package = .init(
359359

360360
.target(name: "SymbolGraphBuilder",
361361
dependencies: [
362-
.product(name: "ArgumentParser", package: "swift-argument-parser"),
363362
.target(name: "MarkdownPluginSwift"),
364363
.target(name: "MarkdownPluginSwift_IndexStoreDB"),
365364
.target(name: "PackageMetadata"),
366365
.target(name: "SymbolGraphCompiler"),
367366
.target(name: "SymbolGraphLinker"),
367+
.target(name: "System_ArgumentParser"),
368368
.target(name: "System"),
369369
]),
370370

@@ -564,6 +564,12 @@ let package:Package = .init(
564564
.product(name: "TraceableErrors", package: "swift-grammar"),
565565
]),
566566

567+
.target(name: "System_ArgumentParser",
568+
dependencies: [
569+
.target(name: "System"),
570+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
571+
]),
572+
567573
.executableTarget(name: "UCFTests",
568574
dependencies: [
569575
.target(name: "UCF"),

Sources/SymbolGraphBuilder/SSGC.Compile.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ArgumentParser
22
import BSON
33
import SymbolGraphs
44
import Symbols
5+
import System_ArgumentParser
56
import System
67

78
extension SSGC

Sources/UnidocServer/Configurations/Unidoc.ServerOptions.Development.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extension Unidoc.ServerOptions
3838
var port:Int
3939

4040
@inlinable public
41-
init()
41+
init(replicaSet:String = "unidoc-rs")
4242
{
4343
self.cloudfront = false
4444

@@ -47,7 +47,7 @@ extension Unidoc.ServerOptions
4747
self.runPolicy = false
4848
self.security = .ignored
4949

50-
self.replicaSet = "unidoc-rs"
50+
self.replicaSet = replicaSet
5151
self.bucket = nil
5252
self.port = 8443
5353
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import ArgumentParser
2+
import MongoClusters
3+
4+
extension Mongo.Host:ExpressibleByArgument
5+
{
6+
}

Sources/unidoc-preview/Unidoc.Preview.swift

Lines changed: 78 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,127 @@
1-
import ArgumentParsing
2-
import GitHubAPI
1+
import ArgumentParser
32
import HTTPServer
43
import MongoDB
54
import NIOPosix
65
import NIOSSL
6+
import System_ArgumentParser
77
import System
88
import UnidocServer
99

1010
extension Unidoc
1111
{
1212
struct Preview
1313
{
14-
var certificates:String
15-
16-
var development:Unidoc.ServerOptions.Development
17-
var mirror:Bool
18-
var https:Bool
19-
var mongo:Mongo.Host
20-
21-
private
22-
init() throws
14+
@Option(
15+
name: [.customLong("certificates"), .customShort("c")],
16+
help: "A path to the certificates directory",
17+
completion: .directory)
18+
var certificates:FilePath.Directory = "Assets/certificates"
19+
20+
@Option(
21+
name: [.customLong("mongo"), .customShort("m")],
22+
help: "The name of a host running mongod to connect to, and optionally, the port")
23+
var mongod:Mongo.Host = "localhost"
24+
25+
@Option(
26+
name: [.customLong("replica-set"), .customShort("s")],
27+
help: "The name of a replica set to connect to")
28+
var replicaSet:String = "unidoc-rs"
29+
30+
@Option(
31+
name: [.customLong("port"), .customShort("p")],
32+
help: "The number of a port to bind the documentation server to")
33+
var port:Int?
34+
35+
@Flag(
36+
name: [.customLong("mirror"), .customShort("q")],
37+
help: "Run in mirror mode, disabling the documentation linker process")
38+
var mirror:Bool = false
39+
40+
@Flag(
41+
name: [.customLong("https"), .customShort("e")],
42+
help: "Use https instead of http")
43+
var https:Bool = false
44+
45+
init()
2346
{
24-
self.certificates = "Assets/certificates"
25-
self.development = .init()
26-
self.development.port = 8080
27-
self.mirror = false
28-
self.https = false
29-
self.mongo = "localhost"
3047
}
3148
}
3249
}
3350
extension Unidoc.Preview
3451
{
35-
private mutating
36-
func parse() throws
52+
private
53+
var serverSSL:NIOSSLContext
3754
{
38-
var arguments:CommandLine.Arguments = .init()
39-
40-
while let argument:String = arguments.next()
55+
get throws
4156
{
42-
switch argument
43-
{
44-
case "-c", "--certificates":
45-
self.certificates = try arguments.next(for: "certificates")
57+
let privateKeyPath:FilePath = self.certificates / "privkey.pem"
58+
let privateKey:NIOSSLPrivateKey = try .init(file: "\(privateKeyPath)", format: .pem)
4659

47-
case "-q", "--mirror":
48-
self.mirror = true
60+
let fullChainPath:FilePath = self.certificates / "fullchain.pem"
61+
let fullChain:[NIOSSLCertificate] = try NIOSSLCertificate.fromPEMFile(
62+
"\(fullChainPath)")
4963

50-
case "-s", "--replica-set":
51-
self.development.replicaSet = try arguments.next(for: "replica-set")
52-
53-
case "-e", "--https":
54-
self.https = true
55-
self.development.port = 8443
56-
57-
case "-m", "--mongo":
58-
self.mongo = .init(try arguments.next(for: "mongo"))
64+
var configuration:TLSConfiguration = .makeServerConfiguration(
65+
certificateChain: fullChain.map(NIOSSLCertificateSource.certificate(_:)),
66+
privateKey: .privateKey(privateKey))
5967

60-
case "-p", "--port":
61-
self.https = true
62-
self.development.port = try arguments.next(for: "port")
68+
// configuration.applicationProtocols = ["h2", "http/1.1"]
69+
configuration.applicationProtocols = ["h2"]
6370

64-
case let option:
65-
throw CommandLine.ArgumentError.unknown(option)
66-
}
71+
return try .init(configuration: configuration)
6772
}
6873
}
69-
}
7074

71-
@main
72-
extension Unidoc.Preview
73-
{
74-
static
75-
func main() async throws
75+
private
76+
var clientSSL:NIOSSLContext
7677
{
77-
var main:Self = try .init()
78-
try main.parse()
79-
try await main.launch()
78+
get throws
79+
{
80+
var configuration:TLSConfiguration = .makeClientConfiguration()
81+
configuration.applicationProtocols = ["h2"]
82+
return try .init(configuration: configuration)
83+
}
8084
}
8185
}
82-
extension Unidoc.Preview
86+
87+
@main
88+
extension Unidoc.Preview:AsyncParsableCommand
8389
{
84-
private consuming
85-
func options() throws -> Unidoc.ServerOptions
90+
func run() async throws
8691
{
87-
let authority:any HTTP.ServerAuthority
88-
if self.https
89-
{
90-
let privateKey:NIOSSLPrivateKey =
91-
try .init(file: "\(self.certificates)/privkey.pem", format: .pem)
92-
let fullChain:[NIOSSLCertificate] =
93-
try NIOSSLCertificate.fromPEMFile("\(self.certificates)/fullchain.pem")
92+
let threads:MultiThreadedEventLoopGroup = .init(numberOfThreads: 2)
9493

95-
var configuration:TLSConfiguration = .makeServerConfiguration(
96-
certificateChain: fullChain.map(NIOSSLCertificateSource.certificate(_:)),
97-
privateKey: .privateKey(privateKey))
94+
defer
95+
{
96+
try? threads.syncShutdownGracefully()
97+
}
9898

99-
// configuration.applicationProtocols = ["h2", "http/1.1"]
100-
configuration.applicationProtocols = ["h2"]
99+
var development:Unidoc.ServerOptions.Development = .init(replicaSet: self.replicaSet)
100+
let authority:any HTTP.ServerAuthority
101101

102-
authority = HTTP.LocalhostSecure.init(
103-
context: try .init(configuration: configuration))
102+
if self.https
103+
{
104+
authority = HTTP.LocalhostSecure.init(context: try self.serverSSL)
105+
development.port = self.port ?? 8443
104106
}
105107
else
106108
{
107109
authority = HTTP.Localhost.init()
110+
development.port = self.port ?? 8080
108111
}
109112

110-
return .init(authority: authority,
113+
let options:Unidoc.ServerOptions = .init(authority: authority,
111114
github: nil,
112115
mirror: self.mirror,
113116
bucket: .init(
114-
assets: self.development.bucket,
115-
graphs: self.development.bucket),
116-
mode: .development(.init(source: "Assets"), self.development))
117-
}
118-
119-
private consuming
120-
func launch() async throws
121-
{
122-
let threads:MultiThreadedEventLoopGroup = .init(numberOfThreads: 2)
123-
124-
defer
125-
{
126-
try? threads.syncShutdownGracefully()
127-
}
128-
129-
let mongod:Mongo.Host = self.mongo
130-
131-
var configuration:TLSConfiguration = .makeClientConfiguration()
132-
configuration.applicationProtocols = ["h2"]
117+
assets: development.bucket,
118+
graphs: development.bucket),
119+
mode: .development(.init(source: "Assets"), development))
133120

134121
let context:Unidoc.ServerPluginContext = .init(threads: threads,
135-
niossl: try .init(configuration: configuration))
136-
let options:Unidoc.ServerOptions = try self.options()
122+
niossl: try self.clientSSL)
137123

138-
let mongodb:Mongo.DriverBootstrap = MongoDB / [mongod] /?
124+
let mongodb:Mongo.DriverBootstrap = MongoDB / [self.mongod] /?
139125
{
140126
$0.executors = .shared(threads)
141127
$0.appname = "Unidoc Preview"

0 commit comments

Comments
 (0)