From ee3e33e78033c3ca8f38ce41c26b7c95d07484cd Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Wed, 6 Nov 2019 13:25:11 -0600 Subject: [PATCH 1/2] Adopt ArgumentParser for the command-line tool --- .gitignore | 2 + Package.swift | 6 +- Sources/tibs/main.swift | 131 ++++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index b0b53449..542ee05f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ Package.resolved /*.xcodeproj /*.sublime-project /*.sublime-workspace +/.swiftpm + diff --git a/Package.swift b/Package.swift index 0195c3e1..fe93ffc2 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,9 @@ let package = Package( name: "tibs", targets: ["tibs"]) ], - dependencies: [], + dependencies: [ + .package(url: "https://github.com/apple/swift-argument-parser", from: "0.0.1"), + ], targets: [ // MARK: Swift interface @@ -45,7 +47,7 @@ let package = Package( // Commandline tool for working with tibs projects. .target( name: "tibs", - dependencies: ["ISDBTibs"]), + dependencies: ["ISDBTibs", "ArgumentParser"]), // Test support library, built on top of tibs. .target( diff --git a/Sources/tibs/main.swift b/Sources/tibs/main.swift index d8b8725c..59941a53 100644 --- a/Sources/tibs/main.swift +++ b/Sources/tibs/main.swift @@ -12,81 +12,84 @@ import ISDBTibs import Foundation +import ArgumentParser -extension FileHandle: TextOutputStream { - public func write(_ string: String) { - guard let data = string.data(using: .utf8) else { - fatalError("failed to get data from string '\(string)'") - } - self.write(data) - } +struct RuntimeError: LocalizedError { + var errorDescription: String? } -var stderr = FileHandle.standardError - -func swiftDepsMerge(output: String, _ files: [String]) { - var allDeps: Set = [] - - for file in files { - guard let makefile = Makefile(path: URL(fileURLWithPath: file)) else { - print("error: could not read dep file '\(file)'", to: &stderr) - exit(1) - } - - let allOutputs = makefile.outputs.flatMap { $0.deps } - allDeps.formUnion(allOutputs) - } - - print("\(output) : \(allDeps.sorted().joined(separator: " "))") +struct Tibs: ParsableCommand { + static var configuration = CommandConfiguration( + subcommands: [Build.self, MergeDependencies.self], + defaultSubcommand: Build.self) } -func main(arguments: [String]) { - - if arguments.count < 2 { - print("usage: tibs ", to: &stderr) - exit(1) - } - - if arguments[1] == "swift-deps-merge" { - if arguments.count < 4 { - print("usage: tibs swift-deps-merge [...]", to: &stderr) - exit(1) +extension Tibs { + struct Build: ParsableCommand { + @Argument() + var projectDir: String + + func run() throws { + let projectRoot = URL(fileURLWithPath: projectDir, isDirectory: true) + + let manifest: TibsManifest + do { + manifest = try TibsManifest.load(projectRoot: projectRoot) + } catch { + throw RuntimeError(errorDescription: "could not read manifest for '\(projectRoot.path)'") + } + + let cwd = URL(fileURLWithPath: FileManager.default.currentDirectoryPath, isDirectory: true) + + let toolchain = TibsToolchain( + swiftc: URL(fileURLWithPath: "/usr/bin/swiftc"), + clang: URL(fileURLWithPath: "/usr/bin/clang"), + tibs: Bundle.main.bundleURL.appendingPathComponent("tibs", isDirectory: false)) + + let builder: TibsBuilder + do { + builder = try TibsBuilder(manifest: manifest, sourceRoot: projectRoot, buildRoot: cwd, toolchain: toolchain) + } catch { + throw RuntimeError(errorDescription: "could not resolve project at '\(projectRoot.path)'") + } + + do { + try builder.writeBuildFiles() + } catch { + throw RuntimeError(errorDescription: "could not write build files") + } } - swiftDepsMerge(output: arguments[2], Array(arguments.dropFirst(3))) - return - } - - let projectDir = URL(fileURLWithPath: arguments.last!, isDirectory: true) - - let manifest: TibsManifest - do { - manifest = try TibsManifest.load(projectRoot: projectDir) - } catch { - print("error: could not read manifest for '\(projectDir.path)': \(error)", to: &stderr) - exit(1) } +} - let cwd = URL(fileURLWithPath: FileManager.default.currentDirectoryPath, isDirectory: true) +extension Tibs { + struct MergeDependencies: ParsableCommand { + static var configuration = CommandConfiguration(commandName: "swift-deps-merge") - let toolchain = TibsToolchain( - swiftc: URL(fileURLWithPath: "/usr/bin/swiftc"), - clang: URL(fileURLWithPath: "/usr/bin/clang"), - tibs: Bundle.main.bundleURL.appendingPathComponent("tibs", isDirectory: false)) + @Argument() + var output: String - let builder: TibsBuilder - do { - builder = try TibsBuilder(manifest: manifest, sourceRoot: projectDir, buildRoot: cwd, toolchain: toolchain) - } catch { - print("error: could not resolve project at '\(projectDir.path)': \(error)", to: &stderr) - exit(1) - } + @Argument() + var files: [String] - do { - try builder.writeBuildFiles() - } catch { - print("error: could not write build files: \(error)", to: &stderr) - exit(1) + mutating func validate() throws { + if files.isEmpty { + throw ValidationError("No files specified") + } + } + + func run() throws { + let allDeps = try files.flatMap { file -> [Substring] in + guard let makefile = Makefile(path: URL(fileURLWithPath: file)) else { + throw RuntimeError(errorDescription: "could not read dep file '\(file)'") + } + return makefile.outputs.flatMap { $0.deps } + } + + let uniqueDeps = Set(allDeps).sorted() + print("\(output) : \(uniqueDeps.joined(separator: " "))") + } } } -main(arguments: CommandLine.arguments) +Tibs.main() From 28182cb7dac574bcafe74b1019069ebda360264d Mon Sep 17 00:00:00 2001 From: Nate Cook Date: Wed, 1 Jul 2020 01:05:09 -0500 Subject: [PATCH 2/2] Update to latest ArgumentParser API --- Package.swift | 2 +- Sources/tibs/main.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index fe93ffc2..764c3cc9 100644 --- a/Package.swift +++ b/Package.swift @@ -19,7 +19,7 @@ let package = Package( targets: ["tibs"]) ], dependencies: [ - .package(url: "https://github.com/apple/swift-argument-parser", from: "0.0.1"), + .package(url: "https://github.com/apple/swift-argument-parser", from: "0.2.0"), ], targets: [ diff --git a/Sources/tibs/main.swift b/Sources/tibs/main.swift index 59941a53..365cfef2 100644 --- a/Sources/tibs/main.swift +++ b/Sources/tibs/main.swift @@ -70,7 +70,7 @@ extension Tibs { var output: String @Argument() - var files: [String] + var files: [String] = [] mutating func validate() throws { if files.isEmpty {