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

[Fix] Focus Resources on Tests Targets #3571

Merged
merged 7 commits into from
Oct 22, 2021
Merged

Conversation

fila95
Copy link
Contributor

@fila95 fila95 commented Oct 19, 2021

Resolves #3523

Short description πŸ“

As per title this PR fixes a crash when focusing on a test framework with resources.

Checklist βœ…

  • The code architecture and patterns are consistent with the rest of the codebase.
  • The changes have been tested following the documented guidelines.
  • The CHANGELOG.md has been updated to reflect the changes. In case of a breaking change, it's been flagged as such.
  • In case the PR introduces changes that affect users, the documentation has been updated.

@danieleformichelli
Copy link
Collaborator

LGTM, probably better if @adellibovi and @kwridan have a look as well πŸ‘€

Copy link
Collaborator

@kwridan kwridan left a comment

Choose a reason for hiding this comment

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

Thanks for submitting this @fila95!

I left a small correction, worth re-testing with it. I hope there aren't any other associated regressions built onto of this first one 😞

@@ -457,7 +457,7 @@ final class BuildPhaseGenerator: BuildPhaseGenerating {
.sorted()
var refs = bundles.compactMap { fileElements.product(target: $0.target.name) }

if target.product.runnable {
if target.product.runnable || target.product.testsBundle {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This may not be 100% correct for example command line executable targets are runnable but do not support resources, the determining factor is target.supportsResources.

Another example is dynamic frameworks, they do support embedding resource bundles however they are not runnable, nor test targets.

Looks like this regressed somewhere along the way, here's the original implementation in a past commit for reference:

public func resourceBundleDependencies(path: AbsolutePath, name: String) -> [TargetNode] {

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually let me double check, this may not be the right place for this fix, the GraphTraverser should be able to provide the correct results (comparing with the original implementation) without further filtering.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like GraphTraverser already has the right logic in place

https://github.com/tuist/tuist/blob/main/Sources/TuistCore/Graph/GraphTraverser.swift#L128

@mstfy I spotted those extra bundles being added here

https://github.com/tuist/tuist/pull/3090/files#diff-66a4d5e17e0b57207bebea5937e202078f6ab946d95168850d2215a0f7d429ffR442

Is this needed? it was my understanding GraphTraverser already returned all the resources bundles applicable for the specified target, perhaps I am missing something here?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I am not %100 sure but I think resourceBundleDependencies in GraphTraverser checks the actual targets that can produce resource bundles. They are represented as GraphDependency.target . Precompiled bundles are represented as GraphDependency.bundle . So this check produces false for precompiled bundles:

let isBundle: (GraphDependency) -> Bool = {
    self.target(from: $0)?.target.product == .bundle
}

self.target(from: $0) returns nil for GraphDependency.bundle

That’s why BuildPhaseGenerator adds compiled bundles to copy files build phase

Copy link
Collaborator

@kwridan kwridan Oct 20, 2021

Choose a reason for hiding this comment

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

Thanks for clarifying @mstfy πŸ‘

Indeed it does, I believe we can update GraphTraverser cater for these cases.

Am I correct in my understanding in the cache scenario we have the following setup?

cached-dependencies

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes this should what graph look like after CacheGraphMutator replaces targets with cached artifacts. I think we should further modify graph to add that Resource bundle as direct dependency of the Target.

Copy link
Collaborator

@kwridan kwridan left a comment

Choose a reason for hiding this comment

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

sorry for the hassle - but worth adding a test to the GraphTraverserTests/ BuildPhaseGeneratorTests that mimics the scenario you encountered to help illustrate the issue

@@ -457,7 +457,7 @@ final class BuildPhaseGenerator: BuildPhaseGenerating {
.sorted()
var refs = bundles.compactMap { fileElements.product(target: $0.target.name) }

if target.product.runnable {
if target.product.runnable || target.product.testsBundle {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like GraphTraverser already has the right logic in place

https://github.com/tuist/tuist/blob/main/Sources/TuistCore/Graph/GraphTraverser.swift#L128

@mstfy I spotted those extra bundles being added here

https://github.com/tuist/tuist/pull/3090/files#diff-66a4d5e17e0b57207bebea5937e202078f6ab946d95168850d2215a0f7d429ffR442

Is this needed? it was my understanding GraphTraverser already returned all the resources bundles applicable for the specified target, perhaps I am missing something here?

fila95 and others added 4 commits October 19, 2021 15:13
- The `resourceBundleDependencies` method on `GraphTraverser` now accounts for precompiled (cached) resource bundles
- The logic was previously partly split between the build phase generator and the graph traverser, now it's consolidated within the traverser
- Tests have been extended to account for the precompiled bundle cases
- To support this change, the signature for the `resourceBundleDependencies` needed to be updated to return a `GraphDependencyReference` instead of a `GraphTarget`
  - Tests / Mocks updated accordingly

Test Plan:

- Verify tests pass
- Re-generate the fixture `projects/tuist/fixtures/ios_app_with_framework_and_resources` and verify all the resource bundles match the ones from before these changes
  - Note: due to the type changes, the sort of the resource bundles in the build phase has changed slightly, but it's expected to remain stable
@pepicrft pepicrft merged commit 9348df0 into main Oct 22, 2021
@pepicrft pepicrft deleted the fix/focus-test-frameworks branch October 22, 2021 16:58
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.

[Cache] Focusing on tests of frameworks with resources make the code crash
5 participants