ho affrontato la stessa sfida, ed ecco il meglio che potessi fare ancora:
Utilizzando mavenPublications
e la Gradle maven-publish
plug lungo il plugin bintray, è possibile pubblicare qualsiasi variante di mavenLocal e bintray.
Ecco il file publish.gradle
applico alla fine di moduli di libreria di tutto il mio progetto voglio pubblicare:
def pomConfig = {
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id 'louiscad'
name 'Louis CAD'
email '[email protected]'
}
}
scm {
connection 'https://github.com/LouisCAD/Splitties.git'
developerConnection 'https://github.com/LouisCAD/Splitties.git'
url siteUrl
}
}
def publicationNames = []
publishing.publications {
android.libraryVariants.all { variant ->
if (variant.buildType.name == "debug") return // Prevents publishing debug library
def flavored = !variant.flavorName.isEmpty()
/**
* Translates "_" in flavor names to "-" for artifactIds, because "-" in flavor name is an
* illegal character, but is well used in artifactId names.
*/
def variantArtifactId = flavored ? variant.flavorName.replace('_', '-') : project.name
/**
* If the javadoc destinationDir wasn't changed per flavor, the libraryVariants would
* overwrite the javaDoc as all variants would write in the same directory
* before the last javadoc jar would have been built, which would cause the last javadoc
* jar to include classes from other flavors that it doesn't include.
*
* Yes, tricky.
*
* Note that "${buildDir}/docs/javadoc" is the default javadoc destinationDir.
*/
def javaDocDestDir = file("${buildDir}/docs/javadoc ${flavored ? variantArtifactId : ""}")
/**
* Includes
*/
def sourceDirs = variant.sourceSets.collect {
it.javaDirectories // Also includes kotlin sources if any.
}
def javadoc = task("${variant.name}Javadoc", type: Javadoc) {
description "Generates Javadoc for ${variant.name}."
source = variant.javaCompile.source // Yes, javaCompile is deprecated,
// but I didn't find any working alternative. Please, tweet @Louis_CAD if you find one.
destinationDir = javaDocDestDir
classpath += files(android.getBootClasspath().join(File.pathSeparator))
classpath += files(configurations.compile)
options.links("http://docs.oracle.com/javase/7/docs/api/");
options.links("http://d.android.com/reference/");
exclude '**/BuildConfig.java'
exclude '**/R.java'
failOnError false
}
def javadocJar = task("${variant.name}JavadocJar", type: Jar, dependsOn: javadoc) {
description "Puts Javadoc for ${variant.name} in a jar."
classifier = 'javadoc'
from javadoc.destinationDir
}
def sourcesJar = task("${variant.name}SourcesJar", type: Jar) {
description "Puts sources for ${variant.name} in a jar."
from sourceDirs
classifier = 'sources'
}
def publicationName = "splitties${variant.name.capitalize()}Library"
publicationNames.add(publicationName)
"$publicationName"(MavenPublication) {
artifactId variantArtifactId
group groupId
version libraryVersion
artifact variant.outputs[0].packageLibrary // This is the aar library
artifact sourcesJar
artifact javadocJar
pom {
packaging 'aar'
withXml {
def root = asNode()
root.appendNode("name", 'Splitties')
root.appendNode("url", siteUrl)
root.children().last() + pomConfig
def depsNode = root["dependencies"][0] ?: root.appendNode("dependencies")
def addDep = {
if (it.group == null) return // Avoid empty dependency nodes
def dependencyNode = depsNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
if (it.hasProperty('optional') && it.optional) {
dependencyNode.appendNode('optional', 'true')
}
}
// Add deps that everyone has
configurations.compile.allDependencies.each addDep
// Add flavor specific deps
if (flavored) {
configurations["${variant.flavorName}Compile"].allDependencies.each addDep
}
// NOTE: This library doesn't use builtTypes specific dependencies, so no need to add them.
}
}
}
}
}
group = groupId
version = libraryVersion
afterEvaluate {
bintray {
user = bintray_user
key = bintray_api_key
publications = publicationNames
override = true
pkg {
repo = 'splitties'
name = project.name
desc = libraryDesc
websiteUrl = siteUrl
issueTrackerUrl = 'https://github.com/LouisCAD/Splitties/issues'
vcsUrl = gitUrl
licenses = ['Apache-2.0']
labels = ['aar', 'android']
publicDownloadNumbers = true
githubRepo = 'LouisCAD/Splitties'
}
}
}
Affinché ciò funzioni, ho bisogno di avere le proprietà bintray_user
e bintray_api_key
definiti. Io personalmente appena li ho nella mia ~/.gradle/gradle.properties
file in questo modo:
bintray_user=my_bintray_user_name
bintray_api_key=my_private_bintray_api_key
Ho anche bisogno di definire le seguenti proprietà ext ho usato nel file publish.gradle
in build.gradle
fascicolo di mio progetto principale:
allprojects {
...
ext {
...
// Libraries
groupId = "xyz.louiscad.splitties"
libraryVersion = "1.2.1"
siteUrl = 'https://github.com/LouisCAD/Splitties'
gitUrl = 'https://github.com/LouisCAD/Splitties.git'
}
}
Ed ora , Posso finalmente usarlo nel mio modulo di libreria Android, dove ho più productFlavors
. Ecco un frammento da build.gradle
file di un modulo di libreria pubblicabile:
plugins {
id "com.jfrog.bintray" version "1.7.3" // Enables publishing to bintray
id "com.github.dcendents.android-maven" version "1.5" // Allows aar in mavenPublications
}
apply plugin: 'com.android.library'
apply plugin: 'maven-publish' // Used for mavenPublications
android {
...
defaultPublishConfig "myLibraryDebug" // Allows using this library in another
// module in this project without publishing to mavenLocal or Bintray.
// Useful for debug purposes, or for your library's sample app.
defaultConfig {
...
versionName libraryVersion
...
}
...
productFlavors {
myLibrary
myLibrary_logged // Here, the "_" will be replaced "-" in artifactId when publishing.
myOtherLibraryFlavor
}
...
}
dependencies {
...
// Timber, a log utility.
myLibrary_loggedCompile "com.jakewharton.timber:timber:${timberVersion}"; // Just an example
}
...
ext {
libraryDesc = "Delegates for kotlin on android that check UI thread"
}
apply from: '../publish.gradle' // Makes this library publishable
Quando hai tutto questo impostato correttamente, con il nome della vostra libreria, invece di mine's (che si può usare come esempio), si può provare l'editoria una versione della libreria aromatizzata cercando di pubblicare prima su mavenLocal. Per fare ciò, eseguire questo comando:
myLibrary $ ../gradlew publishToMavenLocal
si può quindi provare ad aggiungere mavenLocal
nei repository della vostra app (example here) e provare ad aggiungere la libreria come una dipendenza (artifactId dovrebbe essere il nome di sapore, con "_" sostituito con " - ") e costruendolo. Puoi anche controllare con il tuo file explorer (usa cmd + shift + G su Mac in Finder per accedere alla cartella nascosta) la directory ~/.m2
e cercare la tua libreria.
Quando è il momento di pubblicare a bintray/jcenter, è sufficiente eseguire questo comando:
myLibrary $ ../gradlew bintrayUpload
Importante:
Prima di pubblicare la vostra libreria per mavenLocal, Bintray o altro repository Maven , di solito vuoi provare la tua libreria con un'app campione che utilizza la libreria. Questa app di esempio, che dovrebbe essere un altro modulo nello stesso progetto, deve solo avere la dipendenza del progetto, che dovrebbe assomigliare a questa: compile project(':myLibrary')
. Tuttavia, dal momento che la tua libreria ha più productFlavors, ti consigliamo di testarli tutti.Purtroppo, al momento non è possibile specificare quale configurazione si desidera utilizzare dal file build.gradle
dell'app della tua app campione (a meno che non si usi publishNonDefault true
nel file build.gradle
della libreria, che interrompe le pubblicazioni di maven e bintray), ma è possibile specificare la configurazione predefinita (ad esempio buildVariant) nel modulo della libreria in quanto tale: defaultPublishConfig "myLibraryDebug"
nella chiusura android
. Puoi vedere le varianti di build disponibili per la tua libreria nello strumento "Build Variants" Windows in Android Studio.
Sentitevi liberi di esplorare my library "Splitties" here se avete bisogno di un esempio. Il modulo aromatizzato è denominato concurrency
, ma io uso il mio script anche per i moduli di libreria non formattati e l'ho testato in modo approfondito su tutti i moduli di libreria del mio progetto.
Puoi contattarmi se hai bisogno di aiuto per configurarlo.
È necessario aggiornare ogni sapore come un artefatto diverso. –
@GabrieleMariotti come si può specificare l'aroma nelle 'configurazioni 'di bintray? –
Non l'ho provato prima. Ma devi specificare una parte delle configurazioni di bintray all'interno del flavor block per assegnare il nome del manufatto. –