Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt ArgumentParser for the command-line tool #72

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ Package.resolved
/*.xcodeproj
/*.sublime-project
/*.sublime-workspace
/.swiftpm

6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ let package = Package(
name: "tibs",
targets: ["tibs"])
],
dependencies: [],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "0.2.0"),
],
targets: [

// MARK: Swift interface
Expand All @@ -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(
Expand Down
131 changes: 67 additions & 64 deletions Sources/tibs/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<Substring> = []

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 <project-dir>", to: &stderr)
exit(1)
}

if arguments[1] == "swift-deps-merge" {
if arguments.count < 4 {
print("usage: tibs swift-deps-merge <output> <deps1.d> [...]", 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()