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

feat: Common dependency overrides #594

Closed
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/commands/bootstrap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ your `melos.yaml` exists in a package, the dependency version in this
package will be updated to match the version defined in your
bootstrap config every time `melos bootstrap` is run.

When there's a need to override the dependency_overrides
specified in a package's pubspec.yaml, use dependency_overrides in Melos' configuration.
This allows you to specify different package versions than those defined in the package's
own dependency overrides. This is especially useful for situations where you're actively
developing a package that relies on a path dependency not present in the main project.
Heinrich-vanNieuwenhuizen marked this conversation as resolved.
Show resolved Hide resolved

```yaml
# melos.yaml
# ...
Expand All @@ -118,6 +124,10 @@ command:

dev_dependencies:
build_runner: ^2.3.3

dependency_overrides:
Heinrich-vanNieuwenhuizen marked this conversation as resolved.
Show resolved Hide resolved
provider:
git: https://github.com/rrousselGit/provider.git
# ...
```

Expand Down
14 changes: 13 additions & 1 deletion packages/melos/lib/src/commands/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ mixin _BootstrapMixin on _CleanMixin {
try {
if (bootstrapCommandConfig.environment != null ||
bootstrapCommandConfig.dependencies != null ||
bootstrapCommandConfig.devDependencies != null) {
bootstrapCommandConfig.devDependencies != null ||
bootstrapCommandConfig.dependencyOverrides != null) {
final filteredPackages = workspace.filteredPackages.values;
await Stream.fromIterable(filteredPackages).parallel((package) {
return _setSharedDependenciesForPackage(
package,
environment: bootstrapCommandConfig.environment,
dependencies: bootstrapCommandConfig.dependencies,
devDependencies: bootstrapCommandConfig.devDependencies,
dependencyOverrides: bootstrapCommandConfig.dependencyOverrides,
);
}).drain<void>();
}
Expand Down Expand Up @@ -219,6 +221,7 @@ mixin _BootstrapMixin on _CleanMixin {
required Environment? environment,
required Map<String, DependencyReference>? dependencies,
required Map<String, DependencyReference>? devDependencies,
required Map<String, DependencyReference>? dependencyOverrides,
}) async {
final packagePubspecFile = utils.pubspecPathForDirectory(package.path);
final packagePubspecContents = await readTextFileAsync(packagePubspecFile);
Expand All @@ -244,6 +247,13 @@ mixin _BootstrapMixin on _CleanMixin {
pubspecKey: 'dev_dependencies',
);

final updatedDependencyOverridesCount = _updateDependencies(
pubspecEditor: pubspecEditor,
workspaceDependencies: dependencyOverrides,
packageDependencies: package.pubSpec.dependencyOverrides,
pubspecKey: 'dependency_overrides',
);

if (pubspecEditor.edits.isNotEmpty) {
await writeTextFileAsync(
packagePubspecFile,
Expand All @@ -256,6 +266,8 @@ mixin _BootstrapMixin on _CleanMixin {
'Updated $updatedDependenciesCount dependencies',
if (updatedDevDependenciesCount > 0)
'Updated $updatedDevDependenciesCount dev_dependencies',
if (updatedDependencyOverridesCount > 0)
'Updated $updatedDependencyOverridesCount dependency_overrides',
];
if (message.isNotEmpty) {
logger
Expand Down
23 changes: 23 additions & 0 deletions packages/melos/lib/src/workspace_configs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ class BootstrapCommandConfigs {
this.environment,
this.dependencies,
this.devDependencies,
this.dependencyOverrides,
this.dependencyOverridePaths = const [],
this.hooks = LifecycleHooks.empty,
});
Expand Down Expand Up @@ -408,6 +409,16 @@ class BootstrapCommandConfigs {
),
);

final dependencyOverrides = assertKeyIsA<Map<Object?, Object?>?>(
key: 'dependency_overrides',
map: yaml,
)?.map(
(key, value) => MapEntry(
key.toString(),
DependencyReference.fromJson(value),
),
);

final dependencyOverridePaths = assertListIsA<String>(
key: 'dependencyOverridePaths',
map: yaml,
Expand All @@ -434,6 +445,7 @@ class BootstrapCommandConfigs {
environment: environment,
dependencies: dependencies,
devDependencies: devDependencies,
dependencyOverrides: dependencyOverrides,
dependencyOverridePaths: dependencyOverridePaths
.map(
(override) =>
Expand Down Expand Up @@ -466,6 +478,9 @@ class BootstrapCommandConfigs {
/// Dev dependencies to be synced between all packages.
final Map<String, DependencyReference>? devDependencies;

/// Dependency overrides to be synced between all packages.
final Map<String, DependencyReference>? dependencyOverrides;

/// A list of [Glob]s for paths that contain packages to be used as dependency
/// overrides for all packages managed in the Melos workspace.
final List<Glob> dependencyOverridePaths;
Expand All @@ -486,6 +501,10 @@ class BootstrapCommandConfigs {
'dev_dependencies': devDependencies!.map(
(key, value) => MapEntry(key, value.toJson()),
),
if (dependencyOverrides != null)
'dependency_overrides': dependencyOverrides!.map(
(key, value) => MapEntry(key, value.toJson()),
),
if (dependencyOverridePaths.isNotEmpty)
'dependencyOverridePaths':
dependencyOverridePaths.map((path) => path.toString()).toList(),
Expand All @@ -508,6 +527,8 @@ class BootstrapCommandConfigs {
const DeepCollectionEquality().equals(other.dependencies, dependencies) &&
const DeepCollectionEquality()
.equals(other.devDependencies, devDependencies) &&
const DeepCollectionEquality()
.equals(other.dependencyOverrides, dependencyOverrides) &&
const DeepCollectionEquality(_GlobEquality())
.equals(other.dependencyOverridePaths, dependencyOverridePaths) &&
other.hooks == hooks;
Expand All @@ -525,6 +546,7 @@ class BootstrapCommandConfigs {
) ^
const DeepCollectionEquality().hash(dependencies) ^
const DeepCollectionEquality().hash(devDependencies) ^
const DeepCollectionEquality().hash(dependencyOverrides) ^
const DeepCollectionEquality(_GlobEquality())
.hash(dependencyOverridePaths) ^
hooks.hashCode;
Expand All @@ -538,6 +560,7 @@ BootstrapCommandConfigs(
environment: $environment,
dependencies: $dependencies,
devDependencies: $devDependencies,
dependencyOverrides: $dependencyOverrides,
dependencyOverridePaths: $dependencyOverridePaths,
hooks: $hooks,
)''';
Expand Down
97 changes: 97 additions & 0 deletions packages/melos/test/commands/bootstrap_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,26 @@ Generating IntelliJ IDE files...
'path': HostedReference(
VersionConstraint.compatibleWith(Version.parse('1.8.3')),
),
'provider': HostedReference(
VersionConstraint.compatibleWith(Version.parse('6.0.5')),
),
'photo_view': HostedReference(
VersionConstraint.compatibleWith(Version.parse('0.14.0')),
),
},
devDependencies: {
'build_runner': HostedReference(
VersionConstraint.compatibleWith(Version.parse('2.4.6')),
),
},
dependencyOverrides: const {
'provider': GitReference(
'https://github.com/rrousselGit/provider.git',
),
'photo_view': GitReference(
'https://github.com/bluefireteam/photo_view.git',
),
},
),
),
path: path,
Expand Down Expand Up @@ -647,6 +661,14 @@ Generating IntelliJ IDE files...
VersionConstraint.compatibleWith(Version.parse('2.4.0')),
),
},
dependencyOverrides: {
'provider': HostedReference(
VersionConstraint.compatibleWith(Version.parse('6.0.5')),
),
'photo_view': HostedReference(
VersionConstraint.compatibleWith(Version.parse('0.14.0')),
),
},
),
);

Expand All @@ -672,10 +694,54 @@ Generating IntelliJ IDE files...
VersionConstraint.compatibleWith(Version.parse('0.17.0')),
),
'path': HostedReference(VersionConstraint.any),
'provider': HostedReference(VersionConstraint.any),
'photo_view': HostedReference(VersionConstraint.any),
},
dependencyOverrides: const {
'provider': PathReference('provider'),
'photo_view': PathReference('photo_view'),
},
),
);

//create provider package
await createProject(
workspaceDir,
PubSpec(
name: 'provider',
environment: Environment(
VersionRange(
min: Version.parse('2.12.0'),
max: Version.parse('3.0.0'),
includeMin: true,
),
{
'flutter': '>=2.12.0 <3.0.0',
},
),
),
path: p.join(pkgB.path, 'provider'),
);

//create photo_view package
await createProject(
workspaceDir,
PubSpec(
name: 'photo_view',
environment: Environment(
VersionRange(
min: Version.parse('2.12.0'),
max: Version.parse('3.0.0'),
includeMin: true,
),
{
'flutter': '>=2.12.0 <3.0.0',
},
),
),
path: p.join(pkgB.path, 'photo_view'),
);

final logger = TestLogger();
final config =
await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir);
Expand Down Expand Up @@ -717,6 +783,18 @@ Generating IntelliJ IDE files...
}),
);

expect(
pubspecA.dependencyOverrides,
equals({
'provider': const GitReference(
'https://github.com/rrousselGit/provider.git',
),
'photo_view': const GitReference(
'https://github.com/bluefireteam/photo_view.git',
),
}),
);

expect(
pubspecB.environment?.sdkConstraint,
equals(VersionConstraint.parse('>=2.18.0 <3.0.0')),
Expand All @@ -737,12 +815,31 @@ Generating IntelliJ IDE files...
'path': HostedReference(
VersionConstraint.compatibleWith(Version.parse('1.8.3')),
),
'provider': HostedReference(
VersionConstraint.compatibleWith(Version.parse('6.0.5')),
),
'photo_view': HostedReference(
VersionConstraint.compatibleWith(Version.parse('0.14.0')),
),
}),
);

expect(
pubspecB.devDependencies,
equals({}),
);

expect(
pubspecB.dependencyOverrides,
equals({
'provider': const GitReference(
'https://github.com/rrousselGit/provider.git',
),
'photo_view': const GitReference(
'https://github.com/bluefireteam/photo_view.git',
),
}),
);
},
timeout: const Timeout(Duration(days: 2)),
);
Expand Down
Loading