Skip to content

Instantly share code, notes, and snippets.

@MaddTheSane
Forked from listrophy/Glob.swift
Last active August 29, 2015 14:23
Show Gist options
  • Save MaddTheSane/92c045adbdfc5dd275cb to your computer and use it in GitHub Desktop.
Save MaddTheSane/92c045adbdfc5dd275cb to your computer and use it in GitHub Desktop.
//
// Glob.swift
//
// Created by Brad Grzesiak on 6/25/15.
// Copyright © 2015 Bendyworks Inc.
// Released under the Apache v2 License.
//
import Foundation
class Glob: CollectionType {
private var globFlags = GLOB_TILDE | GLOB_BRACE | GLOB_MARK
var paths = [String]()
var startIndex: Int {
return paths.startIndex
}
var endIndex: Int {
return paths.endIndex
}
subscript(i: Int) -> String {
return paths[i]
}
init(pattern: String) {
var gt = glob_t()
if executeGlob(pattern, gt: &gt) {
populateFiles(gt)
}
globfree(&gt)
}
private
func executeGlob(pattern: String, gt: UnsafeMutablePointer<glob_t>) -> Bool {
return 0 == glob(pattern, globFlags, nil, gt)
}
private func populateFiles(gt: glob_t) {
for i in 0 ..< Int(gt.gl_matchc) {
if let path = String.fromCString(gt.gl_pathv[i]) {
paths.append(path)
}
}
}
}
//
// GlobTester.swift
//
// Created by Brad Grzesiak on 6/25/15.
// Copyright © 2015 Bendyworks Inc.
// Released under the Apache v2 License.
//
import XCTest
class GlobTester: XCTestCase {
let tmpFiles = ["foo", "bar", "baz"]
var tmpDir: String?
override func setUp() {
super.setUp()
var tmpDirTmpl = "/tmp/glob-test.XXXXX".cStringUsingEncoding(NSUTF8StringEncoding)!
self.tmpDir = String.fromCString(mkdtemp(&tmpDirTmpl))
for file in tmpFiles {
close(open("\(tmpDir!)/\(file)", O_CREAT))
}
}
override func tearDown() {
for file in tmpFiles {
unlink("\(tmpDir!)/\(file)")
}
rmdir(self.tmpDir!)
super.tearDown()
}
func testBraces() {
let pattern = "\(tmpDir!)/ba{r,y,z}"
let glob = Glob(pattern: pattern)
var contents = [String]()
for file in glob {
contents.append(file)
}
XCTAssertEqual(contents, ["\(tmpDir!)/bar", "\(tmpDir!)/baz"], "matching with braces failed")
}
func testNothingMatches() {
let pattern = "\(tmpDir!)/nothing"
let glob = Glob(pattern: pattern)
var contents = [String]()
for file in glob {
contents.append(file)
}
XCTAssertEqual(contents, [], "expected empty list of files")
}
func testDirectAccess() {
let pattern = "\(tmpDir!)/ba{r,y,z}"
let glob = Glob(pattern: pattern)
XCTAssertEqual(glob.paths, ["\(tmpDir!)/bar", "\(tmpDir!)/baz"], "matching with braces failed")
}
func testIterateTwice() {
let pattern = "\(tmpDir!)/ba{r,y,z}"
let glob = Glob(pattern: pattern)
var contents1 = [String]()
var contents2 = [String]()
for file in glob {
contents1.append(file)
}
let filesAfterOnce = glob.paths
for file in glob {
contents2.append(file)
}
XCTAssertEqual(contents1, contents2, "results for calling for-in twice are the same")
XCTAssertEqual(glob.paths, filesAfterOnce, "calling for-in twice doesn't only memoizes once")
}
func testIndexing() {
let pattern = "\(tmpDir!)/ba{r,y,z}"
let glob = Glob(pattern: pattern)
XCTAssertEqual(glob[0], "\(tmpDir!)/bar", "indexing")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment