Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription
let package = Package(
name: "DocCArchive",
platforms: [
.macOS(.v10_15)
.macOS(.v13)
],
products: [
.library(
Expand All @@ -16,11 +16,15 @@ let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-openapi-generator", from: "1.10.0"),
.package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.8.0"),
.package(url: "https://github.com/apple/swift-nio", from: "2.0.0"),
],
targets: [
.target(
name: "DocCArchive",
dependencies: ["VendoredDocC"]
dependencies: [
"VendoredDocC",
.product(name: "_NIOFileSystem", package: "swift-nio"),
]
),
.target(
name: "VendoredDocC",
Expand All @@ -37,7 +41,7 @@ let package = Package(
"Diagnostics.json",
"Metadata.json",
"ThemeSettings.spec.json",
"Benchmark.json"
"Benchmark.json",
]
),
.testTarget(
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ rm -rf .build
container run -it -c 4 -m 8g -v "$(pwd):/src" -w src/ swift:6.2 swift test
```


### Random Notes

- I'm trying NIOFilesystem as an alternative to Foundation's Bundle structure for navigating and interacting with the filesystem, but I think that I'd like to bind that behind a package trait down the road.
20 changes: 20 additions & 0 deletions Scripts/format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the Swift Argument Parser open source project
##
## Copyright (c) 2025 Apple Inc. and the Swift project authors
## Licensed under Apache License v2.0 with Runtime Library Exception
##
## See https://swift.org/LICENSE.txt for license information
##
##===----------------------------------------------------------------------===##

# Move to the project root
cd "$(dirname "$0")" || exit
cd ..
echo "Formatting Swift sources in $(pwd)"

# Run the format / lint commands
git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place
#git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel
95 changes: 89 additions & 6 deletions Sources/DocCArchive/DocCArchive.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,94 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book
import Foundation
internal import VendoredDocC

import VendoredDocC
public struct Archive {
/// File path to the DocC Archive
public let path: String

let metadata = Components.Schemas.Metadata(
bundleDisplayName: "fred", bundleIdentifier: "org.swift",
schemaVersion: .init(major: 1, minor: 0, patch: 0))
public init(path: String) {
self.path = path
}

// ExampleDocs.doccarchive
// ├── assets.json
// ├── data
// │   └── documentation
// │   ├── exampledocs
// │   │   └── examplearticle.json
// │   └── exampledocs.json
// ├── diagnostics.json ✅ (need an fixture that includes diagnostics)
// ├── index
// │   └── index.json ✅ (includes title, icon, and path in hierarchical tree of nodes)
// │   (The index directory also contains a multi-segment LMDB database, but that doesn't
// │   appear to be used by the DocC Render single-page application. It seems to focus entirely
// │   on the index.json in this directory, flattening the tree structure encoded and using the
// │   `path` property to identify and reference the relevant JSON files to load (RenderNode.spec.json)
// ├── indexing-records.json ✅ (full text search content within a flat list of IndexingRecord)
// ├── linkable-entities.json
// └── metadata.json ✅

let decoder = JSONDecoder()

func parseMetadata() throws -> Components.Schemas.Metadata {
let metadataURL = URL(filePath: path).appending(component: "metadata").appendingPathExtension(
"json")
// print("metadata URL calculated at \(metadataURL.path)")

let metadataBytes = try Data(contentsOf: metadataURL)
let metadata = try decoder.decode(Components.Schemas.Metadata.self, from: metadataBytes)
return metadata
}

func parseDiagnostics() throws -> Components.Schemas.Diagnostics {
let diagnosticsURL = URL(filePath: path).appending(component: "diagnostics")
.appendingPathExtension("json")

let diagnosticsBytes = try Data(contentsOf: diagnosticsURL)
let diagnostics = try decoder.decode(
Components.Schemas.Diagnostics.self, from: diagnosticsBytes)
return diagnostics
}

func parseIndexingRecords() throws -> Components.Schemas.IndexingRecords {
let indexingRecordsURL = URL(filePath: path).appending(component: "indexing-records")
.appendingPathExtension("json")

let indexingRecordsBytes = try Data(contentsOf: indexingRecordsURL)
let indexingRecords = try decoder.decode(
Components.Schemas.IndexingRecords.self, from: indexingRecordsBytes)
return indexingRecords
}

func parseIndex() throws -> Components.Schemas.RenderIndex {
let indexURL = URL(filePath: path).appending(component: "index").appending(component: "index")
.appendingPathExtension("json")

let indexBytes = try Data(contentsOf: indexURL)
let index = try decoder.decode(Components.Schemas.RenderIndex.self, from: indexBytes)
return index
}

// recursive depth-first walk of tree of Nodes through the list provided, doing the
// function stuff on each node (visitor pattern)
func walkRenderIndexNodes(
nodes: [Components.Schemas.Node], doing: (Components.Schemas.Node, Int) -> Void
) {
for node in nodes {
walkRenderIndexNodes(node: node, level: 0, doing: doing)
}
}

func walkRenderIndexNodes(
node: Components.Schemas.Node, level: Int, doing: (Components.Schemas.Node, Int) -> Void
) {
doing(node, level)
if let childNodes = node.children {
for n in childNodes {
walkRenderIndexNodes(node: n, level: level + 1, doing: doing)
}
}
}
}

// JSON files to parse within a DocC Archive:
//
Expand Down
1 change: 1 addition & 0 deletions Sources/VendoredDocC/Benchmark.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"components": {
"schemas": {
"Benchmark": {
"description": "maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Benchmark/BenchmarkResults.swift#L14",
"type": "object",
"required": [
"doccArguments",
Expand Down
1 change: 1 addition & 0 deletions Sources/VendoredDocC/IndexingRecords.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
}
},
"IndexingRecord": {
description: "Maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Indexing/IndexingRecord.swift#L14",
"type": "object",
"required": [
"kind",
Expand Down
1 change: 1 addition & 0 deletions Sources/VendoredDocC/LinkableEntities.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
}
},
"LinkDestinationSummary": {
"description": "maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift#L76",
"type": "object",
"additionalProperties": false,
"required": [
Expand Down
14 changes: 12 additions & 2 deletions Sources/VendoredDocC/Metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
"schemas": {
"Metadata": {
"type": "object",
"description": "maps to Maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Model/BuildMetadata.swift#L14",
"required": [
"bundleDisplayName",
"bundleIdentifier",
"bundleID",
"schemaVersion"
],
"properties": {
"bundleDisplayName": {
"type": "string"
},
"bundleIdentifier": {
"bundleID": {
"type": "string"
},
"schemaVersion": {
Expand All @@ -28,6 +29,7 @@
}
},
"SchemaVersion": {
"description": "A version that follows the [Semantic Versioning](https://semver.org) specification. Maps to https: https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Model/Rendering/SemanticVersion.swift#L14",
"type": "object",
"required": [
"major",
Expand All @@ -43,6 +45,14 @@
},
"patch": {
"type": "integer"
},
"prerelease": {
"type": "string",
"description": "The optional prerelease version component, which may contain non-numeric characters."
},
"buildMetadata": {
"type": "string",
"description": "Optional additional build metadata."
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/VendoredDocC/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ OpenAPI generator accepts a single OpenAPI spec file, so this directory merges t

```bash
npm i openapi-merge-cli
npx openapi-merge.cli
npx openapi-merge-cli
```

To get Swift code for the serialized types, generate the types from the combined spec. The OpenAPI generator
Expand Down
18 changes: 12 additions & 6 deletions Sources/VendoredDocC/RenderIndex.spec.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"openapi": "3.0.0",
"openapi": "3.1.0",
"info": {
"description": "Specification of the Swift-DocC Index.json file.",
"version": "0.1.2",
Expand All @@ -9,10 +9,12 @@
"components": {
"schemas": {
"RenderIndex": {
"description": "maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Indexing/RenderIndexJSON/RenderIndex.swift#L24.",
"type": "object",
"required": [
"schemaVersion",
"interfaceLanguages"
"interfaceLanguages",
"includedArchiveIdentifiers"
],
"properties": {
"schemaVersion": {
Expand Down Expand Up @@ -42,9 +44,13 @@
}
},
"Node": {
"description": "maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Indexing/RenderIndexJSON/RenderIndex.swift#L117.",
"type": "object",
"required": [
"title"
"title",
"deprecated",
"external",
"beta"
],
"properties": {
"title": {
Expand Down Expand Up @@ -95,15 +101,15 @@
"type": "string"
},
"deprecated": {
"type": "boolean",
"type": ["boolean", "null"],
"default": "false"
},
"external": {
"type": "boolean",
"type": ["boolean", "null"],
"default": "false"
},
"beta": {
"type": "boolean",
"type": ["boolean", "null"],
"default": "false"
},
"icon": {
Expand Down
1 change: 1 addition & 0 deletions Sources/VendoredDocC/RenderNode.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"components": {
"schemas": {
"RenderNode": {
"description": "maps to https://github.com/swiftlang/swift-docc/blob/main/Sources/SwiftDocC/Model/Rendering/RenderNode.swift#L91"
"oneOf": [
{
"$ref": "#/components/schemas/TutorialsPageRenderNode"
Expand Down
Loading