Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Replace Commander with ArgumentParser in swift-doc target #20

Merged
merged 1 commit into from
Mar 10, 2020
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
9 changes: 9 additions & 0 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ let package = Package(
.package(url: "https://github.com/SwiftDocOrg/SwiftSemantics.git", .branch("swift-5.2")),
.package(url: "https://github.com/apple/swift-syntax.git", .revision("swift-5.2-DEVELOPMENT-SNAPSHOT-2020-02-12-a")),
.package(url: "https://github.com/kylef/Commander.git", .upToNextMinor(from: "0.9.1")),
.package(url: "https://github.com/apple/swift-argument-parser", .upToNextMinor(from: "0.0.2")),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "swift-doc",
dependencies: ["SwiftDoc", "SwiftSemantics", "SwiftMarkup", "CommonMarkBuilder", "Commander"]
dependencies: ["SwiftDoc", "SwiftSemantics", "SwiftMarkup", "CommonMarkBuilder", "ArgumentParser"]
),
.target(
name: "swift-dcov",
Expand Down
64 changes: 64 additions & 0 deletions Sources/swift-doc/Subcommands/Generate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import ArgumentParser
import Foundation
import SwiftSemantics
import struct SwiftSemantics.Protocol
import SwiftMarkup
import SwiftDoc

extension SwiftDoc {
struct Generate: ParsableCommand {
struct Options: ParsableArguments {
@Argument(help: "One or more paths to Swift files")
var inputs: [String]

@Option(name: .shortAndLong,
default: ".build/documentation",
help: "The path for generated output")
var output: String
}

static var configuration = CommandConfiguration(abstract: "Generates Swift documentation")

@OptionGroup()
var options: Options

func run() throws {
let module = try Module(paths: options.inputs)

let outputDirectoryURL = URL(fileURLWithPath: options.output)
try fileManager.createDirectory(at: outputDirectoryURL, withIntermediateDirectories: true, attributes: fileAttributes)

do {
try HomePage(module: module).write(to: outputDirectoryURL.appendingPathComponent("Home.md"))
try SidebarPage(module: module).write(to: outputDirectoryURL.appendingPathComponent("_Sidebar.md"))
try FooterPage().write(to: outputDirectoryURL.appendingPathComponent("_Footer.md"))

var globals: [String: [Symbol]] = [:]
for symbol in module.topLevelSymbols.filter({ $0.isPublic }) {
switch symbol.declaration {
case is Class:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: symbol.id.description)).md"))
case is Enumeration:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: symbol.id.description)).md"))
case is Structure:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: symbol.id.description)).md"))
case let `protocol` as Protocol:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: `protocol`.name)).md"))
case let `typealias` as Typealias:
try TypealiasPage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: `typealias`.name)).md"))
case let function as Function where !function.isOperator:
globals[function.name, default: []] += [symbol]
case let variable as Variable:
globals[variable.name, default: []] += [symbol]
default:
continue
}
}

for (name, symbols) in globals {
try GlobalPage(module: module, name: name, symbols: symbols).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: name)).md"))
}
}
}
}
}
65 changes: 9 additions & 56 deletions Sources/swift-doc/main.swift
Original file line number Diff line number Diff line change
@@ -1,65 +1,18 @@
import Commander
import ArgumentParser
import Foundation
import SwiftSemantics
import struct SwiftSemantics.Protocol
import SwiftMarkup
import SwiftDoc

let arguments = Array(ProcessInfo.processInfo.arguments.dropFirst())

let fileManager = FileManager.default
let fileAttributes: [FileAttributeKey : Any] = [.posixPermissions: 0o744]

var standardOutput = FileHandle.standardOutput
var standardError = FileHandle.standardError

command(
Option<String>("output", default: ".build/documentation", description: "The path for generated output"),
Argument<[String]>("inputs", description: "One or more paths to Swift files", validator: { (inputs) -> [String] in
inputs.filter { path in
var isDirectory: ObjCBool = false
return fileManager.fileExists(atPath: path, isDirectory: &isDirectory) || isDirectory.boolValue
}
}), { output, inputs in
do {
let module = try Module(paths: inputs)

let outputDirectoryURL = URL(fileURLWithPath: output)
try fileManager.createDirectory(at: outputDirectoryURL, withIntermediateDirectories: true, attributes: fileAttributes)

do {
try HomePage(module: module).write(to: outputDirectoryURL.appendingPathComponent("Home.md"))
try SidebarPage(module: module).write(to: outputDirectoryURL.appendingPathComponent("_Sidebar.md"))
try FooterPage().write(to: outputDirectoryURL.appendingPathComponent("_Footer.md"))

var globals: [String: [Symbol]] = [:]
for symbol in module.topLevelSymbols.filter({ $0.isPublic }) {
switch symbol.declaration {
case is Class:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: symbol.id.description)).md"))
case is Enumeration:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: symbol.id.description)).md"))
case is Structure:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: symbol.id.description)).md"))
case let `protocol` as Protocol:
try TypePage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: `protocol`.name)).md"))
case let `typealias` as Typealias:
try TypealiasPage(module: module, symbol: symbol).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: `typealias`.name)).md"))
case let function as Function where !function.isOperator:
globals[function.name, default: []] += [symbol]
case let variable as Variable:
globals[variable.name, default: []] += [symbol]
default:
continue
}
}
struct SwiftDoc: ParsableCommand {
static var configuration = CommandConfiguration(
abstract: "A utility for generating documentation for Swift code.",
subcommands: [Generate.self],
defaultSubcommand: Generate.self
)
}

for (name, symbols) in globals {
try GlobalPage(module: module, name: name, symbols: symbols).write(to: outputDirectoryURL.appendingPathComponent("\(path(for: name)).md"))
}
}
} catch {
print("Error: \(error)", to: &standardError)
exit(EXIT_FAILURE)
}
}).run()
SwiftDoc.main()