Skip to content

Commit 030dd4e

Browse files
[tool] Fix third_party dependency overrides (#7966)
`made-deps-path-based` would sometimes create invalid relative paths when `third_party/packages` was involved because it was using the sibling directory of `packages` as the base. This updates the logic to always make the paths relative to the repository root; this is often a longer relative path than necessary, but that's harmless, and always using the repo root makes it easier to reason about. Also fixes the fact that paths that were already path based (which is always the case for `some_package/example`'s dependency on `some_package`) were being overridden, causing CI to do some unnecessary duplicate analysis work.
1 parent 4feddff commit 030dd4e

File tree

2 files changed

+78
-19
lines changed

2 files changed

+78
-19
lines changed

script/tool/lib/src/make_deps_path_based_command.dart

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ class MakeDepsPathBasedCommand extends PackageCommand {
153153
return targets;
154154
}
155155

156-
/// If [pubspecFile] has any dependencies on packages in [localDependencies],
157-
/// adds dependency_overrides entries to redirect them to the local version
158-
/// using path-based dependencies.
156+
/// If [pubspecFile] has any non-path dependencies on packages in
157+
/// [localDependencies], adds dependency_overrides entries to redirect them to
158+
/// the local version using path-based dependencies.
159159
///
160160
/// Returns true if any overrides were added.
161161
///
@@ -183,11 +183,13 @@ class MakeDepsPathBasedCommand extends PackageCommand {
183183
final Pubspec pubspec = Pubspec.parse(pubspecContents);
184184
final Iterable<String> combinedDependencies = <String>[
185185
// Filter out any dependencies with version constraint that wouldn't allow
186-
// the target if published.
186+
// the target if published, and anything that is already path-based.
187187
...<MapEntry<String, Dependency>>[
188188
...pubspec.dependencies.entries,
189189
...pubspec.devDependencies.entries,
190190
]
191+
.where((MapEntry<String, Dependency> element) =>
192+
element.value is! PathDependency)
191193
.where((MapEntry<String, Dependency> element) =>
192194
allowsVersion(element.value, versions[element.key]))
193195
.map((MapEntry<String, Dependency> entry) => entry.key),
@@ -205,10 +207,10 @@ class MakeDepsPathBasedCommand extends PackageCommand {
205207
}
206208

207209
// Find the relative path to the common base.
208-
final String commonBasePath = packagesDir.path;
210+
final String repoRootPath = packagesDir.parent.path;
209211
final int packageDepth = path
210-
.split(path.relative(package.directory.absolute.path,
211-
from: commonBasePath))
212+
.split(
213+
path.relative(package.directory.absolute.path, from: repoRootPath))
212214
.length;
213215
final List<String> relativeBasePathComponents =
214216
List<String>.filled(packageDepth, '..');
@@ -223,9 +225,8 @@ class MakeDepsPathBasedCommand extends PackageCommand {
223225
}
224226
for (final String packageName in packagesToOverride) {
225227
// Find the relative path from the common base to the local package.
226-
final List<String> repoRelativePathComponents = path.split(path.relative(
227-
localDependencies[packageName]!.path,
228-
from: commonBasePath));
228+
final List<String> repoRelativePathComponents = path.split(path
229+
.relative(localDependencies[packageName]!.path, from: repoRootPath));
229230
editablePubspec.update(<String>[
230231
dependencyOverridesKey,
231232
packageName
@@ -301,7 +302,7 @@ $dependencyOverridesKey:
301302
if (!package.pubspecFile.existsSync()) {
302303
final String directoryName = p.posix.joinAll(path.split(path.relative(
303304
package.directory.absolute.path,
304-
from: packagesDir.path)));
305+
from: packagesDir.parent.path)));
305306
print(' Skipping $directoryName; deleted.');
306307
continue;
307308
}

script/tool/test/make_deps_path_based_command_test.dart

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,21 @@ void main() {
6464
package.pubspecFile.writeAsStringSync(lines.join('\n'));
6565
}
6666

67+
/// Adds dummy 'dependencies:' entries for each package in [dependencies]
68+
/// to [package], using a path-based dependency.
69+
void addPathDependencies(
70+
RepositoryPackage package, Iterable<String> dependencies,
71+
{required String relativePathBase}) {
72+
final List<String> lines = package.pubspecFile.readAsLinesSync();
73+
final int dependenciesStartIndex = lines.indexOf('dependencies:');
74+
assert(dependenciesStartIndex != -1);
75+
lines.insertAll(dependenciesStartIndex + 1, <String>[
76+
for (final String dependency in dependencies)
77+
' $dependency: { path: $relativePathBase$dependency }',
78+
]);
79+
package.pubspecFile.writeAsStringSync(lines.join('\n'));
80+
}
81+
6782
/// Adds a 'dev_dependencies:' section with entries for each package in
6883
/// [dependencies] to [package].
6984
void addDevDependenciesSection(
@@ -172,15 +187,15 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')}
172187
final Map<String, String?> simplePackageOverrides =
173188
getDependencyOverrides(simplePackage);
174189
expect(simplePackageOverrides.length, 2);
175-
expect(simplePackageOverrides['bar'], '../bar/bar');
190+
expect(simplePackageOverrides['bar'], '../../packages/bar/bar');
176191
expect(simplePackageOverrides['bar_platform_interface'],
177-
'../bar/bar_platform_interface');
192+
'../../packages/bar/bar_platform_interface');
178193

179194
final Map<String, String?> appFacingPackageOverrides =
180195
getDependencyOverrides(pluginAppFacing);
181196
expect(appFacingPackageOverrides.length, 1);
182197
expect(appFacingPackageOverrides['bar_platform_interface'],
183-
'../../bar/bar_platform_interface');
198+
'../../../packages/bar/bar_platform_interface');
184199
});
185200

