Last active
May 15, 2016 05:15
-
-
Save loganwright/777d7c22ecce4009651f93d7afc23a30 to your computer and use it in GitHub Desktop.
A swift script to make dealing with new swift scripts a little easier :)
This file contains hidden or 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
#!/usr/bin/env swift | |
#if os(OSX) | |
import Darwin | |
#else | |
import Glibc | |
#endif | |
import Foundation | |
// MARK: Failure | |
@noreturn func fail(_ msg: String) { | |
print("Error: \(msg)") | |
exit(1) | |
} | |
func run(_ command: String, allowFailure: Bool = false) { | |
let result = system(command) | |
if allowFailure { return } | |
else if result != 0 { | |
fail("error code \(result)") | |
} | |
} | |
func passes(_ command: String) -> Bool { | |
return system(command) == 0 | |
} | |
func getInput() -> String { | |
return readLine(strippingNewline: true) ?? "" | |
} | |
func commandExists(_ command: String) -> Bool { | |
return system("hash \(command) 2>/dev/null") == 0 | |
} | |
// MARK: Command | |
protocol Command { | |
static var description: String { get } | |
static func execute(with args: [String], in directory: String) | |
} | |
extension Command { | |
static var description: String { | |
return "" | |
} | |
} | |
// MARK: Tree | |
var commandTree: [String : Command.Type] = [:] | |
// MARK: Help | |
struct Help: Command { | |
static func execute(with args: [String], in directory: String) { | |
var help = "Available Commands:\n\n" | |
help += commandTree | |
.map { key, val in "\t\(key): \(val.description)"} | |
.joined(separator: "\n") | |
help += "\n" | |
print(help) | |
} | |
} | |
commandTree["help"] = Help.self | |
// MARK: Custom Commands | |
struct New: Command { | |
static func execute(with args: [String], in directory: String) { | |
guard commandExists("wget") else { | |
fail("wget required to create new script. Recommended to install through Homebrew: http://brew.sh/") | |
} | |
guard args.count == 1, let name = args.first else { | |
fail("Unexpected arguments: \(args). Expected single argument as name of script") | |
} | |
let templateUrl = "https://gist.githubusercontent.com/LoganWright/899acec46512a966653206f5dcc27d2a/raw/042f592b24a27f317d7c773fb750525e0a56bb98/swift-script-template.swift" | |
run("wget \(templateUrl) -O \(name)") | |
print("Successfully created swift script \(name)") | |
print("Use the following to run your script") | |
print() | |
print("xcrun") | |
print("\txcrun swift ./\(name)") | |
print() | |
print("xcrun: toolchain") | |
print("\txcrun --toolchain swift swift ./\(name)") | |
print() | |
print("run directly") | |
print("\tRun only once") | |
print("\t\tchmod +x ./\(name)") | |
print("\tThen call directly after that") | |
print("\t\t./\(name)") | |
print() | |
print("run from bin") | |
print("\trun only once") | |
print("\t\tchmod +x ./\(name)") | |
print("\t\tmv ./\(name) /usr/local/bin/\(name)") | |
print("\tnow call directly") | |
print("\t\t\(name)") | |
print() | |
} | |
} | |
struct AddToBin: Command { | |
static func execute(with args: [String], in directory: String) { | |
guard args.count == 1, let file = args.first else { | |
fail("Unexpected arguments: \(args). Expected single argument as file of script to move") | |
} | |
guard passes("test -f \"\(file)\"") else { | |
fail("Unable to find file \(file)") | |
} | |
guard let extractedName = file.components(separatedBy: "/").last else { | |
fail("Unable to find file name") | |
} | |
print("Custom name? (press return to use \(extractedName))") | |
var name = "" | |
if let input = readLine(strippingNewline: true) where !input.isEmpty { | |
name = input | |
} else { | |
name = extractedName | |
} | |
run("chmod +x \(file)") | |
run("mv \(file) /usr/local/bin/\(name)") | |
} | |
} | |
// MARK: Tree | |
commandTree["new"] = New.self | |
commandTree["add-to-bin"] = AddToBin.self | |
// MARK: Execution | |
var iterator = Process.arguments.makeIterator() | |
guard let directory = iterator.next() else { | |
fail("no directory") | |
} | |
guard let commandKey = iterator.next() else { | |
fail("no command") | |
} | |
guard let command = commandTree[commandKey] else { | |
fail("command \(commandKey) doesn't exist") | |
} | |
let arguments = Array(iterator) | |
command.execute(with: arguments, in: directory) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Template: https://gist.github.com/LoganWright/899acec46512a966653206f5dcc27d2a