blob: 29fca279b71d2d49b0912f26efe5fee47c046db4 [file] [log] [blame]
Ian Ni-Lewiseb640c02013-09-09 17:01:04 -07001/*
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
Trevor Johns51540d52013-10-29 17:14:25 -070017// The SampleGenPlugin source is in the buildSrc directory.
18import com.example.android.samples.build.SampleGenPlugin
19apply plugin: SampleGenPlugin
Ian Ni-Lewiseb640c02013-09-09 17:01:04 -070020
21// Add a preflight task that depends on the "refresh" task that gets
22// added by the SampleGenPlugin.
23task preflight {
24 project.afterEvaluate({preflight.dependsOn(project.refresh)})
25}
26
Ian Ni-Lewisfbdb4f42013-10-25 13:15:11 -070027String outPath(String buildType) {
28/*
29 def repoInfo = "repo info platform/developers/build".execute().text
30 def buildPath = (repoInfo =~ /Mount path: (.*)/)[0][1]
31*/
32 return "${samplegen.pathToBuild}/out/${buildType}/${samplegen.targetSampleName()}";
33}
34
35/**
36 * Collapse a path "IntelliJ-style" by putting dots rather than slashes between
37 * path components that have only one child. So the two paths
38 *
39 * com/example/android/foo/bar.java
40 * com/example/android/bar/foo.java
41 *
42 * Become
43 * com.example.android/foo/bar.java
44 * com.example.android/bar/foo.java
45 *
46 * @param path
47 * @param roots
48 * @return
49 */
50Map<String,String> collapsePaths(FileTree path, List<String> roots) {
51 Map result = new HashMap<String,String>();
52
53 println ("******************** Collapse *************************")
54
55 path.visit { FileVisitDetails f ->
56 if (f.isDirectory()) return;
57 StringBuilder collapsedPath = new StringBuilder("${f.name}");
58 File current = f.file;
59
60 //
61 // Starting at this file, walk back to the root of the path and
62 // substitute dots for any directory that has only one child.
63 //
64
65 // Don't substitute a dot for the separator between the end of the
66 // path and the filename, even if there's only one file in the directory.
67 if (!f.isDirectory()) {
68 current = current.parentFile;
69 collapsedPath.insert(0, "${current.name}/")
70 }
71
72 // For everything else, use a dot if there's only one child and
73 // a slash otherwise. Filter out the root paths, too--we only want
74 // the relative path. But wait, Groovy/Gradle is capricious and
75 // won't return the proper value from a call to roots.contains(String)!
76 // I'm using roots.sum here instead of tracking down why a list of
77 // strings can't return true from contains() when given a string that
78 // it quite obviously does contain.
79 current = current.parentFile;
80 while((current != null)
81 && (roots.sum {String r-> return r.equals(current.absolutePath) ? 1 : 0 } == 0)) {
82
83 char separator = current.list().length > 1 ? '/' : '.';
84 collapsedPath.insert(0, "${current.name}${separator}");
85 current = current.parentFile;
86 }
87 result.put(f.file.path, collapsedPath.toString());
88 }
89
Renato Mangini24b63c52014-08-15 18:41:42 -070090 println ("******************** Collapse results *********************")
Ian Ni-Lewisfbdb4f42013-10-25 13:15:11 -070091
Renato Mangini24b63c52014-08-15 18:41:42 -070092 result.each {entry -> println("- ${entry}");}
Ian Ni-Lewisfbdb4f42013-10-25 13:15:11 -070093 return result
94}
95
96
Ian Ni-Lewis7516e752013-09-26 09:04:22 -070097task emitAnt(type:Copy) {
Ian Ni-Lewisfbdb4f42013-10-25 13:15:11 -070098 def outputPath = outPath("ant");
Ian Ni-Lewis7516e752013-09-26 09:04:22 -070099 def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}"
Ian Ni-Lewis7516e752013-09-26 09:04:22 -0700100 into outputPath
101 includeEmptyDirs
102 ["main", "common", "template"].each { input ->
103 [[ "java", "src"], ["res", "res"]].each { filetype ->
104 def srcPath = "${inputPath}/src/${input}/${filetype[0]}"
105 into("${filetype[1]}") {
106 from(srcPath)
107 }
108 }
109 }
110 from("${inputPath}/src/main") { include "AndroidManifest.xml" }
111 from("${inputPath}/src/template") { include "project.properties" }
112}
113
Trevor Johnsf2a47dc2013-10-30 04:54:54 -0700114task emitGradle(type:Copy) {
Trevor Johnsf8841372013-10-30 11:39:50 -0700115 dependsOn(preflight)
Trevor Johns29f40ae2013-10-30 18:33:21 -0700116 def outputPath = outPath("gradle")
Trevor Johnsf2a47dc2013-10-30 04:54:54 -0700117 def inputPath = "${project.projectDir}"
118 // Copy entire sample into output -- since it's already in Gradle format, we'll explicitly exclude content that
119 // doesn't belong here.
Trevor Johnsf2a47dc2013-10-30 04:54:54 -0700120 into outputPath
121 from("${inputPath}") {
122 // Paths to exclude from output
Trevor Johnsd559bdf2013-10-30 11:29:48 -0700123 exclude ".gradle"
124 exclude "_index.jd"
Trevor Johns46ef2262013-10-30 20:34:06 -0700125 exclude "bin"
Trevor Johnsf2a47dc2013-10-30 04:54:54 -0700126 exclude "buildSrc"
Trevor Johns29f40ae2013-10-30 18:33:21 -0700127 exclude "local.properties"
Trevor Johnsd559bdf2013-10-30 11:29:48 -0700128 exclude "template-params.xml"
Trevor Johns46ef2262013-10-30 20:34:06 -0700129 exclude "*.iml"
Trevor Johns7f460452013-10-30 21:22:34 -0700130 exclude "**/.idea"
Trevor Johns2ca423a2013-10-30 19:30:05 -0700131 exclude "**/build"
Trevor Johnsd559bdf2013-10-30 11:29:48 -0700132 exclude "**/proguard-project.txt"
Trevor Johns2ca423a2013-10-30 19:30:05 -0700133 exclude "${samplegen.targetSampleModule()}/**/README*.txt"
Trevor Johns88d9b032014-10-22 18:04:09 -0700134 exclude "**/README-*.txt"
Trevor Johns29f40ae2013-10-30 18:33:21 -0700135
136 // src directory needs to be consolidated, will be done in next section
137 exclude "${samplegen.targetSampleModule()}/src/"
Trevor Johnsf2a47dc2013-10-30 04:54:54 -0700138 }
Trevor Johns29f40ae2013-10-30 18:33:21 -0700139
140 // Consolidate source directories
141 ["main", "common", "template"].each { input ->
Hak Matsudaa5225cd2014-04-08 17:24:04 -0700142 ["java", "res", "assets", "rs"].each { filetype ->
Trevor Johns29f40ae2013-10-30 18:33:21 -0700143 def srcPath = "${inputPath}/${samplegen.targetSampleModule()}/src/${input}/${filetype}"
144 into("${samplegen.targetSampleModule()}/src/main/${filetype}") {
145 from(srcPath)
146 }
147 }
148 }
149
150 // Copy AndroidManifest.xml
151 into ("${samplegen.targetSampleModule()}/src/main") {
152 from("${inputPath}/${samplegen.targetSampleModule()}/src/main/AndroidManifest.xml")
153 }
154
Trevor Johnsf2a47dc2013-10-30 04:54:54 -0700155 // Remove BEGIN_EXCLUDE/END_EXCLUDE blocks from source files
156 eachFile { file ->
157 if (file.name.endsWith(".gradle") || file.name.endsWith(".java")) {
158 // TODO(trevorjohns): Outputs a blank newline for each filtered line. Replace with java.io.FilterReader impl.
159 boolean outputLines = true;
160 def removeExcludeBlocksFilter = { line ->
161 if (line ==~ /\/\/ BEGIN_EXCLUDE/) {
162 outputLines = false;
163 } else if (line ==~ /\/\/ END_EXCLUDE/) {
164 outputLines = true;
165 } else if (outputLines) {
166 return line;
167 }
168 return ""
169 }
170 filter(removeExcludeBlocksFilter)
171 }
172 }
173}
174
Ian Ni-Lewis8e1b2ff2013-09-30 14:20:39 -0700175task emitBrowseable(type:Copy) {
Renato Mangini24b63c52014-08-15 18:41:42 -0700176 def outputPathRoot = outPath("browseable")
177 def modules = project.childProjects.keySet()
178 def hasMultipleModules = modules.size() > 1
179 println "---------------- modules found in sample: ${modules}"
180 into outputPathRoot
Ian Ni-Lewis81ea0312013-10-04 14:13:46 -0700181 from("${project.projectDir}/_index.jd")
182
Renato Mangini24b63c52014-08-15 18:41:42 -0700183 modules.each { moduleName ->
184 // For single module samples (default), we emit the module contents
185 // directly to the root of the browseable sample:
186 def outputPath = "."
187 if (hasMultipleModules) {
188 // For multi module samples, we need an extra directory level
189 // to separate modules:
190 outputPath = "${moduleName}"
191 }
192 println "\n---------------- processing MODULE ${moduleName} to outputPath ${outputPath}"
193 def inputPath = "${project.projectDir}/${moduleName}"
194
195 def srcDirs = ["main", "common", "template"].collect {input -> "${inputPath}/src/${input}" };
196 def javaDirs = srcDirs.collect { input -> "${input}/java"}
197 FileTree javaTree = null;
198 javaDirs.each { dir ->
199 FileTree tree = project.fileTree("${dir}")
200 javaTree = (javaTree == null) ? tree : javaTree.plus(tree)}
201 Map collapsedPaths = collapsePaths(javaTree, javaDirs)
202
203 srcDirs.each { srcPath ->
204 print "** Copying source ${srcPath}...";
205 duplicatesStrategy = 'fail'
206 into("${outputPath}/src") {
207 def javaPath = "${srcPath}/java";
208 from(javaPath)
209 include(["**/*.java", "**/*.xml"])
210 eachFile { FileCopyDetails fcd ->
211 if (fcd.file.isFile()) {
212 def filename = fcd.name;
213 String collapsed = collapsedPaths.get(fcd.file.path);
214 fcd.path = "${outputPath}/src/${collapsed}";
215 } else {fcd.exclude()}
216 }
217 println "done"
Ian Ni-Lewis8da86252013-09-26 16:05:05 -0700218 }
Renato Mangini24b63c52014-08-15 18:41:42 -0700219 into("${outputPath}/res") {
220 from("${srcPath}/res")
221 }
222 into("${outputPath}/src/rs") {
223 from("${srcPath}/rs")
224 }
225 into("${outputPath}") {from("${srcPath}/AndroidManifest.xml")}
Ian Ni-Lewis8da86252013-09-26 16:05:05 -0700226 }
Ian Ni-Lewis8da86252013-09-26 16:05:05 -0700227 }
Ian Ni-Lewis7516e752013-09-26 09:04:22 -0700228}
Alexander Lucasb6985d02013-10-30 18:41:52 -0700229
230task emitGradleZip(dependsOn: [emitBrowseable, emitGradle], type:Zip) {
231 def outputPath = "${samplegen.pathToBuild}/out/browseable"
232 def folderName = "${samplegen.targetSampleName()}"
233 archiveName = "${samplegen.targetSampleName()}.zip"
234 def inputPath = outPath("gradle")
235 from inputPath
236 into folderName
237 include "**"
238 def outDir = project.file(outputPath)
239 destinationDir = outDir
240}