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
[SR-7836] Added swift package update --dry-run #2380
Conversation
Sources/Workspace/Workspace.swift
Outdated
|
||
guard !dryRun else { | ||
let changes = diagnostics.wrap { return try computePackageStateChanges(root: graphRoot, resolvedDependencies: updateResults, updateBranches: true) } ?? [] | ||
logPackageChanges(changes: changes, pins: pinsStore) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Workspace
is a high-level library so it'll be better if we return a structured object from here. Clients can then do whatever they want with the object. In this particular case, maybe you can accept an inout
array to fill for dry run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea! I think it looks way better than splitting updateDependencies
into updateDependencies
and updateDependenciesDryRun
Thanks! This is great. I left some comments inline |
} | ||
stream <<< "\n" | ||
} | ||
stream.flush() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you post what an example output looks like? Just curious!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2019-10-16 13:21:43.723885+0200 swift-package[53147:783737] [default] Starting resolution using pubgrub resolver
Updating https://github.com/attaswift/BigInt.git
Updating https://github.com/apple/swift-protobuf.git
3 dependencies have changed:
+ SwiftProtobuf 1.7.0
~ BigInt 4.0.0 -> BigInt 5.0.0
- swift-nio 2.8.0
Program ended with exit code: 0
@@ -69,6 +69,26 @@ final class PackageToolTests: XCTestCase { | |||
XCTAssertEqual(GitRepository(path: path).tags, ["1.2.3", "1.2.4"]) | |||
} | |||
} | |||
|
|||
func testUpdateDryRun() throws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better if you can write a unit test since they're much much faster to run. You can see WorkspaceTests.swift
for examples. Don't worry about it if it's turning out to be too hard.
Hey @TG908. I ended up being a bit busier than usual this week but I hope to re-review the PR early next week. |
} else if let pinsStore = diagnostics.wrap({ try workspace.pinsStore.load() }), | ||
let changes = try workspace.updateDependenciesDryRun( | ||
root: getWorkspaceRoot(), | ||
diagnostics: diagnostics) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't we discuss passing an inout array to get the changes? Any particular reason for switching to a new method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I had to create a new method due to API stability anyway, I chose to use a return value instead of inout
because I think the in part of inout
would never be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking the parameter would default to nil and we'd use the in
part to determine if this is a dry run operation. Something like:
public func updateDependencies(
root: PackageGraphRootInput,
dryRunResults: [Result]? = nil
diagnostics: DiagnosticsEngine
) {
...
// Fill the dry run results array if one is provided and return without performing the actual update.
if dryRunResults != nil {
dryRunResults = updateResults
return
}
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't work in swift 5.1 inout parameters cannot have a default value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah. What if we add a specialized method ourselves?
public func updateDependencies(
root: PackageGraphRootInput,
diagnostics: DiagnosticsEngine
) {
updateDependencies(root: root, dryRunResults: nil, diagnostics: diagnostics)
}
public func updateDependencies(
root: PackageGraphRootInput,
dryRunResults: [Result]?,
diagnostics: DiagnosticsEngine
) {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it obvious to someone reading the code for the first time that passing a dry run array causes the actual update not to happen?
Without reading the documentation it is more obvious that the method updateDependencies
performs an actual update and updateDependenciesDryRun
does not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, it's not very obvious especially for API consumers. What if we always return the update result and make this method @discardableResult
? Then this method could just take a simple Bool dryRun
.
- Added swift package --dry-run - Added prettyPrinted to Requirement - Added tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some very minor nits but otherwise this is ready to go. Thanks a lot for working on this!
You are welcome. Thank you for your input! |
@swift-ci smoke test |
Given the output in the sample above:
This isn't a proper |
That fetch state is supposed to be an implementation detail. What's your use case? |
As part of the Catalog App I'd like to show a user projects he could update and ideally what is new (just like the Updates section in App Store). But in no way I want to modify any of his precious stuff before he clicks an actual "update" button. Besides, the core definition of I understand that this seems quite hard w/ just git, so I'm probably going to APFS clone projects and run a full update. In any case I suggest that the dox to this "dry-run" explicitly documents that this is going to fetch and not be dry. It's quite unexpected and counter to the point. |
I don't want this behavior documented because it's an implementation detail and we'll probably want to have local shared cache at some point. But it seems fine to consider this behavior as a bug in the current |
|
The best solution would be to just copy the workspace into a temporary directory. In case of a dry run a normal update would be performed on a temporary Workspace. I would also remove the dry run argument for updateDependencies again and just always print the summary of changed packages (should I keep returning the changed packages?). |
That is what I also plan to do for now. Unfortunately it's a little hard to clone into the same directory :-) BTW: Something which would also be appreciated is if this would get the JSON output treatment. |
For getting easy to parse output you could also use the swift package manger library to get the outdated packages. |
I think that's too much coupling for my purpose, I just want to use the Swift the user has active. |
I created an issue |
swift package --dry-run
Requirement