From 8014acbae72310fe906d1950081846e8124c5503 Mon Sep 17 00:00:00 2001 From: Mattt Date: Tue, 10 Mar 2020 05:31:51 -0700 Subject: [PATCH] Replace Commander with ArgumentParser in swift-doc target --- Package.resolved | 9 +++ Package.swift | 3 +- Sources/swift-doc/Subcommands/Generate.swift | 64 +++++++++++++++++++ Sources/swift-doc/main.swift | 65 +++----------------- 4 files changed, 84 insertions(+), 57 deletions(-) create mode 100644 Sources/swift-doc/Subcommands/Generate.swift diff --git a/Package.resolved b/Package.resolved index 8be4b5a3..bca7ef81 100644 --- a/Package.resolved +++ b/Package.resolved @@ -28,6 +28,15 @@ "version": "0.9.0" } }, + { + "package": "swift-argument-parser", + "repositoryURL": "https://github.com/apple/swift-argument-parser", + "state": { + "branch": null, + "revision": "35b76bf577d3cc74820f8991894ce3bcdf024ddc", + "version": "0.0.2" + } + }, { "package": "cmark", "repositoryURL": "https://github.com/SwiftDocOrg/swift-cmark.git", diff --git a/Package.swift b/Package.swift index 74fd1327..f3a53c2c 100644 --- a/Package.swift +++ b/Package.swift @@ -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", diff --git a/Sources/swift-doc/Subcommands/Generate.swift b/Sources/swift-doc/Subcommands/Generate.swift new file mode 100644 index 00000000..dc438cad --- /dev/null +++ b/Sources/swift-doc/Subcommands/Generate.swift @@ -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")) + } + } + } + } +} diff --git a/Sources/swift-doc/main.swift b/Sources/swift-doc/main.swift index 2ea02828..0845c526 100644 --- a/Sources/swift-doc/main.swift +++ b/Sources/swift-doc/main.swift @@ -1,11 +1,5 @@ -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] @@ -13,53 +7,12 @@ let fileAttributes: [FileAttributeKey : Any] = [.posixPermissions: 0o744] var standardOutput = FileHandle.standardOutput var standardError = FileHandle.standardError -command( - Option("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()