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
Add fetch-interval to outdated
command to skip fetching the dependencies
#2714
base: master
Are you sure you want to change the base?
Add fetch-interval to outdated
command to skip fetching the dependencies
#2714
Conversation
Source/carthage/Outdated.swift
Outdated
if shouldIgnoreFetching { | ||
// TODO: Non-fetching changes required. | ||
carthage.println("The dependencies will not be fetched due to non-expired fetch interval.") | ||
return project.outdatedDependencies(options.isVerbose) |
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 noticed that we do download the remote dependencies when we initialise ResolverProtocol
type object:
Carthage/Source/CarthageKit/Project.swift
Lines 505 to 509 in 1c3e23a
let resolver = resolver ?? resolverType.init( | |
versionsForDependency: versions(for:), | |
dependenciesForDependency: dependencies, | |
resolvedGitReference: resolvedGitReference | |
) |
Wondering if modifying the resolver initialisation is a way to go, i.e. passing [:]
to resolver's versions 🤔
Could you guys please give me a hint what would be the best way to ignore fetching the remote dependencies? 🙏
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 think you can just set FetchCache.fetchCacheInterval
to the value that's passed in. That should be all you need to do?
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.
👋 @mdiep Thanks for the comment and your help 🙇 Just to double check: FetchCache.fetchCacheInterval
is just a static property without the persistent storage behind it, so we need the UserDefaults
logic I introduced in this PR anyway, right?
With the suggested changes we are going to have:
...
if shouldIgnoreFetching {
carthage.println("The dependencies will not be fetched due to non-expired fetch interval.")
FetchCache.fetchCacheInterval = TimeInterval(options.fetchInterval)
return project.outdatedDependencies(options.isVerbose)
}
....
Could you please just confirm we are on the same page? 🙏
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.
so we need the UserDefaults logic I introduced in this PR anyway, right?
Why?
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.
Please correct me if I am wrong @mdiep , but I though carthage
(CLI application) process is killed as soon as the command execution ends. It means carthage
does not hold in memory state (the static properties) between the command executions. That's why I introduced UserDefaults
- to keep the state of the application between the command executions.
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 prefer option one.
But failing that, I think we should keep the last fetched time in a file on disk in the dependencies directory. Users sometimes delete the entire cache to get back to a clean state. I'd prefer to keep all the cache info in that directory instead of putting some of it in user defaults.
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.
👋 @mdiep
I was investigating option one and unfortunately couldn't find a reasonable solution.
I was playing with with the option number two - file solution. I'd suggest to modify FetchCache
component and convert it from in-process caching to persistent caching. We could store last fetch timestamp per dependency (../Library/Caches/org.carthage.CarthageKit/dependencies
):
Please tell me what you think about this solution 🙇
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.
What if we set the last modified date of the directory for the dependency?
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.
Good idea, thanks! 👍
Tested on just three dependencies, but already noticed a great improvement (a few seconds):
I implemented the changes and kindly ask you for re-review @mdiep 🙇 🙇
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.
👋 Hey @mdiep 🙂 Just wanted to kindly ask if you did get a chance to have a look at the newest changes? 🙇 🤔
Source/carthage/Outdated.swift
Outdated
if shouldIgnoreFetching { | ||
// TODO: Non-fetching changes required. | ||
carthage.println("The dependencies will not be fetched due to non-expired fetch interval.") | ||
return project.outdatedDependencies(options.isVerbose) |
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 think you can just set FetchCache.fetchCacheInterval
to the value that's passed in. That should be all you need to do?
outdated
command to skip fetching the dependenciesoutdated
command to skip fetching the dependencies
86a4d9d
to
16a2b51
Compare
👋 @jdhealy Thanks for adding yourself as a reviewer 🙇 Please let me know if you have any questions about the implementation 👍 |
High five over the internet Thanks, so much! I've got time for one or two notes before I head out the door this morning. |
Source/CarthageKit/Git.swift
Outdated
fileprivate static func repositoriesLastFetchTime() -> Date? { | ||
do { | ||
let attr = try FileManager.default.attributesOfItem(atPath: Constants.Dependency.repositoriesURL.path) | ||
return attr[FileAttributeKey.modificationDate] as? Date |
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.
For us relying on file system modification date here — there's far too many antivirus scanners and cloud storage sync tools that continually just modify large swaths of files for me to be comfortable with this 😕
Maybe our own xattr (extended attribute), could work? I'll try to give some thought to this later…
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.
Thank you for your suggestion @jdhealy 🙇 I updated the code - now we are using custom extended attribute instead of modification date attribute 💪
Could you please have a 👀 🙏
EDIT: Noticed CI job has failed, but it seems like a global issue. It happened for other pull requests as well 🤔
@mollyIV It doesn't look like this PR is building. Do you have time to follow up? |
fc5440d
to
bfca280
Compare
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Hey guys 👋 Any news about a CI issue? 🤔 Could anyone try to re-run it? 🙏 |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
bfca280
to
3796768
Compare
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
👋@Stale, still in review. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
ping stale 🤖 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
ping stale |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
@@ -22,13 +22,12 @@ public struct FetchCache { | |||
lastFetchTimes.removeAll() | |||
} | |||
|
|||
internal static func needsFetch(forURL url: GitURL) -> Bool { | |||
guard let lastFetch = lastFetchTimes[url] else { | |||
internal static func needsFetch(forURL url: GitURL) -> Bool { |
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.
Carthage uses tabs instead of spaces for indentation -- could you please reformat your changes to do the same?
return true | ||
} | ||
|
||
let difference = Date().timeIntervalSince1970 - lastFetch | ||
|
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.
Could you please revert this change?
} | ||
|
||
func extendedAttribute(for name: String) throws -> Data { | ||
let data = try withUnsafeFileSystemRepresentation { path -> Data in |
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.
Curious -- what are your thoughts on using this approach rather than using the methods provided by NSFileManager
? I've never used either personally.
https://developer.apple.com/documentation/foundation/filemanager/1413667-setattributes
https://developer.apple.com/documentation/foundation/filemanager/1410452-attributesofitem
Motivation and Context
carthage outdated --xcode-warnings
(Xcode build phase) command fetches the dependencies each time when executed. In order to improve the performance of the command, we'd like to introduce a new parameterfetch-interval
. This parameter specifies how often the dependencies should be fetched from the remote location. Example usage:fetch-interval
- the minimum amount of time that must elapse between dependencies fetch operation (provided inminutesseconds)#2698
Description
This PR is draft one [WIP]. Kindly ask you to check the review comments🙏EDIT: PR is ready for review 🙏
It's my first Carthage contribution 🎉