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

Remote Version Validation #1533

Merged
merged 4 commits into from
Nov 6, 2016
Merged

Remote Version Validation #1533

merged 4 commits into from
Nov 6, 2016

Conversation

rodchile
Copy link
Contributor

@rodchile rodchile commented Oct 16, 2016

Verifies if the local version of Carthage is up to date.
It should solve #1181 and #1130

Credits also to @mdiep for his help!

@ikesyo
Copy link
Member

ikesyo commented Oct 16, 2016

I think this would have a negative impact for GitHub API's rate limiting, especially on CI environments.

@mdiep
Copy link
Member

mdiep commented Oct 16, 2016

I think this would have a negative impact for GitHub API's rate limiting, especially on CI environments.

CI environments are already unable to use the GitHub API since it's aggressively rate-limited. Using the API features is basically dependent on authenticated use of the API. So I think this is okay.

Copy link
Member

@mdiep mdiep left a comment

Choose a reason for hiding this comment

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

I think this will be a big improvement. Users frequently have problems when running older versions.


/// Attemps to create an instance of NSScaner and then use the convenience
/// function specified in the protocol
static public func fromString(string: String) -> Result<Self,CarthageError>
Copy link
Member

Choose a reason for hiding this comment

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

There should be a here after the,.


extension Scannable {

/// Attemps to create an instance of NSScaner and then use the convenience
Copy link
Member

Choose a reason for hiding this comment

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

A couple typos here: attempts, NSScanner

/// function specified in the protocol
static public func fromString(string: String) -> Result<Self,CarthageError>
{
return Self.fromScanner(NSScanner(string:string))
Copy link
Member

Choose a reason for hiding this comment

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

There should be a here after the:.

}
}

func fetchLatestCarthageVersion() -> CarthageVersion{
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 it'd be better to split this into two code units:

  1. one to get the latest version from the server
  2. one to get the local version (which could be used for carthage version)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

.timeoutWithError(CarthageError.GitHubAPITimeout, afterInterval: 0.1, onScheduler: QueueScheduler.mainQueueScheduler)
.first()

return CarthageVersion(localVersion: SemanticVersion.fromString(versionString).value!, remoteVersion: latestVersion!.value!)
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't use !s with latestVersion because it shouldn't be a hard error if this API request fails.

let carthageVersion = fetchLatestCarthageVersion()

if carthageVersion.shouldUpgrade() == true {
print("Please update to the latest Carthage version: \(carthageVersion.remoteVersion). You currently are on \(carthageVersion.localVersion)")
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 use carthage.println here to format and color this text. (See Formatting.swift.)

Copy link
Contributor

@NachoSoto NachoSoto left a comment

Choose a reason for hiding this comment

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

There are lots of style violations. I could swear the repo had SwiftLint (I can work on adding it), but in the mean time can you fix them by hand?

/// Attempts to create an instance of NSScanner and then use the convenience
/// function specified in the protocol
static public func fromString(string: String) -> Result<Self, CarthageError>
{
Copy link
Contributor

Choose a reason for hiding this comment

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

Should go on the previous line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

import Result
import Tentacle

public struct CarthageVersion{
Copy link
Contributor

Choose a reason for hiding this comment

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

Space before {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

public struct CarthageVersion{

public let localVersion:SemanticVersion
public let remoteVersion:SemanticVersion
Copy link
Contributor

Choose a reason for hiding this comment

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

Spaces after :. Didn't SwiftLint catch these?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

BTW, I activated SwiftLint and got ˜15000 issues :D in the project. I think that it isn't being used.

public let remoteVersion:SemanticVersion

public init (localVersion: SemanticVersion, remoteVersion:SemanticVersion){
self.localVersion = localVersion
Copy link
Contributor

Choose a reason for hiding this comment

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

No space before (

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

.attemptMap { (release) -> Result<SemanticVersion, CarthageError> in
return SemanticVersion.fromString(release.tag)
}
.timeoutWithError(CarthageError.GitHubAPITimeout, afterInterval: 0.1, onScheduler: QueueScheduler.mainQueueScheduler)
Copy link
Contributor

Choose a reason for hiding this comment

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

Just 0.1s?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the value to 3 seconds. Thanks for catching this.

return SemanticVersion.fromString(release.tag)
}
.timeoutWithError(CarthageError.GitHubAPITimeout, afterInterval: 0.1, onScheduler: QueueScheduler.mainQueueScheduler)
.first()
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm why make this blocking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we want to validate first Carthage version before doing any task. In case their version is behind, we let know right away about that.


let formatting = ColorOptions.Formatting(true)

carthage.println(formatting.bullets + "Please update to the latest Carthage version: \(carthageVersion.remoteVersion). You currently are on \(carthageVersion.localVersion)")
Copy link
Contributor

Choose a reason for hiding this comment

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

Cool

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍🏼

self.remoteVersion = remoteVersion
}

func shouldUpgrade() ->Bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Style

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


func shouldUpgrade() ->Bool {

if localVersion < remoteVersion {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is redundant, can just return localVersion < remoteVersion

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Woah - totally agree. Thanks for catching this.

public let localVersion:SemanticVersion
public let remoteVersion:SemanticVersion

public init (localVersion: SemanticVersion, remoteVersion:SemanticVersion){
Copy link
Contributor

Choose a reason for hiding this comment

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

Style

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

return releases.first!
}
.mapError(CarthageError.GitHubAPIRequestFailed)
.attemptMap { (release) -> Result<SemanticVersion, CarthageError> in
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be

.map { $0.tag }
.attemptMap(SemanticVersion.fromString)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that the more verbose version is easier to understand. @mdiep what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I'd go with @NachoSoto's suggestion. 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried this suggestion and seems that there is an issue with the inferrer based on the $0.tag value.

Copy link
Member

@mdiep mdiep left a comment

Choose a reason for hiding this comment

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

This is great! Almost there!

.attemptMap { (release) -> Result<SemanticVersion, CarthageError> in
return SemanticVersion.fromString(release.tag)
}
.timeoutWithError(CarthageError.GitHubAPITimeout, afterInterval: 3, onScheduler: QueueScheduler.mainQueueScheduler)
Copy link
Member

Choose a reason for hiding this comment

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

This timeout should be much lower. I wouldn't want to keep users waiting for 3 seconds on every carthage invocation. Maybe 0.5?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

func shouldUpgrade() -> Bool {
return localVersion < remoteVersion
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this struct gets us anything. Lets get rid of it and just use localVersion and remoteVersion directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@@ -20,6 +20,15 @@ guard ensureGitVersion().first()?.value == true else {
exit(EXIT_FAILURE)
}

let carthageVersion = fetchLatestCarthageVersion()

if carthageVersion.shouldUpgrade() == true {
Copy link
Member

Choose a reason for hiding this comment

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

With the changes I've suggested, this would become:

if let remoteVersion = remoteVersion() where localVersion() < remoteVersion {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

.timeoutWithError(CarthageError.GitHubAPITimeout, afterInterval: 3, onScheduler: QueueScheduler.mainQueueScheduler)
.first()

return latestRemoteVersion!.value!
Copy link
Member

Choose a reason for hiding this comment

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

This definitely shouldn't use !. This feature is optional, so if GitHub goes down, carthage shouldn't become unusable. The function return a SemanticVersion? and this should be return latestRemoveVersion?.value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

@mdiep
Copy link
Member

mdiep commented Nov 6, 2016

🚢

@mdiep mdiep merged commit 4d28e96 into Carthage:master Nov 6, 2016
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