| // Copyright 2018 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.actions; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.devtools.build.lib.vfs.FileSystem; |
| import com.google.devtools.build.lib.vfs.Path; |
| import com.google.devtools.build.lib.vfs.Root; |
| import javax.annotation.Nullable; |
| |
| /** |
| * An indirection layer on Path resolution of {@link Artifact} and {@link Root}. |
| * |
| * <p>Serves as converter interface primarily for switching the {@link FileSystem} underlying the |
| * values. |
| */ |
| public interface ArtifactPathResolver { |
| |
| /** |
| * @return a resolved Path corresponding to the given actionInput. |
| */ |
| Path toPath(ActionInput actionInput); |
| |
| /** |
| * @return a resolved Path corresponding to the given path. |
| */ |
| Path convertPath(Path path); |
| |
| /** @return a resolved {@link Root} corresponding to the given Root. */ |
| Root transformRoot(Root root); |
| |
| ArtifactPathResolver IDENTITY = new IdentityResolver(null); |
| |
| static ArtifactPathResolver forExecRoot(Path execRoot) { |
| return new IdentityResolver(execRoot); |
| } |
| |
| static ArtifactPathResolver withTransformedFileSystem(Path execRoot) { |
| return new TransformResolver(execRoot); |
| } |
| |
| static ArtifactPathResolver createPathResolver(@Nullable FileSystem fileSystem, |
| Path execRoot) { |
| if (fileSystem == null) { |
| return forExecRoot(execRoot); |
| } else { |
| return withTransformedFileSystem( |
| fileSystem.getPath(execRoot.asFragment())); |
| } |
| } |
| |
| /** |
| * Path resolution that uses an Artifact's path directly, or looks up the input execPath relative |
| * to the given execRoot. |
| */ |
| class IdentityResolver implements ArtifactPathResolver { |
| private final Path execRoot; |
| |
| private IdentityResolver(Path execRoot) { |
| this.execRoot = execRoot; |
| } |
| |
| @Override |
| public Path toPath(ActionInput actionInput) { |
| if (actionInput instanceof Artifact) { |
| return ((Artifact) actionInput).getPath(); |
| } |
| return execRoot.getRelative(actionInput.getExecPath()); |
| } |
| |
| @Override |
| public Root transformRoot(Root root) { |
| return Preconditions.checkNotNull(root); |
| } |
| |
| @Override |
| public Path convertPath(Path path) { |
| return path; |
| } |
| }; |
| |
| /** |
| * A resolver that transforms all results to the same filesystem as the given execRoot. |
| */ |
| class TransformResolver implements ArtifactPathResolver { |
| private final FileSystem fileSystem; |
| private final Path execRoot; |
| |
| private TransformResolver(Path execRoot) { |
| this.execRoot = execRoot; |
| this.fileSystem = Preconditions.checkNotNull(execRoot.getFileSystem()); |
| } |
| |
| @Override |
| public Path toPath(ActionInput input) { |
| if (input instanceof Artifact) { |
| return fileSystem.getPath(((Artifact) input).getPath().asFragment()); |
| } |
| return execRoot.getRelative(input.getExecPath()); |
| } |
| |
| @Override |
| public Root transformRoot(Root root) { |
| return Root.toFileSystem(Preconditions.checkNotNull(root), fileSystem); |
| } |
| |
| @Override |
| public Path convertPath(Path path) { |
| return fileSystem.getPath(path.asFragment()); |
| } |
| } |
| } |