Move PackageIdentifier to cmdline
This is necessary to have TargetResolver depend on it without making it depend
on the packages target. First step of #389.
--
MOS_MIGRATED_REVID=101790345
diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuildFileContainsErrorsException.java b/src/main/java/com/google/devtools/build/lib/packages/BuildFileContainsErrorsException.java
index c116898..a6e4c87 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/BuildFileContainsErrorsException.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/BuildFileContainsErrorsException.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.packages;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+
import javax.annotation.Nullable;
/**
diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuildFileNotFoundException.java b/src/main/java/com/google/devtools/build/lib/packages/BuildFileNotFoundException.java
index e425013..0e5b3e7 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/BuildFileNotFoundException.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/BuildFileNotFoundException.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.packages;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+
/**
* Exception indicating an attempt to access a package which is not found or
* does not exist.
diff --git a/src/main/java/com/google/devtools/build/lib/packages/CachingPackageLocator.java b/src/main/java/com/google/devtools/build/lib/packages/CachingPackageLocator.java
index 3d677990..c8159ae 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/CachingPackageLocator.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/CachingPackageLocator.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.packages;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.vfs.Path;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/DuplicatePackageException.java b/src/main/java/com/google/devtools/build/lib/packages/DuplicatePackageException.java
index 8dff44f..5f2d22a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/DuplicatePackageException.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/DuplicatePackageException.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.packages;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+
/**
* Exception indicating that the same package (i.e. BUILD file) can be loaded
* via different package paths.
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
index f71da8b..2e429ff 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
@@ -18,9 +18,11 @@
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier.RepositoryName;
+import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.events.StoredEventHandler;
-import com.google.devtools.build.lib.packages.PackageIdentifier.RepositoryName;
import com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException;
import com.google.devtools.build.lib.syntax.FuncallExpression;
import com.google.devtools.build.lib.syntax.Label;
@@ -134,7 +136,11 @@
Rule tempRule = RuleFactory.createRule(this, ruleClass, kwargs, eventHandler, ast,
ast.getLocation());
addEvents(eventHandler.getEvents());
- repositoryMap.put(RepositoryName.create("@" + tempRule.getName()), tempRule);
+ try {
+ repositoryMap.put(RepositoryName.create("@" + tempRule.getName()), tempRule);
+ } catch (TargetParsingException e) {
+ throw new SyntaxException(e.getMessage());
+ }
for (Map.Entry<String, Label> entry :
ruleClass.getExternalBindingsFunction().apply(tempRule).entrySet()) {
Label nameLabel = Label.parseAbsolute("//external:" + entry.getKey());
diff --git a/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java b/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java
index af596ff..d459bf6 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/GlobCache.java
@@ -21,6 +21,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.SettableFuture;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.concurrent.ThreadSafety;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.Path;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/InvalidPackageNameException.java b/src/main/java/com/google/devtools/build/lib/packages/InvalidPackageNameException.java
index d4ef8ce..0524d9a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/InvalidPackageNameException.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/InvalidPackageNameException.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.packages;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+
/**
* Exception indicating that a package name was invalid.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NoSuchPackageException.java b/src/main/java/com/google/devtools/build/lib/packages/NoSuchPackageException.java
index 8db0db6..9c2316a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NoSuchPackageException.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NoSuchPackageException.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.packages;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+
import javax.annotation.Nullable;
/**
@@ -22,7 +24,7 @@
*/
public abstract class NoSuchPackageException extends NoSuchThingException {
- private final PackageIdentifier packageId;
+ private final com.google.devtools.build.lib.cmdline.PackageIdentifier packageId;
public NoSuchPackageException(PackageIdentifier packageId, String message) {
this(packageId, "no such package", message);
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index 1a52b5e..71054a1 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -25,6 +25,7 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.Constants;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.collect.CollectionUtils;
import com.google.devtools.build.lib.collect.ImmutableSortedKeyMap;
import com.google.devtools.build.lib.events.Event;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageDeserializer.java b/src/main/java/com/google/devtools/build/lib/packages/PackageDeserializer.java
index f4898fd..95a928f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageDeserializer.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageDeserializer.java
@@ -22,6 +22,8 @@
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
@@ -480,7 +482,7 @@
try {
builder = new Package.Builder(
new PackageIdentifier(packagePb.getRepository(), new PathFragment(packagePb.getName())));
- } catch (SyntaxException e) {
+ } catch (TargetParsingException e) {
throw new PackageDeserializationException(e);
}
StoredEventHandler eventHandler = new StoredEventHandler();
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 8fed87b..c0bb03c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -22,6 +22,7 @@
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.devtools.build.lib.cmdline.LabelValidator;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Location;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageIdentifier.java b/src/main/java/com/google/devtools/build/lib/packages/PackageIdentifier.java
deleted file mode 100644
index f45ecc4..0000000
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageIdentifier.java
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright 2014 Google Inc. 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.packages;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ComparisonChain;
-import com.google.devtools.build.lib.cmdline.LabelValidator;
-import com.google.devtools.build.lib.syntax.Label;
-import com.google.devtools.build.lib.syntax.Label.SyntaxException;
-import com.google.devtools.build.lib.util.StringCanonicalizer;
-import com.google.devtools.build.lib.util.StringUtilities;
-import com.google.devtools.build.lib.vfs.Canonicalizer;
-import com.google.devtools.build.lib.vfs.PathFragment;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.util.Objects;
-import java.util.concurrent.ExecutionException;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * Uniquely identifies a package, given a repository name and a package's path fragment.
- *
- * <p>The repository the build is happening in is the <i>default workspace</i>, and is identified
- * by the workspace name "". Other repositories can be named in the WORKSPACE file. These
- * workspaces are prefixed by {@literal @}.</p>
- */
-@Immutable
-public final class PackageIdentifier implements Comparable<PackageIdentifier>, Serializable {
-
- /**
- * A human-readable name for the repository.
- */
- public static final class RepositoryName {
- private static final LoadingCache<String, RepositoryName> repositoryNameCache =
- CacheBuilder.newBuilder()
- .weakValues()
- .build(
- new CacheLoader<String, RepositoryName> () {
- @Override
- public RepositoryName load(String name) throws SyntaxException {
- String errorMessage = validate(name);
- if (errorMessage != null) {
- errorMessage = "invalid repository name '"
- + StringUtilities.sanitizeControlChars(name) + "': " + errorMessage;
- throw new SyntaxException(errorMessage);
- }
- return new RepositoryName(StringCanonicalizer.intern(name));
- }
- });
-
- /**
- * Makes sure that name is a valid repository name and creates a new RepositoryName using it.
- * @throws SyntaxException if the name is invalid.
- */
- public static RepositoryName create(String name) throws SyntaxException {
- try {
- return repositoryNameCache.get(name);
- } catch (ExecutionException e) {
- Throwables.propagateIfInstanceOf(e.getCause(), SyntaxException.class);
- throw new IllegalStateException("Failed to create RepositoryName from " + name, e);
- }
- }
-
- private final String name;
-
- private RepositoryName(String name) {
- this.name = name;
- }
-
- /**
- * Performs validity checking. Returns null on success, an error message otherwise.
- */
- private static String validate(String name) {
- if (name.isEmpty()) {
- return null;
- }
-
- if (!name.startsWith("@")) {
- return "workspace name must start with '@'";
- }
-
- // "@" isn't a valid workspace name.
- if (name.length() == 1) {
- return "empty workspace name";
- }
-
- // Check for any character outside of [/0-9A-Z_a-z-._]. Try to evaluate the
- // conditional quickly (by looking in decreasing order of character class
- // likelihood).
- if (name.startsWith("@/") || name.endsWith("/")) {
- return "workspace names cannot start nor end with '/'";
- } else if (name.contains("//")) {
- return "workspace names cannot contain multiple '/'s in a row";
- }
-
- for (int i = name.length() - 1; i >= 1; --i) {
- char c = name.charAt(i);
- if ((c < 'a' || c > 'z') && c != '_' && c != '-' && c != '/' && c != '.'
- && (c < '0' || c > '9') && (c < 'A' || c > 'Z')) {
- return "workspace names may contain only A-Z, a-z, 0-9, '-', '_', '.', and '/'";
- }
- }
- return null;
- }
-
- /**
- * Returns the repository name without the leading "{@literal @}". For the default repository,
- * returns "".
- */
- public String strippedName() {
- if (name.isEmpty()) {
- return name;
- }
- return name.substring(1);
- }
-
- /**
- * Returns if this is the default repository, that is, {@link #name} is "".
- */
- public boolean isDefault() {
- return name.isEmpty();
- }
-
- /**
- * Returns the repository name, with leading "{@literal @}" (or "" for the default repository).
- */
- // TODO(bazel-team): Use this over toString()- easier to track its usage.
- public String getName() {
- return name;
- }
-
- /**
- * Returns the repository name, with leading "{@literal @}" (or "" for the default repository).
- */
- @Override
- public String toString() {
- return name;
- }
-
- @Override
- public boolean equals(Object object) {
- if (this == object) {
- return true;
- }
- if (!(object instanceof RepositoryName)) {
- return false;
- }
- return name.equals(((RepositoryName) object).name);
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
- }
-
- public static final String DEFAULT_REPOSITORY = "";
- public static final RepositoryName DEFAULT_REPOSITORY_NAME;
-
- static {
- try {
- DEFAULT_REPOSITORY_NAME = RepositoryName.create(DEFAULT_REPOSITORY);
- } catch (Label.SyntaxException e) {
- throw new IllegalStateException(e);
- }
- }
-
- /**
- * Helper for serializing PackageIdentifiers.
- *
- * <p>PackageIdentifier's field should be final, but then it couldn't be deserialized. This
- * allows the fields to be deserialized and copied into a new PackageIdentifier.</p>
- */
- private static final class SerializationProxy implements Serializable {
- PackageIdentifier packageId;
-
- public SerializationProxy(PackageIdentifier packageId) {
- this.packageId = packageId;
- }
-
- private void writeObject(ObjectOutputStream out) throws IOException {
- out.writeObject(packageId.repository.toString());
- out.writeObject(packageId.pkgName);
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException {
- try {
- packageId = new PackageIdentifier((String) in.readObject(), (PathFragment) in.readObject());
- } catch (SyntaxException e) {
- throw new IOException("Error serializing package identifier: " + e.getMessage());
- }
- }
-
- @SuppressWarnings("unused")
- private void readObjectNoData() throws ObjectStreamException {
- }
-
- private Object readResolve() {
- return packageId;
- }
- }
-
- // Temporary factory for identifiers without explicit repositories.
- // TODO(bazel-team): remove all usages of this.
- public static PackageIdentifier createInDefaultRepo(String name) {
- return createInDefaultRepo(new PathFragment(name));
- }
-
- public static PackageIdentifier createInDefaultRepo(PathFragment name) {
- try {
- return new PackageIdentifier(DEFAULT_REPOSITORY, name);
- } catch (SyntaxException e) {
- throw new IllegalArgumentException("could not create package identifier for " + name
- + ": " + e.getMessage());
- }
- }
-
- /**
- * The identifier for this repository. This is either "" or prefixed with an "@",
- * e.g., "@myrepo".
- */
- private final RepositoryName repository;
-
- /** The name of the package. Canonical (i.e. x.equals(y) <=> x==y). */
- private final PathFragment pkgName;
-
- public PackageIdentifier(String repository, PathFragment pkgName) throws SyntaxException {
- this(RepositoryName.create(repository), pkgName);
- }
-
- public PackageIdentifier(RepositoryName repository, PathFragment pkgName) {
- Preconditions.checkNotNull(repository);
- Preconditions.checkNotNull(pkgName);
- this.repository = repository;
- this.pkgName = Canonicalizer.fragments().intern(pkgName.normalize());
- }
-
- public static PackageIdentifier parse(String input) throws SyntaxException {
- String repo;
- String packageName;
- int packageStartPos = input.indexOf("//");
- if (packageStartPos > 0) {
- repo = input.substring(0, packageStartPos);
- packageName = input.substring(packageStartPos + 2);
- } else if (packageStartPos == 0) {
- repo = PackageIdentifier.DEFAULT_REPOSITORY;
- packageName = input.substring(2);
- } else {
- repo = PackageIdentifier.DEFAULT_REPOSITORY;
- packageName = input;
- }
-
- String error = RepositoryName.validate(repo);
- if (error != null) {
- throw new SyntaxException(error);
- }
-
- error = LabelValidator.validatePackageName(packageName);
- if (error != null) {
- throw new SyntaxException(error);
- }
-
- return new PackageIdentifier(repo, new PathFragment(packageName));
- }
-
- private Object writeReplace() throws ObjectStreamException {
- return new SerializationProxy(this);
- }
-
- private void readObject(ObjectInputStream in)
- throws IOException, ClassNotFoundException {
- throw new IOException("Serialization is allowed only by proxy");
- }
-
- @SuppressWarnings("unused")
- private void readObjectNoData() throws ObjectStreamException {
- }
-
- public RepositoryName getRepository() {
- return repository;
- }
-
- public PathFragment getPackageFragment() {
- return pkgName;
- }
-
- /**
- * Returns a relative path that should be unique across all remote and packages, based on the
- * repository and package names.
- */
- public PathFragment getPathFragment() {
- return repository.isDefault() ? pkgName
- : new PathFragment(ExternalPackage.NAME).getRelative(repository.strippedName())
- .getRelative(pkgName);
- }
-
- /**
- * Returns the name of this package.
- *
- * <p>There are certain places that expect the path fragment as the package name ('foo/bar') as a
- * package identifier. This isn't specific enough for packages in other repositories, so their
- * stringified version is '@baz//foo/bar'.</p>
- */
- @Override
- public String toString() {
- return (repository.isDefault() ? "" : repository + "//") + pkgName;
- }
-
- @Override
- public boolean equals(Object object) {
- if (this == object) {
- return true;
- }
- if (!(object instanceof PackageIdentifier)) {
- return false;
- }
- PackageIdentifier that = (PackageIdentifier) object;
- return pkgName.equals(that.pkgName) && repository.equals(that.repository);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(repository, pkgName);
- }
-
- @Override
- public int compareTo(PackageIdentifier that) {
- return ComparisonChain.start()
- .compare(repository.toString(), that.repository.toString())
- .compare(pkgName, that.pkgName)
- .result();
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RelativePackageNameResolver.java b/src/main/java/com/google/devtools/build/lib/packages/RelativePackageNameResolver.java
index 2cab8a3..30fc815 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RelativePackageNameResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RelativePackageNameResolver.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.packages;
import com.google.common.base.Preconditions;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.vfs.PathFragment;
/**