Files
dotfiles/dots/scripts/build.swift
2023-03-05 14:37:02 -05:00

82 lines
2.2 KiB
Swift
Executable File

#!/usr/bin/env swift
import Foundation
try build()
func build() throws {
try withVersion(in: "Sources/dots/Version.swift", as: currentVersion()) {
try foregroundShell(
"swift", "build",
"--disable-sandbox",
"--configuration", "release",
"-Xswiftc", "-cross-module-optimization"
)
}
}
func withVersion(in file: String, as version: String, _ closure: () throws -> ()) throws {
let fileURL = URL(fileURLWithPath: file)
let originalFileContents = try String(contentsOf: fileURL, encoding: .utf8)
// set version
try originalFileContents
.replacingOccurrences(of: "nil", with: "\"\(version)\"")
.write(to: fileURL, atomically: true, encoding: .utf8)
defer {
// undo set version
try! originalFileContents
.write(to: fileURL, atomically: true, encoding: .utf8)
}
// run closure
try closure()
}
func currentVersion() throws -> String {
do {
let tag = try backgroundShell("git", "describe", "--tags", "--exact-match")
return tag
} catch {
let branch = try backgroundShell("git", "symbolic-ref", "-q", "--short", "HEAD")
let commit = try backgroundShell("git", "rev-parse", "--short", "HEAD")
return "\(branch) (\(commit))"
}
}
func foregroundShell(_ args: String...) throws {
print("$", args.joined(separator: " "))
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
guard task.terminationStatus == 0 else {
throw ShellError(terminationStatus: task.terminationStatus)
}
}
@discardableResult
func backgroundShell(_ args: String...) throws -> String {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
// grab stdout
let output = Pipe()
task.standardOutput = output
// ignore stderr
let error = Pipe()
task.standardError = error
task.launch()
task.waitUntilExit()
guard task.terminationStatus == 0 else {
throw ShellError(terminationStatus: task.terminationStatus)
}
return String(decoding: output.fileHandleForReading.readDataToEndOfFile(), as: UTF8.self)
.trimmingCharacters(in: .whitespacesAndNewlines)
}
struct ShellError: Swift.Error {
var terminationStatus: Int32
}