From c3dfecd7af770e81090c3686bbdba469e0322169 Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Thu, 21 Nov 2024 12:09:41 +0100 Subject: [PATCH] fix: Simple hosted dependencies should be inlined --- .../lib/src/common/extensions/dependency.dart | 32 +++++++---- .../melos/test/commands/bootstrap_test.dart | 54 ++++++++++++++++++- packages/melos/test/utils.dart | 4 ++ 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/packages/melos/lib/src/common/extensions/dependency.dart b/packages/melos/lib/src/common/extensions/dependency.dart index 42c61329..c5eb45f6 100644 --- a/packages/melos/lib/src/common/extensions/dependency.dart +++ b/packages/melos/lib/src/common/extensions/dependency.dart @@ -9,6 +9,18 @@ extension DependencyExtension on Dependency { return null; } + /// Whether the json can be inlined with its parent. + /// + /// For example for [HostedDependency] the version shouldn't be on a separate + /// line when only the version is defined. + bool get inlineVersion { + if (this is HostedDependency) { + return (this as HostedDependency).hosted == null && + versionConstraint != null; + } + return false; + } + Object toJson() { final self = this; if (self is PathDependency) { @@ -34,15 +46,17 @@ extension PathDependencyExtension on PathDependency { } extension HostedDependencyExtension on HostedDependency { - Map toJson() { - return { - 'version': version.toString(), - if (hosted != null) - 'hosted': { - 'name': hosted!.declaredName, - 'url': hosted!.url?.toString(), - }, - }; + Object toJson() { + return inlineVersion + ? version.toString() + : { + 'version': version.toString(), + if (hosted != null) + 'hosted': { + 'name': hosted!.declaredName, + 'url': hosted!.url?.toString(), + }, + }; } } diff --git a/packages/melos/test/commands/bootstrap_test.dart b/packages/melos/test/commands/bootstrap_test.dart index 34d4dd6b..f17e2664 100644 --- a/packages/melos/test/commands/bootstrap_test.dart +++ b/packages/melos/test/commands/bootstrap_test.dart @@ -4,11 +4,13 @@ import 'package:melos/melos.dart'; import 'package:melos/src/command_configs/command_configs.dart'; import 'package:melos/src/commands/runner.dart'; import 'package:melos/src/common/glob.dart'; +import 'package:melos/src/common/io.dart'; import 'package:melos/src/common/utils.dart'; import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:test/test.dart'; +import 'package:yaml/yaml.dart'; import '../matchers.dart'; import '../utils.dart'; @@ -745,7 +747,7 @@ Generating IntelliJ IDE files... }); test( - 'applies dependencies from melos config', + 'applies shared dependencies from melos config', () async { final workspaceDir = await createTemporaryWorkspace( configBuilder: (path) => MelosWorkspaceConfig( @@ -910,6 +912,51 @@ Generating IntelliJ IDE files... }, timeout: const Timeout(Duration(days: 2)), ); + + test('correctly inlines shared dependencies', () async { + final workspaceDir = await createTemporaryWorkspace( + configBuilder: (path) => MelosWorkspaceConfig.fromYaml( + createYamlMap( + { + 'command': { + 'bootstrap': { + 'dependencies': { + 'flame': '^1.21.0', + }, + }, + }, + }, + defaults: configMapDefaults, + ), + path: path, + ), + ); + + final pkgA = await createProject( + workspaceDir, + Pubspec( + 'a', + dependencies: { + 'flame': HostedDependency(version: VersionConstraint.any), + }, + ), + ); + + final logger = TestLogger(); + final config = await MelosWorkspaceConfig.fromWorkspaceRoot(workspaceDir); + final melos = Melos( + logger: logger, + config: config, + ); + + await runMelosBootstrap(melos, logger); + + final pubspecContent = _pubspecContent(pkgA); + expect( + (pubspecContent['dependencies']! as YamlMap)['flame'], + '^1.21.0', + ); + }); }); group('melos bs --skip-linking', () { @@ -1142,3 +1189,8 @@ Future dependencyResolutionTest( await Future.wait(packages.keys.map(validatePackage)); } + +YamlMap _pubspecContent(io.Directory directory) { + final source = readTextFile(pubspecPath(directory.path)); + return loadYaml(source) as YamlMap; +} diff --git a/packages/melos/test/utils.dart b/packages/melos/test/utils.dart index 1116cd1a..0e10f0d8 100644 --- a/packages/melos/test/utils.dart +++ b/packages/melos/test/utils.dart @@ -219,6 +219,10 @@ String packageConfigPath(String packageRoot) { ); } +String pubspecPath(String directory) { + return p.join(directory, 'pubspec.yaml'); +} + PackageConfig packageConfigForPackageAt(Directory dir) { final source = readTextFile(packageConfigPath(dir.path)); return PackageConfig.fromJson(json.decode(source) as Map);