Skip to content

Instantly share code, notes, and snippets.

@vknabel
Last active March 23, 2017 21:35
Show Gist options
  • Save vknabel/64c81bae35dd997d1fe1da9705f7afee to your computer and use it in GitHub Desktop.
Save vknabel/64c81bae35dd997d1fe1da9705f7afee to your computer and use it in GitHub Desktop.
Marathon Script handling paths. MIT License
# 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'
https://github.com/JohnSundell/Files.git
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