Last active
December 29, 2018 05:43
-
-
Save brookinc/02c0694009b736526848bd93803c1190 to your computer and use it in GitHub Desktop.
A simple script to demonstrate some basics of Swift scripting.
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
#!/usr/bin/swift | |
// shell.swift | |
// A simple script to demonstrate some basics of Swift scripting. | |
import Foundation | |
// Docs: https://developer.apple.com/documentation/foundation | |
// ...and: https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Status.md | |
extension CommandLine { | |
// credit: https://stackoverflow.com/a/50035059/5673556 | |
static func run(_ command: String) -> String { | |
let task = Process() | |
task.launchPath = "/bin/bash" | |
task.arguments = ["-c", command] | |
let pipe = Pipe() | |
task.standardOutput = pipe | |
task.launch() | |
let data = pipe.fileHandleForReading.readDataToEndOfFile() | |
let output = String(data: data, encoding: .utf8)! | |
return output | |
} | |
} | |
let scriptName = CommandLine.arguments[0] | |
let currentDir = FileManager.default.currentDirectoryPath | |
let suffix = (CommandLine.argc > 1) ? ":" : "" | |
print("\(scriptName) launched from \(currentDir) with \(CommandLine.argc - 1) additional arguments\(suffix)") | |
if !suffix.isEmpty { | |
dump(CommandLine.arguments) | |
} | |
var showHidden = false | |
var maxToPrint = 10 | |
var filenamePattern: NSRegularExpression? | |
var showPermissions = false | |
for argument in CommandLine.arguments { | |
if argument == "-a" { | |
showHidden = true | |
} else if argument == "-e" { | |
showPermissions = true | |
} else if argument.hasPrefix("-m=") { | |
let startIndex = argument.index(after: argument.index(of: "=")!) // TODO: Swift 4.2 renames String.index(of:) to String.firstIndex(of:) | |
if let maxCount = Int(argument.suffix(from: startIndex)) { | |
maxToPrint = maxCount | |
} | |
} else if argument.hasPrefix("-p=") { | |
let startIndex = argument.index(after: argument.index(of: "=")!) // TODO: Swift 4.2 renames String.index(of:) to String.firstIndex(of:) | |
// Note: we don't support whitespace here yet (even escaped), or quoted patterns (ie. any quotes will be included) | |
let pattern = String(argument.suffix(from: startIndex)) | |
filenamePattern = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) | |
} | |
} | |
var numPrinted = 0 | |
func printFiles(path: URL) { | |
guard showHidden || !path.lastPathComponent.hasPrefix(".") else { | |
return | |
} | |
guard maxToPrint <= 0 || numPrinted < maxToPrint else { | |
return | |
} | |
var doPrint = true | |
if let regex = filenamePattern { | |
let filename = path.lastPathComponent | |
let filenameNS = NSString(string: path.lastPathComponent) | |
if regex.firstMatch(in: String(filename), range: NSRange(location: 0, length: filenameNS.length)) == nil { | |
// we still want to recurse on non-matching directories, so wipe the print flag here instead of returning | |
doPrint = false | |
} | |
} | |
if doPrint { | |
var output = path.path | |
if showPermissions { | |
let shellOutput = CommandLine.run("ls -lda \(path.path)") | |
let columns = shellOutput.split(separator: " ") | |
if columns.count > 0 { | |
output += " -> \(columns[0])" | |
} | |
} | |
print(output) | |
numPrinted += 1 | |
if numPrinted == maxToPrint { | |
print("Maximum output of \(maxToPrint) reached -- use `-m=NUMBER` to set a higher maximum, or `-m=0` for no maximum.") | |
} | |
} | |
if path.hasDirectoryPath { | |
var contents = try! FileManager.default.contentsOfDirectory(at: path, includingPropertiesForKeys: nil) | |
contents.sort { | |
return $0.lastPathComponent.lowercased() <= $1.lastPathComponent.lowercased() | |
} | |
for item in contents { | |
printFiles(path: item) | |
} | |
} | |
} | |
let currentDirectory = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) | |
printFiles(path: currentDirectory) |
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
# force linefeed (Unix-style) line endings for all .swift files, to prevent SwiftLint | |
# vertical_whitespace warnings (and line number mismatches) on Windows host machines | |
*.swift eol=lf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment