diff --git a/script/tool/lib/src/make_deps_path_based_command.dart b/script/tool/lib/src/make_deps_path_based_command.dart index 701cc7512e9..46d46920859 100644 --- a/script/tool/lib/src/make_deps_path_based_command.dart +++ b/script/tool/lib/src/make_deps_path_based_command.dart @@ -236,7 +236,10 @@ class MakeDepsPathBasedCommand extends PackageCommand { // Find the relative path from the common base to the local package. final List repoRelativePathComponents = path.split( - path.relative(localDependencies[packageName]!.path, from: repoRootPath), + path.relative( + localDependencies[packageName]!.directory.absolute.path, + from: repoRootPath, + ), ); final String pathValue = p.posix.joinAll([ ...relativeBasePathComponents, @@ -272,11 +275,14 @@ ${newOverrideLines.join('\n')} // example app doesn't. Since integration tests are run in the example app, // it needs the overrides in order for tests to pass. for (final RepositoryPackage example in package.getExamples()) { + final String parentPackageName = package.parsePubspec().name; await _addDependencyOverridesIfNecessary( example, - localDependencies, + {...localDependencies, parentPackageName: package}, versions, - additionalPackagesToOverride: packagesToOverride, + // Add an override to the parent package in case a transitive dependency has a dependency on it, + // since that (non-path) dependency would conflict with the path-based dependency in the example. + additionalPackagesToOverride: {...packagesToOverride, parentPackageName}, ); } diff --git a/script/tool/test/make_deps_path_based_command_test.dart b/script/tool/test/make_deps_path_based_command_test.dart index d1e99d17a24..c1ca53fa4e9 100644 --- a/script/tool/test/make_deps_path_based_command_test.dart +++ b/script/tool/test/make_deps_path_based_command_test.dart @@ -226,7 +226,8 @@ ${overrides.map((String dep) => ' $dep:\n path: $path').join('\n')} final Map exampleOverrides = getDependencyOverrides( pluginAppFacing.getExamples().first, ); - expect(exampleOverrides.length, 1); + expect(exampleOverrides.length, 2); + expect(exampleOverrides['bar'], '../../../../packages/bar/bar'); expect(exampleOverrides['bar_android'], '../../../../packages/bar/bar_android'); }); @@ -248,8 +249,9 @@ ${overrides.map((String dep) => ' $dep:\n path: $path').join('\n')} final Map exampleOverrides = getDependencyOverrides( pluginAppFacing.getExamples().first, ); - expect(exampleOverrides.length, 2); + expect(exampleOverrides.length, 3); expect(exampleOverrides['another_package'], '../../../../packages/another_package'); + expect(exampleOverrides['bar'], '../../../../packages/bar/bar'); expect(exampleOverrides['bar_android'], '../../../../packages/bar/bar_android'); }); @@ -264,6 +266,50 @@ ${overrides.map((String dep) => ' $dep:\n path: $path').join('\n')} expect(exampleOverrides.length, 0); }); + test( + 'example overrides include parent package to resolve dependency overrides cleanly', + () async { + createFakePackage('material_ui', packagesDir); + final RepositoryPackage cupertinoUi = createFakePlugin('cupertino_ui', packagesDir); + + addDevDependenciesSection(cupertinoUi, ['material_ui']); + + await runCapturingPrint(runner, [ + 'make-deps-path-based', + '--target-dependencies=material_ui', + ]); + + final Map exampleOverrides = getDependencyOverrides( + cupertinoUi.getExamples().first, + ); + expect(exampleOverrides['material_ui'], '../../../packages/material_ui'); + expect(exampleOverrides['cupertino_ui'], '../../../packages/cupertino_ui'); + }, + ); + + test( + 'does not recursively override dependencies of target packages to preserve safety net', + () async { + final RepositoryPackage clientPkg = createFakePackage('pkg_client', packagesDir); + final RepositoryPackage targetPkg = createFakePackage('pkg_target', packagesDir); + createFakePackage('pkg_dependency', packagesDir); + + addDependencies(clientPkg, ['pkg_target', 'pkg_dependency']); + addDependencies(targetPkg, ['pkg_dependency']); + + await runCapturingPrint(runner, [ + 'make-deps-path-based', + '--target-dependencies=pkg_target', + ]); + + final Map clientOverrides = getDependencyOverrides(clientPkg); + expect(clientOverrides['pkg_target'], '../../packages/pkg_target'); + // Dependencies of target packages must not be recursively pathified, + // ensuring clients are tested against published versions to preserve safety. + expect(clientOverrides['pkg_dependency'], isNull); + }, + ); + test( 'alphabetizes overrides from different sections to avoid lint warnings in analysis', () async {