> On Nov 17, 2017, at 11:34 AM, Tony Parker via swift-corelibs-dev > <swift-corelibs-dev@swift.org> wrote: > > It does seem like there is a possibility of some better convenience API here. > > Any ideas on what form it would take? A class method on Process that returns > the output, maybe?
`Process.run(_:arguments:terminationHandler:)` is not a bad basis for this, other than the first argument being a URL. I might add a variant which does a $PATH search and expands tildes: extension Process { class func runInPath(_ commandName: String, with arguments: [String], terminationHandler: ((Process) -> Void)? = nil) -> Process } (I would *not* add a variant which simply shells out, or at least I wouldn't make it the only option. Every scripting language I can think of has this feature, and every one of them discourages its use and pushes people towards something else with pre-split arguments and no shell attack surface.) And then add a method which gathers all stdout output and returns it, along with the termination status (throwing if it's a signal): extension Process { func outputAfterExit() throws -> (output: String, status: Int32) } The result is not *as* convenient as PHP, but it's a lot safe than running things through a shell, too. let (output, _) = try Task.runInPath("find", with: ["~/Desktop", "-name", "*.png"]).outputAfterExit() The biggest problem I see with this design is that expanding tildes in the arguments, but *not* globbing them, happens to be right for this case, but may not be in the general case. One interesting possibility would be to go the custom operator route: /// Returns an absolute path placing `relativePath` in the user's home directory. prefix func ~ (relativePath: String) -> String { return FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(relativePath).path } let (output, _) = try Task.runInPath("find", with: [~"Desktop", "-name", "*.png"]).outputAfterExit() But I'm not sure we'd want that available in million-line Mac apps. On the other hand, maybe Foundation's APIs in general are too verbose for scripting. I could imagine a "Foundation.Script" module which added some unprincipled but convenient shortcuts: extension URL: ExpressibleByStringLiteral { // Should be interpolatable too, but we need to redesign that. public init(stringLiteral value: String) { self.init(fileURLWithPath: value) } } public var FS { return FileManager.default } public var ENV { return ProcessInfo.processInfo.environment } That might be a good place for a leading tilde operator, too. -- Brent Royal-Gordon Architechies
_______________________________________________ swift-corelibs-dev mailing list swift-corelibs-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-corelibs-dev