Skip to content

Commit

Permalink
🔀 Prepare info output for some commands (#19)
Browse files Browse the repository at this point in the history
* ✨ Add possibility to optionally suppress `System` output

* ✨ Add logger for logging output

* ✨ Suppress `ArchiveService` output

* ✨ Add output to `CarthageController` calls

* ✨ Add output to `AutoPrefixService`

* ✨ Add info output to `Download` command

* ✨ Add info output to `Upload` command
  • Loading branch information
olejnjak authored Oct 29, 2021
1 parent fd050de commit 60b35ce
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 24 deletions.
19 changes: 16 additions & 3 deletions Sources/TorinoCore/Commands/Download.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,35 @@ struct Download: ParsableCommand {
@OptionGroup var args: SharedArguments

func run() throws {
let logger = Logger.shared

guard let cwd = localFileSystem.currentWorkingDirectory else {
throw UploadError(message: "Unable to get current working directory")
}

let prefix = try args.prefix ?? AutoPrefixService().autoPrefix()
let pathProvider = try CarthagePathProvider(
base: cwd,
prefix: try args.prefix ?? AutoPrefixService().autoPrefix()
prefix: prefix
)

let lockfilePath = pathProvider.lockfile()
let lockfileContent = try localFileSystem.readFileContents(lockfilePath)
let lockfile = Lockfile.from(string: lockfileContent.cString)

let gcpDownloader = (try? GCPConfig(environment: ProcessEnv.vars))
.map { GCPDownloader(config: $0) }
let gcpDownloader: GCPDownloading? = {
do {
return try GCPDownloader(config: GCPConfig(environment: ProcessEnv.vars))
} catch {
logger.error("Unable to decode GCP configuration")
logger.error(error.localizedDescription)
logger.info("Remote cache will not be used")
}

return nil
}()

logger.info("Trying to download cached dependencies with prefix", prefix)
try LocalDependenciesDownloader(gcpDownloader: gcpDownloader, pathProvider: pathProvider)
.downloadDependencies(
dependencies: lockfile.dependencies.map {
Expand Down
20 changes: 17 additions & 3 deletions Sources/TorinoCore/Commands/Upload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,31 @@ struct Upload: ParsableCommand {
@OptionGroup var args: SharedArguments

func run() throws {
let logger = Logger.shared

guard let cwd = localFileSystem.currentWorkingDirectory else {
throw UploadError(message: "Unable to get current working directory")
}

let prefix = try args.prefix ?? AutoPrefixService().autoPrefix()
let pathProvider = try CarthagePathProvider(
base: cwd,
prefix: try args.prefix ?? AutoPrefixService().autoPrefix()
prefix: prefix
)

let gcpUploader = (try? GCPConfig(environment: ProcessEnv.vars))
.map { GCPUploader(config: $0) }
let gcpUploader: GCPUploading? = {
do {
return try GCPUploader(config: GCPConfig(environment: ProcessEnv.vars))
} catch {
logger.error("Unable to decode GCP configuration")
logger.error(error.localizedDescription)
logger.info("Remote cache will not be used")
}

return nil
}()

logger.info("Trying to upload cached dependencies with prefix", prefix)

try UploadService(
dependenciesLoader: CarthageDependenciesLoader(pathProvider: pathProvider),
Expand Down
2 changes: 1 addition & 1 deletion Sources/TorinoCore/Services/ArchiveService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ final class ZipService: ArchiveServicing {
// MARK: - Private helpers

private func shell(_ args: [String], cwd: AbsolutePath? = nil) throws {
try system.run(args, cwd: cwd)
try system.run(args, cwd: cwd, suppressOutput: true)
}
}
17 changes: 14 additions & 3 deletions Sources/TorinoCore/Services/AutoPrefixService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,24 @@ struct AutoPrefixError: Error {

struct AutoPrefixService: AutoPrefixServicing {
private let system: Systeming
private let logger: Logging

// MARK: - Initializers

init(system: Systeming = System.shared) {
init(
system: Systeming = System.shared,
logger: Logging = Logger.shared
) {
self.system = system
self.logger = logger
}

// MARK: - Interface

func autoPrefix() throws -> String {
let swiftVersion = try system.run("swift", "-version")
logger.info("Trying to automatically detect cache prefix")

let swiftVersion = try system.run("swift", "-version", suppressOutput: true)

let regex = try NSRegularExpression(
pattern: #"Swift Version ([0-9]+\.[0-9]+(\.[0-9]+)?)"#,
Expand All @@ -37,7 +44,11 @@ struct AutoPrefixService: AutoPrefixServicing {

if matchRange == result.range { continue }

return "Swift-" + (swiftVersion as NSString).substring(with: matchRange)
let prefix = "Swift-" + (swiftVersion as NSString).substring(with: matchRange)

logger.info("Detected cache prefix is", prefix)

return prefix
}
}

Expand Down
9 changes: 8 additions & 1 deletion Sources/TorinoCore/Services/CarthageController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ protocol CarthageControlling {

struct CarthageController: CarthageControlling {
private let system: Systeming
private let logger: Logging

// MARK: - Initializers

init(system: Systeming = System.shared) {
init(
system: Systeming = System.shared,
logger: Logging = Logger.shared
) {
self.system = system
self.logger = logger
}

// MARK: - Interface
Expand All @@ -23,6 +28,7 @@ struct CarthageController: CarthageControlling {

func update(_ args: CarthageArguments, noBuild: Bool) throws {
if noBuild {
logger.info("Updating Carthage dependencies without building")
try system.run("carthage", "update", "--no-build")
} else {
try buildUsing(command: "update", args: args)
Expand All @@ -44,6 +50,7 @@ struct CarthageController: CarthageControlling {
command += ["--platform", platform]
}

logger.info("Running `\(command.joined(separator: " "))`")
try system.run(command)
}
}
35 changes: 35 additions & 0 deletions Sources/TorinoCore/Services/Logger.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Foundation
import TSCUtility

protocol Logging {
func logStdout(_ output: String...)
func info(_ info: String...)
}

struct Logger: Logging {
static let shared = Logger()

private init() {

}

func logStdout(_ output: String...) {
print(type: "[OUTPUT]", output: output)
}

func info(_ info: String...) {
print(type: "[INFO]", output: info)
}

func error(_ error: String...) {
print(type: "[ERROR]", output: error)
}

private func print(type: String, output: [String]) {
Swift.print(
type,
output.map { $0.trimmingCharacters(in: .newlines).replacingOccurrences(of: "\n", with: "\n" + type) }
.joined(separator: " ")
)
}
}
64 changes: 51 additions & 13 deletions Sources/TorinoCore/Services/System.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,81 @@ import TSCBasic

protocol Systeming {
@discardableResult
func run(_ arguments: [String], cwd: AbsolutePath?) throws -> String
func run(_ arguments: [String], cwd: AbsolutePath?, suppressOutput: Bool) throws -> String
}

extension Systeming {
@discardableResult
func run(_ arguments: String..., cwd: AbsolutePath? = nil) throws -> String {
try run(Array(arguments), cwd: cwd)
func run(_ arguments: String..., cwd: AbsolutePath? = nil, suppressOutput: Bool = false) throws -> String {
try run(Array(arguments), cwd: cwd, suppressOutput: suppressOutput)
}

@discardableResult
func run(_ arguments: [String]) throws -> String {
try run(arguments, cwd: nil)
try run(arguments, cwd: nil, suppressOutput: false)
}
}

struct SystemError: Error {
enum Reason {
case terminated
case signal
}

let code: Int32
let reason: Reason
let stdOut: String
let stdErr: String
}

struct System: Systeming {
static let shared = System()
static let shared = System(logger: Logger.shared)

private init() {

private init(logger: Logging) {
self.logger = logger
}

private let logger: Logging

@discardableResult
func run(_ args: [String], cwd: AbsolutePath?) throws -> String {
func run(_ args: [String], cwd: AbsolutePath?, suppressOutput: Bool) throws -> String {
var stdout = ""
var stderr = ""

let task: TSCBasic.Process = {
let outputRedirection: TSCBasic.Process.OutputRedirection = .stream(
stdout: { output in
let newOutput = String(decoding: output, as: Unicode.UTF8.self)

stdout += newOutput

if !suppressOutput {
logger.logStdout(newOutput)
}
},
stderr: { output in
let newOutput = String(decoding: output, as: Unicode.UTF8.self)

stderr += newOutput

if !suppressOutput {
logger.logStdout(newOutput)
}
},
redirectStderr: false
)

if let cwd = cwd {
return Process(
arguments: args,
workingDirectory: cwd,
outputRedirection: .collect
outputRedirection: outputRedirection
)
}
return Process(arguments: args)
return Process(
arguments: args,
outputRedirection: outputRedirection
)
}()

try task.launch()
Expand All @@ -48,11 +86,11 @@ struct System: Systeming {
switch result.exitStatus {
case .signalled(signal: let signal):
// Don't care about code/signal
throw SystemError(code: signal)
throw SystemError(code: signal, reason: .signal, stdOut: stdout, stdErr: stderr)
case .terminated(code: let code) where code != 0:
throw SystemError(code: code)
throw SystemError(code: code, reason: .terminated, stdOut: stdout, stdErr: stderr)
case .terminated:
return try result.utf8Output()
return stdout
}
}
}

0 comments on commit 60b35ce

Please sign in to comment.