From a88cfa23b6bfebb53e514f4b65b0562cd76115fd Mon Sep 17 00:00:00 2001 From: Balazs Toth Date: Mon, 29 Jun 2020 21:16:12 +0200 Subject: [PATCH] Replace SwiftCLI Task with Bash command --- Package.resolved | 9 --- Package.swift | 5 -- Sources/Badgy/Commands/Bash.swift | 46 ++++++++++++++ Sources/Badgy/Helpers/Factory+Resizer.swift | 13 ++-- Sources/Badgy/Helpers/Factory+Small.swift | 15 +++-- Sources/Badgy/Helpers/Factory.swift | 67 ++++++++++----------- Sources/Badgy/Helpers/IconSet.swift | 16 +++-- Sources/Badgy/Helpers/RuntimeError.swift | 13 ++++ Sources/Badgy/IconSetDelegate.swift | 7 +-- Sources/Badgy/Loggers/VerboseLogger.swift | 3 +- 10 files changed, 115 insertions(+), 79 deletions(-) create mode 100644 Sources/Badgy/Commands/Bash.swift create mode 100644 Sources/Badgy/Helpers/RuntimeError.swift diff --git a/Package.resolved b/Package.resolved index ae84154..7651309 100644 --- a/Package.resolved +++ b/Package.resolved @@ -27,15 +27,6 @@ "revision": "3d79b2b5a2e5af52c14e462044702ea7728f5770", "version": "0.1.0" } - }, - { - "package": "SwiftCLI", - "repositoryURL": "https://github.com/jakeheis/SwiftCLI", - "state": { - "branch": null, - "revision": "c72c4564f8c0a24700a59824880536aca45a4cae", - "version": "6.0.1" - } } ] }, diff --git a/Package.swift b/Package.swift index 27fdc61..dca10fd 100644 --- a/Package.swift +++ b/Package.swift @@ -9,10 +9,6 @@ let package = Package( .executable(name: "badgy", targets: ["Badgy"]) ], dependencies: [ - .package( - url: "https://github.com/jakeheis/SwiftCLI", - from: "6.0.0" - ), .package( url: "https://github.com/kylef/PathKit", from: "1.0.0" @@ -28,7 +24,6 @@ let package = Package( .target( name: "Badgy", dependencies: [ - "SwiftCLI", "PathKit", .product(name: "ArgumentParser", package: "swift-argument-parser") ]), diff --git a/Sources/Badgy/Commands/Bash.swift b/Sources/Badgy/Commands/Bash.swift new file mode 100644 index 0000000..53fb952 --- /dev/null +++ b/Sources/Badgy/Commands/Bash.swift @@ -0,0 +1,46 @@ +// +// Badgy +// + +import Foundation +import ArgumentParser + +struct Bash { + var command: String + var arguments: [String] + + init(_ command: String, _ arguments: String...) { + self.command = command + self.arguments = arguments + } + + @discardableResult + func run() throws -> String? { + guard var bashCommand = try execute(command: "/bin/bash", arguments: ["-l", "-c", "which \(command)"]) else { + throw ValidationError("\(command) not found") + } + bashCommand = bashCommand.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines) + return try execute(command: bashCommand, arguments: arguments) + } + + // MARK: - Private + + private func execute(command: String, arguments: [String] = []) throws -> String? { + let process = Process() + let pipe = Pipe() + process.arguments = arguments + process.standardOutput = pipe + + if #available(OSX 10.13, *) { + process.executableURL = URL(fileURLWithPath: command) + try process.run() + } else { + process.launchPath = command + process.launch() + } + + let data = pipe.fileHandleForReading.readDataToEndOfFile() + let output = String(data: data, encoding: .utf8) + return output + } +} diff --git a/Sources/Badgy/Helpers/Factory+Resizer.swift b/Sources/Badgy/Helpers/Factory+Resizer.swift index 9ff3531..91bf077 100644 --- a/Sources/Badgy/Helpers/Factory+Resizer.swift +++ b/Sources/Badgy/Helpers/Factory+Resizer.swift @@ -5,7 +5,6 @@ // import Foundation -import SwiftCLI import PathKit struct ImageSize: Codable { @@ -25,11 +24,11 @@ extension Factory { let size = "\($0)x\($0)" Logger.shared.logInfo("Resizing to: ", item: size, color: .purple) do { - try Task.run( + try Bash( "convert", filename.absolute().description, "-resize", size, "\(bareFilename)_\($0).png" - ) + ).run() } catch { Logger.shared.logError("❌ ", item: "Failed to resize icon to \(size)", color: .red) } @@ -41,11 +40,11 @@ extension Factory { .forEach { (info) in Logger.shared.logInfo("Replacing: ", item: info.image, color: .purple) do { - try Task.run( + try Bash( "convert", newBadgeFile.absolute().description, "-resize", info.size.description(), info.image.absolute().description - ) + ).run() } catch { Logger.shared.logError("❌ ", item: "Failed to replace \(info.image)") @@ -58,11 +57,11 @@ extension Factory { .forEach { (info) in Logger.shared.logInfo("Replacing: ", item: info.image, color: .purple) do { - try Task.run( + try Bash( "convert", newBadgeFile.absolute().description, "-resize", info.size.description(), info.image.absolute().description - ) + ).run() } catch { Logger.shared.logError("❌ ", item: "Failed to replace \(info.image)") diff --git a/Sources/Badgy/Helpers/Factory+Small.swift b/Sources/Badgy/Helpers/Factory+Small.swift index 50fe7bf..ad27a52 100644 --- a/Sources/Badgy/Helpers/Factory+Small.swift +++ b/Sources/Badgy/Helpers/Factory+Small.swift @@ -5,7 +5,6 @@ // import Foundation -import SwiftCLI import PathKit extension Factory { @@ -20,10 +19,10 @@ extension Factory { do { let folderBase = folder.absolute().description if !folder.isDirectory { - try Task.run("mkdir", folderBase) + try Bash("mkdir", folderBase).run() } - try Task.run( + try Bash( "convert", "-size", "260x", "-background", color, "-gravity", "Center", @@ -32,9 +31,9 @@ extension Factory { "-fill", color, "caption:'-'", "\(folderBase)/top.png" - ) + ).run() - try Task.run( + try Bash( "convert", "-size", "260x", "-background", color, "-gravity", "Center", @@ -43,12 +42,12 @@ extension Factory { "-fill", "\(tintColor)", "caption:\(label)", "\(folderBase)/bottom.png" - ) + ).run() - try Task.run( + try Bash( "convert", "\(folderBase)/top.png", "\(folderBase)/bottom.png", "-append", "\(folderBase)/badge.png" - ) + ).run() return "\(folderBase)/badge.png" } catch { diff --git a/Sources/Badgy/Helpers/Factory.swift b/Sources/Badgy/Helpers/Factory.swift index 44a496e..fd702be 100644 --- a/Sources/Badgy/Helpers/Factory.swift +++ b/Sources/Badgy/Helpers/Factory.swift @@ -4,7 +4,6 @@ // Created by Arthur Alves on 30/05/2020. // -import SwiftCLI import AppKit import PathKit @@ -25,22 +24,24 @@ struct Factory { let folderBase = folder.absolute().description if !folder.isDirectory { - try Task.run("mkdir", folderBase) + try Bash("mkdir", folderBase).run() } - try Task.run( - "convert", "-size", "1520x", + try Bash( + "convert", + "-size", "1520x", "-background", color, "-gravity", "Center", - "-weight","700", + "-weight", "700", "-pointsize", "50", "-fill", color, "caption:'-'", "\(folderBase)/top.png" - ) + ).run() - try Task.run( - "convert", "-size", "1520x", + try Bash( + "convert", + "-size", "1520x", "-background", color, "-gravity", "Center", "-weight","700", @@ -48,20 +49,18 @@ struct Factory { "-fill", "\(tintColor)", "caption:\(label)", "\(folderBase)/bottom.png" - ) + ).run() - try Task.run( - "convert", "\(folderBase)/top.png", "\(folderBase)/bottom.png", - "-append", "\(folderBase)/badge.png" - ) + try Bash("convert", "\(folderBase)/top.png", "\(folderBase)/bottom.png", + "-append", "\(folderBase)/badge.png" + ).run() if let angle = angle { - try Task.run( - "convert", "\(folderBase)/badge.png", - "-background", "transparent", - "-rotate", "\(angle)", - "\(folderBase)/badge.png" - ) + try Bash("convert", "\(folderBase)/badge.png", + "-background", "transparent", + "-rotate", "\(angle)", + "\(folderBase)/badge.png" + ).run() } return "\(folderBase)/badge.png" @@ -80,18 +79,16 @@ struct Factory { let folderBase = folder.absolute().description let finalFilename = "\(folderBase)/\(label).png" - try Task.run( - "convert", baseIcon, - "-resize", "1024x", - finalFilename - ) + try Bash("convert", baseIcon, + "-resize", "1024x", + finalFilename + ).run() - try Task.run( - "convert", "-composite", - "-gravity", "\(position.cardinal)", - finalFilename, "\(folderBase)/badge.png", - finalFilename - ) + try Bash("convert", "-composite", + "-gravity", "\(position.cardinal)", + finalFilename, "\(folderBase)/badge.png", + finalFilename + ).run() return finalFilename } @@ -100,12 +97,12 @@ struct Factory { do { let folderBase = folder.absolute().description - try Task.run("rm", "-rf", - "\(folderBase)/top.png", - "\(folderBase)/bottom.png", - "\(folderBase)/badge.png") + try Bash("rm", "-rf", + "\(folderBase)/top.png", + "\(folderBase)/bottom.png", + "\(folderBase)/badge.png").run() } catch { - throw CLI.Error(message: "Failed to clean up temporary files") + throw RuntimeError("Failed to clean up temporary files") } } } diff --git a/Sources/Badgy/Helpers/IconSet.swift b/Sources/Badgy/Helpers/IconSet.swift index f48da9d..eece233 100644 --- a/Sources/Badgy/Helpers/IconSet.swift +++ b/Sources/Badgy/Helpers/IconSet.swift @@ -4,7 +4,6 @@ import Foundation import PathKit -import SwiftCLI struct IconSet { typealias ImageInfo = (image: Path, size: ImageSize) @@ -47,15 +46,14 @@ private extension ImageSize { } do { - let result = try Task.capture( - "identify", arguments: [ - "-format", "{\"width\":%[fx:w],\"height\":%[fx:h]}", - imagePath.absolute().description - ] - ) + let result = try Bash( + "identify", + "-format", "{\"width\":%[fx:w],\"height\":%[fx:h]}", + imagePath.absolute().description + ).run() - guard let data = result.stdout.data(using: .utf8) else { - throw CLI.Error(message: "Failed to get image size") + guard let data = result?.data(using: .utf8) else { + throw RuntimeError("Failed to get image size") } return try JSONDecoder().decode(ImageSize.self, from: data) diff --git a/Sources/Badgy/Helpers/RuntimeError.swift b/Sources/Badgy/Helpers/RuntimeError.swift new file mode 100644 index 0000000..d8e3f49 --- /dev/null +++ b/Sources/Badgy/Helpers/RuntimeError.swift @@ -0,0 +1,13 @@ +// +// Badgy +// + +import Foundation + +struct RuntimeError: Error, CustomStringConvertible { + var description: String + + init(_ description: String) { + self.description = description + } +} diff --git a/Sources/Badgy/IconSetDelegate.swift b/Sources/Badgy/IconSetDelegate.swift index 529b652..db08fe4 100644 --- a/Sources/Badgy/IconSetDelegate.swift +++ b/Sources/Badgy/IconSetDelegate.swift @@ -6,7 +6,6 @@ import Foundation import PathKit -import SwiftCLI typealias ImageInfo = (image: Path, size: ImageSize) typealias IconSetImages = (largest: ImageInfo, remaining: [ImageInfo]) @@ -60,9 +59,9 @@ extension IconSetDelegate { private func imageSize(from imagePath: Path) -> ImageSize? { do { - let result = try Task.capture("identify", arguments: ["-format", "{\"width\":%[fx:w],\"height\":%[fx:h]}", imagePath.absolute().description]) - - guard let data = result.stdout.data(using: .utf8) else { return nil } + let result = try Bash("identify", "-format", "{\"width\":%[fx:w],\"height\":%[fx:h]}", imagePath.absolute().description).run() + + guard let data = result?.data(using: .utf8) else { return nil } let jsonDecoder = JSONDecoder() let imageSize: ImageSize = try jsonDecoder.decode(ImageSize.self, from: data) return imageSize diff --git a/Sources/Badgy/Loggers/VerboseLogger.swift b/Sources/Badgy/Loggers/VerboseLogger.swift index b07f882..a838400 100644 --- a/Sources/Badgy/Loggers/VerboseLogger.swift +++ b/Sources/Badgy/Loggers/VerboseLogger.swift @@ -4,7 +4,6 @@ // Created by Arthur Alves on 05/05/2020. // -import SwiftCLI import Foundation public enum ShellColor: String { @@ -58,7 +57,7 @@ extension VerboseLogger { "\(color.rawValue)\(item)\(ShellColor.neutral.rawValue)" ] arguments.forEach { command.append($0) } - try? Task.run("printf", command+"\n") + _ = try? Bash("printf", command+"\n").run() } public func logBack(_ prefix: Any = "", item: Any, indentationLevel: Int = 0) -> String {