186201
test('rewrites "dev_dependencies" references', () async {
@@ -205,7 +220,7 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')}
205220
final Map<String, String?> overrides =
206221
getDependencyOverrides(builderPackage);
207222
expect(overrides.length, 1);
208-
expect(overrides['foo'], '../foo');
223+
expect(overrides['foo'], '../../packages/foo');
209224
});
210225

211226
test('rewrites examples when rewriting the main package', () async {
@@ -230,7 +245,8 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')}
230245
final Map<String, String?> exampleOverrides =
231246
getDependencyOverrides(pluginAppFacing.getExamples().first);
232247
expect(exampleOverrides.length, 1);
233-
expect(exampleOverrides['bar_android'], '../../../bar/bar_android');
248+
expect(exampleOverrides['bar_android'],
249+
'../../../../packages/bar/bar_android');
234250
});
235251

236252
test('example overrides include both local and main-package dependencies',
@@ -258,8 +274,24 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')}
258274
final Map<String, String?> exampleOverrides =
259275
getDependencyOverrides(pluginAppFacing.getExamples().first);
260276
expect(exampleOverrides.length, 2);
261-
expect(exampleOverrides['another_package'], '../../../another_package');
262-
expect(exampleOverrides['bar_android'], '../../../bar/bar_android');
277+
expect(exampleOverrides['another_package'],
278+
'../../../../packages/another_package');
279+
expect(exampleOverrides['bar_android'],
280+
'../../../../packages/bar/bar_android');
281+
});
282+
283+
test('does not rewrite path-based dependencies that are already path based',
284+
() async {
285+
final RepositoryPackage package = createFakePlugin('foo', packagesDir);
286+
final RepositoryPackage example = package.getExamples().first;
287+
addPathDependencies(example, <String>['foo'], relativePathBase: '../');
288+
289+
await runCapturingPrint(
290+
runner, <String>['make-deps-path-based', '--target-dependencies=foo']);
291+
292+
final Map<String, String?> exampleOverrides =
293+
getDependencyOverrides(example);
294+
expect(exampleOverrides.length, 0);
263295
});
264296

265297
test(
@@ -317,6 +349,32 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')}
317349
expect(simplePackageOverrides['bar'], '../../third_party/packages/bar');
318350
});
319351

352+
test('handles third_party target package references in third_party',
353+
() async {
354+
createFakePackage('bar', thirdPartyPackagesDir, isFlutter: true);
355+
final RepositoryPackage otherThirdPartyPackge =
356+
createFakePlugin('foo', thirdPartyPackagesDir);
357+
358+
addDependencies(otherThirdPartyPackge, <String>[
359+
'bar',
360+
]);
361+
362+
final List<String> output = await runCapturingPrint(
363+
runner, <String>['make-deps-path-based', '--target-dependencies=bar']);
364+
365+
expect(
366+
output,
367+
containsAll(<String>[
368+
'Rewriting references to: bar...',
369+
' Modified third_party/packages/foo/pubspec.yaml',
370+
]));
371+
372+
final Map<String, String?> simplePackageOverrides =
373+
getDependencyOverrides(otherThirdPartyPackge);
374+
expect(simplePackageOverrides.length, 1);
375+
expect(simplePackageOverrides['bar'], '../../../third_party/packages/bar');
376+
});
377+
320378
// This test case ensures that running CI using this command on an interim
321379
// PR that itself used this command won't fail on the rewrite step.
322380
test('running a second time no-ops without failing', () async {
@@ -420,7 +478,7 @@ ${devDependencies.map((String dep) => ' $dep: $constraint').join('\n')}
420478
expect(
421479
output,
422480
containsAllInOrder(<Matcher>[
423-
contains('Skipping foo; deleted.'),
481+
contains('Skipping packages/foo; deleted.'),
424482
contains('No target dependencies'),
425483
]),
426484
);

0 commit comments

Comments
 (0)