##// END OF EJS Templates
variants API cleanup
cin -
r29:b379fb9b52c4 default
parent child
Show More
@@ -0,0 +1,12
1 # AGENTS.md
2
3 ## Проектные договоренности
4
5 ### Публичное API библиотек
6
7 - Предпочтителен `non-null` подход.
8 - Там, где значение живет в Gradle Provider API, возвращается `Provider<T>` (не `null`).
9 - Там, где lookup синхронный, возвращается `Optional<T>` (не `null`).
10 - `find*` рассматривается как синоним legacy `get*` (поиск без `fail-fast`).
11 - `require*` это `find*` + `fail-fast` с понятной ошибкой в месте вызова.
12 - Для нового API предпочтительны формы `find/require`; новые `get*` по возможности не добавлять.
@@ -4,9 +4,8 import java.util.ArrayList;
4 4 import java.util.Collection;
5 5 import java.util.Collections;
6 6 import java.util.LinkedHashMap;
7 import java.util.LinkedHashSet;
8 7 import java.util.List;
9 import java.util.Set;
8 import java.util.Optional;
10 9
11 10 import javax.inject.Inject;
12 11
@@ -101,8 +100,14 public abstract class BuildVariant imple
101 100 });
102 101 }
103 102
104 public BuildRole getRoleByName(String name) {
105 return roles.get(name);
103 public Optional<BuildRole> findRole(String name) {
104 return Optional.ofNullable(roles.get(name));
105 }
106
107 public BuildRole requireRole(String name) {
108 return findRole(name)
109 .orElseThrow(() -> new InvalidUserDataException(
110 "Variant '" + this.name + "' doesn't define role '" + name + "'"));
106 111 }
107 112
108 113 public Collection<LayerLink> getLinks() {
@@ -157,17 +162,14 public abstract class BuildVariant imple
157 162 return artifactSlot(name, Closures.action(configure));
158 163 }
159 164
160 public BuildArtifactSlot getArtifactSlotByName(String name) {
161 return artifactSlots.get(name);
165 public Optional<BuildArtifactSlot> findArtifactSlot(String name) {
166 return Optional.ofNullable(artifactSlots.get(name));
162 167 }
163 168
164 Set<String> declaredLayerNames() {
165 var result = new LinkedHashSet<String>();
166
167 for (var role : roles.values())
168 result.addAll(role.getLayers().getOrElse(java.util.List.of()));
169
170 return result;
169 public BuildArtifactSlot requireArtifactSlot(String name) {
170 return findArtifactSlot(name)
171 .orElseThrow(() -> new InvalidUserDataException(
172 "Variant '" + this.name + "' doesn't define artifact slot '" + name + "'"));
171 173 }
172 174
173 175 void finalizeModel() {
@@ -218,8 +220,12 public abstract class BuildVariant imple
218 220 return BuildVariant.this.getRoles();
219 221 }
220 222
221 public BuildRole getByName(String name) {
222 return BuildVariant.this.getRoleByName(name);
223 public Optional<BuildRole> find(String name) {
224 return BuildVariant.this.findRole(name);
225 }
226
227 public BuildRole require(String name) {
228 return BuildVariant.this.requireRole(name);
223 229 }
224 230 }
225 231
@@ -250,8 +256,12 public abstract class BuildVariant imple
250 256 return BuildVariant.this.getArtifactSlots();
251 257 }
252 258
253 public BuildArtifactSlot getByName(String name) {
254 return BuildVariant.this.getArtifactSlotByName(name);
259 public Optional<BuildArtifactSlot> find(String name) {
260 return BuildVariant.this.findArtifactSlot(name);
261 }
262
263 public BuildArtifactSlot require(String name) {
264 return BuildVariant.this.requireArtifactSlot(name);
255 265 }
256 266 }
257 267
@@ -9,6 +9,7 import java.util.LinkedHashMap;
9 9 import java.util.LinkedHashSet;
10 10 import java.util.List;
11 11 import java.util.Map;
12 import java.util.Optional;
12 13 import java.util.Set;
13 14
14 15 import javax.inject.Inject;
@@ -117,8 +118,13 public abstract class BuildVariantsExten
117 118 return Collections.unmodifiableList(all);
118 119 }
119 120
120 public BuildVariant getByName(String name) {
121 return variants.findByName(name);
121 public Optional<BuildVariant> find(String name) {
122 return Optional.ofNullable(variants.findByName(name));
123 }
124
125 public BuildVariant require(String name) {
126 return find(name)
127 .orElseThrow(() -> new InvalidUserDataException("Variant '" + name + "' isn't defined"));
122 128 }
123 129
124 130 public void whenFinalized(Action<? super BuildVariantsExtension> action) {
@@ -15,10 +15,12 import org.gradle.api.provider.Provider;
15 15 public final class VariantAttributes {
16 16 private final ProviderFactory providers;
17 17 private final LinkedHashMap<Attribute<?>, Provider<?>> values = new LinkedHashMap<>();
18 private final Provider<Object> emptyValueProvider;
18 19 private boolean finalized;
19 20
20 21 VariantAttributes(ProviderFactory providers) {
21 22 this.providers = providers;
23 this.emptyValueProvider = providers.provider(() -> null);
22 24 }
23 25
24 26 public <T> void attribute(Attribute<T> key, T value) {
@@ -32,8 +34,18 public final class VariantAttributes {
32 34 }
33 35
34 36 @SuppressWarnings("unchecked")
35 public <T> Provider<T> get(Attribute<T> key) {
36 return (Provider<T>) values.get(key);
37 public <T> Provider<T> find(Attribute<T> key) {
38 return providers
39 .provider(() -> (Provider<T>) values.getOrDefault(key, emptyValueProvider))
40 .flatMap(provider -> provider);
41 }
42
43 public <T> Provider<T> require(Attribute<T> key) {
44 var value = find(key);
45 if (!value.isPresent())
46 throw new InvalidUserDataException("Attribute '" + key.getName() + "' doesn't have a value");
47
48 return value;
37 49 }
38 50
39 51 public boolean contains(Attribute<?> key) {
@@ -53,9 +53,9 class VariantsPluginFunctionalTest {
53 53 }
54 54 }
55 55
56 tasks.register('probe') {
57 doLast {
58 def browser = variants.getByName('browser')
56 tasks.register('probe') {
57 doLast {
58 def browser = variants.require('browser')
59 59 println('attributes=' + browser.attributes.size())
60 60 println('roles=' + browser.roles.size())
61 61 println('links=' + browser.links.size())
@@ -277,7 +277,7 class VariantsPluginFunctionalTest {
277 277 }
278 278
279 279 afterEvaluate {
280 variants.getByName('browser').role('late') { layers('a') }
280 variants.require('browser').role('late') { layers('a') }
281 281 }
282 282 """, "Variant 'browser' is finalized and cannot configure roles");
283 283 }
@@ -99,7 +99,7 Typed-атрибуты (`Attribute<T> -> Provider<T>`) для передачи параметров в
99 99 - `variant(...)` — объявление или конфигурация `BuildVariant`.
100 100 - `layers { ... }`, `variants { ... }` — контейнерный DSL.
101 101 - `all(...)` — callback для всех вариантов.
102 - `getAll()`, `getByName(name)` — доступ к вариантам.
102 - `getAll()`, `find(name)`, `require(name)` — доступ к вариантам.
103 103 - `validate()` — явный запуск валидации.
104 104 - `finalizeModel()` — валидация + финализация модели.
105 105 - `whenFinalized(...)` — callback по завершенной модели (replayable).
General Comments 0
You need to be logged in to leave comments. Login now