Don't use the glob mechanism to parse pre-glob workspace entries (#4711)
diff --git a/lib/src/package.dart b/lib/src/package.dart index 88658d6..6dc6711 100644 --- a/lib/src/package.dart +++ b/lib/src/package.dart
@@ -178,37 +178,46 @@ final workspacePackages = pubspec.workspace.expand((workspacePath) { - final Glob glob; - try { - glob = Glob( - pubspec.languageVersion.supportsWorkspaceGlobs - ? workspacePath - : Glob.quote(workspacePath), - ); - } on FormatException catch (e) { - fail('Failed to parse glob `$workspacePath`. $e'); - } final packages = <Package>[]; - for (final globResult in glob.listSync(root: dir)) { - final pubspecPath = p.join(globResult.path, 'pubspec.yaml'); - if (!fileExists(pubspecPath)) continue; - packages.add( - Package.load( - globResult.path, - loadPubspec: loadPubspec, - withPubspecOverrides: withPubspecOverrides, - ), - ); - } - if (packages.isEmpty) { - final globHint = - !pubspec.languageVersion.supportsWorkspaceGlobs && - _looksLikeGlob(workspacePath) - ? ''' + var globHint = ''; + if (pubspec.languageVersion.supportsWorkspaceGlobs) { + final Glob glob; + try { + glob = Glob(workspacePath); + } on FormatException catch (e) { + fail('Failed to parse glob `$workspacePath`. $e'); + } + for (final globResult in glob.listSync(root: dir)) { + final pubspecPath = p.join(globResult.path, 'pubspec.yaml'); + if (!fileExists(pubspecPath)) continue; + packages.add( + Package.load( + globResult.path, + loadPubspec: loadPubspec, + withPubspecOverrides: withPubspecOverrides, + ), + ); + } + } else { + final pubspecPath = p.join(dir, workspacePath, 'pubspec.yaml'); + if (!fileExists(pubspecPath)) { + if (_looksLikeGlob(workspacePath)) { + globHint = ''' \n\nGlob syntax is only supported from language version ${LanguageVersion.firstVersionWithWorkspaceGlobs}. Consider changing the language version of ${p.join(dir, 'pubspec.yaml')} to ${LanguageVersion.firstVersionWithWorkspaceGlobs}. -''' - : ''; +'''; + } + } else { + packages.add( + Package.load( + p.join(dir, _useBackSlashesOnWindows(workspacePath)), + loadPubspec: loadPubspec, + withPubspecOverrides: withPubspecOverrides, + ), + ); + } + } + if (packages.isEmpty) { fail(''' No workspace packages matching `$workspacePath`. That was included in the workspace of `${p.join(dir, 'pubspec.yaml')}`.$globHint @@ -574,3 +583,9 @@ } bool _looksLikeGlob(String s) => Glob.quote(s) != s; +String _useBackSlashesOnWindows(String path) { + if (Platform.isWindows) { + return p.joinAll(p.split(path)); + } + return path; +}
diff --git a/test/workspace_test.dart b/test/workspace_test.dart index fd060c0..2d33bf3 100644 --- a/test/workspace_test.dart +++ b/test/workspace_test.dart
@@ -1892,6 +1892,29 @@ skip: Platform.isWindows, // Cannot create directory named "*" on Windows. ); + test('preglob workspace entries can use the platform separator', () async { + await dir(appPath, [ + libPubspec( + 'myapp', + '1.2.3', + extras: { + 'workspace': [p.join('pkgs', 'foo')], + }, + sdk: '^3.6.0', + ), + dir('pkgs', [ + dir('foo', [libPubspec('foo', '1.1.1', resolutionWorkspace: true)]), + ]), + ]).create(); + await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '3.11.0'}); + await dir(appPath, [ + packageConfigFile([ + packageConfigEntry(name: 'myapp', path: '.'), + packageConfigEntry(name: 'foo', path: 'pkgs/foo'), + ], generatorVersion: '3.11.0'), + ]).validate(); + }); + test('globs are resolved with newer language versions', () async { await dir(appPath, [ libPubspec(