-
Notifications
You must be signed in to change notification settings - Fork 4.6k
/
ValueSource.java
130 lines (124 loc) · 5.42 KB
/
ValueSource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.api.provider;
import org.gradle.api.Action;
import org.gradle.api.file.RegularFile;
import javax.annotation.Nullable;
import javax.inject.Inject;
/**
* Represents an external source of information used by a Gradle build.
*
* Examples of external sources include client environment variables,
* system properties, configuration files, shell commands, network services,
* among others.
*
* <p>
* Representing external sources as {@link ValueSource}s allows Gradle to transparently manage
* <a href="https://docs.gradle.org/current/userguide/configuration_cache.html" target="_top">the configuration cache</a>
* as values obtained from those sources change.
* For example, a build might run a different set of tasks depending on whether the {@code CI}
* environment variable is set or not.
* </p>
*
* <p>
* To integrate a new type of value source, create an abstract subclass of this interface
* and use {@link ProviderFactory#of(Class, Action)} to get a provider to a configured source.
* The returned {@link org.gradle.api.provider.Provider} can be passed to tasks or queried
* by build logic during the configuration phase. In the latter case, the source would be automatically
* considered as an input to the work graph cache.
* </p>
* <p>
* It is possible to have some Gradle services to be <a href="https://docs.gradle.org/current/userguide/custom_gradle_types.html#service_injection">injected</a>
* into the implementation, similar to tasks and plugins.
* It can be done by adding a parameter to the constructor and annotating the
* constructor with the {@code @Inject} annotation:
* <pre>
* public abstract class MyValueSource implements ValueSource<String, ValueSourceParameters.None> {
* private final ExecOperations execOperations;
*
* {@literal @}Inject
* public MyValueSource(ExecOperations execOperations) {
* this.execOperations = execOperations;
* }
*
* // ...
* }
* </pre>
* Currently, only a small subset of services is supported:
* <ul>
* <li>{@link org.gradle.process.ExecOperations} provides means to execute external processes.
* It is possible to use this service even at configuration time. However, as the
* returned value is used to check the configuration cache, the {@link #obtain()} method will
* be called during each build. Calling slow commands here will slow things down.</li>
* </ul>
*
* <p>
* A value source implementation will most likely take parameters. To do this create a
* subtype of {@link ValueSourceParameters} and declare this type as the type parameter
* to the value source implementation.
* </p>
*
* <p>
* A value source implementation doesn't have to be thread-safe, as the single call
* to {@link #obtain()} is synchronized.
* </p>
*
* <p>
* A value source implementation is exempt from the automatic detection of work graph cache inputs.
* For example, if the {@link #obtain()} method calls {@code System.getenv("FOO")} then changes to
* the {@code FOO} environment variable only invalidate the cache if the value returned by the
* {@code obtain()} method itself changes. The same applies to reading files or system properties.
* Starting an external process with a standard API (for example, {@code java.lang.ProcessBuilder}) is
* also allowed.
* </p>
*
* Implementations of ValueSource are subject to the following constraint:
* <ul>
* <li>Do not implement {@link #getParameters()} in your class, the method will be implemented by Gradle.</li>
* </ul>
*
* @param <T> The type of value obtained from this source.
* @param <P> The source specific parameter type.
* @see ProviderFactory#environmentVariable(String)
* @see ProviderFactory#systemProperty(String)
* @see ProviderFactory#fileContents(RegularFile)
* @see ProviderFactory#of(Class, Action)
* @see <a href="https://docs.gradle.org/current/userguide/configuration_cache.html">Configuration Cache</a>
* @since 6.1
*/
public interface ValueSource<T, P extends ValueSourceParameters> {
/**
* The object provided by {@link ValueSourceSpec#getParameters()} when creating a provider from the value source.
*
* <p>
* Do not implement this method in your subclass.
* Gradle provides the implementation when creating a provider from the value source via {@link ProviderFactory#of(Class, Action)}.
* </p>
*/
@Inject
P getParameters();
/**
* Obtains the value from the source. The returned value must be effectively immutable.
* The implementation is exempt from the automatic detection of work graph cache inputs.
*
* <p>This method must be implemented in the subclass.</p>
* <p>This method is only called if the provider value is requested and only once in that case.</p>
*
* @return the value obtained or {@code null} if the value is not present.
*/
@Nullable
T obtain();
}