Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for specific build type and product flavor dependencies #135

Merged
merged 3 commits into from
Apr 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.kezong.fataar

import com.android.build.gradle.api.LibraryVariant
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.DependencyResolutionListener
import org.gradle.api.artifacts.ResolvableDependencies

class ConfigurationDependencyResolutionListener implements DependencyResolutionListener {

private final Project project

private final Configuration configuration

ConfigurationDependencyResolutionListener(Project project, Configuration configuration) {
this.project = project
this.configuration = configuration
}

@Override
void beforeResolve(ResolvableDependencies resolvableDependencies) {
configuration.dependencies.each { dependency ->
project.dependencies.add('compileOnly', dependency)
}
project.gradle.removeListener(this)
}

@Override
void afterResolve(ResolvableDependencies resolvableDependencies) {
}
}
134 changes: 83 additions & 51 deletions source/src/main/groovy/com/kezong/fataar/FatLibraryPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.ProjectConfigurationException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.DependencyResolutionListener
import org.gradle.api.artifacts.ResolvableDependencies
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.ResolvedDependency

Expand All @@ -24,23 +22,67 @@ class FatLibraryPlugin implements Plugin<Project> {

private Project project

private Configuration embedConf

private Set<ResolvedArtifact> artifacts

private Set<ResolvedDependency> unResolveArtifact

@Override
void apply(Project project) {
this.project = project
Utils.setProject(project)
checkAndroidPlugin()
createConfiguration()
final Configuration embedConf = project.configurations.create('embed')
createConfiguration(embedConf)
print("Creating configuration embed\n")

project.android.buildTypes.all { buildType ->
String configName = buildType.name + 'Embed'
Configuration configuration = project.configurations.create(configName)
createConfiguration(configuration)
print("Creating configuration " + configName + "\n")
}

project.android.productFlavors.all { flavor ->
String configName = flavor.name + 'Embed'
Configuration configuration = project.configurations.create(configName)
createConfiguration(configuration)
print("Creating configuration " + configName + "\n")
}

// project.android.libraryVariants.all { variant ->
// String configName = variant.name + 'Embed'
// final Configuration configuration = project.configurations.create(configName)
// createConfiguration(configuration)
// print("Configuration created: " + configName + "\n")
// }

project.afterEvaluate {
resolveArtifacts()
dealUnResolveArtifacts()
Set<ResolvedArtifact> commonArtifacts = resolveArtifacts(embedConf)
Set<ResolvedDependency> commonUnResolveArtifacts = dealUnResolveArtifacts(embedConf, commonArtifacts)
project.android.libraryVariants.all { variant ->
processVariant(variant)
// String configName = variant.name + 'Embed'

String buildTypeConfigName = variant.getBuildType().name + 'Embed'
Configuration buildTypeConfiguration = project.configurations.getByName(buildTypeConfigName)

/**
* Doesn't support more than one flavor dimension: LibraryVariant does not have
* public interface for VariantConfiguration list(which holds flavor configs).
* Also Library plugin doesn't have API for variants in the project.
*/
String flavorConfigName = variant.getFlavorName() + 'Embed'
Configuration flavorConfiguration
try {
flavorConfiguration = project.configurations.getByName(flavorConfigName)
} catch(Exception ignored) {}

Set<ResolvedArtifact> artifacts = new HashSet<>()
artifacts.addAll(commonArtifacts)
artifacts.addAll(resolveArtifacts(buildTypeConfiguration))
artifacts.addAll(resolveArtifacts(flavorConfiguration))

Set<ResolvedDependency> unResolveArtifacts = new HashSet<>()
unResolveArtifacts.addAll(commonUnResolveArtifacts)
unResolveArtifacts.addAll(dealUnResolveArtifacts(buildTypeConfiguration, artifacts))
unResolveArtifacts.addAll(dealUnResolveArtifacts(flavorConfiguration, artifacts))

processVariant(variant, artifacts, unResolveArtifacts)
}
}

Expand All @@ -53,62 +95,52 @@ class FatLibraryPlugin implements Plugin<Project> {
}
}

private void createConfiguration() {
embedConf = project.configurations.create('embed')
private void createConfiguration(Configuration embedConf) {
embedConf.visible = false
embedConf.transitive = false

project.gradle.addListener(new DependencyResolutionListener() {
@Override
void beforeResolve(ResolvableDependencies resolvableDependencies) {
embedConf.dependencies.each { dependency ->
project.dependencies.add('compileOnly', dependency)
}
project.gradle.removeListener(this)
}

@Override
void afterResolve(ResolvableDependencies resolvableDependencies) {
}
})
project.gradle.addListener(new ConfigurationDependencyResolutionListener(project, embedConf))
}

private void resolveArtifacts() {
private Set<ResolvedArtifact> resolveArtifacts(Configuration configuration) {
def set = new HashSet<>()
embedConf.resolvedConfiguration.resolvedArtifacts.each { artifact ->
// jar file wouldn't be here
if (ARTIFACT_TYPE_AAR == artifact.type || ARTIFACT_TYPE_JAR == artifact.type) {
Utils.logAnytime('[embed detected][' + artifact.type + ']' + artifact.moduleVersion.id)
} else {
throw new ProjectConfigurationException('Only support embed aar and jar dependencies!', null)
if (configuration != null) {
configuration.resolvedConfiguration.resolvedArtifacts.each { artifact ->
// jar file wouldn't be here
if (ARTIFACT_TYPE_AAR == artifact.type || ARTIFACT_TYPE_JAR == artifact.type) {
Utils.logAnytime('[embed detected][' + artifact.type + ']' + artifact.moduleVersion.id)
} else {
throw new ProjectConfigurationException('Only support embed aar and jar dependencies!', null)
}
set.add(artifact)
}
set.add(artifact)
}
artifacts = Collections.unmodifiableSet(set)
return Collections.unmodifiableSet(set)
}

private void processVariant(LibraryVariant variant) {
private void processVariant(LibraryVariant variant, Set<ResolvedArtifact> artifacts, Set<ResolvedDependency> unResolveArtifacts) {
def processor = new VariantProcessor(project, variant)
processor.addArtifacts(artifacts)
processor.addUnResolveArtifact(unResolveArtifact)
processor.addUnResolveArtifact(unResolveArtifacts)
processor.processVariant()
}

private void dealUnResolveArtifacts() {
def dependencies = Collections.unmodifiableSet(embedConf.resolvedConfiguration.firstLevelModuleDependencies)
private Set<ResolvedDependency> dealUnResolveArtifacts(Configuration configuration, Set<ResolvedArtifact> artifacts) {
def dependencySet = new HashSet()
dependencies.each { dependency ->
boolean match = false
artifacts.each { artifact ->
if (dependency.moduleName == artifact.name) {
match = true
if (configuration != null) {
def dependencies = Collections.unmodifiableSet(configuration.resolvedConfiguration.firstLevelModuleDependencies)
dependencies.each { dependency ->
boolean match = false
artifacts.each { artifact ->
if (dependency.moduleName == artifact.name) {
match = true
}
}
if (!match) {
Utils.logAnytime('[unResolve dependency detected][' + dependency.name + ']')
dependencySet.add(dependency)
}
}
if (!match) {
Utils.logAnytime('[unResolve dependency detected][' + dependency.name + ']')
dependencySet.add(dependency)
}
}
unResolveArtifact = Collections.unmodifiableSet(dependencySet)
return Collections.unmodifiableSet(dependencySet)
}
}