13
13
// limitations under the License.
14
14
package com .google .devtools .build .lib .analysis ;
15
15
16
- import static com .google .common .collect .ImmutableSet .toImmutableSet ;
17
- import static com .google .common .collect .ImmutableSortedMap .toImmutableSortedMap ;
18
16
import static java .nio .charset .StandardCharsets .ISO_8859_1 ;
19
17
import static java .util .Comparator .comparing ;
20
18
21
- import com .google .common . collect . ImmutableSet ;
22
- import com .google .common .collect .ImmutableSortedMap ;
19
+ import com .google .auto . value . AutoValue ;
20
+ import com .google .common .collect .ImmutableList ;
23
21
import com .google .devtools .build .lib .actions .ActionExecutionContext ;
24
22
import com .google .devtools .build .lib .actions .ActionKeyContext ;
25
23
import com .google .devtools .build .lib .actions .ActionOwner ;
26
24
import com .google .devtools .build .lib .actions .Artifact ;
27
25
import com .google .devtools .build .lib .actions .Artifact .ArtifactExpander ;
28
26
import com .google .devtools .build .lib .actions .CommandLineExpansionException ;
29
- import com .google .devtools .build .lib .actions .CommandLineItem .MapFn ;
30
27
import com .google .devtools .build .lib .actions .ExecException ;
31
28
import com .google .devtools .build .lib .analysis .actions .AbstractFileWriteAction ;
32
29
import com .google .devtools .build .lib .analysis .actions .DeterministicWriter ;
33
- import com .google .devtools .build .lib .cmdline .RepositoryMapping ;
34
30
import com .google .devtools .build .lib .cmdline .RepositoryName ;
35
- import com .google .devtools .build .lib .collect .nestedset .NestedSet ;
36
31
import com .google .devtools .build .lib .collect .nestedset .NestedSetBuilder ;
37
32
import com .google .devtools .build .lib .collect .nestedset .Order ;
38
- import com .google .devtools .build .lib .packages .Package ;
39
33
import com .google .devtools .build .lib .util .Fingerprint ;
40
34
import java .io .PrintWriter ;
41
- import java .util .Map . Entry ;
35
+ import java .util .List ;
42
36
import java .util .UUID ;
43
37
import javax .annotation .Nullable ;
44
38
import net .starlark .java .eval .EvalException ;
45
39
46
40
/** Creates a manifest file describing the repos and mappings relevant for a runfile tree. */
47
- public final class RepoMappingManifestAction extends AbstractFileWriteAction {
48
-
41
+ public class RepoMappingManifestAction extends AbstractFileWriteAction {
49
42
private static final UUID MY_UUID = UUID .fromString ("458e351c-4d30-433d-b927-da6cddd4737f" );
50
43
51
- // Uses MapFn's args parameter just like Fingerprint#addString to compute a cacheable fingerprint
52
- // of just the repo name and mapping of a given Package.
53
- private static final MapFn <Package > REPO_AND_MAPPING_DIGEST_FN =
54
- (pkg , args ) -> {
55
- args .accept (pkg .getPackageIdentifier ().getRepository ().getName ());
44
+ private final ImmutableList <Entry > entries ;
45
+ private final String workspaceName ;
56
46
57
- var mapping = pkg . getRepositoryMapping (). entries ();
58
- args . accept ( String . valueOf ( mapping . size ()));
59
- mapping . forEach (
60
- ( apparentName , canonicalName ) -> {
61
- args . accept ( apparentName );
62
- args . accept ( canonicalName . getName ());
63
- } );
64
- };
47
+ /** An entry in the repo mapping manifest file. */
48
+ @ AutoValue
49
+ public abstract static class Entry {
50
+ public static Entry of (
51
+ RepositoryName sourceRepo , String targetRepoApparentName , RepositoryName targetRepo ) {
52
+ return new AutoValue_RepoMappingManifestAction_Entry (
53
+ sourceRepo , targetRepoApparentName , targetRepo );
54
+ }
65
55
66
- private final NestedSet <Package > transitivePackages ;
67
- private final NestedSet <Artifact > runfilesArtifacts ;
68
- private final String workspaceName ;
56
+ public abstract RepositoryName sourceRepo ();
57
+
58
+ public abstract String targetRepoApparentName ();
59
+
60
+ public abstract RepositoryName targetRepo ();
61
+ }
69
62
70
63
public RepoMappingManifestAction (
71
- ActionOwner owner ,
72
- Artifact output ,
73
- NestedSet <Package > transitivePackages ,
74
- NestedSet <Artifact > runfilesArtifacts ,
75
- String workspaceName ) {
64
+ ActionOwner owner , Artifact output , List <Entry > entries , String workspaceName ) {
76
65
super (owner , NestedSetBuilder .emptySet (Order .STABLE_ORDER ), output , /*makeExecutable=*/ false );
77
- this .transitivePackages = transitivePackages ;
78
- this .runfilesArtifacts = runfilesArtifacts ;
66
+ this .entries =
67
+ ImmutableList .sortedCopyOf (
68
+ comparing ((Entry e ) -> e .sourceRepo ().getName ())
69
+ .thenComparing (Entry ::targetRepoApparentName ),
70
+ entries );
79
71
this .workspaceName = workspaceName ;
80
72
}
81
73
@@ -86,7 +78,7 @@ public String getMnemonic() {
86
78
87
79
@ Override
88
80
protected String getRawProgressMessage () {
89
- return "Writing repo mapping manifest for " + getOwner ().getLabel ();
81
+ return "writing repo mapping manifest for " + getOwner ().getLabel ();
90
82
}
91
83
92
84
@ Override
@@ -96,61 +88,35 @@ protected void computeKey(
96
88
Fingerprint fp )
97
89
throws CommandLineExpansionException , EvalException , InterruptedException {
98
90
fp .addUUID (MY_UUID );
99
- actionKeyContext .addNestedSetToFingerprint (REPO_AND_MAPPING_DIGEST_FN , fp , transitivePackages );
100
- actionKeyContext .addNestedSetToFingerprint (fp , runfilesArtifacts );
101
91
fp .addString (workspaceName );
92
+ for (Entry entry : entries ) {
93
+ fp .addString (entry .sourceRepo ().getName ());
94
+ fp .addString (entry .targetRepoApparentName ());
95
+ fp .addString (entry .targetRepo ().getName ());
96
+ }
102
97
}
103
98
104
99
@ Override
105
100
public DeterministicWriter newDeterministicWriter (ActionExecutionContext ctx )
106
101
throws InterruptedException , ExecException {
107
102
return out -> {
108
- PrintWriter writer = new PrintWriter (out , /* autoFlush= */ false , ISO_8859_1 );
109
-
110
- ImmutableSet <RepositoryName > reposContributingRunfiles =
111
- runfilesArtifacts .toList ().stream ()
112
- .filter (a -> a .getOwner () != null )
113
- .map (a -> a .getOwner ().getRepository ())
114
- .collect (toImmutableSet ());
115
- transitivePackages .toList ().stream ()
116
- .collect (
117
- toImmutableSortedMap (
118
- comparing (RepositoryName ::getName ),
119
- pkg -> pkg .getPackageIdentifier ().getRepository (),
120
- Package ::getRepositoryMapping ,
121
- // All packages in a given repository have the same repository mapping, so the
122
- // particular way of resolving duplicates does not matter.
123
- (first , second ) -> first ))
124
- .forEach (
125
- (repoName , mapping ) ->
126
- writeRepoMapping (writer , reposContributingRunfiles , repoName , mapping ));
103
+ PrintWriter writer = new PrintWriter (out , /*autoFlush=*/ false , ISO_8859_1 );
104
+ for (Entry entry : entries ) {
105
+ if (entry .targetRepoApparentName ().isEmpty ()) {
106
+ // The apparent repo name can only be empty for the main repo. We skip this line as
107
+ // Rlocation paths can't reference an empty apparent name anyway.
108
+ continue ;
109
+ }
110
+ // The canonical name of the main repo is the empty string, which is not a valid name for a
111
+ // directory, so the "workspace name" is used the name of the directory under the runfiles
112
+ // tree for it.
113
+ String targetRepoDirectoryName =
114
+ entry .targetRepo ().isMain () ? workspaceName : entry .targetRepo ().getName ();
115
+ writer .format (
116
+ "%s,%s,%s\n " ,
117
+ entry .sourceRepo ().getName (), entry .targetRepoApparentName (), targetRepoDirectoryName );
118
+ }
127
119
writer .flush ();
128
120
};
129
121
}
130
-
131
- private void writeRepoMapping (
132
- PrintWriter writer ,
133
- ImmutableSet <RepositoryName > reposContributingRunfiles ,
134
- RepositoryName repoName ,
135
- RepositoryMapping repoMapping ) {
136
- for (Entry <String , RepositoryName > mappingEntry :
137
- ImmutableSortedMap .copyOf (repoMapping .entries ()).entrySet ()) {
138
- if (mappingEntry .getKey ().isEmpty ()) {
139
- // The apparent repo name can only be empty for the main repo. We skip this line as
140
- // Rlocation paths can't reference an empty apparent name anyway.
141
- continue ;
142
- }
143
- if (!reposContributingRunfiles .contains (mappingEntry .getValue ())) {
144
- // We only write entries for repos that actually contribute runfiles.
145
- continue ;
146
- }
147
- // The canonical name of the main repo is the empty string, which is not a valid name for a
148
- // directory, so the "workspace name" is used the name of the directory under the runfiles
149
- // tree for it.
150
- String targetRepoDirectoryName =
151
- mappingEntry .getValue ().isMain () ? workspaceName : mappingEntry .getValue ().getName ();
152
- writer .format (
153
- "%s,%s,%s\n " , repoName .getName (), mappingEntry .getKey (), targetRepoDirectoryName );
154
- }
155
- }
156
122
}
0 commit comments