Skip to content

Commit 735f58b

Browse files
authored
fix: Make serverpod generate compatible with workspaces. (serverpod#3403)
1 parent d974e8a commit 735f58b

File tree

9 files changed

+790
-24
lines changed

9 files changed

+790
-24
lines changed

templates/pubspecs/tools/serverpod_cli/pubspec.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dependencies:
1919
recase: ^4.1.0
2020
built_collection: ^5.1.1
2121
package_config: ^2.1.0
22-
pubspec_parse: ^1.2.2
22+
pubspec_parse: ^1.4.0
2323
source_span: ^1.10.0
2424
super_string: ^1.0.3
2525
watcher: ^1.0.2
@@ -43,6 +43,7 @@ dev_dependencies:
4343
serverpod_lints: SERVERPOD_VERSION
4444
term_glyph: ^1.2.2
4545
test: ^1.24.2
46+
test_descriptor: ^2.0.2
4647

4748
dependency_overrides:
4849
serverpod_shared:

tools/serverpod_cli/lib/src/config/config.dart

+1
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ class GeneratorConfig implements ModelLoadConfig {
337337

338338
var modules = loadModuleConfigs(
339339
packageConfig: packageConfig,
340+
projectPubspec: pubspec,
340341
nickNameOverrides: manualModules,
341342
);
342343

tools/serverpod_cli/lib/src/util/locate_modules.dart

+89-22
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,117 @@
1+
import 'dart:collection';
12
import 'dart:io';
23

34
import 'package:package_config/package_config.dart';
45
import 'package:path/path.dart' as path;
6+
import 'package:pubspec_parse/pubspec_parse.dart';
57
import 'package:serverpod_cli/src/config/config.dart';
8+
import 'package:serverpod_cli/src/util/pubspec_helpers.dart';
69
import 'package:serverpod_shared/serverpod_shared.dart';
710
import 'package:yaml/yaml.dart';
811

912
const _serverSuffix = '_server';
1013

14+
bool _isServerpodModule(String packageName) {
15+
return packageName.endsWith(_serverSuffix) || packageName == 'serverpod';
16+
}
17+
1118
List<ModuleConfig> loadModuleConfigs({
19+
required Pubspec projectPubspec,
1220
required PackageConfig packageConfig,
1321
Map<String, String?> nickNameOverrides = const {},
1422
}) {
15-
var modules = <ModuleConfig>[];
23+
var projectModuleDependencies = _listModuleDependencies(
24+
projectPubspec: projectPubspec,
25+
packageConfig: packageConfig,
26+
);
1627

17-
for (var packageInfo in packageConfig.packages) {
18-
try {
19-
var packageName = packageInfo.name;
28+
var moduleConfigs = _loadModuleConfigs(
29+
modules: projectModuleDependencies,
30+
nickNameOverrides: nickNameOverrides,
31+
);
32+
33+
return moduleConfigs;
34+
}
2035

21-
if (!packageName.endsWith(_serverSuffix) && packageName != 'serverpod') {
36+
Set<Package> _listModuleDependencies({
37+
required Pubspec projectPubspec,
38+
required PackageConfig packageConfig,
39+
}) {
40+
var projectModuleDependencies = <Package>{};
41+
var visitedModules = <String>{};
42+
var foundModules = Queue<String>();
43+
44+
void queueModulesInPubspec(Pubspec projectPubspec) {
45+
for (var dependencyName in projectPubspec.dependencies.keys) {
46+
if (!_isServerpodModule(dependencyName)) {
2247
continue;
2348
}
2449

25-
var packageSrcRoot = packageInfo.packageUriRoot;
26-
var moduleProjectRoot = List<String>.from(packageSrcRoot.pathSegments)
27-
..removeLast()
28-
..removeLast();
29-
var generatorConfigSegments = path
30-
.joinAll([...moduleProjectRoot, 'config', 'generator.yaml']).split(
31-
path.separator);
50+
foundModules.add(dependencyName);
51+
}
52+
}
53+
54+
queueModulesInPubspec(projectPubspec);
55+
56+
while (foundModules.isNotEmpty) {
57+
var moduleName = foundModules.removeFirst();
58+
if (visitedModules.contains(moduleName)) {
59+
continue;
60+
}
61+
62+
visitedModules.add(moduleName);
63+
64+
var packageInfo = packageConfig.packages
65+
.where((pkg) => pkg.name == moduleName)
66+
.firstOrNull;
67+
68+
if (packageInfo == null) {
69+
throw ServerpodModulesNotFoundException(
70+
'Failed to locate module dependency path in package config for '
71+
'dependency: $moduleName',
72+
);
73+
}
74+
75+
projectModuleDependencies.add(packageInfo);
3276

33-
var generatorConfigUri = packageSrcRoot.replace(
34-
pathSegments: generatorConfigSegments,
77+
Pubspec modulePubspec;
78+
try {
79+
var modulePubspecFile = File.fromUri(
80+
packageInfo.root.resolve('pubspec.yaml'),
3581
);
82+
modulePubspec = parsePubspec(modulePubspecFile);
83+
} catch (_) {
84+
continue;
85+
}
86+
87+
queueModulesInPubspec(modulePubspec);
88+
}
89+
90+
return projectModuleDependencies;
91+
}
92+
93+
List<ModuleConfig> _loadModuleConfigs({
94+
required Set<Package> modules,
95+
Map<String, String?> nickNameOverrides = const {},
96+
}) {
97+
var moduleConfigs = <ModuleConfig>[];
98+
99+
for (var packageInfo in modules) {
100+
try {
101+
var packageName = packageInfo.name;
102+
103+
var packageSrcRoot = packageInfo.root;
104+
105+
var generatorConfigUri =
106+
packageSrcRoot.resolve(path.joinAll(['config', 'generator.yaml']));
36107

37108
var generatorConfigFile = File.fromUri(generatorConfigUri);
38109
if (!generatorConfigFile.existsSync()) {
39110
continue;
40111
}
41112

42-
var moduleProjectUri = packageSrcRoot.replace(
43-
pathSegments: moduleProjectRoot,
44-
);
45-
46113
var migrationVersions = findAllMigrationVersionsSync(
47-
directory: Directory.fromUri(moduleProjectUri),
114+
directory: Directory.fromUri(packageSrcRoot),
48115
);
49116

50117
var moduleInfo = loadConfigFile(generatorConfigFile);
@@ -53,21 +120,21 @@ List<ModuleConfig> loadModuleConfigs({
53120
var manualNickname = nickNameOverrides[moduleName];
54121
var nickname = manualNickname ?? moduleInfo['nickname'] ?? moduleName;
55122

56-
modules.add(
123+
moduleConfigs.add(
57124
ModuleConfig(
58125
type: GeneratorConfig.getPackageType(moduleInfo),
59126
name: moduleName,
60127
nickname: nickname,
61128
migrationVersions: migrationVersions,
62-
serverPackageDirectoryPathParts: moduleProjectRoot,
129+
serverPackageDirectoryPathParts: packageSrcRoot.pathSegments,
63130
),
64131
);
65132
} catch (e) {
66133
continue;
67134
}
68135
}
69136

70-
return modules;
137+
return moduleConfigs;
71138
}
72139

73140
Map<dynamic, dynamic> loadConfigFile(File file) {

tools/serverpod_cli/pubspec.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ dependencies:
2020
recase: ^4.1.0
2121
built_collection: ^5.1.1
2222
package_config: ^2.1.0
23-
pubspec_parse: ^1.2.2
23+
pubspec_parse: ^1.4.0
2424
source_span: ^1.10.0
2525
super_string: ^1.0.3
2626
watcher: ^1.0.2
@@ -44,6 +44,7 @@ dev_dependencies:
4444
serverpod_lints: 2.5.0
4545
term_glyph: ^1.2.2
4646
test: ^1.24.2
47+
test_descriptor: ^2.0.2
4748

4849
dependency_overrides:
4950
serverpod_shared:

0 commit comments

Comments
 (0)