Use Shwift library instead of Subprocess
Shwift has a concise API, which makes writing shell code nice and easy. This is an opinionated decision.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import ArgumentParser
|
||||
import Script
|
||||
|
||||
@main
|
||||
struct Command: AsyncParsableCommand {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import ArgumentParser
|
||||
import AsyncAlgorithms
|
||||
import Foundation
|
||||
import Logging
|
||||
import Script
|
||||
import Noora
|
||||
import Subprocess
|
||||
|
||||
struct GenerateDocumentationCommand: AsyncParsableCommand {
|
||||
struct GenerateDocumentationCommand: Script {
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "generate-documentation",
|
||||
abstract: "Generate DocC documentation of all targets inside a Linux container.",
|
||||
@@ -25,6 +23,7 @@ struct GenerateDocumentationCommand: AsyncParsableCommand {
|
||||
let logger = global.makeLogger(labeled: "swift-inotify.cli.task.generate-documentation")
|
||||
let fileManager = FileManager.default
|
||||
let projectDirectory = URL(fileURLWithPath: fileManager.currentDirectoryPath)
|
||||
let docker = try await executable(named: "docker")
|
||||
|
||||
let targets = try await Self.targets(for: projectDirectory)
|
||||
|
||||
@@ -43,28 +42,16 @@ struct GenerateDocumentationCommand: AsyncParsableCommand {
|
||||
let script = Self.makeRunScript(for: targets)
|
||||
|
||||
logger.debug("Container script", metadata: ["script": "\(script)"])
|
||||
let dockerResult = try await Subprocess.run(
|
||||
.name("docker"),
|
||||
arguments: [
|
||||
do {
|
||||
try await docker(
|
||||
"run", "--rm",
|
||||
"-v", "\(tempDirectory.path(percentEncoded: false)):/code",
|
||||
"-v", "\(tempDirectory.path):/code",
|
||||
"--platform", "linux/arm64",
|
||||
"-w", "/code",
|
||||
"swift:latest",
|
||||
"/bin/bash", "-c", script,
|
||||
],
|
||||
preferredBufferSize: 10,
|
||||
) { execution, standardInput, standardOutput, standardError in
|
||||
print("")
|
||||
let stdout = standardOutput.lines()
|
||||
let stderr = standardError.lines()
|
||||
for try await line in merge(stdout, stderr) {
|
||||
noora.passthrough("\(line)")
|
||||
}
|
||||
print("")
|
||||
}
|
||||
|
||||
guard dockerResult.terminationStatus.isSuccess else {
|
||||
)
|
||||
} catch {
|
||||
noora.error("Documentation generation failed.")
|
||||
return
|
||||
}
|
||||
@@ -116,11 +103,10 @@ struct GenerateDocumentationCommand: AsyncParsableCommand {
|
||||
}
|
||||
|
||||
private static func packageTargets() async throws -> [(name: String, path: String)] {
|
||||
let packageDescription = try await Subprocess.run(
|
||||
.name("swift"),
|
||||
arguments: ["package", "describe", "--type", "json"],
|
||||
output: .data(limit: 20_000)
|
||||
)
|
||||
let swift = try await executable(named: "swift")
|
||||
let packageDescriptionOutput = try await outputOf {
|
||||
try await swift("package", "describe", "--type", "json")
|
||||
}
|
||||
|
||||
struct PackageDescription: Codable {
|
||||
let targets: [Target]
|
||||
@@ -130,7 +116,8 @@ struct GenerateDocumentationCommand: AsyncParsableCommand {
|
||||
let path: String
|
||||
}
|
||||
|
||||
let package = try JSONDecoder().decode(PackageDescription.self, from: packageDescription.standardOutput)
|
||||
let data = Data(packageDescriptionOutput.utf8)
|
||||
let package = try JSONDecoder().decode(PackageDescription.self, from: data)
|
||||
return package.targets.map { ($0.name, $0.path) }
|
||||
}
|
||||
|
||||
@@ -175,15 +162,13 @@ struct GenerateDocumentationCommand: AsyncParsableCommand {
|
||||
// MARK: - Dependency Injection
|
||||
|
||||
private func injectDoccPluginDependency(in directory: URL, logger: Logger) async throws {
|
||||
let result = try await Subprocess.run(
|
||||
.name("swift"),
|
||||
arguments: [
|
||||
let swift = try await executable(named: "swift")
|
||||
do {
|
||||
try await swift(
|
||||
"package", "--package-path", directory.path(percentEncoded: false),
|
||||
"add-dependency", "--from", Self.doccPluginMinVersion, Self.doccPluginURL
|
||||
],
|
||||
) { _ in }
|
||||
|
||||
guard result.terminationStatus.isSuccess else {
|
||||
)
|
||||
} catch {
|
||||
throw GenerateDocumentationError.dependencyInjectionFailed
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import ArgumentParser
|
||||
import Script
|
||||
import Logging
|
||||
|
||||
struct GlobalOptions: ParsableArguments {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import ArgumentParser
|
||||
import AsyncAlgorithms
|
||||
import Foundation
|
||||
import Subprocess
|
||||
import Script
|
||||
import Noora
|
||||
|
||||
struct TestCommand: AsyncParsableCommand {
|
||||
struct TestCommand: Script {
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "test",
|
||||
abstract: "Run swift test in a linux container.",
|
||||
@@ -19,26 +17,21 @@ struct TestCommand: AsyncParsableCommand {
|
||||
let noora = Noora()
|
||||
let logger = global.makeLogger(labeled: "swift-inotify.cli.task.test")
|
||||
let currentDirectory = FileManager.default.currentDirectoryPath
|
||||
let docker = try await executable(named: "docker")
|
||||
|
||||
noora.info("Running tests on Linux.")
|
||||
logger.debug("Current directory", metadata: ["current-directory": "\(currentDirectory)"])
|
||||
async let monitorResult = Subprocess.run(
|
||||
.name("docker"),
|
||||
arguments: ["run", "-v", "\(currentDirectory):/code", "--security-opt", "systempaths=unconfined", "--platform", "linux/arm64", "-w", "/code", "swift:latest", "/bin/bash", "-c", "swift test --skip InotifyLimitTests; swift test --skip-build --filter InotifyLimitTests"],
|
||||
preferredBufferSize: 10,
|
||||
) { execution, standardInput, standardOutput, standardError in
|
||||
print("")
|
||||
let stdout = standardOutput.lines()
|
||||
let stderr = standardError.lines()
|
||||
for try await line in merge(stdout, stderr) {
|
||||
noora.passthrough("\(line)")
|
||||
}
|
||||
print("")
|
||||
}
|
||||
|
||||
if (try await monitorResult.terminationStatus.isSuccess) {
|
||||
do {
|
||||
try await docker(
|
||||
"run",
|
||||
"-v", "\(currentDirectory):/code",
|
||||
"--security-opt", "systempaths=unconfined",
|
||||
"--platform", "linux/arm64",
|
||||
"-w", "/code", "swift:latest",
|
||||
"/bin/bash", "-c", "swift test --skip InotifyLimitTests; swift test --skip-build --filter InotifyLimitTests"
|
||||
)
|
||||
noora.success("All tests completed successfully.")
|
||||
} else {
|
||||
} catch {
|
||||
noora.error("Not all tests completed successfully.")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user