jstart
6/18/2015 - 10:19 PM

pggrep.swift

//
//  main.swift
//  pggrep
//
//  Created by Erica Sadun on 6/17/15.
//  Copyright © 2015 Erica Sadun. All rights reserved.
//

import Foundation

// mdfind 'kMDItemDisplayName == *.playground'
func PlaygroundList() -> [String] {
    let task = NSTask()
    task.launchPath = "/usr/bin/mdfind"
    task.arguments = ["kMDItemDisplayName == *.playground"]
    
    let pipe = NSPipe()
    task.standardOutput = pipe
    task.launch()
    task.waitUntilExit()
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    
    guard var s = NSString(data: data, encoding: NSUTF8StringEncoding) else {return []}
    s = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    return s.componentsSeparatedByString("\n")
}

func SwiftList() -> [String] {
    let task = NSTask()
    task.launchPath = "/usr/bin/mdfind"
    task.arguments = ["kMDItemDisplayName == *.swift"]
    
    let pipe = NSPipe()
    task.standardOutput = pipe
    task.launch()
    task.waitUntilExit()
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    
    guard var s = NSString(data: data, encoding: NSUTF8StringEncoding) else {return []}
    s = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    return s.componentsSeparatedByString("\n")
}

func PerformQuery(query : String, path: String) -> NSString {
    let task = NSTask()
    task.launchPath = "/usr/bin/grep"
    task.arguments = ["-R", query, path]
    
    let pipe = NSPipe()
    task.standardOutput = pipe
    task.launch()
    task.waitUntilExit()
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    guard var s = NSString(data: data, encoding: NSUTF8StringEncoding) else {return ""}
    s = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    return s
}

func grep(query: String) {
    
    print("Searching for \(query)")

    // Iterate through each playground
    let pgPaths = PlaygroundList()
    for path in pgPaths {

        // Fetch results
        let s = PerformQuery(query, path: path)
        if s.length == 0 {continue}
        
        // Defer printing playground info until a match is found
        var isFirst = true
        
        // Decompose the grep results into lines
        let array = s.componentsSeparatedByString("\n")
        for line in array {
            
            // Ignore any "Binary" files
            if line.hasPrefix("Binary") {continue}
            
            // Split the rest into fileName:match
            let splits = split(line.characters, maxSplit: 1, allowEmptySlices: false, isSeparator: {$0 == ":"}).map{String($0)}
            let fname = splits[0].lastPathComponent
            if !fname.hasSuffix("swift") {continue}
            if splits.count < 2 {continue}
            
            // If this is a first match, show the playground info
            if isFirst {
                let playgroundName = path.lastPathComponent.stringByDeletingPathExtension
                print(String(count:playgroundName.characters.count, repeatedValue:Character("-")))
                print(playgroundName)
                print(String(count:playgroundName.characters.count, repeatedValue:Character("-")))
                print("\(path.stringByDeletingLastPathComponent)")
                isFirst = false
            }
            
            // Print the file name and the match
            let rest = splits[1]
            print("    \(fname):\n      \(rest)")
        }
        
        // Leave spaces between playground results
        if !isFirst {print("")}
    }
}

var args = Array(dropFirst(Process.arguments))
if args.count == 0 {
    print("Must suply query")
    exit(-1)
}
grep(" ".join(args))