/* * Copyright 2013 The Android Open Source Project * * 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. */ // The SampleGenPlugin source is in the buildSrc directory. import com.example.android.samples.build.SampleGenPlugin apply plugin: SampleGenPlugin // Add a preflight task that depends on the "refresh" task that gets // added by the SampleGenPlugin. task preflight { project.afterEvaluate({preflight.dependsOn(project.refresh)}) } String outPath(String buildType) { /* def repoInfo = "repo info platform/developers/build".execute().text def buildPath = (repoInfo =~ /Mount path: (.*)/)[0][1] */ return "${samplegen.pathToBuild}/out/${buildType}/${samplegen.targetSampleName()}"; } /** * Collapse a path "IntelliJ-style" by putting dots rather than slashes between * path components that have only one child. So the two paths * * com/example/android/foo/bar.java * com/example/android/bar/foo.java * * Become * com.example.android/foo/bar.java * com.example.android/bar/foo.java * * @param path * @param roots * @return */ Map collapsePaths(FileTree path, List roots) { Map result = new HashMap(); println ("******************** Collapse *************************") path.visit { FileVisitDetails f -> if (f.isDirectory()) return; StringBuilder collapsedPath = new StringBuilder("${f.name}"); File current = f.file; // // Starting at this file, walk back to the root of the path and // substitute dots for any directory that has only one child. // // Don't substitute a dot for the separator between the end of the // path and the filename, even if there's only one file in the directory. if (!f.isDirectory()) { current = current.parentFile; collapsedPath.insert(0, "${current.name}/") } // For everything else, use a dot if there's only one child and // a slash otherwise. Filter out the root paths, too--we only want // the relative path. But wait, Groovy/Gradle is capricious and // won't return the proper value from a call to roots.contains(String)! // I'm using roots.sum here instead of tracking down why a list of // strings can't return true from contains() when given a string that // it quite obviously does contain. current = current.parentFile; while((current != null) && (roots.sum {String r-> return r.equals(current.absolutePath) ? 1 : 0 } == 0)) { char separator = current.list().length > 1 ? '/' : '.'; collapsedPath.insert(0, "${current.name}${separator}"); current = current.parentFile; } result.put(f.file.path, collapsedPath.toString()); } println ("******************** Collapse results *********************") result.each {entry -> println("- ${entry}");} return result } task emitAnt(type:Copy) { def outputPath = outPath("ant"); def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}" into outputPath includeEmptyDirs ["main", "common", "template"].each { input -> [[ "java", "src"], ["res", "res"]].each { filetype -> def srcPath = "${inputPath}/src/${input}/${filetype[0]}" into("${filetype[1]}") { from(srcPath) } } } from("${inputPath}/src/main") { include "AndroidManifest.xml" } from("${inputPath}/src/template") { include "project.properties" } } task emitGradle(type:Copy) { dependsOn(preflight) def outputPath = outPath("gradle") def inputPath = "${project.projectDir}" // Copy entire sample into output -- since it's already in Gradle format, we'll explicitly exclude content that // doesn't belong here. into outputPath from("${inputPath}") { // Paths to exclude from output exclude ".gradle" exclude "_index.jd" exclude "bin" exclude "buildSrc" exclude "local.properties" exclude "template-params.xml" exclude "*.iml" exclude "**/.idea" exclude "**/build" exclude "**/proguard-project.txt" exclude "${samplegen.targetSampleModule()}/**/README*.txt" exclude "**/README-*.txt" // src directory needs to be consolidated, will be done in next section exclude "${samplegen.targetSampleModule()}/src/" } // Consolidate source directories ["main", "common", "template"].each { input -> ["java", "res", "assets", "rs"].each { filetype -> def srcPath = "${inputPath}/${samplegen.targetSampleModule()}/src/${input}/${filetype}" into("${samplegen.targetSampleModule()}/src/main/${filetype}") { from(srcPath) } } } // Copy AndroidManifest.xml into ("${samplegen.targetSampleModule()}/src/main") { from("${inputPath}/${samplegen.targetSampleModule()}/src/main/AndroidManifest.xml") } // Remove BEGIN_EXCLUDE/END_EXCLUDE blocks from source files eachFile { file -> if (file.name.endsWith(".gradle") || file.name.endsWith(".java")) { // TODO(trevorjohns): Outputs a blank newline for each filtered line. Replace with java.io.FilterReader impl. boolean outputLines = true; def removeExcludeBlocksFilter = { line -> if (line ==~ /\/\/ BEGIN_EXCLUDE/) { outputLines = false; } else if (line ==~ /\/\/ END_EXCLUDE/) { outputLines = true; } else if (outputLines) { return line; } return "" } filter(removeExcludeBlocksFilter) } } } task emitBrowseable(type:Copy) { def outputPathRoot = outPath("browseable") def modules = project.childProjects.keySet() def hasMultipleModules = modules.size() > 1 println "---------------- modules found in sample: ${modules}" into outputPathRoot from("${project.projectDir}/_index.jd") modules.each { moduleName -> // For single module samples (default), we emit the module contents // directly to the root of the browseable sample: def outputPath = "." if (hasMultipleModules) { // For multi module samples, we need an extra directory level // to separate modules: outputPath = "${moduleName}" } println "\n---------------- processing MODULE ${moduleName} to outputPath ${outputPath}" def inputPath = "${project.projectDir}/${moduleName}" def srcDirs = ["main", "common", "template"].collect {input -> "${inputPath}/src/${input}" }; def javaDirs = srcDirs.collect { input -> "${input}/java"} FileTree javaTree = null; javaDirs.each { dir -> FileTree tree = project.fileTree("${dir}") javaTree = (javaTree == null) ? tree : javaTree.plus(tree)} Map collapsedPaths = collapsePaths(javaTree, javaDirs) srcDirs.each { srcPath -> print "** Copying source ${srcPath}..."; duplicatesStrategy = 'fail' into("${outputPath}/src") { def javaPath = "${srcPath}/java"; from(javaPath) include(["**/*.java", "**/*.xml"]) eachFile { FileCopyDetails fcd -> if (fcd.file.isFile()) { def filename = fcd.name; String collapsed = collapsedPaths.get(fcd.file.path); fcd.path = "${outputPath}/src/${collapsed}"; } else {fcd.exclude()} } println "done" } into("${outputPath}/res") { from("${srcPath}/res") } into("${outputPath}/src/rs") { from("${srcPath}/rs") } into("${outputPath}") {from("${srcPath}/AndroidManifest.xml")} } } } task emitGradleZip(dependsOn: [emitBrowseable, emitGradle], type:Zip) { def outputPath = "${samplegen.pathToBuild}/out/browseable" def folderName = "${samplegen.targetSampleName()}" archiveName = "${samplegen.targetSampleName()}.zip" def inputPath = outPath("gradle") from inputPath into folderName include "**" def outDir = project.file(outputPath) destinationDir = outDir }