124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar/*
224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar *
424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * you may not use this file except in compliance with the License.
624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * You may obtain a copy of the License at
724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar *
824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar *
1024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * Unless required by applicable law or agreed to in writing, software
1124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * See the License for the specific language governing permissions and
1424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar * limitations under the License.
1524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar */
1624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyarpackage android.databinding
1724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
1824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyarimport org.gradle.api.DefaultTask;
1924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyarimport org.gradle.api.artifacts.ResolvedArtifact
2024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyarimport org.gradle.api.tasks.TaskAction;
2124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
2224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyarclass ExportLicensesTask extends DefaultTask {
2324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    List<ResolvedArtifact> artifacts = new ArrayList();
2424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
2524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    static def knownLicenses = [
2624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
27499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                    libraries: ["kotlin-stdlib", "kotlin-runtime", "kotlin-annotation-processing", "kotlin-gradle-plugin", "kotlin-gradle-plugin-api",
28499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                    "kdoc", "kotlin-gradle-plugin-core", "kotlin-jdk-annotations", "kotlin-compiler", "kotlin-compiler-embeddable"],
2924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/LICENSE.txt",
3024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                                "http://www.apache.org/licenses/LICENSE-2.0.txt"],
3124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notices  : ["https://raw.githubusercontent.com/JetBrains/kotlin/master/license/NOTICE.txt"]
3224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
3324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
3424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["antlr4", "antlr4-runtime", "antlr-runtime", "antlr4-annotations"],
3524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt"]
3624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
3724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
3824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["antlr"],
3924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses: ["http://www.antlr3.org/license.html", "http://www.antlr2.org/license.html"]
4024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
4124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
4224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["java.g4"],
4324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt"]
4424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
4524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
4624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["ST4", "stringtemplate"],
4724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://raw.githubusercontent.com/antlr/stringtemplate4/master/LICENSE.txt"]
4824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
4924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
5024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["org.abego.treelayout.core"],
5124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["http://treelayout.googlecode.com/files/LICENSE.TXT"]
5224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
5324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
5424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["junit"],
5524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://raw.githubusercontent.com/junit-team/junit/master/LICENSE-junit.txt"],
5624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notices  : ["https://raw.githubusercontent.com/junit-team/junit/master/NOTICE.txt"]
5724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
5824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
5924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["commons-io"],
6024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["http://svn.apache.org/viewvc/commons/proper/io/trunk/LICENSE.txt?view=co"],
6124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notices  : ["http://svn.apache.org/viewvc/commons/proper/io/trunk/NOTICE.txt?view=co"]
6224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
6324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
6424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["commons-codec"],
6524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses: ["http://svn.apache.org/viewvc/commons/proper/codec/trunk/LICENSE.txt?view=co"],
6624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notices: ["http://svn.apache.org/viewvc/commons/proper/codec/trunk/NOTICE.txt?view=co"]
6724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
6824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
6924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["commons-lang3"],
7024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://git-wip-us.apache.org/repos/asf?p=commons-lang.git;a=blob_plain;f=LICENSE.txt;hb=refs/heads/master"],
7124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notices  : ["https://git-wip-us.apache.org/repos/asf?p=commons-lang.git;a=blob_plain;f=NOTICE.txt;hb=refs/heads/master"]
7224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
7324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
7424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["guava"],
7524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["http://www.apache.org/licenses/LICENSE-2.0.txt"]
7624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
7724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
7824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["hamcrest-core"],
7924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["https://raw.githubusercontent.com/hamcrest/JavaHamcrest/master/LICENSE.txt"]
8024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
8124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
8224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["avalon-framework"],
8324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses : ["http://archive.apache.org/dist/avalon/LICENSE.txt"]
8424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
8524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
8624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["log4j"],
8724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses: ["https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=blob_plain;f=LICENSE.txt;hb=HEAD"],
8824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notices: ["https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=blob_plain;f=NOTICE.txt;hb=HEAD"]
8924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
9024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
9124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["ant", "ant-launcher"],
9224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses: ["http://www.apache.org/licenses/LICENSE-2.0.html"]
9324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
9424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
9524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["xz"],
9624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    licenses: ["http://git.tukaani.org/?p=xz-java.git;a=blob_plain;f=COPYING;hb=HEAD"]
9724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            ],
9824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            [
9924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    libraries: ["logkit"],
100499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                    licenseText: ["unknown. see: http://commons.apache.org/proper/commons-logging/dependencies.html"]
101499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            ],
102499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            [
103499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                    libraries: ["juniversalchardet"],
104499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                    licenses: ["https://mozorg.cdn.mozilla.net/media/MPL/1.1/index.0c5913925d40.txt"]
105499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            ],
10624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    ]
10724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
10824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    Map<String, Object> usedLicenses = new HashMap<>();
10924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    static Map<String, Object> licenseLookup = new HashMap<>();
11024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    static {
11124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        knownLicenses.each {license ->
11224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            license.libraries.each {
11324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                licenseLookup.put(it, license)
11424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            }
11524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        }
11624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
11724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
11824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    ExportLicensesTask() {
11924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
12024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
12124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public void add(ResolvedArtifact artifact) {
12224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        artifacts.add(artifact)
12324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        println("adding artifact $artifact")
12424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
12524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
12624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    @TaskAction
12724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public void exportNotice() {
128499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar        project.configurations.compile.getResolvedConfiguration()
129499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                .getFirstLevelModuleDependencies().each {
130499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            if (!it.getModuleGroup().equals("com.android.tools.build")) {
131499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                it.getAllModuleArtifacts().each { add(it) }
132499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            }
13324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        }
13424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        resolveLicenses()
13524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        def notice = buildNotice(usedLicenses)
136499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar        def noticeFile = new File("${project.projectDir}/src/main/resources",'NOTICE.txt')
13724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        noticeFile.delete()
13824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        println ("writing notice file to: ${noticeFile.getAbsolutePath()}")
13924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        noticeFile << notice
14024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
14124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
14224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public void resolveLicenses() {
14324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        artifacts.each { artifact ->
14424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            if (!shouldSkip(artifact)) {
14524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                def license = licenseLookup.get(artifact.name)
14624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                if (license  == null) {
14724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    throw new RuntimeException("Cannot find license for ${artifact.getModuleVersion().id} in ${artifact.getFile()}")
14824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                }
14924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                usedLicenses.put(artifact, license)
15024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            }
15124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        }
15224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
15324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
15424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public static Object findLicenseFor(String artifactId) {
15524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        return licenseLookup.get(artifactId)
15624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
15724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
15824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public static String urlToText(String url) {
159499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar        return new URL(url).getText()
16024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
16124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
16224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public boolean shouldSkip(ResolvedArtifact artifact) {
16324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        return artifact.getModuleVersion().id.group.startsWith("com.android");
16424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
16524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar
16624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    public static String buildNotice(Map<String, Object> licenses) {
16724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        // now build the output
16824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        StringBuilder notice = new StringBuilder();
16924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        notice.append("List of 3rd party licenses:")
17024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        licenses.each {
17124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            notice.append("\n-----------------------------------------------------------------------------")
17224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            notice.append("\n* ${it.key}")
17324bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            notice.append("\n")
17424bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            def license = it.value
17524bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            if (license.notices != null) {
17624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                license.notices.each {
17724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                    notice.append("\n ****** NOTICE:\n${urlToText(it)}")
17824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                }
17924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            }
18024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            license.licenses.each {
18124bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar                notice.append("\n ****** LICENSE:\n${urlToText(it)}")
18224bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            }
183499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            license.licenseText.each {
184499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar                notice.append("\n ****** LICENSE:\n${it}")
185499cacaab504a8166dfe44515e0242b9852d8673Yigit Boyar            }
18624bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar            notice.append("\n\n\n")
18724bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        }
18824bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar        return notice.toString()
18924bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar    }
19024bec1cc542de69e0e21cc774469f20d34811ad9Yigit Boyar}