-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,16 +13,19 @@ | |
// limitations under the License. | ||
package com.google.devtools.build.lib.analysis; | ||
|
||
import static com.google.common.collect.ImmutableList.toImmutableList; | ||
import static java.nio.charset.StandardCharsets.ISO_8859_1; | ||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
import com.google.common.collect.ImmutableList; | ||
import com.google.devtools.build.lib.actions.ActionExecutionContext; | ||
import com.google.devtools.build.lib.actions.ActionKeyContext; | ||
import com.google.devtools.build.lib.actions.ActionOwner; | ||
import com.google.devtools.build.lib.actions.Artifact; | ||
import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction; | ||
import com.google.devtools.build.lib.analysis.actions.DeterministicWriter; | ||
import com.google.devtools.build.lib.collect.nestedset.NestedSet; | ||
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; | ||
import com.google.devtools.build.lib.collect.nestedset.Order; | ||
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; | ||
|
@@ -99,6 +102,8 @@ void writeEntry( | |
|
||
private final boolean remotableSourceManifestActions; | ||
|
||
private NestedSet<Artifact> symlinkArtifacts = null; | ||
|
||
/** | ||
* Creates a new AbstractSourceManifestAction instance using latin1 encoding to write the manifest | ||
* file and with a specified root path for manifest entries. | ||
|
@@ -135,6 +140,17 @@ public SourceManifestAction( | |
this.remotableSourceManifestActions = remotableSourceManifestActions; | ||
} | ||
|
||
@Override | ||
public synchronized NestedSet<Artifact> getInputs() { | ||
if (symlinkArtifacts == null) { | ||
ImmutableList<Artifact> symlinks = runfiles.getArtifacts().toList().stream() | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
fmeum
Author
Owner
|
||
.filter(Artifact::isSymlink) | ||
.collect(toImmutableList()); | ||
symlinkArtifacts = NestedSetBuilder.wrap(Order.STABLE_ORDER, symlinks); | ||
} | ||
return symlinkArtifacts; | ||
} | ||
|
||
@VisibleForTesting | ||
public void writeOutputFile(OutputStream out, EventHandler eventHandler) throws IOException { | ||
writeFile(out, runfiles.getRunfilesInputs(eventHandler, getOwner().getLocation())); | ||
|
@@ -227,7 +243,11 @@ public void writeEntry(Writer manifestWriter, PathFragment rootRelativePath, Art | |
// This trailing whitespace is REQUIRED to process the single entry line correctly. | ||
manifestWriter.append(' '); | ||
if (symlink != null) { | ||
manifestWriter.append(symlink.getPath().getPathString()); | ||
if (symlink.isSymlink()) { | ||
manifestWriter.append(symlink.getPath().readSymbolicLink().getPathString()); | ||
} else { | ||
manifestWriter.append(symlink.getPath().getPathString()); | ||
} | ||
} | ||
manifestWriter.append('\n'); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Copyright 2022 The Bazel Authors. All rights reserved. | ||
// | ||
// 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 com.google.devtools.build.lib.analysis.starlark; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
import com.google.devtools.build.lib.actions.AbstractAction; | ||
import com.google.devtools.build.lib.actions.ActionExecutionContext; | ||
import com.google.devtools.build.lib.actions.ActionExecutionException; | ||
import com.google.devtools.build.lib.actions.ActionKeyContext; | ||
import com.google.devtools.build.lib.actions.ActionOwner; | ||
import com.google.devtools.build.lib.actions.ActionResult; | ||
import com.google.devtools.build.lib.actions.Artifact; | ||
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; | ||
import com.google.devtools.build.lib.analysis.actions.SymlinkAction; | ||
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; | ||
import com.google.devtools.build.lib.collect.nestedset.Order; | ||
import com.google.devtools.build.lib.server.FailureDetails; | ||
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail; | ||
import com.google.devtools.build.lib.server.FailureDetails.SymlinkAction.Code; | ||
import com.google.devtools.build.lib.util.DetailedExitCode; | ||
import com.google.devtools.build.lib.util.Fingerprint; | ||
import com.google.devtools.build.lib.vfs.Path; | ||
import com.google.devtools.build.lib.vfs.PathFragment; | ||
import java.io.IOException; | ||
import javax.annotation.Nullable; | ||
|
||
/** | ||
* Action to create a possibly unresolved symbolic link to a raw path. | ||
* | ||
* To create a symlink to a known-to-exist target with alias semantics similar to a true copy of the | ||
* input, use {@link SymlinkAction} instead. | ||
*/ | ||
public final class UnresolvedSymlinkAction extends AbstractAction { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
fmeum
Author
Owner
|
||
private static final String GUID = "0f302651-602c-404b-881c-58913193cfe7"; | ||
|
||
private final String target; | ||
private final String progressMessage; | ||
|
||
public UnresolvedSymlinkAction( | ||
ActionOwner owner, | ||
Artifact primaryOutput, | ||
String target, | ||
String progressMessage) { | ||
super( | ||
owner, | ||
NestedSetBuilder.emptySet(Order.STABLE_ORDER), | ||
ImmutableSet.of(primaryOutput)); | ||
this.target = target; | ||
this.progressMessage = progressMessage; | ||
} | ||
|
||
@Override | ||
public ActionResult execute(ActionExecutionContext actionExecutionContext) | ||
throws ActionExecutionException { | ||
|
||
Path outputPath = actionExecutionContext.getInputPath(getPrimaryOutput()); | ||
try { | ||
// TODO: PathFragment#create normalizes the symlink target, which may change how it resolves | ||
// when combined with directory symlinks. Ideally, Bazel's file system abstraction would | ||
// offer a way to create symlinks without any preprocessing of the target. | ||
outputPath.createSymbolicLink(PathFragment.create(target)); | ||
} catch (IOException e) { | ||
String message = | ||
String.format( | ||
"failed to create symbolic link '%s' to '%s' due to I/O error: %s", | ||
getPrimaryOutput().getExecPathString(), target, e.getMessage()); | ||
DetailedExitCode code = createDetailedExitCode(message, Code.LINK_CREATION_IO_EXCEPTION); | ||
throw new ActionExecutionException(message, e, this, false, code); | ||
} | ||
|
||
return ActionResult.EMPTY; | ||
} | ||
|
||
@Override | ||
protected void computeKey( | ||
ActionKeyContext actionKeyContext, | ||
@Nullable ArtifactExpander artifactExpander, | ||
Fingerprint fp) { | ||
fp.addString(GUID); | ||
fp.addString(target); | ||
} | ||
|
||
@Override | ||
public String getMnemonic() { | ||
return "UnresolvedSymlink"; | ||
} | ||
|
||
@Override | ||
protected String getRawProgressMessage() { | ||
return progressMessage; | ||
} | ||
|
||
private static DetailedExitCode createDetailedExitCode(String message, Code detailedCode) { | ||
return DetailedExitCode.of( | ||
FailureDetail.newBuilder() | ||
.setMessage(message) | ||
.setSymlinkAction(FailureDetails.SymlinkAction.newBuilder().setCode(detailedCode)) | ||
.build()); | ||
} | ||
} |
toList
is certainly something we would want to avoid given that will expand the nested set.