Last active
March 23, 2017 21:35
-
-
Save vknabel/64c81bae35dd997d1fe1da9705f7afee to your computer and use it in GitHub Desktop.
Marathon Script handling paths. MIT License
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Where global scripts are located; Optional | |
export SPRINT_PATH='~/Marathon' | |
# Appended to each possible path | |
export SPRINT_SUBFOLDER_PATH='Scripts' | |
# Allows running 'sprint myScript' from anywhere | |
alias sprint='marathon run $SPRINT_PATH/Sprint' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://github.com/JohnSundell/Files.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Files | |
enum SprintError: Error { | |
case invalidEnvironmentFolder(FileSystem.Item.PathError) | |
case unknownError(Error) | |
case noScriptFound(String) | |
case noArgumentGiven | |
case scriptFailed(Int32) | |
} | |
extension FileSystem.Item { | |
var recursiveParents: [Folder] { | |
if let parent = self.parent { | |
return [parent] + parent.recursiveParents | |
} else { | |
return [] | |
} | |
} | |
} | |
extension Folder { | |
var includingImplicitSubfolder: [Folder] { | |
return [self, try? subfolder(atPath: CommandLine.implicitSubfolderPath)] | |
.flatMap { $0 } | |
} | |
} | |
extension CommandLine { | |
/// Only throws `SprintError` | |
static func environmentFolders() throws -> [Folder] { | |
if let sprintFolderPath = ProcessInfo.processInfo.environment["SPRINT_PATH"] { | |
do { | |
let folder = try Folder(path: sprintFolderPath) | |
return folder.recursiveParents | |
} catch let error as FileSystem.Item.PathError { | |
throw SprintError.invalidEnvironmentFolder(error) | |
} catch { | |
throw SprintError.unknownError(error) | |
} | |
} else { | |
return [] | |
} | |
} | |
static var implicitSubfolderPath: String { | |
return ProcessInfo.processInfo.environment["SPRINT_SUBFOLDER_PATH"] ?? "Scripts" | |
} | |
} | |
/// Should only throw `SprintError` | |
func searchFolders(fileSystem: FileSystem = FileSystem()) throws -> [Folder] { | |
let folders = try fileSystem.currentFolder.recursiveParents | |
+ CommandLine.environmentFolders() | |
return folders.flatMap { $0.includingImplicitSubfolder } | |
} | |
func script(atPath path: String) throws -> File { | |
let script = try searchFolders().lazy | |
.flatMap { try? $0.file(atPath: path) } | |
.first | |
if let script = script { | |
return script | |
} else { | |
throw SprintError.noScriptFound(path) | |
} | |
} | |
do { | |
guard CommandLine.arguments.count > 1 else { | |
throw SprintError.noArgumentGiven | |
} | |
let task = Process() | |
task.launchPath = "/usr/bin/env" | |
task.arguments = ["marathon", "run"] + Array(CommandLine.arguments.dropFirst()) | |
task.launch() | |
task.waitUntilExit() | |
if task.terminationStatus != 0 { | |
throw SprintError.scriptFailed(task.terminationStatus) | |
} | |
} catch let error as SprintError { | |
switch error { | |
case let .invalidEnvironmentFolder(error): | |
print("ππ₯ Invalid environment folder '\(error)'") | |
exit(1) | |
case let .noScriptFound(nameOrPath): | |
print("ππ₯ Could not find a Swift script at '\(nameOrPath).swift'") | |
print("ππ Please check that the path is valid and try again") | |
case .noArgumentGiven: | |
print("ππ₯ No script path given") | |
print("ππ Pass the path to a script file to run (for example 'marathon run script.swift')") | |
case let .unknownError(error): | |
print("ππ₯ An unknown error occurred: \(error)") | |
print("ππ This may be an error in Sprint itself") | |
exit(1) | |
case let .scriptFailed(status): | |
exit(status) | |
} | |
} catch { | |
fatalError( | |
"ππ₯ Unrecognized error: \(error)\n" | |
+ "ππ This may be an error in Sprint itself" | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment