| /* |
| * Copyright 2012-present Facebook, Inc. |
| * |
| * 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.facebook.buck.model; |
| |
| import com.facebook.buck.util.BuckConstant; |
| import com.facebook.buck.util.Paths; |
| import com.facebook.buck.util.ProjectFilesystem; |
| import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| import com.fasterxml.jackson.annotation.JsonProperty; |
| import com.google.common.base.Preconditions; |
| |
| import java.io.File; |
| import java.nio.file.Path; |
| |
| import javax.annotation.Nullable; |
| |
| @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, |
| getterVisibility = JsonAutoDetect.Visibility.NONE, |
| setterVisibility = JsonAutoDetect.Visibility.NONE) |
| public final class BuildTarget implements Comparable<BuildTarget> { |
| |
| public static final String BUILD_TARGET_PREFIX = "//"; |
| |
| private final String baseName; |
| private final String shortName; |
| private final String fullyQualifiedName; |
| |
| public BuildTarget(String baseName, String shortName) { |
| Preconditions.checkNotNull(baseName); |
| Preconditions.checkArgument(baseName.startsWith(BUILD_TARGET_PREFIX), |
| "baseName must start with // but was %s", |
| baseName); |
| |
| // On Windows, basePath may contain backslashes, which are not permitted by BuildTarget. |
| if (Paths.containsBackslash(baseName)) { |
| baseName = Paths.normalizePathSeparator(baseName); |
| } |
| |
| this.baseName = baseName; |
| this.shortName = Preconditions.checkNotNull(shortName); |
| this.fullyQualifiedName = String.format("%s:%s", baseName, shortName); |
| } |
| |
| /** |
| * For use by InputRule, which is synthetic, and therefore has no buildFile. |
| * @param inputFile Input file. |
| * @param relativePath |
| */ |
| private BuildTarget(File inputFile, String relativePath) { |
| Preconditions.checkNotNull(inputFile); |
| Preconditions.checkNotNull(relativePath); |
| this.baseName = String.format("//%s", relativePath); |
| this.shortName = inputFile.getName(); |
| this.fullyQualifiedName = String.format("%s:%s", baseName, shortName); |
| } |
| |
| /** |
| * For exclusive use by {@link com.facebook.buck.rules.InputRule#InputRule(File, String)}. |
| */ |
| public static BuildTarget createBuildTargetForInputFile(File inputFile, String relativePath) { |
| return new BuildTarget(inputFile, relativePath); |
| } |
| |
| /** |
| * The build file in which this rule was defined. |
| * @throws MissingBuildFileException if the build file for the target does not exist. |
| */ |
| public File getBuildFile(ProjectFilesystem projectFilesystem) throws MissingBuildFileException { |
| String pathToBuildFile = getBasePathWithSlash() + BuckConstant.BUILD_RULES_FILE_NAME; |
| File buildFile = projectFilesystem.getFileForRelativePath(pathToBuildFile); |
| if (buildFile.isFile()) { |
| return buildFile; |
| } else { |
| throw new MissingBuildFileException(this); |
| } |
| } |
| |
| @SuppressWarnings("serial") |
| public static class MissingBuildFileException extends BuildTargetException { |
| |
| private MissingBuildFileException(BuildTarget buildTarget) { |
| super(String.format("No build file at %s when resolving target %s.", |
| buildTarget.getBasePathWithSlash() + BuckConstant.BUILD_RULES_FILE_NAME, |
| buildTarget.getFullyQualifiedName())); |
| } |
| |
| @Override |
| public String getHumanReadableErrorMessage() { |
| return getMessage(); |
| } |
| } |
| |
| public Path getBuildFilePath() { |
| return java.nio.file.Paths.get(getBaseNameWithSlash() + BuckConstant.BUILD_RULES_FILE_NAME); |
| } |
| |
| /** |
| * If this build target were //third_party/java/guava:guava-latest, then this would return |
| * "guava-latest". |
| */ |
| @JsonProperty("shortName") |
| public String getShortName() { |
| return shortName; |
| } |
| |
| /** |
| * If this build target were //third_party/java/guava:guava-latest, then this would return |
| * "//third_party/java/guava". |
| */ |
| @JsonProperty("baseName") |
| public String getBaseName() { |
| return baseName; |
| } |
| |
| /** |
| * If this build target were //third_party/java/guava:guava-latest, then this would return |
| * "//third_party/java/guava/". |
| */ |
| public String getBaseNameWithSlash() { |
| return getBaseNameWithSlash(baseName); |
| } |
| |
| /** |
| * Helper function for getting BuildTarget base names with a trailing slash if needed. |
| * |
| * If baseName were //third_party/java/guava, then this would return "//third_party/java/guava/". |
| * If it were //, it would return //. |
| */ |
| @Nullable |
| public static String getBaseNameWithSlash(@Nullable String baseName) { |
| return baseName == null || baseName.equals(BUILD_TARGET_PREFIX) ? baseName : baseName + "/"; |
| } |
| |
| /** |
| * If this build target were //third_party/java/guava:guava-latest, then this would return |
| * "third_party/java/guava". This does not contain the "//" prefix so that it can be appended to |
| * a file path. |
| */ |
| public String getBasePath() { |
| return baseName.substring(BUILD_TARGET_PREFIX.length()); |
| } |
| |
| /** |
| * @return the value of {@link #getBasePath()} with a trailing slash, unless |
| * {@link #getBasePath()} returns the empty string, in which case this also returns the empty |
| * string |
| */ |
| public String getBasePathWithSlash() { |
| String basePath = getBasePath(); |
| return basePath.isEmpty() ? "" : basePath + "/"; |
| } |
| |
| /** |
| * If this build target is //third_party/java/guava:guava-latest, then this would return |
| * "//third_party/java/guava:guava-latest". |
| */ |
| public String getFullyQualifiedName() { |
| return fullyQualifiedName; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof BuildTarget)) { |
| return false; |
| } |
| BuildTarget that = (BuildTarget)o; |
| return this.fullyQualifiedName.equals(that.fullyQualifiedName); |
| } |
| |
| @Override |
| public int hashCode() { |
| return fullyQualifiedName.hashCode(); |
| } |
| |
| /** @return {@link #getFullyQualifiedName()} */ |
| @Override |
| public String toString() { |
| return getFullyQualifiedName(); |
| } |
| |
| @Override |
| public int compareTo(BuildTarget target) { |
| Preconditions.checkNotNull(target); |
| return getFullyQualifiedName().compareTo(target.getFullyQualifiedName()); |
| } |
| } |