1 /* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // The SampleGenPlugin source is in the buildSrc directory. 18 import com.example.android.samples.build.SampleGenPlugin 19 apply plugin: SampleGenPlugin 20 21 // Add a preflight task that depends on the "refresh" task that gets 22 // added by the SampleGenPlugin. 23 task preflight { 24 project.afterEvaluate({preflight.dependsOn(project.refresh)}) 25 } 26 27 task wrapper(type: Wrapper) { 28 gradleVersion = '1.8' 29 } 30 31 32 String outPath(String buildType) { 33 /* 34 def repoInfo = "repo info platform/developers/build".execute().text 35 def buildPath = (repoInfo =~ /Mount path: (.*)/)[0][1] 36 */ 37 return "${samplegen.pathToBuild}/out/${buildType}/${samplegen.targetSampleName()}"; 38 } 39 40 /** 41 * Collapse a path "IntelliJ-style" by putting dots rather than slashes between 42 * path components that have only one child. So the two paths 43 * 44 * com/example/android/foo/bar.java 45 * com/example/android/bar/foo.java 46 * 47 * Become 48 * com.example.android/foo/bar.java 49 * com.example.android/bar/foo.java 50 * 51 * @param path 52 * @param roots 53 * @return 54 */ 55 Map<String,String> collapsePaths(FileTree path, List<String> roots) { 56 Map result = new HashMap<String,String>(); 57 58 println ("******************** Collapse *************************") 59 60 path.visit { FileVisitDetails f -> 61 if (f.isDirectory()) return; 62 StringBuilder collapsedPath = new StringBuilder("${f.name}"); 63 File current = f.file; 64 65 // 66 // Starting at this file, walk back to the root of the path and 67 // substitute dots for any directory that has only one child. 68 // 69 70 // Don't substitute a dot for the separator between the end of the 71 // path and the filename, even if there's only one file in the directory. 72 if (!f.isDirectory()) { 73 current = current.parentFile; 74 collapsedPath.insert(0, "${current.name}/") 75 } 76 77 // For everything else, use a dot if there's only one child and 78 // a slash otherwise. Filter out the root paths, too--we only want 79 // the relative path. But wait, Groovy/Gradle is capricious and 80 // won't return the proper value from a call to roots.contains(String)! 81 // I'm using roots.sum here instead of tracking down why a list of 82 // strings can't return true from contains() when given a string that 83 // it quite obviously does contain. 84 current = current.parentFile; 85 while((current != null) 86 && (roots.sum {String r-> return r.equals(current.absolutePath) ? 1 : 0 } == 0)) { 87 88 char separator = current.list().length > 1 ? '/' : '.'; 89 collapsedPath.insert(0, "${current.name}${separator}"); 90 current = current.parentFile; 91 } 92 result.put(f.file.path, collapsedPath.toString()); 93 } 94 95 println ("******************** Results *************************") 96 97 result.each {entry -> println("${entry}\n\n");} 98 return result 99 } 100 101 102 task emitAnt(type:Copy) { 103 def outputPath = outPath("ant"); 104 def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}" 105 mkdir outputPath 106 into outputPath 107 includeEmptyDirs 108 ["main", "common", "template"].each { input -> 109 [[ "java", "src"], ["res", "res"]].each { filetype -> 110 def srcPath = "${inputPath}/src/${input}/${filetype[0]}" 111 into("${filetype[1]}") { 112 from(srcPath) 113 } 114 } 115 } 116 from("${inputPath}/src/main") { include "AndroidManifest.xml" } 117 from("${inputPath}/src/template") { include "project.properties" } 118 } 119 120 task emitGradle(type:Copy) { 121 dependsOn(preflight) 122 def outputPath = outPath("gradle") 123 def inputPath = "${project.projectDir}" 124 // Copy entire sample into output -- since it's already in Gradle format, we'll explicitly exclude content that 125 // doesn't belong here. 126 mkdir outputPath 127 into outputPath 128 from("${inputPath}") { 129 // Paths to exclude from output 130 exclude ".gradle" 131 exclude "_index.jd" 132 exclude "bin" 133 exclude "buildSrc" 134 exclude "local.properties" 135 exclude "template-params.xml" 136 exclude "*.iml" 137 exclude "**/.idea" 138 exclude "**/build" 139 exclude "**/proguard-project.txt" 140 exclude "${samplegen.targetSampleModule()}/**/README*.txt" 141 142 // src directory needs to be consolidated, will be done in next section 143 exclude "${samplegen.targetSampleModule()}/src/" 144 } 145 146 // Consolidate source directories 147 ["main", "common", "template"].each { input -> 148 ["java", "res", "assets"].each { filetype -> 149 def srcPath = "${inputPath}/${samplegen.targetSampleModule()}/src/${input}/${filetype}" 150 into("${samplegen.targetSampleModule()}/src/main/${filetype}") { 151 from(srcPath) 152 } 153 } 154 } 155 156 // Copy AndroidManifest.xml 157 into ("${samplegen.targetSampleModule()}/src/main") { 158 from("${inputPath}/${samplegen.targetSampleModule()}/src/main/AndroidManifest.xml") 159 } 160 161 // Remove BEGIN_EXCLUDE/END_EXCLUDE blocks from source files 162 eachFile { file -> 163 if (file.name.endsWith(".gradle") || file.name.endsWith(".java")) { 164 // TODO(trevorjohns): Outputs a blank newline for each filtered line. Replace with java.io.FilterReader impl. 165 boolean outputLines = true; 166 def removeExcludeBlocksFilter = { line -> 167 if (line ==~ /\/\/ BEGIN_EXCLUDE/) { 168 outputLines = false; 169 } else if (line ==~ /\/\/ END_EXCLUDE/) { 170 outputLines = true; 171 } else if (outputLines) { 172 return line; 173 } 174 return "" 175 } 176 filter(removeExcludeBlocksFilter) 177 } 178 } 179 } 180 181 task emitBrowseable(type:Copy) { 182 def outputPath =outPath("browseable"); 183 def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}" 184 mkdir outputPath 185 into outputPath 186 187 from("${project.projectDir}/_index.jd") 188 def srcDirs = ["main", "common", "template"].collect {input -> "${inputPath}/src/${input}" }; 189 def javaDirs = srcDirs.collect { input -> "${input}/java"} 190 FileTree javaTree = null; 191 javaDirs.each { dir -> 192 FileTree tree = project.fileTree("${dir}") 193 javaTree = (javaTree == null) ? tree : javaTree.plus(tree)} 194 println javaTree; 195 println srcDirs 196 Map collapsedPaths = collapsePaths(javaTree, javaDirs) 197 198 srcDirs.each { srcPath -> 199 println srcPath; 200 into("src") { 201 def javaPath = "${srcPath}/java"; 202 from(javaPath) 203 include(["**/*.java", "**/*.xml"]) 204 eachFile { FileCopyDetails fcd -> 205 if (fcd.file.isFile()) { 206 def filename = fcd.name; 207 String collapsed = collapsedPaths.get(fcd.file.path); 208 fcd.path = "src/${collapsed}"; 209 } else {fcd.exclude()} 210 } 211 println "***************** done" 212 } 213 into("res") { 214 from("${srcPath}/res") 215 } 216 into(".") {from("${srcPath}/AndroidManifest.xml")} 217 } 218 } 219 220 task emitGradleZip(dependsOn: [emitBrowseable, emitGradle], type:Zip) { 221 def outputPath = "${samplegen.pathToBuild}/out/browseable" 222 def folderName = "${samplegen.targetSampleName()}" 223 archiveName = "${samplegen.targetSampleName()}.zip" 224 def inputPath = outPath("gradle") 225 from inputPath 226 into folderName 227 include "**" 228 def outDir = project.file(outputPath) 229 destinationDir = outDir 230 } 231