| /* | |
| * 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<String,String> collapsePaths(FileTree path, List<String> roots) { | |
| Map result = new HashMap<String,String>(); | |
| 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 | |
| } |