-
Notifications
You must be signed in to change notification settings - Fork 822
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
Improve Carthage dependency lookup performance #298
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -681,29 +681,34 @@ public class PBXProjGenerator { | |
return "\(carthagePath)/\(platformName)" | ||
} | ||
|
||
func getAllCarthageDependencies(target: Target, visitedTargets: [String: Bool] = [:]) -> [Dependency] { | ||
|
||
func getAllCarthageDependencies(target: Target) -> [Dependency] { | ||
// this is used to resolve cyclical target dependencies | ||
var visitedTargets = visitedTargets | ||
visitedTargets[target.name] = true | ||
|
||
var visitedTargets: Set<String> = [] | ||
var frameworks: [Dependency] = [] | ||
|
||
for dependency in target.dependencies { | ||
switch dependency.type { | ||
case .carthage: | ||
frameworks.append(dependency) | ||
case .target: | ||
let targetName = dependency.reference | ||
if visitedTargets[targetName] == true { | ||
return [] | ||
} | ||
if let target = project.getTarget(targetName) { | ||
frameworks += getAllCarthageDependencies(target: target, visitedTargets: visitedTargets) | ||
var queue: [Target] = [target] | ||
while !queue.isEmpty { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this traversing the same graph, but just doing it in one function instead of recursively? I think to get this really performant the carthage dependencies for a target could be cached by just running this once for all targets at the beginning, instead of each target going through the whole graph again There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is traversing the same dependencies yes. It should have the exact same result. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could do that, I figured that would be a larger enough change that if we could do this fast enough it's not really worth it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @yonaskolb The recursive version is passing |
||
let target = queue.removeFirst() | ||
if visitedTargets.contains(target.name) { | ||
continue | ||
} | ||
|
||
for dependency in target.dependencies { | ||
switch dependency.type { | ||
case .carthage: | ||
frameworks.append(dependency) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this result in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The carthage dependencies are de-duplicated later on when they are added to a target. This could be done here, but maybe it might be useful at some point to know how many times a dependency is being used |
||
case .target: | ||
if let target = project.getTarget(dependency.reference) { | ||
queue.append(target) | ||
} | ||
default: | ||
break | ||
} | ||
default: break | ||
} | ||
|
||
visitedTargets.update(with: target.name) | ||
} | ||
|
||
return frameworks | ||
} | ||
} | ||
|
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 should be recreated on the
targets
didSet
as wellThere 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.
done, looks like this is only used for tests, seems like we should remove that mutability.
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.
The
ProjectSpec
module can also be used as a framework in other projects.Personally I've never seen the point of making properties on a Struct immutable, as the property referencing that struct can just be a
let
to control the immutability from a single place, while still allowing easy mutability for other cases without reaching into a full blown initializer