From 6be754d45d0c9015eede6d41692a89eaefe84a39 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Sun, 5 Mar 2023 21:11:56 -0500 Subject: [PATCH] wip --- dots/.gitignore | 9 -- dots/Makefile | 18 ---- dots/Package.swift | 75 --------------- dots/README.md | 3 - dots/Sources/CliMiddleware/Middleware.swift | 90 ------------------ .../CliMiddlewareLive/Internals/Brew.swift | 95 ------------------- .../CliMiddlewareLive/Internals/Zsh.swift | 87 ----------------- dots/Sources/CliMiddlewareLive/LiveKey.swift | 19 ---- dots/Sources/FileClient/Client.swift | 70 -------------- dots/Sources/FileClient/LiveKey.swift | 78 --------------- dots/Sources/LoggingDependency/Live.swift | 32 ------- dots/Sources/ShellClient/Client.swift | 37 -------- dots/Sources/ShellClient/LiveKey.swift | 59 ------------ dots/Sources/dots/CliContext.swift | 24 ----- dots/Sources/dots/Commands/Brew.swift | 44 --------- dots/Sources/dots/Commands/Zsh.swift | 57 ----------- dots/Sources/dots/GlobalOptions.swift | 24 ----- dots/Sources/dots/Version.swift | 2 - dots/Sources/dots/dots.swift | 13 --- dots/Tests/dotsTests/dotsTests.swift | 8 -- dots/scripts/build.swift | 81 ---------------- macOS/.config/macOS/AppStore.Brewfile | 4 +- 22 files changed, 2 insertions(+), 927 deletions(-) delete mode 100644 dots/.gitignore delete mode 100644 dots/Makefile delete mode 100644 dots/Package.swift delete mode 100644 dots/README.md delete mode 100644 dots/Sources/CliMiddleware/Middleware.swift delete mode 100644 dots/Sources/CliMiddlewareLive/Internals/Brew.swift delete mode 100644 dots/Sources/CliMiddlewareLive/Internals/Zsh.swift delete mode 100644 dots/Sources/CliMiddlewareLive/LiveKey.swift delete mode 100644 dots/Sources/FileClient/Client.swift delete mode 100644 dots/Sources/FileClient/LiveKey.swift delete mode 100644 dots/Sources/LoggingDependency/Live.swift delete mode 100644 dots/Sources/ShellClient/Client.swift delete mode 100644 dots/Sources/ShellClient/LiveKey.swift delete mode 100644 dots/Sources/dots/CliContext.swift delete mode 100644 dots/Sources/dots/Commands/Brew.swift delete mode 100644 dots/Sources/dots/Commands/Zsh.swift delete mode 100644 dots/Sources/dots/GlobalOptions.swift delete mode 100644 dots/Sources/dots/Version.swift delete mode 100644 dots/Sources/dots/dots.swift delete mode 100644 dots/Tests/dotsTests/dotsTests.swift delete mode 100755 dots/scripts/build.swift diff --git a/dots/.gitignore b/dots/.gitignore deleted file mode 100644 index 3b29812..0000000 --- a/dots/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj -xcuserdata/ -DerivedData/ -.swiftpm/config/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/dots/Makefile b/dots/Makefile deleted file mode 100644 index 0145afe..0000000 --- a/dots/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -PREFIX ?= $(HOME)/.local -BINDIR = $(PREFIX)/bin -COMPLETIONDIR = $(PREFIX)/completions -LIBDIR = $(PREFIX)/lib - -build: - swiftc ./scripts/build.swift - ./build - rm ./build - -install: build - install -d "$(BINDIR)" "$(LIBDIR)" - install ./.build/release/dots "$(BINDIR)" - -uninstall: - rm "$(BINDIR)/dots" - rm "$(COMPLETIONDIR)/_dots" - diff --git a/dots/Package.swift b/dots/Package.swift deleted file mode 100644 index 38ce302..0000000 --- a/dots/Package.swift +++ /dev/null @@ -1,75 +0,0 @@ -// swift-tools-version: 5.7 - - -import PackageDescription - -let package = Package( - name: "dots", - platforms: [ - .macOS(.v12) - ], - products: [ - .executable(name: "dots", targets: ["dots"]), - .library(name: "CliMiddleware", targets: ["CliMiddleware"]), - .library(name: "CliMiddlewareLive", targets: ["CliMiddlewareLive"]), - .library(name: "FileClient", targets: ["FileClient"]), - .library(name: "LoggingDependency", targets: ["LoggingDependency"]), - .library(name: "ShellClient", targets: ["ShellClient"]), - ], - dependencies: [ - .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), - .package(url: "https://github.com/pointfreeco/swift-dependencies.git", from: "0.1.4"), - .package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"), - .package(url: "https://github.com/adorkable/swift-log-format-and-pipe.git", from: "0.1.0"), - ], - targets: [ - .target( - name: "CliMiddleware", - dependencies: [ - .product(name: "Dependencies", package: "swift-dependencies"), - ] - ), - .target( - name: "CliMiddlewareLive", - dependencies: [ - "CliMiddleware", - "FileClient", - "LoggingDependency", - "ShellClient" - ] - ), - .target( - name: "FileClient", - dependencies: [ - .product(name: "Dependencies", package: "swift-dependencies"), - ] - ), - .target( - name: "LoggingDependency", - dependencies: [ - .product(name: "Dependencies", package: "swift-dependencies"), - .product(name: "Logging", package: "swift-log"), - .product(name: "LoggingFormatAndPipe", package: "swift-log-format-and-pipe"), - ] - ), - .executableTarget( - name: "dots", - dependencies: [ - "CliMiddlewareLive", - .product(name: "ArgumentParser", package: "swift-argument-parser"), - .product(name: "Dependencies", package: "swift-dependencies"), - ] - ), - .testTarget( - name: "dotsTests", - dependencies: ["dots"] - ), - .target( - name: "ShellClient", - dependencies: [ - "LoggingDependency", - .product(name: "Dependencies", package: "swift-dependencies") - ] - ), - ] -) diff --git a/dots/README.md b/dots/README.md deleted file mode 100644 index 7b6d177..0000000 --- a/dots/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# dots - -A description of this package. diff --git a/dots/Sources/CliMiddleware/Middleware.swift b/dots/Sources/CliMiddleware/Middleware.swift deleted file mode 100644 index 558c070..0000000 --- a/dots/Sources/CliMiddleware/Middleware.swift +++ /dev/null @@ -1,90 +0,0 @@ -import Dependencies -import Foundation -import XCTestDynamicOverlay - -/// Implements the logic for the `dots` command line tool. -/// -/// Each command and it's sub-commands are implemented in the ``CliMiddlewareLive`` module. While this -/// represents the interface. -/// -public struct CliMiddleware { - - public var brew: (BrewContext) async throws -> Void - public var zsh: (ZshContext) async throws -> Void - - public init( - brew: @escaping (BrewContext) async throws -> Void, - zsh: @escaping (ZshContext) async throws -> Void - ) { - self.brew = brew - self.zsh = zsh - } - - public struct GlobalContext { - public let dryRun: Bool - - public init(dryRun: Bool) { - self.dryRun = dryRun - } - } - - public struct BrewContext { - public let routes: [Route] - - public init( - routes: [Route] - ) { - self.routes = routes - } - - public enum Route: String, CaseIterable { - case all - case appStore - case brews - case casks - } - } - - public struct ZshContext { - - public let context: Context - - public init( - context: Context - ) { - self.context = context - } - - public enum Context { - case install - case uninstall - } - } -} - -extension CliMiddleware.GlobalContext: TestDependencyKey { - public static let testValue: CliMiddleware.GlobalContext = .init(dryRun: true) -} - -extension CliMiddleware: TestDependencyKey { - - public static let noop = Self.init( - brew: unimplemented("\(Self.self).brew"), - zsh: unimplemented("\(Self.self).zsh") - ) - - public static let testValue = CliMiddleware.noop -} - -extension DependencyValues { - - public var cliMiddleware: CliMiddleware { - get { self[CliMiddleware.self] } - set { self[CliMiddleware.self] = newValue } - } - - public var globals: CliMiddleware.GlobalContext { - get { self[CliMiddleware.GlobalContext.self] } - set { self[CliMiddleware.GlobalContext.self] = newValue } - } -} diff --git a/dots/Sources/CliMiddlewareLive/Internals/Brew.swift b/dots/Sources/CliMiddlewareLive/Internals/Brew.swift deleted file mode 100644 index 2276464..0000000 --- a/dots/Sources/CliMiddlewareLive/Internals/Brew.swift +++ /dev/null @@ -1,95 +0,0 @@ -import Dependencies -import CliMiddleware -import FileClient -import Foundation -import LoggingDependency -import ShellClient - -struct Brew { - @Dependency(\.fileClient) var fileClient - @Dependency(\.globals.dryRun) var dryRun - @Dependency(\.logger) var logger - @Dependency(\.shellClient) var shellClient - - let context: CliMiddleware.BrewContext - - func run() async throws { - logger.info("Installing homebrew dependencies.") - for brewfile in try context.routes.brewfiles() { - logger.info("Installing dependencies from brewfile: \(brewfile.absoluteString)") - if !dryRun { - try shellClient.install(brewfile: brewfile) - logger.debug("Done installing dependencies from brewfile: \(brewfile.absoluteString)") - } - } - logger.info("Done installing homebrew dependencies.") - } -} - -extension ShellClient { - - func install(brewfile: URL) throws { - try foregroundShell( - "/opt/homebrew/bin/brew", - "bundle", - "--no-lock", - "--cleanup", - "--debug", - "--file", - brewfile.absoluteString - ) - } -} - -fileprivate extension FileClient { - var brewFileDirectory: URL { - dotfilesDirectory() - .appendingPathComponent("macOS") - .appendingPathComponent(".config") - .appendingPathComponent("macOS") - } -} - -fileprivate extension CliMiddleware.BrewContext.Route { - - static func allBrews() throws -> [URL] { - let brews: [Self] = [.appStore, .brews, .casks] - return try brews.map { try $0.brewfile() } - } - - func brewfile() throws -> URL { - @Dependency(\.fileClient) var fileClient - switch self { - case .all: - // should never happen. - throw BrewfileError() - case .appStore: - return fileClient.brewFileDirectory.appendingPathComponent("AppStore.Brewfile") - case .brews: - return fileClient.brewFileDirectory.appendingPathComponent("Brewfile") - case .casks: - return fileClient.brewFileDirectory.appendingPathComponent("Casks.Brewfile") - } - } -} - -fileprivate extension Array where Element == CliMiddleware.BrewContext.Route { - - func brewfiles() throws -> [URL] { - - if self.count == 1 && self.first == .all { - return try CliMiddleware.BrewContext.Route.allBrews() - } - - var urls = [URL]() - for route in self { - if route != .all { - let url = try route.brewfile() - urls.append(url) - } - } - return urls - } -} - -struct BrewfileError: Error { } diff --git a/dots/Sources/CliMiddlewareLive/Internals/Zsh.swift b/dots/Sources/CliMiddlewareLive/Internals/Zsh.swift deleted file mode 100644 index d608e2b..0000000 --- a/dots/Sources/CliMiddlewareLive/Internals/Zsh.swift +++ /dev/null @@ -1,87 +0,0 @@ -import CliMiddleware -import Dependencies -import FileClient -import Foundation -import LoggingDependency - -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif - -struct Zsh { - @Dependency(\.globals.dryRun) var dryRun - @Dependency(\.fileClient) var fileClient - @Dependency(\.logger) var logger - - let context: CliMiddleware.ZshContext - - func install() async throws { - let configString = fileClient.zshConfigDestination.absoluteString - .replacingOccurrences(of: "file://", with: "") - - let destination = fileClient.zshEnvDestination - - let destinationString = destination.absoluteString - .replacingOccurrences(of: "file://", with: "") - - logger.info("Linking zsh configuration to: \(configString)") - logger.info("Linking .zshenv file to: \(destinationString)") - - if !dryRun { - try await linkZshConfig() - try await fileClient.createSymlink( - source: fileClient.zshEnvSource, - destination: destination - ) - } - logger.info("Done installing zsh configuration files.") - } - - func uninstall() async throws { - logger.info("Uninstalling zsh configuration from: \(fileClient.zshConfigDestination.absoluteString)") - if !dryRun { - logger.debug("Moving configuration to the trash.") - try await fileClient.moveToTrash(fileClient.zshConfigDestination) - logger.debug("Moving .zshenv to the trash.") - try await fileClient.moveToTrash(fileClient.zshEnvDestination) - } - logger.info("Done uninstalling zsh configuration, you will need to reload your shell.") - } - - func run() async throws { - switch context.context { - case .install: - try await self.install() - case .uninstall: - try await self.uninstall() - } - } - - func linkZshConfig() async throws { - try await fileClient.createDirectory(at: fileClient.configDirectory()) - try await fileClient.createSymlink( - source: fileClient.zshDirectory, - destination: fileClient.zshConfigDestination - ) - } -} - -fileprivate extension FileClient { - var zshDirectory: URL { - dotfilesDirectory() - .appendingPathComponent("zsh") - .appendingPathComponent("config") - } - - var zshConfigDestination: URL { - configDirectory().appendingPathComponent("zsh") - } - - var zshEnvDestination: URL { - homeDirectory().appendingPathComponent(".zshenv") - } - - var zshEnvSource: URL { - zshDirectory.appendingPathComponent(".zshenv") - } -} diff --git a/dots/Sources/CliMiddlewareLive/LiveKey.swift b/dots/Sources/CliMiddlewareLive/LiveKey.swift deleted file mode 100644 index 6f92d2b..0000000 --- a/dots/Sources/CliMiddlewareLive/LiveKey.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Dependencies -@_exported import CliMiddleware -@_exported import FileClient -@_exported import LoggingDependency -@_exported import ShellClient -import Foundation - -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif - -extension CliMiddleware: DependencyKey { - public static var liveValue: CliMiddleware { - .init( - brew: { try await Brew(context: $0).run() }, - zsh: { try await Zsh(context: $0).run() } - ) - } -} diff --git a/dots/Sources/FileClient/Client.swift b/dots/Sources/FileClient/Client.swift deleted file mode 100644 index b4fac39..0000000 --- a/dots/Sources/FileClient/Client.swift +++ /dev/null @@ -1,70 +0,0 @@ -import Dependencies -import Foundation -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif -import XCTestDynamicOverlay - -/// Represents interactions with the file system. -/// -public struct FileClient { - - public var configDirectory: () -> URL - public var createDirectory: (URL, Bool) async throws -> Void - public var createSymlink: (URL, URL) async throws -> Void - public var dotfilesDirectory: () -> URL - public var homeDirectory: () -> URL - public var exists: (URL) async throws -> Bool - public var readFile: (URL) async throws -> Data - public var moveToTrash: (URL) async throws -> Void - public var writeFile: (Data, URL) async throws -> Void - - public func createDirectory( - at url: URL, - withIntermediates: Bool = true - ) async throws { - let exists = try await self.exists(url) - if !exists { - try await createDirectory(url, withIntermediates) - } - } - - public func createSymlink( - source: URL, - destination: URL - ) async throws { - try await self.createSymlink(source, destination) - } - - public func read(file: URL) async throws -> Data { - try await self.readFile(file) - } - - public func write(data: Data, to file: URL) async throws { - try await writeFile(data, file) - } -} - -extension FileClient: TestDependencyKey { - public static let noop = Self.init( - configDirectory: unimplemented(placeholder: URL(string: "/")!), - createDirectory: unimplemented(), - createSymlink: unimplemented(), - dotfilesDirectory: unimplemented(placeholder: URL(string: "/")!), - homeDirectory: unimplemented(), - exists: unimplemented(placeholder: false), - readFile: unimplemented(placeholder: Data()), - moveToTrash: unimplemented(), - writeFile: unimplemented() - ) - - public static let testValue: FileClient = .noop - -} - -extension DependencyValues { - public var fileClient: FileClient { - get { self[FileClient.self] } - set { self[FileClient.self] = newValue } - } -} diff --git a/dots/Sources/FileClient/LiveKey.swift b/dots/Sources/FileClient/LiveKey.swift deleted file mode 100644 index 6e114a0..0000000 --- a/dots/Sources/FileClient/LiveKey.swift +++ /dev/null @@ -1,78 +0,0 @@ -import Dependencies -import Foundation -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif - -extension FileClient: DependencyKey { - - public static var liveValue: FileClient { - .live(environment: ProcessInfo.processInfo.environment) - } - - public static func live(environment: [String: String] = [:]) -> Self { - let environment = Environment(environment: environment) - return .init( - configDirectory: { - guard let xdgConfigHome = environment.xdgConfigHome, - let configUrl = URL(string: xdgConfigHome) - else { - return FileManager.default.homeDirectoryForCurrentUser - .appendingPathComponent(".config") - } - return configUrl - }, - createDirectory: { url, withIntermediates in - try FileManager.default.createDirectory( - at: url, - withIntermediateDirectories: withIntermediates - ) - }, - createSymlink: { source, destination in - try FileManager.default.createSymbolicLink( - at: source, - withDestinationURL: destination - ) - }, - dotfilesDirectory: { - guard let dotfiles = environment.dotfilesDirectory, - let dotfilesUrl = URL(string: dotfiles) - else { - return FileManager.default.homeDirectoryForCurrentUser - .appendingPathComponent(".dotfiles") - } - return dotfilesUrl - }, - homeDirectory: { - FileManager.default.homeDirectoryForCurrentUser - }, - exists: { path in - FileManager.default.fileExists(atPath: path.absoluteString) - }, - readFile: { path in - try Data(contentsOf: path) - }, - moveToTrash: { path in - try FileManager.default.trashItem(at: path, resultingItemURL: nil) - }, - writeFile: { data, path in - try data.write(to: path) - } - ) - } -} - -fileprivate struct Environment { - let xdgConfigHome: String? - let dotfilesDirectory: String? - - enum CodingKeys: String, CodingKey { - case xdgConfigHome = "XDG_CONFIG_HOME" - case dotfilesDirectory = "DOTFILES" - } - - init(environment: [String: String]) { - self.xdgConfigHome = environment[CodingKeys.xdgConfigHome.rawValue] - self.dotfilesDirectory = environment[CodingKeys.dotfilesDirectory.rawValue] - } -} diff --git a/dots/Sources/LoggingDependency/Live.swift b/dots/Sources/LoggingDependency/Live.swift deleted file mode 100644 index 0fefb7e..0000000 --- a/dots/Sources/LoggingDependency/Live.swift +++ /dev/null @@ -1,32 +0,0 @@ -import Dependencies -import Foundation -@_exported import Logging -import LoggingFormatAndPipe - -extension Logger: DependencyKey { - - fileprivate static func factory(label: String) -> Self { - Logger(label: "dots") { _ in - LoggingFormatAndPipe.Handler( - formatter: BasicFormatter([.message]), - pipe: LoggerTextOutputStreamPipe.standardOutput - ) - } - } - - public static var liveValue: Logger { - factory(label: "dots") - } - - public static var testValue: Logger { - factory(label: "dots-test") - } - -} - -extension DependencyValues { - public var logger: Logger { - get { self[Logger.self] } - set { self[Logger.self] = newValue } - } -} diff --git a/dots/Sources/ShellClient/Client.swift b/dots/Sources/ShellClient/Client.swift deleted file mode 100644 index 8595537..0000000 --- a/dots/Sources/ShellClient/Client.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Dependencies -import Foundation -import XCTestDynamicOverlay -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif - -public struct ShellClient { - public var foregroundShell: ([String]) throws -> Void - public var backgroundShell: ([String]) throws -> String - - public func foregroundShell(_ arguments: String...) throws { - try self.foregroundShell(arguments) - } - - @discardableResult - public func backgroundShell(_ arguments: String...) throws -> String { - try self.backgroundShell(arguments) - } -} - -extension ShellClient: TestDependencyKey { - - public static let noop = Self.init( - foregroundShell: unimplemented(), - backgroundShell: unimplemented(placeholder: "") - ) - - public static let testValue: ShellClient = .noop -} - -extension DependencyValues { - public var shellClient: ShellClient { - get { self[ShellClient.self] } - set { self[ShellClient.self] = newValue } - } -} diff --git a/dots/Sources/ShellClient/LiveKey.swift b/dots/Sources/ShellClient/LiveKey.swift deleted file mode 100644 index 542eafb..0000000 --- a/dots/Sources/ShellClient/LiveKey.swift +++ /dev/null @@ -1,59 +0,0 @@ -import Dependencies -import Foundation -import LoggingDependency -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif - -extension ShellClient: DependencyKey { - - public static var liveValue: ShellClient { - @Dependency(\.logger) var logger - - return .init( - foregroundShell: { arguments in - logger.debug("Running in foreground shell.") - logger.debug("$ \(arguments.joined(separator: " "))") - - let task = Process() - task.launchPath = "/usr/bin/env" - task.arguments = arguments - task.launch() - task.waitUntilExit() - - guard task.terminationStatus == 0 else { - throw ShellError(terminationStatus: task.terminationStatus) - } - }, - backgroundShell: { arguments in - logger.debug("Running background shell.") - logger.debug("$ \(arguments.joined(separator: " "))") - - let task = Process() - task.launchPath = "/usr/bin/env" - task.arguments = arguments - // 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 -} diff --git a/dots/Sources/dots/CliContext.swift b/dots/Sources/dots/CliContext.swift deleted file mode 100644 index 20ef8f4..0000000 --- a/dots/Sources/dots/CliContext.swift +++ /dev/null @@ -1,24 +0,0 @@ -import ArgumentParser -import Dependencies -import Foundation - -struct CliContext { - let globals: GlobalOptions - let _run: () async throws -> Void - - init(globals: GlobalOptions, run: @escaping () async throws -> Void) { - self.globals = globals - self._run = run - } - - func run() async throws { - try await withDependencies { - if globals.verbose { - $0.logger.logLevel = .debug - } - $0.globals = .live(globals) - } operation: { - try await _run() - } - } -} diff --git a/dots/Sources/dots/Commands/Brew.swift b/dots/Sources/dots/Commands/Brew.swift deleted file mode 100644 index 8aa7c94..0000000 --- a/dots/Sources/dots/Commands/Brew.swift +++ /dev/null @@ -1,44 +0,0 @@ -import ArgumentParser -import CliMiddleware -import Dependencies -import Foundation -import LoggingDependency - -extension Dots { - - struct Brew: AsyncParsableCommand { - static var configuration = CommandConfiguration( - abstract: "Manage homebrew dependency installation.", - subcommands: [ - Install.self - ], - defaultSubcommand: Install.self - ) - - struct Install: AsyncParsableCommand { - - static let configuration = CommandConfiguration( - abstract: "Install brew dependencies from the brewfiles." - ) - - @OptionGroup var globals: GlobalOptions - - @Flag(help: "The homebrew dependencies to install from their brewfiles.") - var routes: [CliMiddleware.BrewContext.Route] = [.all] - - func run() async throws { - try await CliContext(globals: globals) { - @Dependency(\.cliMiddleware.brew) var brew - @Dependency(\.logger) var logger: Logger - - logger.debug("Routes: \(routes)") - try await brew(.init(routes: routes)) - logger.info("Done.") - } - .run() - } - } - } -} - -extension CliMiddleware.BrewContext.Route: EnumerableFlag { } diff --git a/dots/Sources/dots/Commands/Zsh.swift b/dots/Sources/dots/Commands/Zsh.swift deleted file mode 100644 index b523904..0000000 --- a/dots/Sources/dots/Commands/Zsh.swift +++ /dev/null @@ -1,57 +0,0 @@ -import ArgumentParser -import CliMiddleware -import Dependencies -import Foundation -import LoggingDependency - -extension Dots { - struct Zsh: AsyncParsableCommand { - static let configuration = CommandConfiguration( - abstract: "Manage zsh configuration.", - subcommands: [ - Install.self, - Uninstall.self - ], - defaultSubcommand: Install.self - ) - - - struct Install: AsyncParsableCommand { - static let configuration = CommandConfiguration( - abstract: "Install zsh configuration files." - ) - - @OptionGroup var globals: GlobalOptions - - func run() async throws { - try await CliContext(globals: globals) { - @Dependency(\.cliMiddleware.zsh) var zsh - @Dependency(\.logger) var logger: Logger - - try await zsh(.init(context: .install)) - logger.info("Done.") - } - .run() - } - } - - struct Uninstall: AsyncParsableCommand { - static let configuration = CommandConfiguration( - abstract: "Uninstall zsh configuration files." - ) - - @OptionGroup var globals: GlobalOptions - - func run() async throws { - try await CliContext(globals: globals) { - @Dependency(\.cliMiddleware.zsh) var zsh - @Dependency(\.logger) var logger: Logger - - try await zsh(.init(context: .uninstall)) - logger.info("Done.") - } - .run() - } - } - } -} diff --git a/dots/Sources/dots/GlobalOptions.swift b/dots/Sources/dots/GlobalOptions.swift deleted file mode 100644 index e23985a..0000000 --- a/dots/Sources/dots/GlobalOptions.swift +++ /dev/null @@ -1,24 +0,0 @@ -import ArgumentParser -import CliMiddleware -import Dependencies -import Foundation - -struct GlobalOptions: ParsableArguments { - @Flag( - name: .long, - help: "Perform an action as a dry-run, not removing or installing anything." - ) - var dryRun: Bool = false - - @Flag( - name: .long, - help: "Increase logging output level." - ) - var verbose: Bool = false -} - -extension CliMiddleware.GlobalContext { - static func live(_ globalOptions: GlobalOptions) -> Self { - .init(dryRun: globalOptions.dryRun) - } -} diff --git a/dots/Sources/dots/Version.swift b/dots/Sources/dots/Version.swift deleted file mode 100644 index 815a5a6..0000000 --- a/dots/Sources/dots/Version.swift +++ /dev/null @@ -1,2 +0,0 @@ -// Do not change this value, it get's set by the build script -let VERSION: String? = nil diff --git a/dots/Sources/dots/dots.swift b/dots/Sources/dots/dots.swift deleted file mode 100644 index df1989d..0000000 --- a/dots/Sources/dots/dots.swift +++ /dev/null @@ -1,13 +0,0 @@ -import ArgumentParser - -@main -struct Dots: AsyncParsableCommand { - static var configuration = CommandConfiguration( - abstract: "Commands for installing / uninstalling dotfile configuration.", - version: VERSION ?? "0.0.0", - subcommands: [ - Brew.self, - Zsh.self - ] - ) -} diff --git a/dots/Tests/dotsTests/dotsTests.swift b/dots/Tests/dotsTests/dotsTests.swift deleted file mode 100644 index 1b26747..0000000 --- a/dots/Tests/dotsTests/dotsTests.swift +++ /dev/null @@ -1,8 +0,0 @@ -import XCTest -@testable import dots - -final class dotsTests: XCTestCase { - func testExample() throws { - XCTAssert(true) - } -} diff --git a/dots/scripts/build.swift b/dots/scripts/build.swift deleted file mode 100755 index 231e4af..0000000 --- a/dots/scripts/build.swift +++ /dev/null @@ -1,81 +0,0 @@ -#!/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 -} diff --git a/macOS/.config/macOS/AppStore.Brewfile b/macOS/.config/macOS/AppStore.Brewfile index e15bb32..088d8fa 100644 --- a/macOS/.config/macOS/AppStore.Brewfile +++ b/macOS/.config/macOS/AppStore.Brewfile @@ -1,2 +1,2 @@ -mas "pwSafe", id: "520993579" -mas "Home Assistant", id: "1099568401" +mas "pwSafe", id: 520993579 +mas "Home Assistant", id: 1099568401