Skip to content

Commit fefe2ea

Browse files
committed
Add servedocc example
Has error checking and everything ;-)
1 parent a1a7a5a commit fefe2ea

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed

Package.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ let package = Package(
1414
.executable(name: "httpd-helloworld", targets: [ "httpd-helloworld" ]),
1515
.executable(name: "connect-static", targets: [ "connect-static" ]),
1616
.executable(name: "express-simple", targets: [ "express-simple" ]),
17+
.executable(name: "servedocc", targets: [ "servedocc" ]),
1718
.executable(name: "todomvc", targets: [ "todomvc" ]),
1819
.executable(name : "express-simple-lambda",
1920
targets : [ "express-simple-lambda" ])
@@ -36,6 +37,7 @@ let package = Package(
3637
.target(name: "httpd-helloworld", dependencies: [ "Macro" ]),
3738
.target(name: "connect-static", dependencies: [ "MacroExpress" ]),
3839
.target(name: "express-simple", dependencies: [ "MacroExpress", "cows" ]),
40+
.target(name: "servedocc", dependencies: [ "MacroExpress" ]),
3941
.target(name: "todomvc", dependencies: [ "MacroExpress" ]),
4042

4143
.target(name: "express-simple-lambda",

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,19 @@ $ swift run todomvc
173173
2020-06-03T14:58:59+0200 notice: Server listening on http://localhost:1337
174174
```
175175

176+
### [servedocc](Sources/servedocc/)
177+
178+
Macro server to serve "DocC" archives, a format to document Swift frameworks
179+
and packages:
180+
[Documenting a Swift Framework or Package](https://developer.apple.com/documentation/Xcode/documenting-a-swift-framework-or-package).
181+
182+
```bash
183+
$ swift run servedocc SlothCreator.doccarchive
184+
2021-06-26T17:14:08+0200 notice μ.console : Server listening on: http://localhost:1337/
185+
2021-06-26T17:14:08+0200 notice μ.console : DocC Archive: /Users/helge/Downloads/SlothCreator.doccarchive
186+
2021-06-26T17:14:13+0200 notice μ.console : GET /documentation/ 200 - - 2 ms
187+
```
188+
176189

177190
## Who
178191

Sources/servedocc/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<h2>Macro.swift servedocc
2+
<img src="http://zeezide.com/img/macro/MacroExpressIcon128.png"
3+
align="right" width="100" height="100" />
4+
</h2>
5+
6+
Macro server to serve "DocC" archives, a format to document Swift frameworks
7+
and packages:
8+
[Documenting a Swift Framework or Package](https://developer.apple.com/documentation/Xcode/documenting-a-swift-framework-or-package).
9+
10+
*Note*: This is for serving an exported documentation archive (`.doccarchive`),
11+
not for building documentation from a DocC catalog.
12+
13+
## Usage
14+
15+
The server can be either run as a
16+
[swift-sh](https://github.com/mxcl/swift-sh) script
17+
(install using a simple `brew install mxcl/made/swift-sh`),
18+
from within Xcode or via `swift run`.
19+
20+
### Via swift-sh
21+
22+
Example:
23+
```bash
24+
$ cd Sources/servedocc
25+
$ ./main.swift ~/Downloads/SlothCreator.doccarchive
26+
```
27+
28+
29+
### Who
30+
31+
**Macro** is brought to you by
32+
the
33+
[Always Right Institute](http://www.alwaysrightinstitute.com)
34+
and
35+
[ZeeZide](http://zeezide.de).
36+
We like
37+
[feedback](https://twitter.com/ar_institute),
38+
GitHub stars,
39+
cool [contract work](http://zeezide.com/en/services/services.html),
40+
presumably any form of praise you can think of.
41+
42+
There is a `#microexpress` channel on the
43+
[Noze.io Slack](http://slack.noze.io/). Feel free to join!

Sources/servedocc/main.swift

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/swift sh
2+
3+
import MacroExpress // @Macro-swift
4+
5+
6+
// MARK: - Parse Commandline Arguments & Usage
7+
8+
func usage() {
9+
let tool = path.basename(process.argv.first ?? "servedocc")
10+
print(
11+
"""
12+
Usage: \(tool) <docc archive folder>
13+
14+
Example:
15+
16+
\(tool) SlothCreator.doccarchive
17+
18+
"""
19+
)
20+
}
21+
22+
guard process.argv.count == 2 else {
23+
usage()
24+
process.exit(1)
25+
}
26+
27+
let archivePath = process.argv[1]
28+
let indexPath = archivePath + "/index.html"
29+
let docPath = archivePath + "/data/documentation"
30+
31+
guard fs.existsSync(archivePath) else {
32+
print("Specified file does not exist:", archivePath)
33+
process.exit(2)
34+
}
35+
guard fs.existsSync(indexPath), fs.existsSync(docPath) else {
36+
print("File does not look like a DocC archive:", archivePath)
37+
process.exit(3)
38+
}
39+
40+
guard let dataIndex = (try? fs.readdirSync(docPath))?
41+
.first(where: { $0.hasSuffix(".json")} )
42+
else {
43+
print("File does not look like a DocC archive, missing data index:",
44+
archivePath)
45+
process.exit(3)
46+
}
47+
let dataIndexPath = docPath + "/" + dataIndex
48+
49+
50+
// MARK: - Serve Individual
51+
52+
/// This serves individual, fixed files.
53+
func serveFile(_ path: String) -> Middleware {
54+
return { req, res, next in
55+
fs.createReadStream(path)
56+
.pipe(res)
57+
.onError { error in
58+
console.error("Failed to serve \(path):", error)
59+
res.status(500)
60+
}
61+
}
62+
}
63+
64+
65+
// MARK: - Configure and Start the Server
66+
67+
let staticDirs = [ "css", "data", "downloads", "images", "img",
68+
"index", "js", "videos" ]
69+
let staticFiles = [ "favicon.ico", "favicon.svg", "theme-settings.json" ]
70+
71+
let app = express()
72+
app.use(logger("dev"))
73+
74+
// Map all matching requests to this index.html
75+
app.get("/documentation/*", serveFile(indexPath))
76+
app.get("/tutorials/*", serveFile(indexPath))
77+
app.get("/data/documentation.json", serveFile(dataIndexPath))
78+
79+
for path in staticDirs { // serve the whole directory ("/*" match)
80+
app.get("/" + path + "/*", serveStatic(archivePath))
81+
}
82+
for path in staticFiles { // just serve the specific file
83+
app.get("/" + path, serveStatic(archivePath))
84+
}
85+
86+
// redirects
87+
app.get("/tutorials") { _, res, _ in res.redirect("/tutorials/") }
88+
.get("/documentation") { _, res, _ in res.redirect("/documentation/") }
89+
.get { _, res, _ in res.redirect("/documentation/") }
90+
91+
app.listen(1337) {
92+
console.log("Server listening on: http://localhost:1337/")
93+
console.log("DocC Archive:", archivePath)
94+
}

0 commit comments

Comments
 (0)