diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index c334be719ee..2c29b22720b 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -70,6 +70,11 @@ gradlePlugin {
id = 'firebase-library'
implementationClass = 'com.google.firebase.gradle.plugins.FirebaseLibraryPlugin'
}
+
+ firebaseJavaLibraryPlugin {
+ id = "firebase-java-library"
+ implementationClass = 'com.google.firebase.gradle.plugins.FirebaseJavaLibraryPlugin'
+ }
}
}
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/Dokka.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/Dokka.java
index 19e5030cc62..2f628e5ed69 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/Dokka.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/Dokka.java
@@ -16,6 +16,7 @@
import com.android.build.gradle.LibraryExtension;
import com.google.common.collect.ImmutableMap;
+import com.sun.istack.Nullable;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
@@ -29,6 +30,7 @@
import org.gradle.api.tasks.Copy;
import org.jetbrains.dokka.DokkaConfiguration;
import org.jetbrains.dokka.gradle.DokkaAndroidTask;
+import org.jetbrains.dokka.gradle.DokkaTask;
final class Dokka {
/**
@@ -47,94 +49,63 @@ final class Dokka {
*
Remove the "https://firebase.google.com" prefix from all urls
*/
static void configure(
- Project project, LibraryExtension android, FirebaseLibraryExtension firebaseLibrary) {
- project.apply(ImmutableMap.of("plugin", "org.jetbrains.dokka-android"));
+ Project project,
+ @Nullable LibraryExtension android,
+ FirebaseLibraryExtension firebaseLibrary) {
+
+ String dokkaPluginName =
+ android == null ? "org.jetbrains.dokka" : "org.jetbrains.dokka-android";
+ project.apply(ImmutableMap.of("plugin", dokkaPluginName));
if (!firebaseLibrary.publishJavadoc) {
project.getTasks().register("kotlindoc");
return;
}
- DokkaAndroidTask dokkaAndroidTask =
- project
- .getTasks()
- .create(
- "kotlindocDokka",
- DokkaAndroidTask.class,
- dokka -> {
- dokka.setOutputDirectory(project.getBuildDir() + "/dokka/firebase");
- dokka.setOutputFormat("dac");
-
- dokka.setGenerateClassIndexPage(false);
- dokka.setGeneratePackageIndexPage(false);
- if (!project.getPluginManager().hasPlugin("kotlin-android")) {
- dokka.dependsOn("docStubs");
- dokka.setSourceDirs(
- Collections.singletonList(
- project.file(project.getBuildDir() + "/doc-stubs")));
- }
+ Class extends DokkaTask> taskClass =
+ android == null ? DokkaTask.class : DokkaAndroidTask.class;
+ DokkaTask dokkaTask = configure(project, taskClass);
- dokka.setNoAndroidSdkLink(true);
+ if (dokkaTask instanceof DokkaAndroidTask) {
+ ((DokkaAndroidTask) dokkaTask).setNoAndroidSdkLink(true);
- createLink(
- project,
- "https://developers.android.com/reference/kotlin/",
- "kotlindoc/package-lists/android/package-list")
- .map(dokka.getExternalDocumentationLinks()::add);
- createLink(
- project,
- "https://developers.google.com/android/reference/",
- "kotlindoc/package-lists/google/package-list")
- .map(dokka.getExternalDocumentationLinks()::add);
- createLink(
- project,
- "https://firebase.google.com/docs/reference/kotlin/",
- "kotlindoc/package-lists/firebase/package-list")
- .map(dokka.getExternalDocumentationLinks()::add);
- createLink(
- project,
- "https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/",
- "kotlindoc/package-lists/coroutines/package-list")
- .map(dokka.getExternalDocumentationLinks()::add);
+ android
+ .getLibraryVariants()
+ .all(
+ v -> {
+ if (v.getName().equals("release")) {
+ project.afterEvaluate(
+ p -> {
+ FileCollection artifactFiles =
+ v.getRuntimeConfiguration()
+ .getIncoming()
+ .artifactView(
+ view -> {
+ view.attributes(
+ attrs ->
+ attrs.attribute(
+ Attribute.of("artifactType", String.class),
+ "jar"));
+ view.componentFilter(
+ c ->
+ !c.getDisplayName()
+ .startsWith("androidx.annotation:annotation:"));
+ })
+ .getArtifacts()
+ .getArtifactFiles()
+ .plus(project.files(android.getBootClasspath()));
+ dokkaTask.setClasspath(artifactFiles);
+ });
+ }
+ });
+ }
- android
- .getLibraryVariants()
- .all(
- v -> {
- if (v.getName().equals("release")) {
- project.afterEvaluate(
- p -> {
- FileCollection artifactFiles =
- v.getRuntimeConfiguration()
- .getIncoming()
- .artifactView(
- view -> {
- view.attributes(
- attrs ->
- attrs.attribute(
- Attribute.of(
- "artifactType", String.class),
- "jar"));
- view.componentFilter(
- c ->
- !c.getDisplayName()
- .startsWith(
- "androidx.annotation:annotation:"));
- })
- .getArtifacts()
- .getArtifactFiles()
- .plus(project.files(android.getBootClasspath()));
- dokka.setClasspath(artifactFiles);
- });
- }
- });
- });
project
.getTasks()
.create(
"kotlindoc",
Copy.class,
copy -> {
- copy.dependsOn(dokkaAndroidTask);
+ copy.dependsOn(dokkaTask);
copy.setDestinationDir(
project.file(project.getRootProject().getBuildDir() + "/firebase-kotlindoc"));
copy.from(
@@ -161,6 +132,49 @@ static void configure(
});
}
+ static T configure(Project project, Class taskType) {
+ return project
+ .getTasks()
+ .create(
+ "kotlindocDokka",
+ taskType,
+ dokka -> {
+ dokka.setOutputDirectory(project.getBuildDir() + "/dokka/firebase");
+ dokka.setOutputFormat("dac");
+
+ dokka.setGenerateClassIndexPage(false);
+ dokka.setGeneratePackageIndexPage(false);
+ if (!project.getPluginManager().hasPlugin("kotlin-android")) {
+ dokka.dependsOn("docStubs");
+ dokka.setSourceDirs(
+ Collections.singletonList(project.file(project.getBuildDir() + "/doc-stubs")));
+ }
+
+ dokka.setNoJdkLink(true);
+
+ createLink(
+ project,
+ "https://developers.android.com/reference/kotlin/",
+ "kotlindoc/package-lists/android/package-list")
+ .map(dokka.getExternalDocumentationLinks()::add);
+ createLink(
+ project,
+ "https://developers.google.com/android/reference/",
+ "kotlindoc/package-lists/google/package-list")
+ .map(dokka.getExternalDocumentationLinks()::add);
+ createLink(
+ project,
+ "https://firebase.google.com/docs/reference/kotlin/",
+ "kotlindoc/package-lists/firebase/package-list")
+ .map(dokka.getExternalDocumentationLinks()::add);
+ createLink(
+ project,
+ "https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/",
+ "kotlindoc/package-lists/coroutines/package-list")
+ .map(dokka.getExternalDocumentationLinks()::add);
+ });
+ }
+
private static Optional createLink(
Project project, String url, String packageListPath) {
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseJavaLibraryPlugin.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseJavaLibraryPlugin.java
new file mode 100644
index 00000000000..a90c0d2fa90
--- /dev/null
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseJavaLibraryPlugin.java
@@ -0,0 +1,200 @@
+// Copyright 2019 Google LLC
+//
+// 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.firebase.gradle.plugins;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.firebase.gradle.plugins.apiinfo.ApiInformationTask;
+import com.google.firebase.gradle.plugins.apiinfo.GenerateApiTxtFileTask;
+import com.google.firebase.gradle.plugins.apiinfo.GenerateStubsTask;
+import com.google.firebase.gradle.plugins.apiinfo.GetMetalavaJarTask;
+import com.google.firebase.gradle.plugins.ci.Coverage;
+import java.io.File;
+import java.nio.file.Paths;
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+import org.gradle.api.attributes.Attribute;
+import org.gradle.api.file.FileCollection;
+import org.gradle.api.plugins.JavaPluginConvention;
+import org.gradle.api.tasks.SourceSet;
+import org.gradle.api.tasks.TaskProvider;
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile;
+
+// TODO(vkryachko): extract functionality common across Firebase{,Java}LibraryPlugin plugins.
+public class FirebaseJavaLibraryPlugin implements Plugin {
+
+ @Override
+ public void apply(Project project) {
+ project.apply(ImmutableMap.of("plugin", "java-library"));
+ FirebaseLibraryExtension firebaseLibrary =
+ project
+ .getExtensions()
+ .create("firebaseLibrary", FirebaseLibraryExtension.class, project, LibraryType.JAVA);
+
+ // reduce the likelihood of kotlin module files colliding.
+ project
+ .getTasks()
+ .withType(
+ KotlinCompile.class,
+ kotlin ->
+ kotlin
+ .getKotlinOptions()
+ .setFreeCompilerArgs(
+ ImmutableList.of("-module-name", kotlinModuleName(project))));
+
+ setupStaticAnalysis(project, firebaseLibrary);
+ project.afterEvaluate(p -> Dokka.configure(project, null, firebaseLibrary));
+ }
+
+ private static void setupStaticAnalysis(Project project, FirebaseLibraryExtension library) {
+ project.afterEvaluate(
+ p ->
+ project
+ .getConfigurations()
+ .all(
+ c -> {
+ if ("annotationProcessor".equals(c.getName())) {
+ for (String checkProject : library.staticAnalysis.errorproneCheckProjects) {
+ project
+ .getDependencies()
+ .add("annotationProcessor", project.project(checkProject));
+ }
+ }
+ if ("lintChecks".equals(c.getName())) {
+ for (String checkProject :
+ library.staticAnalysis.androidLintCheckProjects) {
+ project
+ .getDependencies()
+ .add("lintChecks", project.project(checkProject));
+ }
+ }
+ }));
+
+ setupApiInformationAnalysis(project);
+
+ project.getTasks().register("firebaseLint", task -> task.dependsOn("lint"));
+ Coverage.apply(library);
+ }
+
+ private static void setupApiInformationAnalysis(Project project) {
+ File metalavaOutputJarFile = new File(project.getRootProject().getBuildDir(), "metalava.jar");
+ SourceSet mainSourceSet =
+ project
+ .getConvention()
+ .getPlugin(JavaPluginConvention.class)
+ .getSourceSets()
+ .getByName("main");
+ File outputFile =
+ project
+ .getRootProject()
+ .file(
+ Paths.get(
+ project.getRootProject().getBuildDir().getPath(),
+ "apiinfo",
+ project.getPath().substring(1).replace(":", "_")));
+ File outputApiFile = new File(outputFile.getAbsolutePath() + "_api.txt");
+
+ project
+ .getTasks()
+ .register(
+ "getMetalavaJar",
+ GetMetalavaJarTask.class,
+ task -> {
+ task.setOutputFile(metalavaOutputJarFile);
+ });
+ File apiTxt =
+ project.file("api.txt").exists()
+ ? project.file("api.txt")
+ : project.file(project.getRootDir() + "/empty-api.txt");
+ TaskProvider apiInfo =
+ project
+ .getTasks()
+ .register(
+ "apiInformation",
+ ApiInformationTask.class,
+ task -> {
+ task.setApiTxt(apiTxt);
+ task.setMetalavaJarPath(metalavaOutputJarFile.getAbsolutePath());
+ task.setSourceSet(mainSourceSet);
+ task.setOutputFile(outputFile);
+ task.setBaselineFile(project.file("baseline.txt"));
+ task.setOutputApiFile(outputApiFile);
+ if (project.hasProperty("updateBaseline")) {
+ task.setUpdateBaseline(true);
+ } else {
+ task.setUpdateBaseline(false);
+ }
+ task.dependsOn("getMetalavaJar");
+ });
+
+ TaskProvider generateApiTxt =
+ project
+ .getTasks()
+ .register(
+ "generateApiTxtFile",
+ GenerateApiTxtFileTask.class,
+ task -> {
+ task.setApiTxt(project.file("api.txt"));
+ task.setMetalavaJarPath(metalavaOutputJarFile.getAbsolutePath());
+ task.setSourceSet(mainSourceSet);
+ task.setBaselineFile(project.file("baseline.txt"));
+ task.setUpdateBaseline(project.hasProperty("updateBaseline"));
+ task.dependsOn("getMetalavaJar");
+ });
+
+ TaskProvider docStubs =
+ project
+ .getTasks()
+ .register(
+ "docStubs",
+ GenerateStubsTask.class,
+ task -> {
+ task.setMetalavaJarPath(metalavaOutputJarFile.getAbsolutePath());
+ task.setOutputDir(new File(project.getBuildDir(), "doc-stubs"));
+ task.dependsOn("getMetalavaJar");
+
+ task.setSourceSet(mainSourceSet);
+ });
+ project.getTasks().getByName("check").dependsOn(docStubs);
+
+ project.afterEvaluate(
+ p -> {
+ FileCollection classpath =
+ project
+ .getConfigurations()
+ .getByName("runtimeClasspath")
+ .getIncoming()
+ .artifactView(
+ config ->
+ config.attributes(
+ container ->
+ container.attribute(
+ Attribute.of("artifactType", String.class), "jar")))
+ .getArtifacts()
+ .getArtifactFiles();
+
+ apiInfo.configure(t -> t.setClassPath(classpath));
+ generateApiTxt.configure(t -> t.setClassPath(classpath));
+ docStubs.configure(t -> t.setClassPath(classpath));
+ });
+ }
+
+ private static String kotlinModuleName(Project project) {
+
+ String fullyQualifiedProjectPath = project.getPath().replaceAll(":", "-");
+
+ return project.getRootProject().getName() + fullyQualifiedProjectPath;
+ }
+}
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryExtension.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryExtension.java
index fdf6cd66263..9f7149d6565 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryExtension.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/FirebaseLibraryExtension.java
@@ -14,8 +14,10 @@
package com.google.firebase.gradle.plugins;
+import com.android.build.gradle.LibraryExtension;
import com.google.common.collect.ImmutableSet;
import com.google.firebase.gradle.plugins.ci.device.FirebaseTestLabExtension;
+import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
@@ -27,6 +29,7 @@
import org.gradle.api.Project;
import org.gradle.api.UnknownDomainObjectException;
import org.gradle.api.internal.provider.DefaultProvider;
+import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.provider.Property;
import org.gradle.api.publish.maven.MavenPom;
@@ -180,6 +183,36 @@ public String getPath() {
return project.getPath();
}
+ public Set getSrcDirs() {
+ switch (type) {
+ case ANDROID:
+ return project
+ .getExtensions()
+ .getByType(LibraryExtension.class)
+ .getSourceSets()
+ .getByName("main")
+ .getJava()
+ .getSrcDirs();
+ case JAVA:
+ return project
+ .getConvention()
+ .getPlugin(JavaPluginConvention.class)
+ .getSourceSets()
+ .getByName("main")
+ .getJava()
+ .getSrcDirs();
+ default:
+ throw new IllegalStateException("Unsupported project type: " + type);
+ }
+ }
+
+ public String getRuntimeClasspath() {
+ if (type.equals(LibraryType.ANDROID)) {
+ return "releaseRuntimeClasspath";
+ }
+ return "runtimeClasspath";
+ }
+
@Override
public String toString() {
return String.format(
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/LibraryType.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/LibraryType.java
index f29e10ff881..2be7d76b450 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/LibraryType.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/LibraryType.java
@@ -27,4 +27,8 @@ public enum LibraryType {
public String getFormat() {
return format;
}
+
+ public String getComponentName() {
+ return name().toLowerCase();
+ }
}
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/SdkUtil.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/SdkUtil.java
index e8e0906718f..5d8fe665781 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/SdkUtil.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/SdkUtil.java
@@ -48,7 +48,7 @@ public static File getSdkDir(Project project) {
public static File getAndroidJar(Project project) {
LibraryExtension android = project.getExtensions().findByType(LibraryExtension.class);
if (android == null) {
- throw new GradleException("Project " + project.getPath() + " is not an android library.");
+ return null;
}
return new File(
getSdkDir(project),
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/ApiInformationTask.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/ApiInformationTask.java
index 6fe7a089ef1..ec20994484d 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/ApiInformationTask.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/ApiInformationTask.java
@@ -16,25 +16,22 @@
import com.android.build.gradle.api.AndroidSourceSet;
import com.google.firebase.gradle.plugins.SdkUtil;
-
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
-import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
+import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskAction;
/**
@@ -49,7 +46,7 @@ public abstract class ApiInformationTask extends DefaultTask {
@InputFile
abstract File getApiTxt();
- abstract AndroidSourceSet getSourceSet();
+ abstract Object getSourceSet();
@InputFiles
abstract FileCollection getClassPath();
@@ -66,7 +63,7 @@ public abstract class ApiInformationTask extends DefaultTask {
@OutputFile
abstract File getOutputFile();
- public abstract void setSourceSet(AndroidSourceSet value);
+ public abstract void setSourceSet(Object value);
public abstract void setClassPath(FileCollection value);
@@ -82,10 +79,19 @@ public abstract class ApiInformationTask extends DefaultTask {
public abstract void setOutputFile(File value);
+ private Set getSourceDirs() {
+ if (getSourceSet() instanceof SourceSet) {
+ return ((SourceSet) getSourceSet()).getJava().getSrcDirs();
+ } else if (getSourceSet() instanceof AndroidSourceSet) {
+ return ((AndroidSourceSet) getSourceSet()).getJava().getSrcDirs();
+ }
+ throw new IllegalStateException("Unsupported sourceSet provided: " + getSourceSet().getClass());
+ }
+
@TaskAction
void execute() {
String sourcePath =
- getSourceSet().getJava().getSrcDirs().stream()
+ getSourceDirs().stream()
.filter(File::exists)
.map(File::getAbsolutePath)
.collect(Collectors.joining(":"));
@@ -97,11 +103,17 @@ void execute() {
}
String classPath =
- Stream.concat(
- getClassPath().getFiles().stream(), Stream.of(SdkUtil.getAndroidJar(getProject())))
+ getClassPath().getFiles().stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(":"));
+ File androidJar = SdkUtil.getAndroidJar(getProject());
+ if (androidJar != null) {
+ classPath += ":" + androidJar.getAbsolutePath();
+ }
+
+ String cp = classPath;
+
File outputFileDir = getOutputFile().getParentFile();
if (!outputFileDir.exists()) {
outputFileDir.mkdirs();
@@ -119,7 +131,7 @@ void execute() {
"--source-path",
sourcePath,
"--classpath",
- classPath,
+ cp,
"--api",
getOutputApiFile().getAbsolutePath(),
"--format=v2"));
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateApiTxtFileTask.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateApiTxtFileTask.java
index 412ff890341..ded7f12956d 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateApiTxtFileTask.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateApiTxtFileTask.java
@@ -16,19 +16,18 @@
import com.android.build.gradle.api.AndroidSourceSet;
import com.google.firebase.gradle.plugins.SdkUtil;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
import org.gradle.api.DefaultTask;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
+import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskAction;
public abstract class GenerateApiTxtFileTask extends DefaultTask {
@@ -39,7 +38,7 @@ public abstract class GenerateApiTxtFileTask extends DefaultTask {
@OutputFile
abstract File getApiTxt();
- abstract AndroidSourceSet getSourceSet();
+ abstract Object getSourceSet();
@InputFiles
public abstract FileCollection getClassPath();
@@ -50,7 +49,7 @@ public abstract class GenerateApiTxtFileTask extends DefaultTask {
@Input
abstract boolean getUpdateBaseline();
- public abstract void setSourceSet(AndroidSourceSet value);
+ public abstract void setSourceSet(Object value);
public abstract void setClassPath(FileCollection value);
@@ -62,10 +61,19 @@ public abstract class GenerateApiTxtFileTask extends DefaultTask {
public abstract void setApiTxt(File value);
+ private Set getSourceDirs() {
+ if (getSourceSet() instanceof SourceSet) {
+ return ((SourceSet) getSourceSet()).getJava().getSrcDirs();
+ } else if (getSourceSet() instanceof AndroidSourceSet) {
+ return ((AndroidSourceSet) getSourceSet()).getJava().getSrcDirs();
+ }
+ throw new IllegalStateException("Unsupported sourceSet provided: " + getSourceSet().getClass());
+ }
+
@TaskAction
void execute() {
String sourcePath =
- getSourceSet().getJava().getSrcDirs().stream()
+ getSourceDirs().stream()
.filter(File::exists)
.map(File::getAbsolutePath)
.collect(Collectors.joining(":"));
@@ -76,10 +84,14 @@ void execute() {
return;
}
String classPath =
- Stream.concat(
- getClassPath().getFiles().stream(), Stream.of(SdkUtil.getAndroidJar(getProject())))
+ getClassPath().getFiles().stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(":"));
+
+ File androidJar = SdkUtil.getAndroidJar(getProject());
+ if (androidJar != null) {
+ classPath += ":" + androidJar.getAbsolutePath();
+ }
List args =
new ArrayList<>(
Arrays.asList(
@@ -88,7 +100,7 @@ void execute() {
"--source-path",
sourcePath,
"--classpath",
- classPath,
+ classPath,
"--api",
getApiTxt().getAbsolutePath(),
"--format=v2"));
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateStubsTask.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateStubsTask.java
index e39a0e882eb..8fff3b252d7 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateStubsTask.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/apiinfo/GenerateStubsTask.java
@@ -16,17 +16,16 @@
import com.android.build.gradle.api.AndroidSourceSet;
import com.google.firebase.gradle.plugins.SdkUtil;
-
import java.io.File;
import java.util.Arrays;
+import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
import org.gradle.api.DefaultTask;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
+import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskAction;
public abstract class GenerateStubsTask extends DefaultTask {
@@ -35,12 +34,12 @@ public abstract class GenerateStubsTask extends DefaultTask {
public abstract void setMetalavaJarPath(String path);
- public abstract AndroidSourceSet getSourceSet();
+ public abstract Object getSourceSet();
@InputFiles
public abstract FileCollection getClassPath();
- public abstract void setSourceSet(AndroidSourceSet sourceSet);
+ public abstract void setSourceSet(Object sourceSet);
public abstract void setClassPath(FileCollection value);
@@ -49,20 +48,35 @@ public abstract class GenerateStubsTask extends DefaultTask {
public abstract void setOutputDir(File dir);
+ private Set getSourceDirs() {
+ if (getSourceSet() instanceof SourceSet) {
+ return ((SourceSet) getSourceSet()).getJava().getSrcDirs();
+ } else if (getSourceSet() instanceof AndroidSourceSet) {
+ return ((AndroidSourceSet) getSourceSet()).getJava().getSrcDirs();
+ }
+ throw new IllegalStateException("Unsupported sourceSet provided: " + getSourceSet().getClass());
+ }
+
@TaskAction
public void run() {
String sourcePath =
- getSourceSet().getJava().getSrcDirs().stream()
+ getSourceDirs().stream()
.filter(File::exists)
.map(File::getAbsolutePath)
.collect(Collectors.joining(":"));
String classPath =
- Stream.concat(
- getClassPath().getFiles().stream(), Stream.of(SdkUtil.getAndroidJar(getProject())))
+ getClassPath().getFiles().stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(":"));
+ File androidJar = SdkUtil.getAndroidJar(getProject());
+ if (androidJar != null) {
+ classPath += ":" + androidJar.getAbsolutePath();
+ }
+
+ String cp = classPath;
+
getProject()
.javaexec(
spec -> {
@@ -74,7 +88,7 @@ public void run() {
"--source-path",
sourcePath,
"--classpath",
- classPath,
+ cp,
"--include-annotations",
"--doc-stubs",
getOutputDir().getAbsolutePath()));
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/ci/SmokeTestsPlugin.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/ci/SmokeTestsPlugin.java
index 426cf07813a..5c73a641845 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/ci/SmokeTestsPlugin.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/ci/SmokeTestsPlugin.java
@@ -112,7 +112,9 @@ private static Set getChangedProjects(Project p) {
private static void getChangedProjectsLoop(Collection projects, Set changed) {
for (Project p : projects) {
// Skip project if it is not a Firebase library.
- if (p.getExtensions().findByType(FirebaseLibraryExtension.class) == null) {
+ FirebaseLibraryExtension library =
+ p.getExtensions().findByType(FirebaseLibraryExtension.class);
+ if (library == null) {
continue;
}
@@ -123,7 +125,7 @@ private static void getChangedProjectsLoop(Collection projects, Set affected =
all.stream()
.filter(it -> it instanceof ProjectDependency)
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/Publisher.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/Publisher.java
index b9531c0ad97..72cd594205e 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/Publisher.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/Publisher.java
@@ -90,7 +90,7 @@ private static void validatePomXml(FirebaseLibraryExtension library, Element roo
}
private static void processDependencies(FirebaseLibraryExtension library, Element rootElement) {
- Map deps = getDependencyTypes(library.project);
+ Map deps = getDependencyTypes(library);
NodeList dependencies = rootElement.getElementsByTagName("dependency");
List depsToRemove = new ArrayList<>();
@@ -125,13 +125,14 @@ private static String renderVersion(String baseVersion, Mode mode) {
return baseVersion + (Mode.SNAPSHOT.equals(mode) ? "-SNAPSHOT" : "");
}
- private static Map getDependencyTypes(Project project) {
+ private static Map getDependencyTypes(FirebaseLibraryExtension firebaseLibrary) {
+ Project project = firebaseLibrary.project;
Configuration dummyDependencyConfiguration =
project.getConfigurations().create("publisherDummyConfig");
Set nonProjectDependencies =
project
.getConfigurations()
- .getByName("releaseRuntimeClasspath")
+ .getByName(firebaseLibrary.getRuntimeClasspath())
.getAllDependencies()
.stream()
.filter(dep -> !(dep instanceof ProjectDependency))
@@ -141,7 +142,7 @@ private static Map getDependencyTypes(Project project) {
try {
return project
.getConfigurations()
- .getByName("releaseRuntimeClasspath")
+ .getByName(firebaseLibrary.getRuntimeClasspath())
.getAllDependencies()
.stream()
.map(dep -> getType(dummyDependencyConfiguration, dep))
diff --git a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/PublishingPlugin.java b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/PublishingPlugin.java
index 0387f6fb786..d92c78bacd8 100644
--- a/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/PublishingPlugin.java
+++ b/buildSrc/src/main/java/com/google/firebase/gradle/plugins/publish/PublishingPlugin.java
@@ -14,7 +14,6 @@
package com.google.firebase.gradle.plugins.publish;
-import com.android.build.gradle.LibraryExtension;
import com.google.common.collect.ImmutableMap;
import com.google.firebase.gradle.plugins.FirebaseLibraryExtension;
import digital.wup.android_maven_publish.AndroidMavenPublishPlugin;
@@ -106,11 +105,11 @@ public void apply(Project project) {
Publisher publisher = new Publisher(publishMode, projectsToPublish);
project.subprojects(
sub -> {
- if (!sub.getPlugins().hasPlugin("firebase-library")) {
+ FirebaseLibraryExtension firebaseLibrary =
+ sub.getExtensions().findByType(FirebaseLibraryExtension.class);
+ if (firebaseLibrary == null) {
return;
}
- FirebaseLibraryExtension firebaseLibrary =
- sub.getExtensions().getByType(FirebaseLibraryExtension.class);
sub.apply(ImmutableMap.of("plugin", AndroidMavenPublishPlugin.class));
PublishingExtension publishing =
@@ -132,7 +131,9 @@ public void apply(Project project) {
"mavenAar",
MavenPublication.class,
publication -> {
- publication.from(sub.getComponents().findByName("android"));
+ publication.from(
+ sub.getComponents()
+ .findByName(firebaseLibrary.type.getComponentName()));
publication.setArtifactId(firebaseLibrary.artifactId.get());
publication.setGroupId(firebaseLibrary.groupId.get());
if (firebaseLibrary.publishSources) {
@@ -142,13 +143,7 @@ public void apply(Project project) {
"sourceJar",
Jar.class,
jar -> {
- jar.from(
- sub.getExtensions()
- .getByType(LibraryExtension.class)
- .getSourceSets()
- .getByName("main")
- .getJava()
- .getSrcDirs());
+ jar.from(firebaseLibrary.getSrcDirs());
jar.getArchiveClassifier().set("sources");
}));
}
diff --git a/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/PublishingPluginTests.kt b/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/PublishingPluginTests.kt
index 7492c3fa6eb..6e138919e28 100644
--- a/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/PublishingPluginTests.kt
+++ b/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/PublishingPluginTests.kt
@@ -78,6 +78,49 @@ licenses {
scope = "compile")))
}
+ @Test
+ fun `Publishing dependent projects one of which is a jar succeeds`() {
+ val project1 = Project(name = "childProject1", version = "1.0", libraryType = LibraryType.JAVA)
+ val project2 = Project(
+ name = "childProject2",
+ version = "0.9",
+ projectDependencies = setOf(project1),
+ customizePom = """
+licenses {
+ license {
+ name = 'Hello'
+ }
+}
+""")
+ subprojectsDefined(project1, project2)
+ val result = publish(Mode.RELEASE, project1, project2)
+ assertThat(result.task(":firebasePublish")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
+
+ val pomOrNull1 = project1.getPublishedPom("${testProjectDir.root}/build/m2repository")
+ val pomOrNull2 = project2.getPublishedPom("${testProjectDir.root}/build/m2repository")
+ assertThat(pomOrNull1).isNotNull()
+ assertThat(pomOrNull2).isNotNull()
+ val pom1 = pomOrNull1!!
+ val pom2 = pomOrNull2!!
+
+ assertThat(pom1.artifact.version).isEqualTo(project1.version)
+ assertThat(pom2.artifact.version).isEqualTo(project2.version)
+ assertThat(pom1.license).isEqualTo(License(
+ "The Apache Software License, Version 2.0",
+ "http://www.apache.org/licenses/LICENSE-2.0.txt"))
+ assertThat(pom2.license).isEqualTo(License(
+ "Hello",
+ ""))
+
+ assertThat(pom2.dependencies).isEqualTo(
+ listOf(Artifact(
+ groupId = project1.group,
+ artifactId = project1.name,
+ version = project1.version,
+ type = Type.JAR,
+ scope = "compile")))
+ }
+
@Test
fun `Publish with unreleased dependency`() {
val project1 = Project(name = "childProject1", version = "1.0")
diff --git a/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/publishing.kt b/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/publishing.kt
index 409e2423dbf..285643724ae 100644
--- a/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/publishing.kt
+++ b/buildSrc/src/test/kotlin/com/google/firebase/gradle/plugins/publishing.kt
@@ -28,12 +28,13 @@ data class Project(
val projectDependencies: Set = setOf(),
val externalDependencies: Set = setOf(),
val releaseWith: Project? = null,
- val customizePom: String? = null
+ val customizePom: String? = null,
+ val libraryType: LibraryType = LibraryType.ANDROID
) {
fun generateBuildFile(): String {
return """
plugins {
- id 'firebase-library'
+ id 'firebase-${if (libraryType == LibraryType.JAVA) "java-" else ""}library'
}
group = '$group'
version = '$version'
@@ -42,7 +43,7 @@ data class Project(
${if (releaseWith != null) "releaseWith project(':${releaseWith.name}')" else ""}
${if (customizePom != null) "customizePom {$customizePom}" else ""}
}
- android.compileSdkVersion = 26
+ ${if (libraryType == LibraryType.ANDROID) "android.compileSdkVersion = 26" else ""}
repositories {
google()