Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation for the swift run command #1187

Merged
merged 1 commit into from Jun 17, 2017
Merged

Conversation

hartbit
Copy link
Collaborator

@hartbit hartbit commented May 15, 2017

No description provided.


/// Executes and returns execution status. Prints output on standard streams.
private func run(path: AbsolutePath) throws {
let process = Process(arguments: [path.asString] + options.arguments, redirectOutput: false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On UNIX, we should exec the process rather than run it in a subprocess. These will ensure that we don't influence the programs behavior w.r.t. signal handling, buffering, etc.

/// Builds the "executable" target if enabled in options.
///
/// - Returns: The path to the executable binary.
private func buildIfNeeded() throws -> AbsolutePath {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels weird that this returns path to the executable. We can just inline this for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I was just reproducing the structure of swift test in case that's what you preferred. Will inline it.


return buildPath
.appending(RelativePath(options.config.dirname))
.appending(component: executable.name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be using buildplan to get the path to executable, can you land the refactor first?

@ddunbar
Copy link
Member

ddunbar commented May 31, 2017

We accepted SE-179 with revisions:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170529/036909.html
which we should incorporate here.

@hartbit
Copy link
Collaborator Author

hartbit commented May 31, 2017

I have an implementation ready for the accepted (revised) version. Just need to wait for #1215 to be merged first.

@hartbit hartbit force-pushed the swift-run branch 2 times, most recently from 66f7067 to 32e47e2 Compare May 31, 2017 22:11
@hartbit hartbit assigned ddunbar and ankitspd and unassigned hartbit May 31, 2017
@hartbit hartbit added pending evolution proposal and removed WIP Work in progress labels May 31, 2017
@hartbit hartbit changed the title [WIP] Implementation for the swift run command Implementation for the swift run command May 31, 2017
case .executableNotFound(let executable):
return "could not find executable '\(executable)'"
case .multipleExecutables:
return "multiple products defined"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make this more descriptive, maybe something like: "There are multiple executable products in the package. Use 'swift run ' to run one of the executable".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to also list the executables, so users don't then have to look up the names.

private enum RunError: Swift.Error {
case noExecutableFound
case executableNotFound(String)
case multipleExecutables
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc comments

}
}

/// Executes and returns execution status. Prints output on standard streams.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment


let product = try findExecutable(in: plan)
let path = plan.buildParameters.buildPath.appending(component: product.name)
try run(at: path)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds wrong. Maybe findExectuable can return the path of the exe and then we can do this:

...
let executable = try findExecutable(in: plan)
try run(executable)
...

}

return executableProduct
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Else is not required

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That you can just put the else branch after the if, since it early returns.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, got it!

throw RunError.multipleExecutables
}

return executableProducts.first!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: return executableProducts[0] feels nicer for some reason.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have an extension .only which returns the only item iff array has one element, this is a not uncommon pattern, and that utility works nicely in guard.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a nice utility! Separate PR I guess?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, I wouldn't block this one on it, just update it to use it if we decide it is a good idea.


/// Executes and returns execution status. Prints output on standard streams.
private func run(at path: AbsolutePath) throws {
if let workingDirectory = options.workingDirectory {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this became dead code, and the option can be removed.

try POSIX.chdir(workingDirectory.asString)
}

let relativePath = path.relative(to: currentWorkingDirectory)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currentWorkingDirectory -> originalWorkingDirectory

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a test case that fails w/o this fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. Looking at the code, it seems originalWorkingDirectory is currently only set once to currentWorkingDirectory. Not quite sure what its use case is.

@@ -929,6 +929,18 @@ public final class ArgumentBinder<Options> {
}
}

/// Bind an array positional argument.
public func bindArray<T>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this in a separate commit/PR


func testVersion() throws {
XCTAssert(try execute(["--version"]).contains("Swift Package Manager"))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a basic functional test. We can extend one of the executable related functional test.

@ankitspd ankitspd added WIP Work in progress and removed pending evolution proposal labels Jun 1, 2017
@ankitspd ankitspd removed their assignment Jun 1, 2017
case .executableNotFound(let executable):
return "could not find executable '\(executable)'"
case .multipleExecutables:
return "multiple products defined"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to also list the executables, so users don't then have to look up the names.


/// Executes and returns execution status. Prints output on standard streams.
private func run(at path: AbsolutePath) throws {
if let workingDirectory = options.workingDirectory {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this became dead code, and the option can be removed.

public convenience init(args: [String]) {
self.init(
toolName: "run",
usage: "[options] [executable <arguments>]",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somewhat unconventional syntax for usage, I would spell it as:
[executable [arguments ...]]

throw RunError.multipleExecutables
}

return executableProducts.first!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have an extension .only which returns the only item iff array has one element, this is a not uncommon pattern, and that utility works nicely in guard.

try POSIX.chdir(workingDirectory.asString)
}

let relativePath = path.relative(to: currentWorkingDirectory)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a test case that fails w/o this fix.

@ddunbar ddunbar assigned hartbit and unassigned ddunbar Jun 1, 2017
@hartbit hartbit force-pushed the swift-run branch 3 times, most recently from 815cde3 to ffc6e67 Compare June 4, 2017 21:24
@hartbit hartbit assigned ddunbar and ankitspd and unassigned hartbit Jun 4, 2017
}
}

/// Find executable path based on options.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The API guidelines recommend wording the doc comments in terms of what the method returns. Something like Returns executable path ... will be more appropriate.

product = executableProducts[0]
}

return plan.buildParameters.buildPath.appending(component: product.name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Consider adding some high level comments on whats going on in this method.


/// Executes the executable at the specified path.
private func run(_ excutablePath: AbsolutePath) throws {
let relativePath = excutablePath.relative(to: originalWorkingDirectory)
Copy link
Member

@ankitspd ankitspd Jun 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name relativePath is too vague.

See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import class Foundation.ProcessInfo
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

@hartbit
Copy link
Collaborator Author

hartbit commented Jun 16, 2017

@swift-ci please smoke test

1 similar comment
@hartbit
Copy link
Collaborator Author

hartbit commented Jun 16, 2017

@swift-ci please smoke test

@hartbit
Copy link
Collaborator Author

hartbit commented Jun 16, 2017

@swift-ci please smoke test

2 similar comments
@hartbit
Copy link
Collaborator Author

hartbit commented Jun 16, 2017

@swift-ci please smoke test

@hartbit
Copy link
Collaborator Author

hartbit commented Jun 16, 2017

@swift-ci please smoke test

@hartbit
Copy link
Collaborator Author

hartbit commented Jun 17, 2017

@swift-ci please smoke test

1 similar comment
@hartbit
Copy link
Collaborator Author

hartbit commented Jun 17, 2017

@swift-ci please smoke test

@hartbit hartbit merged commit b4d728c into apple:master Jun 17, 2017
@hartbit hartbit deleted the swift-run branch June 27, 2017 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants