refactor to use metadata, address code review comments
This commit is contained in:
parent
52fe8fd119
commit
f0871503da
|
@ -80,7 +80,7 @@ public final class XCFrameworkBuilder: XCFrameworkBuilding {
|
|||
let outputDirectory = try TemporaryDirectory(removeTreeOnDeinit: false)
|
||||
let temporaryPath = try TemporaryDirectory(removeTreeOnDeinit: false)
|
||||
|
||||
logger.notice("Building .xcframework for \(target.name)".as(.section))
|
||||
logger.notice("Building .xcframework for \(target.name)", metadata: .section)
|
||||
|
||||
// Build for the device
|
||||
// Without the BUILD_LIBRARY_FOR_DISTRIBUTION argument xcodebuild doesn't generate the .swiftinterface file
|
||||
|
@ -95,7 +95,7 @@ public final class XCFrameworkBuilder: XCFrameworkBuilding {
|
|||
.buildSetting("SKIP_INSTALL", "NO"),
|
||||
.buildSetting("BUILD_LIBRARY_FOR_DISTRIBUTION", "YES"))
|
||||
.do(onSubscribed: {
|
||||
logger.notice("Building \(target.name) for device".as(.subsection))
|
||||
logger.notice("Building \(target.name) for device", metadata: .subsection)
|
||||
})
|
||||
|
||||
// Build for the simulator
|
||||
|
@ -113,7 +113,7 @@ public final class XCFrameworkBuilder: XCFrameworkBuilding {
|
|||
.buildSetting("SKIP_INSTALL", "NO"),
|
||||
.buildSetting("BUILD_LIBRARY_FOR_DISTRIBUTION", "YES"))
|
||||
.do(onSubscribed: {
|
||||
logger.notice("Building \(target.name) for simulator".as(.subsection))
|
||||
logger.notice("Building \(target.name) for simulator", metadata: .subsection)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ public final class XCFrameworkBuilder: XCFrameworkBuilding {
|
|||
let xcframeworkPath = outputDirectory.path.appending(component: "\(target.productName).xcframework")
|
||||
let xcframeworkObservable = xcodeBuildController.createXCFramework(frameworks: frameworkpaths, output: xcframeworkPath)
|
||||
.do(onSubscribed: {
|
||||
logger.notice("Exporting xcframework for \(target.platform.caseValue)".as(.subsection))
|
||||
logger.notice("Exporting xcframework for \(target.platform.caseValue)", metadata: .subsection)
|
||||
})
|
||||
|
||||
return deviceArchiveObservable
|
||||
|
|
|
@ -88,7 +88,7 @@ final class WorkspaceGenerator: WorkspaceGenerating {
|
|||
tuistConfig _: TuistConfig) throws -> AbsolutePath {
|
||||
let workspaceName = "\(graph.name).xcworkspace"
|
||||
|
||||
logger.info("Generating workspace \(workspaceName)".as(.section))
|
||||
logger.info("Generating workspace \(workspaceName)", metadata: .section)
|
||||
|
||||
/// Projects
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ final class CocoaPodsInteractor: CocoaPodsInteracting {
|
|||
|
||||
// The installation of Pods might fail if the local repository that contains the specs
|
||||
// is outdated.
|
||||
logger.info("Installing CocoaPods dependencies defined in \(node.podfilePath)".as(.section))
|
||||
logger.info("Installing CocoaPods dependencies defined in \(node.podfilePath)", metadata: .section)
|
||||
|
||||
var mightNeedRepoUpdate: Bool = false
|
||||
let outputClosure: ([UInt8]) -> Void = { bytes in
|
||||
|
|
|
@ -52,10 +52,10 @@ class EditCommand: NSObject, Command {
|
|||
try! FileHandler.shared.delete(EditCommand.temporaryDirectory.path)
|
||||
exit(0)
|
||||
}
|
||||
logger.info("Opening Xcode to edit the project. Press \("CTRL + C".green().bold()) once you are done editing")
|
||||
logger.info("Opening Xcode to edit the project. Press \("CTRL + C", .keystroke) once you are done editing")
|
||||
try opener.open(path: xcodeprojPath, wait: true)
|
||||
} else {
|
||||
logger.info("Xcode project generated at \(xcodeprojPath.pathString)".as(.success))
|
||||
logger.info("Xcode project generated at \(xcodeprojPath.pathString)", metadata: .success)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ class GenerateCommand: NSObject, Command {
|
|||
|
||||
let time = String(format: "%.3f", timer.stop())
|
||||
|
||||
logger.info("Project generated.".as(.success))
|
||||
logger.info("Project generated.", metadata: .success)
|
||||
logger.info("Total time taken: \(time)s")
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,6 @@ class GraphCommand: NSObject, Command {
|
|||
}
|
||||
|
||||
try FileHandler.shared.write(graph, path: path, atomically: true)
|
||||
logger.info("Graph exported to \(path.pathString)".as(.success))
|
||||
logger.info("Graph exported to \(path.pathString)", metadata: .success)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ class InitCommand: NSObject, Command {
|
|||
try generateTuistConfig(path: path)
|
||||
try generateGitIgnore(path: path)
|
||||
|
||||
logger.info("Project generated at path \(path.pathString).".as(.success))
|
||||
logger.info("Project generated at path \(path.pathString).", metadata: .success)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ class LintCommand: NSObject, Command {
|
|||
issues.append(contentsOf: graphLinter.lint(graph: graph))
|
||||
|
||||
if issues.isEmpty {
|
||||
logger.notice("No linting issues found".as(.success))
|
||||
logger.notice("No linting issues found", metadata: .success)
|
||||
} else {
|
||||
try issues.printAndThrowIfNeeded()
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class SetupLoader: SetupLoading {
|
|||
.printAndThrowIfNeeded()
|
||||
try setup.forEach { command in
|
||||
if try !command.isMet(projectPath: path) {
|
||||
logger.info("Configuring \(command.name)".as(.subsection))
|
||||
logger.info("Configuring \(command.name, .command)", metadata: .subsection)
|
||||
try command.meet(projectPath: path)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,13 @@ public struct UnhandledError: FatalError {
|
|||
public let type: ErrorType = .bug
|
||||
|
||||
/// Error description.
|
||||
public var description: String { "UnhandledError - \(error.localizedDescription)\n\(error)" }
|
||||
public var description: String {
|
||||
"""
|
||||
We received an error that we couldn't handle:
|
||||
- Localized description: \(error.localizedDescription)
|
||||
- Error: \(error)"
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
/// Fatal error protocol.
|
||||
|
|
|
@ -1,32 +1,39 @@
|
|||
public enum ConsolePrettyToken: String {
|
||||
|
||||
case highlight
|
||||
case success
|
||||
case section
|
||||
case subsection
|
||||
case command
|
||||
case keystroke
|
||||
|
||||
var tokens: Set<ConsoleToken> {
|
||||
switch self {
|
||||
case .highlight:
|
||||
return [ .bold ]
|
||||
case .success:
|
||||
return [ .green, .bold ]
|
||||
case .section:
|
||||
return [ .lightCyan, .bold ]
|
||||
case .subsection:
|
||||
return [ .lightCyan ]
|
||||
case .command:
|
||||
return [ .white, .bold ]
|
||||
case .keystroke:
|
||||
return [ .cyan ]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension String {
|
||||
extension Logger.Metadata {
|
||||
|
||||
public func `as`(_ token: ConsolePrettyToken...) -> Logger.Message {
|
||||
return Logger.Message("\(self, token)")
|
||||
public static let colored: String = "is"
|
||||
|
||||
public static let successKey: String = "success"
|
||||
public static var success: Logger.Metadata {
|
||||
return [ colored: .string(successKey) ]
|
||||
}
|
||||
|
||||
public static let sectionKey: String = "section"
|
||||
public static var section: Logger.Metadata {
|
||||
return [ colored: .string(sectionKey) ]
|
||||
}
|
||||
|
||||
public static let subsectionKey: String = "subsection"
|
||||
public static var subsection: Logger.Metadata {
|
||||
return [ colored: .string(subsectionKey) ]
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,19 +27,15 @@ public struct DetailedLogHandler: LogHandler {
|
|||
file: String, function: String, line: UInt
|
||||
) {
|
||||
|
||||
var log: String = "\(timestamp()) \(level.rawValue, .highlight) \(label)"
|
||||
var log: String = "\(timestamp()) \(level.rawValue) \(label)"
|
||||
|
||||
let mergedMetadata = metadata.map{ self.metadata.merging($0, uniquingKeysWith: { $1 }) } ?? self.metadata
|
||||
let mergedMetadata = metadata.map { self.metadata.merging($0, uniquingKeysWith: { $1 }) } ?? self.metadata
|
||||
|
||||
if mergedMetadata.isEmpty == false {
|
||||
log.append(mergedMetadata.pretty)
|
||||
}
|
||||
|
||||
if Environment.shared.shouldOutputBeColoured {
|
||||
log.append(message.colorize(for: level).description)
|
||||
} else {
|
||||
log.append(message.description)
|
||||
}
|
||||
|
||||
output(for: level).log(level: level, message: message, metadata: metadata, file: file, function: function, line: line)
|
||||
|
||||
|
|
|
@ -1,30 +1,58 @@
|
|||
@_exported import Logging
|
||||
import class Foundation.ProcessInfo
|
||||
|
||||
let logger = Logger(label: "io.tuist.support")
|
||||
|
||||
import class Foundation.ProcessInfo
|
||||
public struct LoggingConfig {
|
||||
|
||||
public enum LoggerType {
|
||||
case console, detailed, osLog
|
||||
}
|
||||
|
||||
public var loggerType: LoggerType
|
||||
public var verbose: Bool
|
||||
|
||||
}
|
||||
|
||||
extension LoggingConfig {
|
||||
public static var `default`: LoggingConfig {
|
||||
|
||||
let environment = ProcessInfo.processInfo.environment
|
||||
|
||||
let os_log = environment["TUIST_OS_LOG"] != nil
|
||||
let detailed = environment["TUIST_DETAILED_LOG"] != nil
|
||||
let verbose = environment["TUIST_VERBOSE"] != nil
|
||||
|
||||
if os_log {
|
||||
return .init(loggerType: .osLog, verbose: verbose)
|
||||
} else if detailed {
|
||||
return .init(loggerType: .detailed, verbose: verbose)
|
||||
} else {
|
||||
return .init(loggerType: .console, verbose: verbose)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public enum LogOutput {
|
||||
|
||||
static var environment = ProcessInfo.processInfo.environment
|
||||
|
||||
public static func bootstrap() {
|
||||
|
||||
let os_log = environment["TUIST_OS_LOG"] != nil
|
||||
let detailed = environment["TUIST_DETAILED_LOG"] != nil
|
||||
public static func bootstrap(config: LoggingConfig = .default) {
|
||||
|
||||
let handler: VerboseLogHandler.Type
|
||||
|
||||
if os_log {
|
||||
switch config.loggerType {
|
||||
case .osLog:
|
||||
handler = OSLogHandler.self
|
||||
} else if detailed {
|
||||
case .detailed:
|
||||
handler = DetailedLogHandler.self
|
||||
} else {
|
||||
case .console:
|
||||
handler = StandardLogHandler.self
|
||||
}
|
||||
|
||||
let verbose = environment["TUIST_VERBOSE"] != nil
|
||||
|
||||
if verbose {
|
||||
if config.verbose {
|
||||
LoggingSystem.bootstrap(handler.verbose)
|
||||
} else {
|
||||
LoggingSystem.bootstrap(handler.init)
|
|
@ -26,7 +26,18 @@ public struct StandardLogHandler: LogHandler {
|
|||
let log: Logger.Message
|
||||
|
||||
if Environment.shared.shouldOutputBeColoured {
|
||||
|
||||
switch metadata?[Logger.Metadata.colored] {
|
||||
case .string(Logger.Metadata.successKey)?:
|
||||
log = Logger.Message(stringLiteral: message.description.apply([ .green, .bold ]))
|
||||
case .string(Logger.Metadata.sectionKey)?:
|
||||
log = Logger.Message(stringLiteral: message.description.apply([ .cyan, .bold ]))
|
||||
case .string(Logger.Metadata.subsectionKey)?:
|
||||
log = Logger.Message(stringLiteral: message.description.apply([ .cyan ]))
|
||||
default:
|
||||
log = message.colorize(for: level)
|
||||
}
|
||||
|
||||
} else {
|
||||
log = message
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import Foundation
|
||||
import enum Basic.ProcessEnv
|
||||
import enum TuistSupport.LogOutput
|
||||
|
||||
if CommandLine.arguments.contains("--verbose") {
|
||||
try? ProcessEnv.setVar("TUIST_VERBOSE", value: "true")
|
||||
}
|
||||
|
||||
import enum TuistSupport.LogOutput
|
||||
LogOutput.bootstrap()
|
||||
|
||||
import TuistKit
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import Foundation
|
||||
import TuistEnvKit
|
||||
|
||||
import enum TuistSupport.LogOutput
|
||||
|
||||
LogOutput.bootstrap()
|
||||
|
|
Loading…
Reference in New Issue