diff options
author | Adam Michael <ajmichael@google.com> | 2016-10-27 17:01:40 +0000 |
---|---|---|
committer | John Cater <jcater@google.com> | 2016-10-27 17:12:03 +0000 |
commit | f2c46a0262e17c3d6f6504a0bc20fcb5ca8a4d49 (patch) | |
tree | 178420a741018c6442fbf3d42c2843a4bed316f1 /src | |
parent | 3ab8f9d343bdf63a46c04807c44a25e341f09f98 (diff) |
Rollback of commit fac9be905f0f82f793eb1cc61afab42698769dcf.
*** Reason for rollback ***
Rollforward with fixes for android_integration_test.sh
*** Original change description ***
Automated [] rollback of commit 2fcf0e4cfb97af7cc8b8a090c5144c87b759bc13.
*** Reason for rollback ***
Breaks android_integration_test, see https://github.com/bazelbuild/bazel/issues/1927
*** Original change description ***
Generate aar_import and java_import rules for local maven repositories in <sdk>/extras for sdk in android_sdk_repository.
Addresses https://github.com/bazelbuild/bazel/issues/1745.
--
MOS_MIGRATED_REVID=137407118
Diffstat (limited to 'src')
8 files changed, 527 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index 5852a19012..b916bdddf4 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -13,6 +13,9 @@ // limitations under the License. package com.google.devtools.build.lib.bazel.rules.android; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.AttributeMap; @@ -35,6 +38,7 @@ import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; import java.io.IOException; import java.util.Properties; +import javax.annotation.Nullable; /** * Implementation of the {@code android_sdk_repository} rule. @@ -90,6 +94,26 @@ public class AndroidSdkRepositoryFunction extends RepositoryFunction { .replaceAll("%build_tools_directory%", buildToolsDirectory) .replaceAll("%api_level%", apiLevel.toString()); + // All local maven repositories that are shipped in the Android SDK. + // TODO(ajmichael): Create SkyKeys so that if the SDK changes, this function will get rerun. + Iterable<Path> localMavenRepositories = ImmutableList.of( + outputDirectory.getRelative("extras/android/m2repository"), + outputDirectory.getRelative("extras/google/m2repository")); + try { + SdkMavenRepository sdkExtrasRepository = + SdkMavenRepository.create(Iterables.filter(localMavenRepositories, new Predicate<Path>() { + @Override + public boolean apply(@Nullable Path path) { + return path.isDirectory(); + } + })); + sdkExtrasRepository.writeBuildFiles(outputDirectory); + buildFile = buildFile.replaceAll( + "%exported_files%", sdkExtrasRepository.getExportsFiles(outputDirectory)); + } catch (IOException e) { + throw new RepositoryFunctionException(e, Transience.TRANSIENT); + } + writeBuildFile(outputDirectory, buildFile); return RepositoryDirectoryValue.create(outputDirectory); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/SdkMavenRepository.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/SdkMavenRepository.java new file mode 100644 index 0000000000..136da18742 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/SdkMavenRepository.java @@ -0,0 +1,282 @@ +// Copyright 2016 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.bazel.rules.android; + +import com.google.auto.value.AutoValue; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Ordering; +import com.google.devtools.build.lib.vfs.FileSystemUtils; +import com.google.devtools.build.lib.vfs.Path; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import javax.annotation.Nullable; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * A collection of .pom contents that reference versioned archive files with dependencies. + */ +final class SdkMavenRepository { + private enum PackagingType { + AAR { + @Override + ImmutableList<String> createRule( + String name, String archiveLabel, ImmutableList<String> dependencyLabels) { + ImmutableList.Builder<String> ruleLines = new ImmutableList.Builder<>(); + ruleLines.add("aar_import("); + ruleLines.add(" name = '" + name + "',"); + ruleLines.add(" aar = '" + archiveLabel + "',"); + ruleLines.add(" exports = ["); + for (String dependencyLabel : dependencyLabels) { + ruleLines.add(" '" + dependencyLabel + "',"); + } + ruleLines.add(" ],"); + ruleLines.add(")"); + ruleLines.add(""); + return ruleLines.build(); + } + }, + JAR { + @Override + ImmutableList<String> createRule( + String name, String archiveLabel, ImmutableList<String> dependencyLabels) { + ImmutableList.Builder<String> ruleLines = new ImmutableList.Builder<>(); + ruleLines.add("java_import("); + ruleLines.add(" name = '" + name + "',"); + ruleLines.add(" jars = ['" + archiveLabel + "'],"); + ruleLines.add(" exports = ["); + for (String dependencyLabel : dependencyLabels) { + ruleLines.add(" '" + dependencyLabel + "',"); + } + ruleLines.add(" ],"); + ruleLines.add(")"); + ruleLines.add(""); + return ruleLines.build(); + } + }, + UNKNOWN { + @Override + ImmutableList<String> createRule(String name, String archiveLabel, + ImmutableList<String> dependencyLabels) { + ImmutableList.Builder<String> ruleLines = new ImmutableList.Builder<>(); + ruleLines.add("genrule("); + ruleLines.add(" name = '" + name + "',"); + ruleLines.add(" outs = ['ignored_" + name + "'],"); + ruleLines.add(" cmd = 'echo Bazel does not recognize the Maven packaging type for: \"" + + archiveLabel + "\"; exit 1',"); + ruleLines.add(")"); + ruleLines.add(""); + return ruleLines.build(); + } + }; + + static PackagingType getPackagingType(String name) { + for (PackagingType packagingType : PackagingType.values()) { + if (packagingType.name().equalsIgnoreCase(name)) { + return packagingType; + } + } + return UNKNOWN; + } + + abstract ImmutableList<String> createRule( + String name, String archiveLabel, ImmutableList<String> dependencyLabels); + } + + private final ImmutableSortedSet<Pom> poms; + private final ImmutableSet<MavenCoordinate> allKnownCoordinates; + + private SdkMavenRepository(ImmutableSortedSet<Pom> poms) { + this.poms = poms; + ImmutableSet.Builder<MavenCoordinate> coordinates = new ImmutableSet.Builder<>(); + for (Pom pom : poms) { + if (!PackagingType.getPackagingType(pom.packaging()).equals(PackagingType.UNKNOWN)) { + coordinates.add(pom.mavenCoordinate()); + } + } + allKnownCoordinates = coordinates.build(); + } + + /** + * Parses a set of maven repository directory trees looking for and parsing .pom files. + */ + static SdkMavenRepository create(Iterable<Path> mavenRepositories) throws IOException { + Collection<Path> pomPaths = new ArrayList<>(); + for (Path mavenRepository : mavenRepositories) { + pomPaths.addAll(FileSystemUtils.traverseTree(mavenRepository, new Predicate<Path>() { + @Override + public boolean apply(@Nullable Path path) { + return path.toString().endsWith(".pom"); + } + })); + } + + ImmutableSortedSet.Builder<Pom> poms = + new ImmutableSortedSet.Builder<>(Ordering.usingToString()); + for (Path pomPath : pomPaths) { + try { + Pom pom = Pom.parse(pomPath); + if (pom != null) { + poms.add(pom); + } + } catch (ParserConfigurationException | SAXException e) { + throw new IOException(e); + } + } + return new SdkMavenRepository(poms.build()); + } + + /** + * Creates BUILD files at {@code @<android sdk>/<group id>/BUILD} containing aar_import and + * java_import rules with dependencies as {@code exports}. The targets are named + * {@code @<android sdk>//<group id>:<artifact id>-<version id>}. + */ + void writeBuildFiles(Path outputDirectory) throws IOException { + for (Pom pom : poms) { + Path buildFilePath = outputDirectory.getRelative(pom.mavenCoordinate().groupId() + "/BUILD"); + + if (!buildFilePath.getParentDirectory().exists()) { + buildFilePath.getParentDirectory().createDirectory(); + } + + if (!buildFilePath.exists()) { + FileSystemUtils.writeContentAsLatin1( + buildFilePath, "package(default_visibility = [\"//visibility:public\"])\n\n"); + } + + ImmutableList.Builder<String> dependencyLabels = new ImmutableList.Builder<>(); + for (MavenCoordinate dependencyCoordinate : pom.dependencyCoordinates()) { + // Filter out dependencies that are not present in the Maven repository or have unknown + // packaging types. + if (allKnownCoordinates.contains(dependencyCoordinate)) { + dependencyLabels.add(dependencyCoordinate.targetLabel()); + } + } + + ImmutableList<String> ruleLines = PackagingType.getPackagingType(pom.packaging()) + .createRule( + pom.mavenCoordinate().targetName(), + pom.archiveLabel(outputDirectory), + dependencyLabels.build()); + FileSystemUtils.appendLinesAs(buildFilePath, StandardCharsets.ISO_8859_1, ruleLines); + } + } + + /** + * Creates the contents of the exports_files rule list containing all of the archives specified by + * the pom files in the Maven repositories. + */ + String getExportsFiles(Path outputDirectory) { + StringBuilder exportedFiles = new StringBuilder(); + for (Pom pom : poms) { + exportedFiles.append(String.format( + " '%s',\n", pom.archivePath().relativeTo(outputDirectory).getPathString())); + } + return exportedFiles.toString(); + } + + /** + * The relevant contents of a .pom file needed to populate BUILD files for aars and jars in the + * Android SDK extras maven repositories. + */ + @AutoValue + abstract static class Pom { + private static final String DEFAULT_PACKAGING = "jar"; + + static Pom parse(Path path) throws IOException, ParserConfigurationException, SAXException { + Document pomDocument = + DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(path.getInputStream()); + Node packagingNode = pomDocument.getElementsByTagName("packaging").item(0); + String packaging = packagingNode == null ? DEFAULT_PACKAGING : packagingNode.getTextContent(); + MavenCoordinate coordinate = MavenCoordinate.create( + pomDocument.getElementsByTagName("groupId").item(0).getTextContent(), + pomDocument.getElementsByTagName("artifactId").item(0).getTextContent(), + pomDocument.getElementsByTagName("version").item(0).getTextContent()); + + ImmutableSortedSet.Builder<MavenCoordinate> dependencyCoordinates = + new ImmutableSortedSet.Builder<>(Ordering.usingToString()); + NodeList dependencies = pomDocument.getElementsByTagName("dependency"); + for (int i = 0; i < dependencies.getLength(); i++) { + if (dependencies.item(i) instanceof Element) { + Element dependency = (Element) dependencies.item(i); + dependencyCoordinates.add(MavenCoordinate.create( + dependency.getElementsByTagName("groupId").item(0).getTextContent(), + dependency.getElementsByTagName("artifactId").item(0).getTextContent(), + dependency.getElementsByTagName("version").item(0).getTextContent())); + } + } + + return new AutoValue_SdkMavenRepository_Pom( + path, packaging, coordinate, dependencyCoordinates.build()); + } + + abstract Path path(); + + abstract String packaging(); + + abstract MavenCoordinate mavenCoordinate(); + + abstract ImmutableSortedSet<MavenCoordinate> dependencyCoordinates(); + + String name() { + String pomFilename = path().getBaseName(); + return pomFilename.substring(0, pomFilename.lastIndexOf(".pom")); + } + + Path archivePath() { + return path().getParentDirectory().getRelative(name() + "." + packaging()); + } + + /** The label for the .aar or .jar file in the repository. */ + String archiveLabel(Path outputDirectory) { + return "//:" + archivePath().relativeTo(outputDirectory); + } + } + + /** + * A 3-tuple of group id, artifact id and version used to identify Maven targets. + */ + @AutoValue + abstract static class MavenCoordinate { + static MavenCoordinate create(String groupId, String artifactId, String version) { + return new AutoValue_SdkMavenRepository_MavenCoordinate(groupId, artifactId, version); + } + + abstract String groupId(); + + abstract String artifactId(); + + abstract String version(); + + /** The target name for the java_import or aar_import for the Maven coordinate. */ + String targetName() { + return artifactId() + "-" + version(); + } + + /** The target label for the java_import or aar_import for the Maven coordinate. */ + String targetLabel() { + return "//" + groupId() + ":" + targetName(); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt index e82b5e4c16..2630685589 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_sdk_repository_template.txt @@ -8,3 +8,6 @@ create_android_sdk_rules( build_tools_directory = "%build_tools_directory%", api_level = %api_level%, ) + +exports_files([ +%exported_files%]) diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index 0556e41c5a..f7ae7d599a 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -959,6 +959,7 @@ java_test( ":analysis_testutil", ":foundations_testutil", ":test_runner", + ":testutil", "//src/main/java/com/google/devtools/build/lib:android-rules", "//src/main/java/com/google/devtools/build/lib:bazel-main", "//src/main/java/com/google/devtools/build/lib:bazel-rules", @@ -966,9 +967,11 @@ java_test( "//src/main/java/com/google/devtools/build/lib:events", "//src/main/java/com/google/devtools/build/lib:java-compilation", "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib:syntax", "//src/main/java/com/google/devtools/build/lib:util", "//src/main/java/com/google/devtools/build/lib:vfs", "//src/main/java/com/google/devtools/build/lib/actions", + "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/protobuf:crosstool_config_java_proto", "//src/test/java/com/google/devtools/build/lib:actions_testutil", "//third_party:guava", diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java index d89d4c8caf..1189d99f31 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java @@ -111,6 +111,11 @@ public final class BazelAnalysisMock extends AnalysisMock { config.create( "/bazel_tools_workspace/tools/android/BUILD", androidBuildContents.toArray(new String[androidBuildContents.size()])); + config.create( + "/bazel_tools_workspace/tools/android/android_sdk_repository_template.bzl", + "def create_android_sdk_rules(" + + "name, build_tools_version, build_tools_directory, api_level):", + " pass"); config.create( "/bazel_tools_workspace/tools/genrule/BUILD", "exports_files(['genrule-setup.sh'])"); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java index d01db4f360..c1c8a55fbb 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java @@ -18,6 +18,8 @@ import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.analysis.ConfigurationCollectionFactory; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.config.ConfigurationFactory; +import com.google.devtools.build.lib.bazel.rules.android.AndroidSdkRepositoryFunction; +import com.google.devtools.build.lib.bazel.rules.android.AndroidSdkRepositoryRule; import com.google.devtools.build.lib.flags.InvocationPolicyEnforcer; import com.google.devtools.build.lib.packages.PackageFactory; import com.google.devtools.build.lib.packages.util.LoadingMock; @@ -110,7 +112,8 @@ public abstract class AnalysisMock extends LoadingMock { // Some tests require the local_repository rule so we need the appropriate SkyFunctions. RepositoryFunction localRepositoryFunction = new LocalRepositoryFunction(); ImmutableMap<String, RepositoryFunction> repositoryHandlers = ImmutableMap.of( - LocalRepositoryRule.NAME, localRepositoryFunction); + LocalRepositoryRule.NAME, localRepositoryFunction, + AndroidSdkRepositoryRule.NAME, new AndroidSdkRepositoryFunction()); return ImmutableMap.of( SkyFunctions.REPOSITORY_DIRECTORY, diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryTest.java new file mode 100644 index 0000000000..a970d41125 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryTest.java @@ -0,0 +1,67 @@ +// Copyright 2016 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.bazel.rules.android; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.vfs.FileSystemUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link AndroidNdkRepositoryFunction}. */ +@RunWith(JUnit4.class) +public class AndroidSdkRepositoryTest extends BuildViewTestCase { + + @Before + public void setup() throws Exception { + scratch.setWorkingDir("/sdk"); + scratch.file("extras/google/m2repository/com/google/android/foo/1.0.0/foo.pom", + "<project>", + " <groupId>com.google.android</groupId>", + " <artifactId>foo</artifactId>", + " <version>1.0.0</version>", + " <packaging>aar</packaging>", + "</project>"); + + scratch.setWorkingDir("/workspace"); + FileSystemUtils.appendIsoLatin1(scratch.resolve("WORKSPACE"), + "android_sdk_repository(", + " name = 'mysdk',", + " path = '/sdk',", + " build_tools_version = '24.0.0',", + " api_level = 24,", + ")"); + } + + @Test + public void testGeneratedAarImport() throws Exception { + invalidatePackages(); + ConfiguredTarget aarImportTarget = getConfiguredTarget("@mysdk//com.google.android:foo-1.0.0"); + assertThat(aarImportTarget.getTarget().getAssociatedRule().getRuleClass()) + .isEqualTo("aar_import"); + } + + @Test + public void testExportsFiles() throws Exception { + invalidatePackages(); + ConfiguredTarget aarTarget = getConfiguredTarget( + "@mysdk//:extras/google/m2repository/com/google/android/foo/1.0.0/foo.aar"); + assertThat(aarTarget).isNotNull(); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/android/SdkMavenRepositoryTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/SdkMavenRepositoryTest.java new file mode 100644 index 0000000000..02cf802a6a --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/SdkMavenRepositoryTest.java @@ -0,0 +1,139 @@ +// Copyright 2016 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.bazel.rules.android; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.packages.AttributeMap; +import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.packages.RawAttributeMapper; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.syntax.Type; +import com.google.devtools.build.lib.vfs.Path; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link SdkMavenRepository}. */ +@RunWith(JUnit4.class) +public class SdkMavenRepositoryTest extends BuildViewTestCase { + Path workspaceDir; + Path repoPath; + SdkMavenRepository sdkMavenRepository; + + @Before + public void setup() throws Exception { + repoPath = scratch.dir("repo"); + workspaceDir = scratch.dir(""); + + scratch.file("repo/com/google/android/foo/1.0.0/foo.pom", + "<project>", + " <groupId>com.google.android</groupId>", + " <artifactId>foo</artifactId>", + " <version>1.0.0</version>", + "</project>"); + scratch.file("repo/com/google/android/bar/1.0.0/bar.pom", + "<project>", + " <groupId>com.google.android</groupId>", + " <artifactId>bar</artifactId>", + " <version>1.0.0</version>", + " <packaging>aar</packaging>", + " <dependencies>", + " <dependency>", + " <groupId>com.google.android</groupId>", + " <artifactId>foo</artifactId>", + " <version>1.0.0</version>", + " </dependency>", + " <dependency>", + " <groupId>com.google.android</groupId>", + " <artifactId>baz</artifactId>", + " <version>1.0.0</version>", + " </dependency>", + " </dependencies>", + "</project>"); + scratch.file("repo/com/google/android/baz/1.0.0/baz.pom", + "<project>", + " <groupId>com.google.android</groupId>", + " <artifactId>baz</artifactId>", + " <version>1.0.0</version>", + " <packaging>par</packaging>", + "</project>"); + sdkMavenRepository = SdkMavenRepository.create(ImmutableList.of(repoPath)); + scratch.file("BUILD", + "exports_files([", + sdkMavenRepository.getExportsFiles(workspaceDir), + "])"); + } + + @Test + public void testExportsFiles() throws Exception { + assertThat(sdkMavenRepository.getExportsFiles(workspaceDir)).isEqualTo( + " 'repo/com/google/android/bar/1.0.0/bar.aar',\n" + + " 'repo/com/google/android/baz/1.0.0/baz.par',\n" + + " 'repo/com/google/android/foo/1.0.0/foo.jar',\n" + ); + } + + @Test + public void testBuildFilesWritten() throws Exception { + sdkMavenRepository.writeBuildFiles(workspaceDir); + + Path groupIdPath = scratch.resolve("com.google.android"); + assertThat(workspaceDir.getDirectoryEntries()).containsAllOf(repoPath, groupIdPath); + + Path buildFilePath = groupIdPath.getRelative("BUILD"); + assertThat(groupIdPath.getDirectoryEntries()).containsExactly(buildFilePath); + } + + @Test + public void testGeneratedAarImport() throws Exception { + sdkMavenRepository.writeBuildFiles(workspaceDir); + Rule aarImport = + getConfiguredTarget("//com.google.android:bar-1.0.0").getTarget().getAssociatedRule(); + assertThat(aarImport.getRuleClass()).isEqualTo("aar_import"); + AttributeMap attributes = RawAttributeMapper.of(aarImport); + assertThat(attributes.get("aar", BuildType.LABEL)) + .isEqualTo(Label.parseAbsoluteUnchecked("//:repo/com/google/android/bar/1.0.0/bar.aar")); + assertThat(attributes.get("exports", BuildType.LABEL_LIST)) + .containsExactly(Label.parseAbsoluteUnchecked("//com.google.android:foo-1.0.0")); + } + + @Test + public void testGeneratedJavaImport() throws Exception { + sdkMavenRepository.writeBuildFiles(workspaceDir); + Rule javaImport = + getConfiguredTarget("//com.google.android:foo-1.0.0").getTarget().getAssociatedRule(); + assertThat(javaImport.getRuleClass()).isEqualTo("java_import"); + AttributeMap attributes = RawAttributeMapper.of(javaImport); + assertThat(attributes.get("jars", BuildType.LABEL_LIST)).containsExactly( + Label.parseAbsoluteUnchecked("//:repo/com/google/android/foo/1.0.0/foo.jar")); + assertThat(attributes.get("exports", BuildType.LABEL_LIST)).isEmpty(); + } + + @Test + public void testGeneratedRuleForInvalidPackaging() throws Exception { + sdkMavenRepository.writeBuildFiles(workspaceDir); + Rule invalidPackagingGenrule = + getConfiguredTarget("//com.google.android:baz-1.0.0").getTarget().getAssociatedRule(); + assertThat(invalidPackagingGenrule.getRuleClass()).isEqualTo("genrule"); + assertThat(RawAttributeMapper.of(invalidPackagingGenrule).get("cmd", Type.STRING)) + .isEqualTo("echo Bazel does not recognize the Maven packaging type for: " + + "\"//:repo/com/google/android/baz/1.0.0/baz.par\"; exit 1"); + } +} |