> On Nov 17, 2017, at 11:34 AM, Tony Parker via swift-corelibs-dev
> <[email protected]> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev