• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
18import com.example.android.samples.build.SampleGenPlugin
19apply plugin: SampleGenPlugin
20
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
27String 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
90    println ("******************** Collapse results *********************")
91
92    result.each {entry -> println("- ${entry}");}
93    return result
94}
95
96
97task emitAnt(type:Copy) {
98    def outputPath = outPath("ant");
99    def inputPath = "${project.projectDir}/${samplegen.targetSampleModule()}"
100    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
114task emitGradle(type:Copy) {
115    dependsOn(preflight)
116    def outputPath = outPath("gradle")
117    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.
120    into outputPath
121    from("${inputPath}") {
122        // Paths to exclude from output
123        exclude ".gradle"
124        exclude "_index.jd"
125        exclude "bin"
126        exclude "buildSrc"
127        exclude "local.properties"
128        exclude "template-params.xml"
129        exclude "*.iml"
130        exclude "**/.idea"
131        exclude "**/build"
132        exclude "**/proguard-project.txt"
133        exclude "${samplegen.targetSampleModule()}/**/README*.txt"
134        exclude "**/README-*.txt"
135
136        // src directory needs to be consolidated, will be done in next section
137        exclude "${samplegen.targetSampleModule()}/src/"
138    }
139
140    // Consolidate source directories
141    ["main", "common", "template"].each { input ->
142        ["java", "res", "assets", "rs"].each { filetype ->
143            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
155    // 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
175task emitBrowseable(type:Copy) {
176    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
181    from("${project.projectDir}/_index.jd")
182
183    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"
218            }
219            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")}
226        }
227    }
228}
229
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}
241