diff --git a/SwiftShell.xcodeproj/project.pbxproj b/SwiftShell.xcodeproj/project.pbxproj index 93ec084..5b9f9e2 100644 --- a/SwiftShell.xcodeproj/project.pbxproj +++ b/SwiftShell.xcodeproj/project.pbxproj @@ -268,7 +268,8 @@ BAAE15C719A3FB5D00DA3462 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = "NotTooBad Software"; TargetAttributes = { BAAE15CF19A3FB5E00DA3462 = { @@ -402,6 +403,7 @@ COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -478,6 +480,7 @@ INFOPLIST_FILE = SwiftShell/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = NO; }; @@ -498,6 +501,7 @@ INFOPLIST_FILE = SwiftShell/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = NO; }; @@ -518,6 +522,7 @@ ); INFOPLIST_FILE = SwiftShellTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; @@ -534,6 +539,7 @@ ); INFOPLIST_FILE = SwiftShellTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -553,6 +559,7 @@ ); INFOPLIST_FILE = SwiftShell_Speed_Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; @@ -569,6 +576,7 @@ ); INFOPLIST_FILE = SwiftShell_Speed_Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell.xcscheme b/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell.xcscheme index 8a1f114..af5ed4a 100644 --- a/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell.xcscheme +++ b/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell.xcscheme @@ -1,6 +1,6 @@ + + + + diff --git a/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell_Speed_Tests.xcscheme b/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell_Speed_Tests.xcscheme index b924460..d43950d 100644 --- a/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell_Speed_Tests.xcscheme +++ b/SwiftShell.xcodeproj/xcshareddata/xcschemes/SwiftShell_Speed_Tests.xcscheme @@ -1,6 +1,6 @@ + + (lhs: ReadableStreamType, @autoclosure rhs: () -> ReadableStream Run a shell command synchronously with no standard input, or if to the right of a "ReadableStreamType |> ", use the stream on the left side as standard input. -:returns: Standard output +- returns: Standard output */ public func run (shellcommand: String) -> ReadableStreamType { let task = newtask(shellcommand) @@ -85,5 +85,5 @@ public func $ (shellcommand: String) -> String { /** Turn a sequence into valid parameters for a shell command, properly quoted */ public func parameters (sequence: S) -> String { - return " " + ( sequence |> map { "\"\(toString($0))\"" } |> join(" ") ) + return " " + " ".join( sequence.map { "\"\($0)\"" } ) } diff --git a/SwiftShell/FileHandle.swift b/SwiftShell/FileHandle.swift index 3b19475..7ad3eab 100644 --- a/SwiftShell/FileHandle.swift +++ b/SwiftShell/FileHandle.swift @@ -35,8 +35,8 @@ extension FileHandle: ReadableStreamType { } } - public func lines () -> SequenceOf { - return split(delimiter: "\n")(stream: self) + public func lines () -> AnySequence { + return split("\n")(stream: self) } public func writeTo (inout target: Target) { @@ -66,8 +66,8 @@ extension FileHandle: WriteableStreamType { } /** Print message to standard error and halt execution. */ -@noreturn public func printErrorAndExit (errormessage: String) { - standarderror.writeln("SwiftShell: " + errormessage) +@noreturn public func printErrorAndExit (errormessage: T) { + standarderror.writeln("SwiftShell: \(errormessage)") exit(EXIT_FAILURE) } @@ -75,23 +75,24 @@ extension FileHandle: WriteableStreamType { public func open (path: String) -> ReadableStreamType { let url = toURLOrError(path) - var error: NSError? - let filehandle = FileHandle(forReadingFromURL: url, error: &error) - - if let error = error { - var fileaccesserror: NSError? - url.checkResourceIsReachableAndReturnError(&fileaccesserror) - printErrorAndExit( fileaccesserror?.localizedDescription ?? error.localizedDescription ) + do { + let filehandle = try FileHandle(forReadingFromURL: url) + return filehandle + } catch { + do { + try url.checkResourceIsReachable() + } catch { + printErrorAndExit(error) + } + printErrorAndExit(error) } - - return filehandle! } /** Open a file for writing, create it if it doesn't exist, and exit if an error occurs. If the file already exists and overwrite=false, the writing will begin at the end of the file. -:param: overwrite If true, replace the file if it exists. +- parameter overwrite: If true, replace the file if it exists. */ public func open (forWriting path: String, overwrite: Bool = false) -> WriteableStreamType { @@ -100,21 +101,22 @@ public func open (forWriting path: String, overwrite: Bool = false) -> Writeable File.createFileAtPath(url.path!, contents: nil, attributes: nil) } - var error: NSError? - let filehandle = FileHandle(forWritingToURL: url, error: &error) - - if let error = error { - var fileaccesserror: NSError? - url.checkResourceIsReachableAndReturnError(&fileaccesserror) - printErrorAndExit( fileaccesserror?.localizedDescription ?? error.localizedDescription ) - } else { - filehandle!.seekToEndOfFile() - return filehandle! + do { + let filehandle = try FileHandle(forWritingToURL: url) + filehandle.seekToEndOfFile() + return filehandle + } catch { + do { + try url.checkResourceIsReachable() + } catch { + printErrorAndExit(error) + } + printErrorAndExit(error) } } -public let environment = NSProcessInfo.processInfo().environment as! [String: String] +public let environment = NSProcessInfo.processInfo().environment as [String: String] public let standardinput = FileHandle.fileHandleWithStandardInput() as ReadableStreamType public let standardoutput = FileHandle.fileHandleWithStandardOutput() as WriteableStreamType public let standarderror = FileHandle.fileHandleWithStandardError() as WriteableStreamType diff --git a/SwiftShell/Files.swift b/SwiftShell/Files.swift index d9ff4b6..152f376 100644 --- a/SwiftShell/Files.swift +++ b/SwiftShell/Files.swift @@ -10,11 +10,9 @@ import Foundation func toURLOrError (path: String) -> NSURL { - if let url = NSURL(fileURLWithPath: path) { - return url - } else { - printErrorAndExit("Invalid file path: \(path)") - } + // no longer returns an optional. Weird. And it also seems to confuse the compiler (Swift 2 b2) + let result = NSURL.fileURLWithPath(path) + return result } /** The default NSFileManager */ @@ -25,17 +23,19 @@ The tempdirectory is unique each time a script is run and is created the first t It lies in the user's temporary directory and will be automatically deleted at some point. */ public let tempdirectory: String = { - var error: NSError? let tempdirectory = NSTemporaryDirectory() / "SwiftShell-" + NSProcessInfo.processInfo().globallyUniqueString - File.createDirectoryAtPath(tempdirectory, withIntermediateDirectories:true, attributes: nil, error: &error) - if let error = error { + do { + try File.createDirectoryAtPath(tempdirectory, withIntermediateDirectories:true, attributes: nil) + } catch let error as NSError { printErrorAndExit("Could not create new temporary directory '\(tempdirectory)':\n\(error.localizedDescription)") + } catch { + printErrorAndExit("Unexpected error: \(error)") } return tempdirectory -}() + }() -/** +/** The current working directory. Must be used instead of `run("cd ...")` because all the `run` commands are executed in a diff --git a/SwiftShell/Info.plist b/SwiftShell/Info.plist index a856b80..ebac9a8 100644 --- a/SwiftShell/Info.plist +++ b/SwiftShell/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SwiftShell/Pipes.swift b/SwiftShell/Pipes.swift index b2f48ac..2340f44 100644 --- a/SwiftShell/Pipes.swift +++ b/SwiftShell/Pipes.swift @@ -38,7 +38,7 @@ public func sorted (source: S) -> [S.Generator.Element] { - return sorted(source, isOrderedBefore) + return source.sort(isOrderedBefore) } /** Lazily return a sequence containing the results of mapping transform over source. */ @@ -59,11 +59,11 @@ public func reduce (sequence: S) -> U { - return reduce(sequence, initial, combine) + return sequence.reduce(initial, combine: combine) } /** Split text over delimiter, returning an array. */ -public func split (_ delimiter: String = "\n")(text: String) -> [String] { +public func split (delimiter delimiter: String = "\n")(text: String) -> [String] { return text.componentsSeparatedByString(delimiter) } @@ -87,7 +87,7 @@ public func drop LazySequence> { - return sequence |> filter { !contains(tobedropped, $0) } + return sequence |> filter { !tobedropped.contains($0) } } /** Return at most the first `numbertotake` elements of sequence */ diff --git a/SwiftShell/Stream.swift b/SwiftShell/Stream.swift index bb9d522..0586130 100644 --- a/SwiftShell/Stream.swift +++ b/SwiftShell/Stream.swift @@ -19,7 +19,7 @@ public protocol ReadableStreamType : Streamable { Whatever amount of text the stream feels like providing. If the source is a file this will read everything at once. - :returns: more text from the stream, or nil if we have reached the end. + - returns: more text from the stream, or nil if we have reached the end. */ func readSome () -> String? @@ -27,7 +27,7 @@ public protocol ReadableStreamType : Streamable { func read () -> String /** Lazily split the stream into lines. */ - func lines () -> SequenceOf + func lines () -> AnySequence /** Enable stream to be used by "println" and "toString". */ func writeTo (inout target: Target) @@ -66,7 +66,7 @@ stream { } } -:returns: The output stream. +- returns: The output stream. */ public func stream ( closure:() -> () -> String? ) -> ReadableStreamType { let getmoretext = closure() @@ -138,8 +138,8 @@ struct StringStreamGenerator : GeneratorType { } /** Split a stream lazily */ -public func split (delimiter: String = "\n")(stream: ReadableStreamType) -> SequenceOf { - return SequenceOf({StringStreamGenerator (stream: stream, delimiter: delimiter)}) +public func split (delimiter: String = "\n")(stream: ReadableStreamType) -> AnySequence { + return AnySequence({StringStreamGenerator (stream: stream, delimiter: delimiter)}) } @@ -149,7 +149,7 @@ Write something to a stream. something |> writeTo(writablestream) */ public func writeTo (stream: WriteableStreamType)(input: T) { - stream.write( toString(input) ) + stream.write( String(input) ) } // needed to avoid `writeTo(SequenceType)` being called instead, diff --git a/SwiftShell/String.swift b/SwiftShell/String.swift index 1c47f5b..5ce318c 100644 --- a/SwiftShell/String.swift +++ b/SwiftShell/String.swift @@ -33,13 +33,13 @@ extension String { } public func countOccurrencesOf (substring: String) -> Int { - return self.findAll(substring) |> toArray |> count + return (self.findAll(substring) |> toArray).count } /** A lazy sequence of the ranges of `findstring` in this string. */ - public func findAll (findstring: String) -> SequenceOf> { + public func findAll (findstring: String) -> AnySequence> { var rangeofremainder: Range = self.startIndex.. parameters + let result = AnySequence( [stream("one"), stream("two"), stream("three")].generate() ) |> parameters XCTAssertEqual( result, " \"one\" \"two\" \"three\"" ) } diff --git a/SwiftShellTests/FileHandle_Tests.swift b/SwiftShellTests/FileHandle_Tests.swift index 4fa047b..07d506f 100644 --- a/SwiftShellTests/FileHandle_Tests.swift +++ b/SwiftShellTests/FileHandle_Tests.swift @@ -13,7 +13,7 @@ class FileHandle_Tests: XCTestCase { func notestOpenForReadingFileWhichDoesNotExist () { // prints error message and stops execution. - let file = open("file which does not exist") + open("file which does not exist") } func testReadFileLineByLine () { diff --git a/SwiftShellTests/Files_Tests.swift b/SwiftShellTests/Files_Tests.swift index 54f5b37..ab0587c 100644 --- a/SwiftShellTests/Files_Tests.swift +++ b/SwiftShellTests/Files_Tests.swift @@ -20,10 +20,10 @@ class Files_Tests: XCTestCase { } func testWorkDirectory_CanChange () { - workdirectory = "/private/tmp" + workdirectory = "/tmp" XCTAssertEqual( workdirectory, "/private/tmp" ) - XCTAssertEqual( $("pwd"), "/private/tmp" ) + XCTAssertEqual( $("pwd"), "/tmp" ) } func testURLConcatenationOperator () { diff --git a/SwiftShellTests/Info.plist b/SwiftShellTests/Info.plist index 9b7623c..ba72822 100644 --- a/SwiftShellTests/Info.plist +++ b/SwiftShellTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SwiftShellTests/Pipes_Tests.swift b/SwiftShellTests/Pipes_Tests.swift index 26ea994..5556bcb 100644 --- a/SwiftShellTests/Pipes_Tests.swift +++ b/SwiftShellTests/Pipes_Tests.swift @@ -10,21 +10,23 @@ import SwiftShell import XCTest class Pipes_Tests: XCTestCase { - + + /* func testSplitMapFilterSortedAndJoinWithPipeForwardOperator () { let numbers = "4,1,6,2,5,3,9,7,0,8" // doing this on one line takes a very very long time to compile (6.1 beta 2) - let numberslessthan5 = numbers |> split(",") |> map {$0.toInt()!} |> filter {$0<5} - let result = numberslessthan5 |> sorted {$0>$1} |> map(toString) |> join(",") + let numberslessthan5 = numbers |> split(delimiter: ",") |> map {Int($0)!} |> filter {$0<5} + let result = numberslessthan5 |> sorted {$0>$1} |> map {String($0)!} |> join(",") XCTAssertEqual( result, "4,3,2,1,0" ) } + */ func testSplitAndReduceWithPipeForwardOperator () { let numbers = "4,1,6,2,5,3,9,7,0,8" - let result = numbers |> split(",") |> reduce(0) {$0 + $1.toInt()!} + let result = numbers |> split(delimiter: ",") |> reduce(0) {$0 + Int($1)!} XCTAssertEqual( result, 45 ) } @@ -32,7 +34,7 @@ class Pipes_Tests: XCTestCase { func testTurnSequenceIntoArray () { let numbers = [4,1,6] - let result = SequenceOf(numbers) |> toArray + let result = AnySequence(numbers) |> toArray XCTAssertEqual( result, [4,1,6] ) } diff --git a/SwiftShellTests/Scripts/print_arguments.swift b/SwiftShellTests/Scripts/print_arguments.swift index 2c1380b..529d084 100755 --- a/SwiftShellTests/Scripts/print_arguments.swift +++ b/SwiftShellTests/Scripts/print_arguments.swift @@ -2,4 +2,4 @@ import SwiftShell -println(Process.arguments) +print(Process.arguments) diff --git a/SwiftShellTests/Scripts/readfilelinebyline.swift b/SwiftShellTests/Scripts/readfilelinebyline.swift index 3977b21..a4ced91 100755 --- a/SwiftShellTests/Scripts/readfilelinebyline.swift +++ b/SwiftShellTests/Scripts/readfilelinebyline.swift @@ -4,5 +4,5 @@ import SwiftShell for line in open("onetwothree.txt").lines() { // Do something with each line - println(line) + print(line) } diff --git a/SwiftShellTests/Stream_Tests.swift b/SwiftShellTests/Stream_Tests.swift index 51ef893..58a35c7 100644 --- a/SwiftShellTests/Stream_Tests.swift +++ b/SwiftShellTests/Stream_Tests.swift @@ -36,7 +36,7 @@ class Stream_Tests: XCTestCase { } func testPrintStreamToStream () { - var (writable, readable) = streams() + let (writable, readable) = streams() stream("this goes in") |>> writable @@ -44,7 +44,7 @@ class Stream_Tests: XCTestCase { } func testPrintStreamToStreamInPieces () { - var (writable, readable) = streams() + let (writable, readable) = streams() stream(["this ", "goes", " in"]) |>> writable @@ -53,7 +53,7 @@ class Stream_Tests: XCTestCase { } func testPrintStringToStream () { - var (writable, readable) = streams() + let (writable, readable) = streams() "this goes in" |>> writable @@ -61,7 +61,7 @@ class Stream_Tests: XCTestCase { } func testCommandChainToStream () { - var (writable, readable) = streams() + let (writable, readable) = streams() SwiftShell.run("echo this is streamed") |> SwiftShell.run("wc -w") |>> writable @@ -69,19 +69,19 @@ class Stream_Tests: XCTestCase { } func testSequenceOfStreamsToStream () { - var (writable, readable) = streams() + let (writable, readable) = streams() // make sure the array isn't printed as a Printable. - SequenceOf([stream("line 1"), stream("line 2"), stream("line 3")].generate()) |>> writable + AnySequence([stream("line 1"), stream("line 2"), stream("line 3")].generate()) |>> writable XCTAssertEqual( readable.readSome()!.trim(), "line 1line 2line 3" ) } func testChainWithSequenceOfStreamsPrintedToStream () { - var (writable, readable) = streams() + let (writable, readable) = streams() let dict = ["test":"line 1:line 2:line 3"] - dict["test"]! |> split(":") + dict["test"]! |> split(delimiter: ":") |> map { line in SwiftShell.run("echo \(line)") } |>> writable @@ -89,7 +89,7 @@ class Stream_Tests: XCTestCase { } func testChainWithSequenceOfStringsPrintedToStream () { - var (writable, readable) = streams() + let (writable, readable) = streams() var i = 1 stream("line 1\nline 2\nline 3").lines() |> map {line in "line \(i++): \(line)\n"} |>> writable diff --git a/SwiftShell_Speed_Tests/Info.plist b/SwiftShell_Speed_Tests/Info.plist index 9b7623c..ba72822 100644 --- a/SwiftShell_Speed_Tests/Info.plist +++ b/SwiftShell_Speed_Tests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.nottoobadsoftware.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SwiftShell_Speed_Tests/Stream_Iteration_SpeedTests.swift b/SwiftShell_Speed_Tests/Stream_Iteration_SpeedTests.swift index 1f7f591..f4232d5 100644 --- a/SwiftShell_Speed_Tests/Stream_Iteration_SpeedTests.swift +++ b/SwiftShell_Speed_Tests/Stream_Iteration_SpeedTests.swift @@ -116,18 +116,18 @@ class Stream_Iteration_SpeedTests: XCTestCase { } func testWhenSplitFileAsStringBecomesQuicker() { - println() + print("") let splitarray = allSpeedsSplitFileAsString() let myarray = allSpeedIterateOverFile() for i in 0.. splitarray[i] { - println(" splitting strings is faster after \(i) of \(splitarray.count) iterations") - println() + print("splitting strings is faster after \(i) of \(splitarray.count) iterations") + print("") return } } - println( "splitting strings was never faster!") - println() + print("splitting strings was never faster!") + print("") } }