|
20 | 20 | import com.google.common.base.Preconditions;
|
21 | 21 | import com.google.common.collect.ImmutableSet;
|
22 | 22 | import com.google.common.collect.ImmutableSortedSet;
|
| 23 | +import com.google.common.collect.Iterables; |
23 | 24 | import com.google.common.collect.Sets;
|
24 | 25 | import com.google.devtools.build.docgen.annot.DocCategory;
|
25 | 26 | import com.google.devtools.build.lib.cmdline.RepositoryName;
|
26 | 27 | import com.google.devtools.build.lib.events.Event;
|
27 | 28 | import com.google.devtools.build.lib.events.EventHandler;
|
28 | 29 | import java.util.Collection;
|
29 | 30 | import java.util.LinkedHashSet;
|
30 |
| -import java.util.List; |
31 | 31 | import java.util.Optional;
|
32 | 32 | import java.util.Set;
|
33 | 33 | import java.util.stream.Collectors;
|
@@ -82,23 +82,11 @@ static ModuleExtensionMetadata create(
|
82 | 82 | // root_module_direct_dev_deps = [], but not root_module_direct_dev_deps = ["some_repo"].
|
83 | 83 | if (rootModuleDirectDepsUnchecked.equals("all")
|
84 | 84 | && rootModuleDirectDevDepsUnchecked.equals(StarlarkList.immutableOf())) {
|
85 |
| - if (extensionId.getIsolationKey().isPresent() |
86 |
| - && extensionId.getIsolationKey().get().isDevUsage()) { |
87 |
| - throw Starlark.errorf( |
88 |
| - "root_module_direct_deps must be empty for an isolated extension usage with " |
89 |
| - + "dev_dependency = True"); |
90 |
| - } |
91 | 85 | return new ModuleExtensionMetadata(null, null, UseAllRepos.REGULAR);
|
92 | 86 | }
|
93 | 87 |
|
94 | 88 | if (rootModuleDirectDevDepsUnchecked.equals("all")
|
95 | 89 | && rootModuleDirectDepsUnchecked.equals(StarlarkList.immutableOf())) {
|
96 |
| - if (extensionId.getIsolationKey().isPresent() |
97 |
| - && !extensionId.getIsolationKey().get().isDevUsage()) { |
98 |
| - throw Starlark.errorf( |
99 |
| - "root_module_direct_dev_deps must be empty for an isolated extension usage with " |
100 |
| - + "dev_dependency = False"); |
101 |
| - } |
102 | 90 | return new ModuleExtensionMetadata(null, null, UseAllRepos.DEV);
|
103 | 91 | }
|
104 | 92 |
|
@@ -128,20 +116,6 @@ static ModuleExtensionMetadata create(
|
128 | 116 | Sequence.cast(
|
129 | 117 | rootModuleDirectDevDepsUnchecked, String.class, "root_module_direct_dev_deps");
|
130 | 118 |
|
131 |
| - if (extensionId.getIsolationKey().isPresent()) { |
132 |
| - ModuleExtensionId.IsolationKey isolationKey = extensionId.getIsolationKey().get(); |
133 |
| - if (isolationKey.isDevUsage() && !rootModuleDirectDeps.isEmpty()) { |
134 |
| - throw Starlark.errorf( |
135 |
| - "root_module_direct_deps must be empty for an isolated extension usage with " |
136 |
| - + "dev_dependency = True"); |
137 |
| - } |
138 |
| - if (!isolationKey.isDevUsage() && !rootModuleDirectDevDeps.isEmpty()) { |
139 |
| - throw Starlark.errorf( |
140 |
| - "root_module_direct_dev_deps must be empty for an isolated extension usage with " |
141 |
| - + "dev_dependency = False"); |
142 |
| - } |
143 |
| - } |
144 |
| - |
145 | 119 | Set<String> explicitRootModuleDirectDeps = new LinkedHashSet<>();
|
146 | 120 | for (String dep : rootModuleDirectDeps) {
|
147 | 121 | try {
|
@@ -192,40 +166,46 @@ Optional<Event> generateFixupMessage(
|
192 | 166 | // expected to modify any other module's MODULE.bazel file.
|
193 | 167 | return Optional.empty();
|
194 | 168 | }
|
| 169 | + // Every module only has at most a single usage of a given extension. |
| 170 | + ModuleExtensionUsage rootUsage = Iterables.getOnlyElement(rootUsages); |
195 | 171 |
|
196 | 172 | var rootModuleDirectDevDeps = getRootModuleDirectDevDeps(allRepos);
|
197 | 173 | var rootModuleDirectDeps = getRootModuleDirectDeps(allRepos);
|
198 | 174 | if (rootModuleDirectDevDeps.isEmpty() && rootModuleDirectDeps.isEmpty()) {
|
199 | 175 | return Optional.empty();
|
200 | 176 | }
|
201 |
| - |
202 | 177 | Preconditions.checkState(
|
203 | 178 | rootModuleDirectDevDeps.isPresent() && rootModuleDirectDeps.isPresent());
|
| 179 | + |
| 180 | + if (!rootUsage.getHasNonDevUseExtension() && !rootModuleDirectDeps.get().isEmpty()) { |
| 181 | + throw Starlark.errorf( |
| 182 | + "root_module_direct_deps must be empty if the root module contains no " |
| 183 | + + "usages with dev_dependency = False"); |
| 184 | + } |
| 185 | + if (!rootUsage.getHasDevUseExtension() && !rootModuleDirectDevDeps.get().isEmpty()) { |
| 186 | + throw Starlark.errorf( |
| 187 | + "root_module_direct_dev_deps must be empty if the root module contains no " |
| 188 | + + "usages with dev_dependency = True"); |
| 189 | + } |
| 190 | + |
204 | 191 | return generateFixupMessage(
|
205 |
| - rootUsages, allRepos, rootModuleDirectDeps.get(), rootModuleDirectDevDeps.get()); |
| 192 | + rootUsage, allRepos, rootModuleDirectDeps.get(), rootModuleDirectDevDeps.get()); |
206 | 193 | }
|
207 | 194 |
|
208 | 195 | private static Optional<Event> generateFixupMessage(
|
209 |
| - List<ModuleExtensionUsage> rootUsages, |
| 196 | + ModuleExtensionUsage rootUsage, |
210 | 197 | Set<String> allRepos,
|
211 | 198 | Set<String> expectedImports,
|
212 | 199 | Set<String> expectedDevImports) {
|
213 |
| - var actualDevImports = |
214 |
| - rootUsages.stream() |
215 |
| - .flatMap(usage -> usage.getDevImports().stream()) |
216 |
| - .collect(toImmutableSet()); |
| 200 | + var actualDevImports = ImmutableSet.copyOf(rootUsage.getDevImports()); |
217 | 201 | var actualImports =
|
218 |
| - rootUsages.stream() |
219 |
| - .flatMap(usage -> usage.getImports().values().stream()) |
| 202 | + rootUsage.getImports().values().stream() |
220 | 203 | .filter(repo -> !actualDevImports.contains(repo))
|
221 | 204 | .collect(toImmutableSet());
|
222 | 205 |
|
223 |
| - // All label strings that map to the same Label are equivalent for buildozer as it implements |
224 |
| - // the same normalization of label strings with no or empty repo name. |
225 |
| - ModuleExtensionUsage firstUsage = rootUsages.get(0); |
226 |
| - String extensionBzlFile = firstUsage.getExtensionBzlFile(); |
227 |
| - String extensionName = firstUsage.getExtensionName(); |
228 |
| - Location location = firstUsage.getLocation(); |
| 206 | + String extensionBzlFile = rootUsage.getExtensionBzlFile(); |
| 207 | + String extensionName = rootUsage.getExtensionName(); |
| 208 | + Location location = rootUsage.getLocation(); |
229 | 209 |
|
230 | 210 | var importsToAdd = ImmutableSortedSet.copyOf(Sets.difference(expectedImports, actualImports));
|
231 | 211 | var importsToRemove =
|
@@ -290,28 +270,28 @@ private static Optional<Event> generateFixupMessage(
|
290 | 270 | importsToAdd,
|
291 | 271 | extensionBzlFile,
|
292 | 272 | extensionName,
|
293 |
| - firstUsage.getIsolationKey()), |
| 273 | + rootUsage.getIsolationKey()), |
294 | 274 | makeUseRepoCommand(
|
295 | 275 | "use_repo_remove",
|
296 | 276 | false,
|
297 | 277 | importsToRemove,
|
298 | 278 | extensionBzlFile,
|
299 | 279 | extensionName,
|
300 |
| - firstUsage.getIsolationKey()), |
| 280 | + rootUsage.getIsolationKey()), |
301 | 281 | makeUseRepoCommand(
|
302 | 282 | "use_repo_add",
|
303 | 283 | true,
|
304 | 284 | devImportsToAdd,
|
305 | 285 | extensionBzlFile,
|
306 | 286 | extensionName,
|
307 |
| - firstUsage.getIsolationKey()), |
| 287 | + rootUsage.getIsolationKey()), |
308 | 288 | makeUseRepoCommand(
|
309 | 289 | "use_repo_remove",
|
310 | 290 | true,
|
311 | 291 | devImportsToRemove,
|
312 | 292 | extensionBzlFile,
|
313 | 293 | extensionName,
|
314 |
| - firstUsage.getIsolationKey())) |
| 294 | + rootUsage.getIsolationKey())) |
315 | 295 | .flatMap(Optional::stream);
|
316 | 296 |
|
317 | 297 | return Optional.of(
|
|
0 commit comments