diff --git a/.buckversion b/.buckversion index ed3f099e3..ee2d5e65d 100644 --- a/.buckversion +++ b/.buckversion @@ -1 +1 @@ -18b5de7165c511070034976be0b852eeb27151ca +800d5a9669417d5a8b4bc455e34a629422ed1ff1 diff --git a/README-zh.md b/README-zh.md index e0953016d..0ffcbc46b 100644 --- a/README-zh.md +++ b/README-zh.md @@ -9,7 +9,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.uber:okbuck:0.20.9' + classpath 'com.uber:okbuck:0.21.0' } } diff --git a/README.md b/README.md index 8b9695cff..33c3e4a19 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.uber:okbuck:0.20.9' + classpath 'com.uber:okbuck:0.21.0' } } diff --git a/app/build.gradle b/app/build.gradle index a40a39bae..e3fbe4849 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,7 +62,6 @@ dependencies { compile deps.external.xlogAndroidIdle compile deps.apt.autoValue - compile project(':libraries:emptyResourceLibrary') compile project(':libraries:emptylibrary') compile project(':libraries:kotlinandroidlibrary') devCompile project(path: ':dummylibrary', configuration: 'freeRelease') diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index fa68fd2c3..28f3807ea 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -47,7 +47,7 @@ task sourcesJar(type: Jar) { classifier = 'sources' } -def publishVersion = '0.20.9-SQUARE-2' +def publishVersion = '0.21.0-SQUARE-1' group = 'com.uber' version = publishVersion def siteUrl = 'https://github.com/uber/okbuck' diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/OkBuckGradlePlugin.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/OkBuckGradlePlugin.groovy index 582618068..e0bc89170 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/OkBuckGradlePlugin.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/OkBuckGradlePlugin.groovy @@ -141,8 +141,7 @@ class OkBuckGradlePlugin implements Plugin { true, true, intellij.sources, - !lint.disabled, - okbuckExt.buckProjects) + !lint.disabled) // Fetch Lint deps if needed if (!lint.disabled && lint.version != null) { diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/config/DotBuckConfigLocalFile.java b/buildSrc/src/main/groovy/com/uber/okbuck/config/DotBuckConfigLocalFile.java index b3cc0e59b..cabb97a50 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/config/DotBuckConfigLocalFile.java +++ b/buildSrc/src/main/groovy/com/uber/okbuck/config/DotBuckConfigLocalFile.java @@ -14,8 +14,7 @@ public final class DotBuckConfigLocalFile extends BuckConfigFile { private final String target; private final List ignore; private final String groovyHome; - private final String kotlinCompiler; - private final String kotlinRuntime; + private final String kotlinHome; private final String proguardJar; private final Set defs; @@ -25,8 +24,7 @@ public DotBuckConfigLocalFile( String target, List ignore, String groovyHome, - String kotlinCompiler, - String kotlinRuntime, + String kotlinHome, String proguardJar, Set defs) { this.aliases = aliases; @@ -34,8 +32,7 @@ public DotBuckConfigLocalFile( this.target = target; this.ignore = ignore; this.groovyHome = groovyHome; - this.kotlinCompiler = kotlinCompiler; - this.kotlinRuntime = kotlinRuntime; + this.kotlinHome = kotlinHome; this.proguardJar = proguardJar; this.defs = defs; } @@ -67,10 +64,9 @@ public final void print(PrintStream printer) { printer.println(); } - if (!StringUtils.isEmpty(kotlinCompiler) && !StringUtils.isEmpty(kotlinRuntime)) { + if (!StringUtils.isEmpty(kotlinHome)) { printer.println("[kotlin]"); - printer.println("\tcompiler = " + kotlinCompiler); - printer.println("\truntime_jar = " + kotlinRuntime); + printer.println("\tkotlin_home = " + kotlinHome); printer.println(); } diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/DependencyCache.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/DependencyCache.groovy index 29f457fcc..2316378cf 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/DependencyCache.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/DependencyCache.groovy @@ -7,7 +7,9 @@ import org.gradle.api.Project import org.gradle.api.artifacts.ComponentSelection import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.ResolvedArtifact +import org.gradle.api.artifacts.component.ComponentIdentifier +import org.gradle.api.artifacts.component.ModuleComponentIdentifier +import org.gradle.api.artifacts.result.ResolvedArtifactResult import org.gradle.plugins.ide.internal.IdeDependenciesExtractor import java.nio.file.FileSystem @@ -35,7 +37,6 @@ class DependencyCache { private final Map> annotationProcessors = [:] private final Map externalDeps = [:] - private final Map projectDeps = [:] DependencyCache( String name, @@ -46,8 +47,7 @@ class DependencyCache { boolean cleanup = true, boolean useFullDepName = false, boolean fetchSources = false, - boolean extractLintJars = false, - Set depProjects = null) { + boolean extractLintJars = false) { this.rootProject = rootProject this.cacheDir = new File(rootProject.projectDir, cacheDirPath) @@ -62,11 +62,12 @@ class DependencyCache { this.useFullDepName = useFullDepName this.fetchSources = fetchSources this.extractLintJars = extractLintJars - build(cleanup, depProjects) + build(cleanup) } String get(VersionlessDependency dependency) { - ExternalDependency externalDependency = externalDeps.get(dependency) + ExternalDependency externalDependency = dependency.isLocal ? + (ExternalDependency) dependency : externalDeps.get(dependency) if (externalDependency == null) { throw new IllegalStateException("Could not find dependency path for ${dependency}") } @@ -91,22 +92,56 @@ class DependencyCache { } } - private void build(boolean cleanup, Set depProjects) { - Set resolvedFiles = [] as Set + String getLintJar(VersionlessDependency dependency) { + return lintJars.get(dependency) + } - if (depProjects) { - depProjects.each { Project project -> - ProjectDependency dependency = new ProjectDependency(project) - projectDeps.put(dependency, dependency) + private File fetchSourcesFor(ExternalDependency dependency) { + // We do not have sources for these dependencies + if (isWhiteListed(dependency.depFile)) { + return null + } + + File cachedCopy = new File(cacheDir, dependency.getSourceCacheName(useFullDepName)) + + if (!cachedCopy.exists()) { + String sourcesJarName = dependency.getSourceCacheName(false) + File sourcesJar = new File(dependency.depFile.parentFile, sourcesJarName) + + if (!sourcesJar.exists()) { + def sourceJars = rootProject.fileTree( + dir: dependency.depFile.parentFile.parentFile.absolutePath, + includes: ["**/${sourcesJarName}"]) as List + if (sourceJars.size() == 1) { + sourcesJar = sourceJars[0] + } else if (sourceJars.size() > 1) { + throw new IllegalStateException("Found multiple source jars: ${sourceJars} for ${dependency}") + } + } + if (sourcesJar.exists()) { + Files.createSymbolicLink(cachedCopy.toPath(), sourcesJar.toPath()) } } - superConfiguration.resolvedConfiguration.resolvedArtifacts.each { ResolvedArtifact artifact -> - ExternalDependency dependency = new ExternalDependency(artifact.moduleVersion.id, artifact.file, - artifact.classifier) - if (!projectDeps.containsKey(dependency.withoutClassifier())) { - externalDeps.put(dependency, dependency) + return cachedCopy.exists() ? cachedCopy : null + } + + private void build(boolean cleanup) { + Set resolvedFiles = [] as Set + + superConfiguration.incoming.artifacts.each { ResolvedArtifactResult artifact -> + ComponentIdentifier identifier = artifact.id.componentIdentifier + ExternalDependency dependency + if (identifier instanceof ModuleComponentIdentifier) { + dependency = new ExternalDependency( + identifier.group, + identifier.module, + identifier.version, + artifact.file) + } else { + dependency = ExternalDependency.fromLocal(artifact.file) } + externalDeps.put(dependency, dependency) resolvedFiles.add(artifact.file) } @@ -173,17 +208,43 @@ class DependencyCache { } } - Project getProject(VersionlessDependency dependency) { - ProjectDependency targetDependency = projectDeps.get(dependency.withoutClassifier()) - if (targetDependency) { - return targetDependency.project + static boolean isWhiteListed(File depFile) { + return WHITELIST_LOCAL_PATTERNS.find { depFile.absolutePath.contains(it) } != null + } + + static File getPackagedLintJarFrom(File aar) { + File lintJar = new File(aar.parentFile, aar.name.replaceFirst(/\.aar$/, '-lint.jar')) + if (lintJar.exists()) { + return lintJar + } + FileSystem zipFile = FileSystems.newFileSystem(aar.toPath(), null) + Path packagedLintJar = zipFile.getPath("lint.jar") + if (Files.exists(packagedLintJar)) { + Files.copy(packagedLintJar, lintJar.toPath(), StandardCopyOption.REPLACE_EXISTING) + return lintJar } else { return null } } - boolean isWhiteListed(File depFile) { - return WHITELIST_LOCAL_PATTERNS.find { depFile.absolutePath.contains(it) } != null + static File getAnnotationProcessorsFile(File jar) { + File processors = new File(jar.parentFile, jar.name.replaceFirst(/\.jar$/, '.processors')) + if (processors.exists()) { + return processors + } + + JarFile jarFile = new JarFile(jar) + JarEntry jarEntry = (JarEntry) jarFile.getEntry("META-INF/services/javax.annotation.processing.Processor") + if (jarEntry) { + List processorClasses = IOUtils.toString(jarFile.getInputStream(jarEntry)) + .trim().split("\\n").findAll { String entry -> + !entry.startsWith('#') && !entry.trim().empty // filter out comments and empty lines + } + processors.text = processorClasses.join('\n') + } else { + processors.createNewFile() + } + return processors } private static Configuration createSuperConfiguration(Project project, @@ -222,73 +283,4 @@ class DependencyCache { println "\n${message}\n" } } - - String getLintJar(VersionlessDependency dependency) { - return lintJars.get(dependency) - } - - private File fetchSourcesFor(ExternalDependency dependency) { - // We do not have sources for these dependencies - if (isWhiteListed(dependency.depFile)) { - return null - } - - File cachedCopy = new File(cacheDir, dependency.getSourceCacheName(useFullDepName)) - - if (!cachedCopy.exists()) { - String sourcesJarName = dependency.getSourceCacheName(false) - File sourcesJar = new File(dependency.depFile.parentFile, sourcesJarName) - - if (!sourcesJar.exists()) { - def sourceJars = rootProject.fileTree( - dir: dependency.depFile.parentFile.parentFile.absolutePath, - includes: ["**/${sourcesJarName}"]) as List - if (sourceJars.size() == 1) { - sourcesJar = sourceJars[0] - } else if (sourceJars.size() > 1) { - throw new IllegalStateException("Found multiple source jars: ${sourceJars} for ${dependency}") - } - } - if (sourcesJar.exists()) { - Files.createSymbolicLink(cachedCopy.toPath(), sourcesJar.toPath()) - } - } - - return cachedCopy.exists() ? cachedCopy : null - } - - static File getPackagedLintJarFrom(File aar) { - File lintJar = new File(aar.parentFile, aar.name.replaceFirst(/\.aar$/, '-lint.jar')) - if (lintJar.exists()) { - return lintJar - } - FileSystem zipFile = FileSystems.newFileSystem(aar.toPath(), null) - Path packagedLintJar = zipFile.getPath("lint.jar") - if (Files.exists(packagedLintJar)) { - Files.copy(packagedLintJar, lintJar.toPath(), StandardCopyOption.REPLACE_EXISTING) - return lintJar - } else { - return null - } - } - - static File getAnnotationProcessorsFile(File jar) { - File processors = new File(jar.parentFile, jar.name.replaceFirst(/\.jar$/, '.processors')) - if (processors.exists()) { - return processors - } - - JarFile jarFile = new JarFile(jar) - JarEntry jarEntry = (JarEntry) jarFile.getEntry("META-INF/services/javax.annotation.processing.Processor") - if (jarEntry) { - List processorClasses = IOUtils.toString(jarFile.getInputStream(jarEntry)) - .trim().split("\\n").findAll { String entry -> - !entry.startsWith('#') && !entry.trim().empty // filter out comments and empty lines - } - processors.text = processorClasses.join('\n') - } else { - processors.createNewFile() - } - return processors - } } diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ExternalDependency.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ExternalDependency.groovy index 493f4604d..65f6b1076 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ExternalDependency.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ExternalDependency.groovy @@ -2,8 +2,6 @@ package com.uber.okbuck.core.dependency import org.apache.commons.io.FilenameUtils import org.apache.maven.artifact.versioning.DefaultArtifactVersion -import org.gradle.api.artifacts.ModuleIdentifier -import org.gradle.api.artifacts.ModuleVersionIdentifier class ExternalDependency extends VersionlessDependency { @@ -13,12 +11,16 @@ class ExternalDependency extends VersionlessDependency { final DefaultArtifactVersion version final File depFile - ExternalDependency(ModuleVersionIdentifier identifier, File depFile, String classifier) { - super(identifier, classifier) - if (identifier.version) { - version = new DefaultArtifactVersion(identifier.version) + ExternalDependency(String group, String name, String version, File depFile) { + this(group, name, version, depFile, false) + } + + private ExternalDependency(String group, String name, String version, File depFile, boolean isLocal) { + super(group, name, isLocal) + if (version) { + this.version = new DefaultArtifactVersion(version) } else { - version = new DefaultArtifactVersion(LOCAL_DEP_VERSION) + this.version = new DefaultArtifactVersion(LOCAL_DEP_VERSION) } this.depFile = depFile @@ -26,9 +28,6 @@ class ExternalDependency extends VersionlessDependency { @Override String toString() { - if (classifier) { - return "${this.group}:${this.name}:${this.version}-${this.classifier} -> ${this.depFile.toString()}" - } return "${this.group}:${this.name}:${this.version} -> ${this.depFile.toString()}" } @@ -50,10 +49,6 @@ class ExternalDependency extends VersionlessDependency { static ExternalDependency fromLocal(File localDep) { String baseName = FilenameUtils.getBaseName(localDep.name) - ModuleVersionIdentifier identifier = getDepIdentifier( - baseName, - baseName, - LOCAL_DEP_VERSION) - return new ExternalDependency(identifier, localDep, null) + return new ExternalDependency(baseName, baseName, LOCAL_DEP_VERSION, localDep, true) } } diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ProjectDependency.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ProjectDependency.groovy deleted file mode 100644 index 4a93a18ae..000000000 --- a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/ProjectDependency.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package com.uber.okbuck.core.dependency - -import org.gradle.api.Project - -class ProjectDependency extends VersionlessDependency { - - final Project project - - ProjectDependency(Project project) { - super(getDepIdentifier(project.group, - project.hasProperty("archiveBaseName") ? project.archiveBaseName : project.name), null) - this.project = project - } - - @Override - String toString() { - if (classifier) { - return "${this.group}:${this.name}-${this.classifier} -> ${this.project}" - } - return "${this.group}:${this.name} -> ${this.project}" - } -} diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/VersionlessDependency.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/VersionlessDependency.groovy index 6d42f2588..3736ee106 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/VersionlessDependency.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/core/dependency/VersionlessDependency.groovy @@ -1,56 +1,26 @@ package com.uber.okbuck.core.dependency import groovy.transform.EqualsAndHashCode -import org.gradle.api.artifacts.ModuleIdentifier -import org.gradle.api.artifacts.ModuleVersionIdentifier @EqualsAndHashCode class VersionlessDependency { final String group final String name - final String classifier + final boolean isLocal - VersionlessDependency(ModuleVersionIdentifier identifier, String classifier) { - group = identifier.group - name = identifier.name - this.classifier = classifier + VersionlessDependency(String group, String name) { + this(group, name, false) } - VersionlessDependency withoutClassifier(){ - return new VersionlessDependency(getDepIdentifier(group, name), null) + protected VersionlessDependency(String group, String name, boolean isLocal) { + this.group = group + this.name = name + this.isLocal = isLocal } @Override String toString() { - if (classifier) { - return "${this.group}:${this.name}-${this.classifier}" - } return "${this.group}:${this.name}" } - - static ModuleVersionIdentifier getDepIdentifier(String group, String name, String version = null) { - return new ModuleVersionIdentifier() { - - @Override - String getVersion() { - return version - } - - @Override - String getGroup() { - return group - } - - @Override - String getName() { - return name - } - - @Override - ModuleIdentifier getModule() { - return null - } - } - } } diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/Scope.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/Scope.groovy index 08bc68c95..f26b1c477 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/Scope.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/Scope.groovy @@ -9,9 +9,11 @@ import groovy.transform.EqualsAndHashCode import org.apache.commons.io.FilenameUtils import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.ResolvedArtifact -import org.gradle.api.artifacts.ResolvedDependency import org.gradle.api.artifacts.UnknownConfigurationException +import org.gradle.api.artifacts.component.ComponentIdentifier +import org.gradle.api.artifacts.component.ModuleComponentIdentifier +import org.gradle.api.artifacts.component.ProjectComponentIdentifier +import org.gradle.api.artifacts.result.ResolvedArtifactResult @EqualsAndHashCode class Scope { @@ -24,7 +26,6 @@ class Scope { protected final Project project protected final Set external = [] as Set - protected final Set firstLevel = [] as Set Scope(Project project, Collection configurations, @@ -57,7 +58,7 @@ class Scope { } Set getAnnotationProcessors() { - return ((firstLevel.collect { + return ((external.collect { depCache.getAnnotationProcessors(it) } + targetDeps.collect { Target target -> target.getProp(project.rootProject.okbuck.annotationProcessors as Map, []) as Set @@ -70,74 +71,34 @@ class Scope { try { Configuration configuration = project.configurations.getByName(configName) validConfigurations.add(configuration) - } catch (UnknownConfigurationException ignored) { - } + } catch (UnknownConfigurationException ignored) { } } validConfigurations = useful(validConfigurations) - // get all first level external dependencies - validConfigurations.collect { - it.resolvedConfiguration.firstLevelModuleDependencies.each { ResolvedDependency resolvedDependency -> - if (!resolvedDependency.moduleArtifacts.empty) { - ResolvedArtifact artifact = resolvedDependency.moduleArtifacts[0] - VersionlessDependency dependency = new VersionlessDependency(artifact.moduleVersion.id, artifact.classifier) - - if (!depCache.getProject(dependency)) { - firstLevel.add(dependency) - } - } - } - } - - // get all resolved artifacts including transitives - Set artifacts = validConfigurations.collect { - it.resolvedConfiguration.resolvedArtifacts - }.flatten() as Set - - Set files = validConfigurations.collect { - it.files - }.flatten() as Set - - Set resolvedFiles = [] as Set - artifacts.each { ResolvedArtifact artifact -> - VersionlessDependency dependency = new VersionlessDependency(artifact.moduleVersion.id, artifact.classifier) - - Project targetProject = depCache.getProject(dependency) - if (targetProject) { - File artifactFile - if (artifact.id.componentIdentifier.displayName.contains(" ")) { - artifactFile = artifact.file - } else { - // Get the default configuration artifact file if an external - // artifact is getting resolved to a project dependency. - artifactFile = targetProject.configurations.getByName("default").allArtifacts.files.files[0] - } - - Target target = ProjectUtil.getTargetForOutput(targetProject, artifactFile) - if (target == null) { - throw new IllegalStateException("No such artifact: ${artifactFile} for ${targetProject} with " + - "artifact id: ${dependency}") - } else if (target.project != project) { - targetDeps.add(target) - } + Set artifacts = validConfigurations.collect { + it.incoming.artifacts.artifacts + }.flatten() as Set + + artifacts.each { ResolvedArtifactResult artifact -> + ComponentIdentifier identifier = artifact.id.componentIdentifier + if (identifier instanceof ProjectComponentIdentifier) { + targetDeps.add(ProjectUtil.getTargetForOutput(project.project(identifier.projectPath), artifact.file)) + } else if (identifier instanceof ModuleComponentIdentifier) { + external.add(new ExternalDependency( + identifier.group, + identifier.module, + identifier.version, + artifact.file + )) } else { - external.add(dependency) - } - - resolvedFiles.add(artifact.file) - } - - // add remaining local jar/aar files to external dependency - files.findAll { File resolved -> - !resolvedFiles.contains(resolved) - }.each { File localDep -> - if (!FilenameUtils.directoryContains(project.rootProject.projectDir.absolutePath, localDep.absolutePath) - && !depCache.isWhiteListed(localDep)) { - throw new IllegalStateException("Local dependencies should be under project root. Dependencies " + - "outside the project can cause hard to reproduce builds. Please move dependency: ${localDep} " + - "inside ${project.rootProject.projectDir}") + if (!FilenameUtils.directoryContains(project.rootProject.projectDir.absolutePath, + artifact.file.absolutePath) && !depCache.isWhiteListed(artifact.file)) { + throw new IllegalStateException("Local dependencies should be under project root. Dependencies " + + "outside the project can cause hard to reproduce builds. Please move dependency: ${localDep} " + + "inside ${project.rootProject.projectDir}") + } + external.add(ExternalDependency.fromLocal(artifact.file)) } - external.add(ExternalDependency.fromLocal(localDep)) } } diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/TargetCache.java b/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/TargetCache.java index 18e98521a..967f71735 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/TargetCache.java +++ b/buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/TargetCache.java @@ -3,7 +3,8 @@ import com.android.build.gradle.AppExtension; import com.android.build.gradle.LibraryExtension; import com.android.build.gradle.api.BaseVariant; -import com.android.build.gradle.api.BaseVariantOutput; +import com.google.common.base.CaseFormat; +import com.google.common.base.Converter; import com.uber.okbuck.core.model.android.AndroidAppTarget; import com.uber.okbuck.core.model.android.AndroidLibTarget; import com.uber.okbuck.core.model.groovy.GroovyLibTarget; @@ -13,7 +14,9 @@ import com.uber.okbuck.core.model.kotlin.KotlinLibTarget; import com.uber.okbuck.core.util.ProjectUtil; +import org.apache.commons.io.FilenameUtils; import org.gradle.api.Project; +import org.gradle.api.plugins.BasePluginConvention; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -23,8 +26,11 @@ public class TargetCache { + private static final Converter NAME_CONVERTER = + CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_HYPHEN); + private final Map> store = new HashMap<>(); - private final Map outputToTarget = new HashMap<>(); + private final Map> artifactNameToTarget = new HashMap<>(); public Map getTargets(Project project) { Map projectTargets = store.get(project); @@ -43,15 +49,20 @@ public Map getTargets(Project project) { case KOTLIN_ANDROID_LIB: case ANDROID_LIB: projectTargets = new HashMap<>(); + Map projectArtifacts = new HashMap<>(); + String archiveBaseName = project.getConvention().getPlugin(BasePluginConvention.class) + .getArchivesBaseName(); for (BaseVariant v : project.getExtensions() .getByType(LibraryExtension.class) .getLibraryVariants()) { Target target = new AndroidLibTarget(project, v.getName()); projectTargets.put(v.getName(), target); - for (BaseVariantOutput o : v.getOutputs()) { - outputToTarget.put(o.getOutputFile(), target); - } + + String artifactName = String.format("%s-%s", archiveBaseName, + NAME_CONVERTER.convert(v.getName())); + projectArtifacts.put(artifactName, target); } + artifactNameToTarget.put(project, projectArtifacts); break; case GROOVY_LIB: projectTargets = Collections.singletonMap(JvmTarget.MAIN, @@ -80,13 +91,17 @@ public Map getTargets(Project project) { } @Nullable - public Target getTargetForOutput(Project targetProject, File output) { + public Target getTargetForOutput(Project targetProject, File artifact) { Target result; ProjectType type = ProjectUtil.getType(targetProject); switch (type) { case ANDROID_LIB: case KOTLIN_ANDROID_LIB: - result = outputToTarget.get(output); + result = artifactNameToTarget.get(targetProject) + .get(FilenameUtils.getBaseName(artifact.getName())); + if (result == null) { + throw new IllegalStateException("No target found for " + artifact.toString()); + } break; case GROOVY_LIB: case JAVA_APP: diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/generator/DotBuckConfigLocalGenerator.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/generator/DotBuckConfigLocalGenerator.groovy index 76840bca2..2eeae7c4f 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/generator/DotBuckConfigLocalGenerator.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/generator/DotBuckConfigLocalGenerator.groovy @@ -18,8 +18,7 @@ final class DotBuckConfigLocalGenerator { */ static DotBuckConfigLocalFile generate(OkBuckExtension okbuck, String groovyHome, - String kotlinCompiler, - String kotlinRuntime, + String kotlinHome, String proguardJar, Set defs) { Map aliases = [:] @@ -37,8 +36,7 @@ final class DotBuckConfigLocalGenerator { okbuck.target, [".git", "**/.svn"], groovyHome, - kotlinCompiler, - kotlinRuntime, + kotlinHome, proguardJar, defs) } diff --git a/buildSrc/src/main/groovy/com/uber/okbuck/rule/android/AndroidResourceRule.groovy b/buildSrc/src/main/groovy/com/uber/okbuck/rule/android/AndroidResourceRule.groovy index e9d02bd70..babab369f 100644 --- a/buildSrc/src/main/groovy/com/uber/okbuck/rule/android/AndroidResourceRule.groovy +++ b/buildSrc/src/main/groovy/com/uber/okbuck/rule/android/AndroidResourceRule.groovy @@ -22,7 +22,7 @@ final class AndroidResourceRule extends BuckRule { @Override protected final void printContent(PrintStream printer) { printer.println("\tpackage = '${mPackage}',") - if (mRes || mResourceUnion) { + if (mRes) { printer.println("\tres = res_glob([") mRes.each { printer.println("\t\t('${it}', '**'),") diff --git a/buildSrc/src/main/java/com/uber/okbuck/core/task/OkBuckTask.java b/buildSrc/src/main/java/com/uber/okbuck/core/task/OkBuckTask.java index 0fa9ac6a6..1ea18588c 100644 --- a/buildSrc/src/main/java/com/uber/okbuck/core/task/OkBuckTask.java +++ b/buildSrc/src/main/java/com/uber/okbuck/core/task/OkBuckTask.java @@ -48,15 +48,13 @@ void okbuck() { boolean hasKotlinLib = okBuckExtension.buckProjects.stream() .map(ProjectUtil::getType) .anyMatch(type -> type == ProjectType.KOTLIN_LIB || type == ProjectType.KOTLIN_ANDROID_LIB || type == ProjectType.KOTLIN_ANDROID_APP); - Pair kotlinDeps = null; if (hasKotlinLib) { - kotlinDeps = KotlinUtil.setupKotlinHome(getProject()); + KotlinUtil.setupKotlinHome(getProject()); } generate(okBuckExtension, hasGroovyLib ? GroovyUtil.GROOVY_HOME_LOCATION : null, - kotlinDeps != null ? kotlinDeps.getLeft(): null, - kotlinDeps != null ? kotlinDeps.getRight(): null); + hasKotlinLib ? KotlinUtil.KOTLIN_HOME_LOCATION : null); } @Override public String getGroup() { @@ -82,8 +80,7 @@ public File dotBuckConfigLocal() { return getProject().file(".buckconfig.local"); } - private void generate(OkBuckExtension okbuckExt, String groovyHome, - String kotlinCompiler, String KotlinRuntime) { + private void generate(OkBuckExtension okbuckExt, String groovyHome, String kotlinHome) { // generate empty .buckconfig if it does not exist if (!dotBuckConfig().exists()) { try { @@ -105,8 +102,7 @@ private void generate(OkBuckExtension okbuckExt, String groovyHome, PrintStream configPrinter = new PrintStream(dotBuckConfigLocal())) { DotBuckConfigLocalGenerator.generate(okbuckExt, groovyHome, - kotlinCompiler, - KotlinRuntime, + kotlinHome, ProguardUtil.getProguardJarPath(getProject()), defs).print(configPrinter); } catch (IOException e) { diff --git a/buildSrc/src/main/java/com/uber/okbuck/core/util/KotlinUtil.java b/buildSrc/src/main/java/com/uber/okbuck/core/util/KotlinUtil.java index cf1cd18e6..9334b5655 100644 --- a/buildSrc/src/main/java/com/uber/okbuck/core/util/KotlinUtil.java +++ b/buildSrc/src/main/java/com/uber/okbuck/core/util/KotlinUtil.java @@ -1,80 +1,65 @@ package com.uber.okbuck.core.util; -import com.google.common.collect.ImmutableMap; import com.uber.okbuck.OkBuckGradlePlugin; import com.uber.okbuck.core.dependency.DependencyCache; -import org.apache.commons.lang3.tuple.Pair; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ModuleVersionIdentifier; -import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.dsl.DependencyHandler; -import org.jetbrains.annotations.Nullable; -import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Collections; public final class KotlinUtil { private static final String KOTLIN_DEPS_CONFIG = "okbuck_kotlin_deps"; private static final String KOTLIN_GROUP = "org.jetbrains.kotlin"; - private static final String KOTLIN_COMPILER_MODULE = "kotlin-compiler-embeddable"; - private static final String KOTLIN_RUNTIME_MODULE = "kotlin-runtime"; - private static final String KOTLIN_HOME_LOCATION = OkBuckGradlePlugin.DEFAULT_CACHE_PATH + "/kotlin_installation"; - private static final String KOTLIN_PREVIEW_VERSION = "1.1.3-eap-58"; + private static final String KOTLIN_COMPILER_MODULE = "kotlin-compiler"; + private static final String KOTLIN_GRADLE_MODULE = "kotlin-gradle-plugin"; + private static final String KOTLIN_STDLIB_MODULE = "kotlin-stdlib"; + public static final String KOTLIN_HOME_LOCATION = OkBuckGradlePlugin.DEFAULT_CACHE_PATH + "/kotlin_home"; private KotlinUtil() {} - @Nullable - public static String getKotlinVersion(Project project) { - // We hard code the kotlin version instead of looking it up in the plugin since a dev version - // of the plugin has not been released yet. - return KOTLIN_PREVIEW_VERSION; - /** - return project.getBuildscript() - .getConfigurations() - .getByName("classpath") - .getResolvedConfiguration() - .getResolvedArtifacts() - .stream() - .filter(resolvedArtifact -> { - ModuleVersionIdentifier identifier = resolvedArtifact.getModuleVersion().getId(); - return (KOTLIN_GROUP.equals(identifier.getGroup()) && - KOTLIN_COMPILER_MODULE.equals(identifier.getName())); - }) - .findFirst() - .map(r -> r.getModuleVersion().getId().getVersion()) - .orElse(null); - **/ - } - @SuppressWarnings("ResultOfMethodCallIgnored") - public static Pair setupKotlinHome(Project rootProject) { - String kotlinVersion = getKotlinVersion(rootProject); - + public static void setupKotlinHome(Project rootProject) { + String kotlinVersion = ProjectUtil.findVersionInClasspath(rootProject, KOTLIN_GROUP, KOTLIN_GRADLE_MODULE); Configuration kotlinConfig = rootProject.getConfigurations().maybeCreate(KOTLIN_DEPS_CONFIG); DependencyHandler handler = rootProject.getDependencies(); handler.add(KOTLIN_DEPS_CONFIG, String.format("%s:%s:%s", KOTLIN_GROUP, KOTLIN_COMPILER_MODULE, kotlinVersion)); - handler.add(KOTLIN_DEPS_CONFIG, String.format("%s:%s:%s", KOTLIN_GROUP, KOTLIN_RUNTIME_MODULE, kotlinVersion)); + handler.add(KOTLIN_DEPS_CONFIG, String.format("%s:%s:%s", KOTLIN_GROUP, KOTLIN_STDLIB_MODULE, kotlinVersion)); new DependencyCache("kotlin", rootProject, - KOTLIN_HOME_LOCATION + "/lib", + KOTLIN_HOME_LOCATION, Collections.singleton(kotlinConfig), null); - File kotlinHome = new File(KOTLIN_HOME_LOCATION); - - File kotlinc = new File(kotlinHome, "bin/kotlinc"); - FileUtil.copyResourceToProject("kotlin/bin/kotlinc", - new File(kotlinHome, "bin/kotlinc"), - ImmutableMap.of("template-kotlin-version", kotlinVersion)); - kotlinc.setExecutable(true); + removeVersions(Paths.get(KOTLIN_HOME_LOCATION), + KOTLIN_COMPILER_MODULE, + KOTLIN_STDLIB_MODULE); + } - String kotlinCompiler = rootProject.relativePath(kotlinc); - String kotlinRuntime = String.format("%s/lib/%s-%s.jar", KOTLIN_HOME_LOCATION, KOTLIN_RUNTIME_MODULE, - kotlinVersion); - return Pair.of(kotlinCompiler, kotlinRuntime); + private static void removeVersions(Path dir, String... toRename) { + for (String rename : toRename) { + try { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + String fileName = file.getFileName().toString(); + if (fileName.startsWith(rename)) { + Files.move(file, file.getParent().resolve(rename + ".jar")); + } + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException ignored) {} + } } } diff --git a/buildSrc/src/main/java/com/uber/okbuck/core/util/LintUtil.java b/buildSrc/src/main/java/com/uber/okbuck/core/util/LintUtil.java index fa1fe8eef..e66f46c14 100644 --- a/buildSrc/src/main/java/com/uber/okbuck/core/util/LintUtil.java +++ b/buildSrc/src/main/java/com/uber/okbuck/core/util/LintUtil.java @@ -7,8 +7,6 @@ import org.apache.commons.io.FileUtils; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ModuleVersionIdentifier; -import org.gradle.api.artifacts.ResolvedArtifact; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -31,19 +29,7 @@ private LintUtil() {} @Nullable public static String getDefaultLintVersion(Project project) { - return project.getBuildscript() - .getConfigurations() - .getByName("classpath") - .getResolvedConfiguration() - .getResolvedArtifacts() - .stream() - .filter(resolvedArtifact -> { - ModuleVersionIdentifier identifier = resolvedArtifact.getModuleVersion().getId(); - return (LINT_GROUP.equals(identifier.getGroup()) && LINT_MODULE.equals(identifier.getName())); - }) - .findFirst() - .map(r -> r.getModuleVersion().getId().getVersion()) - .orElse(null); + return ProjectUtil.findVersionInClasspath(project, LINT_GROUP, LINT_MODULE); } @SuppressWarnings("ResultOfMethodCallIgnored") @@ -95,8 +81,7 @@ public static DependencyCache getLintDepsCache(Project project) { true, false, false, - false, - okBuckExtension.buckProjects); + false); } return okBuckGradlePlugin.lintDepCache; } diff --git a/buildSrc/src/main/java/com/uber/okbuck/core/util/ProguardUtil.java b/buildSrc/src/main/java/com/uber/okbuck/core/util/ProguardUtil.java index effe98b27..c50aafe21 100644 --- a/buildSrc/src/main/java/com/uber/okbuck/core/util/ProguardUtil.java +++ b/buildSrc/src/main/java/com/uber/okbuck/core/util/ProguardUtil.java @@ -6,8 +6,6 @@ import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ModuleVersionIdentifier; -import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency; import org.jetbrains.annotations.Nullable; @@ -23,37 +21,17 @@ private ProguardUtil() {} @Nullable public static String getProguardJarPath(Project project) { + String proguardVersion = ProjectUtil.findVersionInClasspath(project, PROGUARD_GROUP, PROGUARD_MODULE); Configuration proguardConfiguration = project.getConfigurations().detachedConfiguration( - new DefaultExternalModuleDependency(PROGUARD_GROUP, PROGUARD_MODULE, - getProguardVersion(project))); + new DefaultExternalModuleDependency(PROGUARD_GROUP, PROGUARD_MODULE, proguardVersion)); DependencyCache proguardCache = new DependencyCache("proguard", project.getRootProject(), PROGUARD_DEPS_CACHE, Collections.singleton(proguardConfiguration)); String proguardJarPath = null; try { - proguardJarPath = proguardCache.get(new VersionlessDependency( - VersionlessDependency.getDepIdentifier(PROGUARD_GROUP, PROGUARD_MODULE), null)); + proguardJarPath = proguardCache.get(new VersionlessDependency(PROGUARD_GROUP, PROGUARD_MODULE)); } catch (IllegalStateException ignored) {} return proguardJarPath; } - - @Nullable - private static String getProguardVersion(Project project) { - return project.getBuildscript() - .getConfigurations() - .getByName("classpath") - .getResolvedConfiguration() - .getResolvedArtifacts() - .stream() - .filter(ProguardUtil::findProguard) - .findFirst() - .map(r -> r.getModuleVersion().getId().getVersion()) - .orElse(null); - } - - private static boolean findProguard(ResolvedArtifact artifact) { - ModuleVersionIdentifier identifier = artifact.getModuleVersion().getId(); - return (PROGUARD_GROUP.equals(identifier.getGroup()) && PROGUARD_MODULE.equals(identifier.getName())); - } } diff --git a/buildSrc/src/main/java/com/uber/okbuck/core/util/ProjectUtil.java b/buildSrc/src/main/java/com/uber/okbuck/core/util/ProjectUtil.java index dd13384a4..9acb49236 100644 --- a/buildSrc/src/main/java/com/uber/okbuck/core/util/ProjectUtil.java +++ b/buildSrc/src/main/java/com/uber/okbuck/core/util/ProjectUtil.java @@ -10,6 +10,7 @@ import java.io.File; import java.util.Map; import org.gradle.api.Project; +import org.gradle.api.artifacts.component.ModuleComponentIdentifier; import org.gradle.api.plugins.ApplicationPlugin; import org.gradle.api.plugins.GroovyPlugin; import org.gradle.api.plugins.JavaPlugin; @@ -65,4 +66,23 @@ static OkBuckGradlePlugin getPlugin(Project project) { private static TargetCache getTargetCache(Project project) { return getPlugin(project).targetCache; } + + static String findVersionInClasspath(Project project, String group, String module) { + return project.getBuildscript() + .getConfigurations() + .getByName("classpath") + .getIncoming() + .getArtifacts() + .getArtifacts() + .stream() + .filter(resolvedArtifactResult -> { + ModuleComponentIdentifier identifier = + (ModuleComponentIdentifier) resolvedArtifactResult.getId().getComponentIdentifier(); + return (group.equals(identifier.getGroup()) && + module.equals(identifier.getModule())); + }) + .findFirst() + .map(r -> ((ModuleComponentIdentifier) r.getId().getComponentIdentifier()).getVersion()) + .orElse(null); + } } diff --git a/buildSrc/src/main/resources/com/uber/okbuck/core/util/kotlin/bin/kotlinc b/buildSrc/src/main/resources/com/uber/okbuck/core/util/kotlin/bin/kotlinc deleted file mode 100755 index 221b2b96f..000000000 --- a/buildSrc/src/main/resources/com/uber/okbuck/core/util/kotlin/bin/kotlinc +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env bash -# -# Modified for okbuck -############################################################################## -# Copyright 2002-2011, LAMP/EPFL -# Copyright 2011-2015, JetBrains -# -# This is free software; see the distribution for copying conditions. -# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. -############################################################################## - -cygwin=false; -case "`uname`" in - CYGWIN*) cygwin=true ;; -esac - -# Based on findScalaHome() from scalac script -findKotlinHome() { - local source="${BASH_SOURCE[0]}" - while [ -h "$source" ] ; do - local linked="$(readlink "$source")" - local dir="$(cd -P $(dirname "$source") && cd -P $(dirname "$linked") && pwd)" - source="$dir/$(basename "$linked")" - done - (cd -P "$(dirname "$source")/.." && pwd) -} - -KOTLIN_HOME="$(findKotlinHome)" - -if $cygwin; then - # Remove spaces from KOTLIN_HOME on windows - KOTLIN_HOME=`cygpath --windows --short-name "$KOTLIN_HOME"` -fi - -[ -n "$JAVA_OPTS" ] || JAVA_OPTS="-Xmx256M -Xms32M" - -declare -a java_args -declare -a kotlin_args - -while [ $# -gt 0 ]; do - case "$1" in - -D*) - java_args=("${java_args[@]}" "$1") - shift - ;; - -J*) - java_args=("${java_args[@]}" "${1:2}") - shift - ;; - *) - kotlin_args=("${kotlin_args[@]}" "$1") - shift - ;; - esac -done - -if [ -z "$JAVACMD" -a -n "$JAVA_HOME" -a -x "$JAVA_HOME/bin/java" ]; then - JAVACMD="$JAVA_HOME/bin/java" -fi - -declare -a kotlin_app - -if [ -n "$KOTLIN_RUNNER" ]; -then - java_args=("${java_args[@]}" "-Dkotlin.home=${KOTLIN_HOME}") - kotlin_app=("${KOTLIN_HOME}/lib/kotlin-runner.jar" "org.jetbrains.kotlin.runner.Main") -else - [ -n "$KOTLIN_COMPILER" ] || KOTLIN_COMPILER=org.jetbrains.kotlin.cli.jvm.K2JVMCompiler - java_args=("${java_args[@]}" "-noverify") - - if [[ -n $(command -v head) && -n $(command -v tail) && $($JAVACMD -version 2>&1 | head -2 | tail -1) =~ build\ 9 ]]; then - java_args=("${java_args[@]}" \ - "--add-opens" "java.base/java.lang=ALL-UNNAMED" \ - "--add-opens" "java.base/java.util=ALL-UNNAMED" \ - "--add-opens" "java.base/java.util.concurrent.atomic=ALL-UNNAMED" \ - "--add-opens" "java.base/jdk.internal.misc=ALL-UNNAMED") - fi - - kotlin_app=("${KOTLIN_HOME}/lib/kotlin-compiler-embeddable-${template-kotlin-version}.jar" $KOTLIN_COMPILER) -fi - -"${JAVACMD:=java}" $JAVA_OPTS "${java_args[@]}" -cp "${kotlin_app[@]}" "${kotlin_args[@]}" diff --git a/dependencies.gradle b/dependencies.gradle index 268a8f494..b92ae6541 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -4,7 +4,7 @@ def versions = [ kotlinVersion : '1.1.2-3', leakCanaryVersion : '1.5', supportVersion : '25.0.1', - androidPluginVersion : '2.3.0', + androidPluginVersion : '2.3.2', ] def build = [ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cdc5b8641..c3d9c26b1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-4.0-milestone-2-bin.zip +distributionUrl=https://services.gradle.org/distributions/gradle-4.0-rc-1-bin.zip diff --git a/libraries/emptyResourceLibrary/build.gradle b/libraries/emptyResourceLibrary/build.gradle deleted file mode 100644 index 7179ab40b..000000000 --- a/libraries/emptyResourceLibrary/build.gradle +++ /dev/null @@ -1,6 +0,0 @@ -apply plugin: 'com.android.library' - -dependencies { - compile project(':libraries:emptylibrary') - compile deps.support.appCompat -} diff --git a/libraries/emptyResourceLibrary/src/main/AndroidManifest.xml b/libraries/emptyResourceLibrary/src/main/AndroidManifest.xml deleted file mode 100644 index 0621e997d..000000000 --- a/libraries/emptyResourceLibrary/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/libraries/emptyResourceLibrary/src/main/java/com/uber/okbuck/library/empty/resources/Test.java b/libraries/emptyResourceLibrary/src/main/java/com/uber/okbuck/library/empty/resources/Test.java deleted file mode 100644 index 0ee0a112d..000000000 --- a/libraries/emptyResourceLibrary/src/main/java/com/uber/okbuck/library/empty/resources/Test.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.uber.okbuck.library.empty.resources; - -import android.content.Context; - -public class Test { - - public String foo(Context context) { - return context.getString(R.string.empty_release_string); - } -} diff --git a/settings.gradle b/settings.gradle index f7fc1a036..03ede627c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,7 +2,6 @@ include 'app' include 'another-app' include 'dummylibrary' include 'kotlinapp' -include 'libraries:emptyResourceLibrary' include 'libraries:common' include 'libraries:customLintLibrary' include 'libraries:emptylibrary'