import groovy.xml.MarkupBuilder apply plugin: 'maven-publish' // Task to generate our public.xml file // See https://developer.android.com/studio/projects/android-library.html#PrivateResources // We assume resources within res-public are public task generatepublicxml { def resDir = project.projectDir.absolutePath + "/src/main/res" def publicDir = resDir + "-public" def resFolder = file(resDir + "/values") def publicFolder = file(publicDir + "/values") if (!publicFolder.exists()) { // No res; no need for contents if (!resFolder.exists()) { return } publicFolder.mkdirs() } // Include the desired res types // Note: we don't need the qualified resource directories, // since those resources will already be defined in the unqualified directories // however, there are special cases like transition-v21 that is only available on lollipop and up def tree = fileTree(dir: publicDir, includes: ['**/anim/*.xml', '**/color/*.xml', '**/drawable/*.xml', '**/layout/*.xml', '**/transition-v21/*.xml', '**/values/*.xml' ], exclude: '**/public.xml' ) println "Generating public XML: ${project.name}" // Create new public.xml with writer file(publicDir + "/values/public.xml").withWriter { writer -> // Create MarkupBuilder with 4 space indent def destXml = new MarkupBuilder(new IndentPrinter(writer, " ", true)) def destXmlMkp = destXml.getMkp() // GIST NOTE: our project needed the ResourceName suppression, but it's not needed in general destXml.resources( 'xmlns:tools': 'http://schemas.android.com/tools', 'tools:ignore': 'ResourceName' ) { // Leave file comment destXmlMkp.yield "\r\n" destXmlMkp.comment("AUTO-GENERATED FILE. DO NOT MODIFY. public.xml is generated by the generatepublicxml gradle task") if (tree.isEmpty()) "public"("name": "dummy", "type": "id") else tree.each { resFile -> // use the directory name to get the type String type = resFile.getParentFile().getName() if (type == "values") { // Resource files under values. Parse the file, and pull out the resource definitions def parsePublicResources = new XmlParser().parse(resFile) parsePublicResources.children().each { // Type is usually the element, but sometimes a type attribute is present // example: 1.4 type = it.name() if (it.@type) { type = it.@type } // it.@name is value in name= "public"("name": it.@name, "type": type) } } else { // Drawable, layout, etc files "public"("name": resFile.getName().tokenize('.')[0], "type": type.tokenize('-')[0]) } } } } } afterEvaluate { publishing { publications { release(MavenPublication) { from components.release groupId = group artifactId = project.name } } } } build.dependsOn generatepublicxml