-
Notifications
You must be signed in to change notification settings - Fork 28.5k
SPM migrator should exit when unmigrated custom targets are found #165115
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
base: master
Are you sure you want to change the base?
SPM migrator should exit when unmigrated custom targets are found #165115
Conversation
final int packageProductDependenciesIndex = lines.indexWhere( | ||
(String line) => line.trim().contains('packageProductDependencies'), | ||
runnerNativeTargetStartIndex, | ||
lines.insertAll(nativeTargetStartIndex + 1, newContent); |
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 used an early return to avoid the else here, hence the odd diff.
|
||
if (applicationNativeTargets.isEmpty) { | ||
throw Exception( | ||
'Unable to find parsed PBXNativeTargets for ${_xcodeProject.hostAppProjectName} project.', |
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 old code had target.
at the end, but that is a bit misleading. It's the Runner
project that has N Targets.
Because the migrator now handles multiple Targets, it gets more confusing so I updated it here to rectify that.
if (packageProductDependenciesIndex == -1 || | ||
packageProductDependenciesIndex > endSectionIndex) { | ||
throw Exception( | ||
'Unable to find packageProductDependencies for ${_xcodeProject.hostAppProjectName} PBXNativeTarget.', |
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.
Should we use the name of the affected target? I also saw that there isn't an existing test for this throw statement. I guess this cannot really happen since the nativeTarget.packageProductDependencies
are not null at this point?
if (packageProductDependenciesIndex == -1 || | ||
packageProductDependenciesIndex > endSectionIndex) { | ||
throw Exception( | ||
'Unable to find packageProductDependencies for $pbxTargetName in ${_xcodeProject.hostAppProjectName} project.', |
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.
Added the name of the affected target + clarifying that hostAppProjectName is the project
/// - The migrator is rerun through the flutter CLI upon executing `flutter run` | ||
/// - The migrator should skip sections like 'PBXBuildFile' or 'XCSwiftPackageProductDependency', | ||
/// since they are already migrated | ||
void _ensureNewIdentifiersNotUsed(List<String> lines) { |
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.
When adding the missing check for already migrated targets back, I encountered an issue:
The _ensureNewIdentifiersNotUsed
is too conservative with its checks.
So I had to fix this by allowing the identifiers in the sections where these might occur after the migrator ran once. This enables the migrator to run again when additional application targets are added.
I'm not sure if there is a better solution to this issue?
/// Returns false if the [identifier] does not occur in the given [lines]. | ||
/// Returns false if the [identifier] only occurs within the sections denoted by the [sectionNames]. | ||
/// Returns true otherwise. | ||
bool _isIdentifierOutsideAllowedSections( |
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 is used by the new duplicate identifier check
@@ -671,6 +744,57 @@ void main() { | |||
expect(testLogger.traceText, contains('project.pbxproj already migrated. Skipping...')); | |||
}); | |||
|
|||
testWithoutContext('skips PBXNativeTarget migration if all targets are migrated', () async { |
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.
There was no "skip" test for when the Runner target was already migrated. This is one of several new tests to cover that.
@@ -2980,15 +3272,16 @@ String migratedNativeTargetSection( | |||
SupportedPlatform platform, { | |||
bool missingPackageProductDependencies = false, | |||
bool withOtherDependency = false, | |||
String? otherNativeTarget, |
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 updated this method to allow for inserting an additional PBXNativeTarget. To keep the readability for the Runner target, I went with a StringBuffer, to allow for splitting it up, while preserving the sections.
/// A variant of [migratedNativeTargetSection] | ||
/// that includes an additional PBXNativeTarget, "OtherTarget", that is not migrated. | ||
String migratedRunnerWithUnmigratedOtherTargetSection(SupportedPlatform platform) { | ||
final String otherTarget = <String>[ |
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 only added this target for an iOS specific test. Not sure if we need a MacOS variant also? The only real difference is the identifiers being slightly different.
@@ -671,6 +755,183 @@ void main() { | |||
expect(testLogger.traceText, contains('project.pbxproj already migrated. Skipping...')); | |||
}); | |||
|
|||
testWithoutContext('skips Runner PBXNativeTarget migration if already migrated', () async { |
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.
There was no test that verified that the migrator could skip the PBXNativeTargets, so I added some for good measure.
expect(testLogger.traceText, contains('PBXNativeTargets already migrated. Skipping...')); | ||
}); | ||
|
||
testWithoutContext( |
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 is a variant of the test above, but with an extra custom target
Done! |
Edit: It seems we only need some extra handling for the There is one failing set of tests, but that is because the Flutter tool itself also provides custom targets & schemes.
|
); | ||
} | ||
|
||
bool _isNotATestingNativeTarget(ParsedNativeTarget target) { |
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 check should help with the failures for the RunnerTests target.
IIRC the migrator previously didn't do anything for that type of target, so I think we can exclude testing targets from the migrator?
@@ -294,7 +331,7 @@ class SwiftPackageManagerIntegrationMigration extends ProjectMigrator { | |||
<EnvironmentBuildable> | |||
<BuildableReference | |||
BuildableIdentifier = "primary" | |||
BlueprintIdentifier = "$_runnerNativeTargetIdentifier" | |||
BlueprintIdentifier = "$blueprintIdentifier" |
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.
Undo, we only will ever insert the $_runnerNativeTargetIdentifier
.
index = lineIndex; | ||
break; | ||
} | ||
} |
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 may match on the wrong Blueprint Identifier.
For example, when I change the target of my scheme, $_runnerNativeTargetIdentifier
is the first BlueprintIdentifier
found in the scheme file, but now buildForRunning
equals NO
.
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "788C022D2DA97110009DD71A"
BuildableName = "NEW_TARGET.app"
BlueprintName = "NEW_TARGET"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
...
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.
Since the scheme file is XML, I think it would be better to use XmlDocument.parse
to try and figure this out.
So steps would be
- Parse the XML
- Check if the LaunchAction > BuildableProductRunnable > BuildableReference matches
_runnerNativeTargetIdentifier
, if not throw an error. Otherwise, get the BuildableName, BlueprintName, ReferencedContainer
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.
Shouldn't all changes below this point be removed since we're not migrating any custom targets?
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.
You're right about that, we're only supposed to detect the custom targets in the pbxproj, not the active xcscheme file.
And good point about using the XML parser, no need to reinvent the wheel.
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.
Done!
$buildableName | ||
$blueprintName | ||
$referencedContainer | ||
BuildableName = "$buildableName" |
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.
Since the BlueprintIdentifier
attribute also keeps the XML attribute in the template, I opted for doing that for the others also.
This PR updates the Swift Package Manager project migrator to detect when custom targets are used and exits with a message pointing to the docs, if any of the custom targets are not migrated yet.
I also found some discrepancies in the wording around when a reference in the pbxproj is for the project or a native target.
That has been corrected in this PR as well.
Fixes #164099
If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].
Pre-launch Checklist
///
).