[swift-corelibs-dev] Better integration with UNIX tools
William Dillon
wdillon at deluge.housedillon.com
Fri Nov 17 21:10:11 CST 2017
I cosign all of this. Nice work, Brent.
> On Nov 17, 2017, at 4:47 PM, Brent Royal-Gordon via swift-corelibs-dev <swift-corelibs-dev at swift.org> wrote:
>
>> On Nov 17, 2017, at 11:34 AM, Tony Parker via swift-corelibs-dev <swift-corelibs-dev at swift.org <mailto:swift-corelibs-dev at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-corelibs-dev/attachments/20171117/2a8079cf/attachment.html>
More information about the swift-corelibs-dev
mailing list