Skip to content

Conversation

louisunlimited
Copy link
Contributor

Manually added checks at the start of each command (apart from self-update and init) to check for version mismatches, if found, it will try to prompt the user with:

"A new release of swiftly is available"
"Please run `swiftly self-update` to update."

It also tries to prompt the user at the very last stage of the command, ensuring the update prompt will always show at the end to avoid being buried.

@louisunlimited
Copy link
Contributor Author

I'm thinking about possibly refactoring this in some way to make things coherent, maybe all as a method under SwiftlyCommand like the existing:

public mutating func validateSwiftly(_ ctx: SwiftlyCoreContext) throws {

mutating func run(_ ctx: SwiftlyCoreContext) async throws {
try validateSwiftly(ctx)

let swiftlyRelease = try await ctx.httpClient.getCurrentSwiftlyRelease()
Copy link
Member

Choose a reason for hiding this comment

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

question: can we put this code in validateSwiftly() as a kind of validation check? I think that it might make sense to have it there.

Copy link
Member

Choose a reason for hiding this comment

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

I see that one problem is with the defer block. Perhaps the validate function can return a function that should be deferred by the caller?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea, this would also make all commands that does validateSwiftly(ctx) do version checks. Which includes self-update , for now I have discarded the returned func for self-update as we don't need checks before the command that actually updates itself.

let shouldUpdateSwiftly = try swiftlyRelease.swiftlyVersion > SwiftlyCore.version
defer {
if shouldUpdateSwiftly {
ctx.print("A new release of swiftly is available")
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: Print these messages to stderr so that it doesn't interfere with other tools that might be parsing stdout. It also has the benefit of being able to quieted at the shell if a user wants using redirects like this: swiftly install 2>/dev/null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a predefined way of doing prints to stderr? Currently I'm using fileHandler to route to stderr, I see that print() depends on the context and would it be better modifying outputHandler in the context to be stderr and then change it back to being stdout?

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 that it's ok in this context to print directly to stderr outside of the ctx.print(). The context is there for the purpose of mocks during testing, and I don't think that this feature warrants testing of what it prints to stderr.

In terms of how to print to stderr, I think that these FileHandle API's in Foundation could work for this:
https://developer.apple.com/documentation/foundation/filehandle/standarderror
https://developer.apple.com/documentation/foundation/filehandle/write(contentsof:)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh nice, that's exactly what I used for printing out to stderr, I'll mark this pr for review then, thanks!

Copy link
Member

@cmcgee1024 cmcgee1024 left a comment

Choose a reason for hiding this comment

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

praise: this is a great start on this feature!

@cmcgee1024
Copy link
Member

It looks like the big URL -> FilePath created conflicts on this PR.

@louisunlimited
Copy link
Contributor Author

Hi @cmcgee1024 I just merged main into this branch, lmk if you need anything else!

if shouldUpdateSwiftly {
let updateMessage = """
-----------------------------
A new release of swiftly is available
Copy link
Member

Choose a reason for hiding this comment

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

nitpick: This sentence needs a period at the end.

@cmcgee1024
Copy link
Member

@swift-ci test macOS

// Verify that the configuration exists and can be loaded
_ = try await Config.load(ctx)

let swiftlyRelease = try await ctx.httpClient.getCurrentSwiftlyRelease()
Copy link
Member

Choose a reason for hiding this comment

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

issue(blocking): This will throw an error if there's some kind of an HTTP connection problem fetching the current swiftly release. That shouldn't abort the principal operation, such as use/install/etc.

suggestion: Change this to try? await so that the release is optional. Only if the release can be found and it is larger than the current version would trigger the message.

Copy link
Contributor Author

@louisunlimited louisunlimited Apr 25, 2025

Choose a reason for hiding this comment

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

Sounds good, done.

@cmcgee1024
Copy link
Member

@louisunlimited I suspect that the tests are failing because mocked http executor is producing fatal errors due to this attempt to make a network request. The idea is to keep the vast majority of tests from making real network requests so that they can run quickly and are immune to changes on swift.org that make them brittle.

Perhaps this could produce a mocked swiftly version instead, based on the current version in SwiftlyVersion?

@cmcgee1024
Copy link
Member

@louisunlimited you can fix the formatting error by running swift run swiftformat . and then commit the formatting fixes.

@louisunlimited
Copy link
Contributor Author

louisunlimited commented Apr 26, 2025

@louisunlimited I suspect that the tests are failing because mocked http executor is producing fatal errors due to this attempt to make a network request. The idea is to keep the vast majority of tests from making real network requests so that they can run quickly and are immune to changes on swift.org that make them brittle.

Perhaps this could produce a mocked swiftly version instead, based on the current version in SwiftlyVersion?

Yeah I was going through tests locally and I see that by wrapping tests inside something like

try await SwiftlyTests.withMockedSwiftlyVersion(latestSwiftlyVersion: SwiftlyVersion(major: SwiftlyCore.version.major, minor: 0, patch: 0)) {
    ...
}

would fix it. I could just wrap this around all the tests (or the helper func they call), but was thinking if there are better ways. Any suggestions?

@cmcgee1024
Copy link
Member

would fix it. I could just wrap this around all the tests (or the helper func they call), but was thinking if there are better ways. Any suggestions?

I think that's pretty consistent with what's being done in other cases in the test suite, so that seems fine to me.

@louisunlimited
Copy link
Contributor Author

louisunlimited commented Apr 28, 2025

@cmcgee1024 Just updated the tests! Lmk what you think, and also if it's necessary to add a "shouldPromptVersionUpate" test for each of the commands. End up with using Traits instead of wrapping them because there seems to be some ordering issues with how ctx is being passed around. All test are passing locally.

@cmcgee1024
Copy link
Member

@swift-ci test macOS

1 similar comment
@cmcgee1024
Copy link
Member

@swift-ci test macOS

@cmcgee1024 cmcgee1024 merged commit 102a5c3 into swiftlang:main Apr 29, 2025
23 checks passed
@cmcgee1024
Copy link
Member

Thanks for your contribution @louisunlimited

@louisunlimited louisunlimited deleted the louis/update-check branch April 29, 2025 20:29
@louisunlimited louisunlimited restored the louis/update-check branch April 29, 2025 20:29
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.

Gentle reminder about updated swiftly

2 participants