1/*
2 * Copyright 2018 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
17package androidx.build
18
19import androidx.build.ArtifactsPredicate.All
20import androidx.build.ArtifactsPredicate.Exact
21import androidx.build.ArtifactsPredicate.Group
22import androidx.build.Strategy.TipOfTree
23import androidx.build.Strategy.Prebuilts
24import androidx.build.Strategy.Ignore
25
26val RELEASE_RULE = docsRules("public") {
27    val defaultVersion = "1.0.0-alpha3"
28    prebuilts(LibraryGroups.ANNOTATION, defaultVersion)
29    prebuilts(LibraryGroups.APPCOMPAT, defaultVersion)
30    prebuilts(LibraryGroups.ASYNCLAYOUTINFLATER, defaultVersion)
31    prebuilts(LibraryGroups.BROWSER, defaultVersion)
32    prebuilts(LibraryGroups.CAR, defaultVersion)
33            .addStubs("car/car-stubs/android.car.jar")
34    prebuilts(LibraryGroups.CARDVIEW, defaultVersion)
35    prebuilts(LibraryGroups.COLLECTION, defaultVersion)
36    prebuilts(LibraryGroups.CONTENTPAGER, defaultVersion)
37    prebuilts(LibraryGroups.COORDINATORLAYOUT, defaultVersion)
38    prebuilts(LibraryGroups.CORE, defaultVersion)
39    prebuilts(LibraryGroups.CURSORADAPTER, defaultVersion)
40    prebuilts(LibraryGroups.CUSTOMVIEW, defaultVersion)
41    prebuilts(LibraryGroups.DOCUMENTFILE, defaultVersion)
42    prebuilts(LibraryGroups.DRAWERLAYOUT, defaultVersion)
43    prebuilts(LibraryGroups.DYNAMICANIMATION, defaultVersion)
44    prebuilts(LibraryGroups.EMOJI, defaultVersion)
45    prebuilts(LibraryGroups.EXIFINTERFACE, defaultVersion)
46    prebuilts(LibraryGroups.FRAGMENT, defaultVersion)
47    prebuilts(LibraryGroups.GRIDLAYOUT, defaultVersion)
48    prebuilts(LibraryGroups.HEIFWRITER, defaultVersion)
49    prebuilts(LibraryGroups.INTERPOLATOR, defaultVersion)
50    prebuilts(LibraryGroups.LEANBACK, defaultVersion)
51    prebuilts(LibraryGroups.LEGACY, defaultVersion)
52    prebuilts(LibraryGroups.LOADER, defaultVersion)
53    prebuilts(LibraryGroups.LOCALBROADCASTMANAGER, defaultVersion)
54    prebuilts(LibraryGroups.MEDIA, defaultVersion)
55    prebuilts(LibraryGroups.MEDIAROUTER, defaultVersion)
56    prebuilts(LibraryGroups.PALETTE, defaultVersion)
57    prebuilts(LibraryGroups.PERCENTLAYOUT, defaultVersion)
58    prebuilts(LibraryGroups.PREFERENCE, defaultVersion)
59    prebuilts(LibraryGroups.PRINT, defaultVersion)
60    prebuilts(LibraryGroups.RECOMMENDATION, defaultVersion)
61    prebuilts(LibraryGroups.RECYCLERVIEW, defaultVersion)
62    prebuilts(LibraryGroups.SLICE, defaultVersion)
63    prebuilts(LibraryGroups.SLIDINGPANELAYOUT, defaultVersion)
64    prebuilts(LibraryGroups.SWIPEREFRESHLAYOUT, defaultVersion)
65    prebuilts(LibraryGroups.TEXTCLASSIFIER, defaultVersion)
66    prebuilts(LibraryGroups.TRANSITION, defaultVersion)
67    prebuilts(LibraryGroups.TVPROVIDER, defaultVersion)
68    prebuilts(LibraryGroups.VECTORDRAWABLE, defaultVersion)
69    prebuilts(LibraryGroups.VIEWPAGER, defaultVersion)
70    prebuilts(LibraryGroups.WEAR, defaultVersion)
71            .addStubs("wear/wear_stubs/com.google.android.wearable-stubs.jar")
72    prebuilts(LibraryGroups.WEBKIT, defaultVersion)
73    val flatfootVersion = "2.0.0-alpha1"
74    prebuilts(LibraryGroups.ROOM, flatfootVersion)
75    prebuilts(LibraryGroups.PERSISTENCE, flatfootVersion)
76    prebuilts(LibraryGroups.LIFECYCLE, flatfootVersion)
77    prebuilts(LibraryGroups.ARCH_CORE, flatfootVersion)
78    prebuilts(LibraryGroups.PAGING, flatfootVersion)
79    prebuilts(LibraryGroups.NAVIGATION, "1.0.0-alpha01")
80    prebuilts(LibraryGroups.WORKMANAGER, "1.0.0-alpha02")
81    default(Ignore)
82}
83
84val TIP_OF_TREE = docsRules("tipOfTree") {
85    default(TipOfTree)
86}
87
88/**
89 * Rules are resolved in addition order. So if you have two rules that specify how docs should be
90 * built for a module, first defined rule wins.
91 */
92fun docsRules(name: String, init: PublishDocsRulesBuilder.() -> Unit): PublishDocsRules {
93    val f = PublishDocsRulesBuilder(name)
94    f.init()
95    return f.build()
96}
97
98class PublishDocsRulesBuilder(private val name: String) {
99
100    private val rules: MutableList<DocsRule> = mutableListOf()
101    /**
102     * docs for projects within [groupName] will be built from sources.
103     */
104    fun tipOfTree(groupName: String) {
105        rules.add(DocsRule(Group(groupName), TipOfTree))
106    }
107
108    /**
109     * docs for a project with the given [groupName] and [name] will be built from sources.
110     */
111    fun tipOfTree(groupName: String, name: String) {
112        rules.add(DocsRule(Exact(groupName, name), TipOfTree))
113    }
114
115    /**
116     * docs for a project with the given [groupName] and [name] will be built from a prebuilt with
117     * the given [version].
118     */
119    fun prebuilts(groupName: String, moduleName: String, version: String) {
120        rules.add(DocsRule(Exact(groupName, moduleName), Prebuilts(Version(version))))
121    }
122
123    /**
124     * docs for projects within [groupName] will be built from prebuilts with the given [version]
125     */
126    fun prebuilts(groupName: String, version: String) = prebuilts(groupName, Version(version))
127
128    /**
129     * docs for projects within [groupName] will be built from prebuilts with the given [version]
130     */
131    fun prebuilts(groupName: String, version: Version): Prebuilts {
132        val strategy = Prebuilts(version)
133        rules.add(DocsRule(Group(groupName), strategy))
134        return strategy
135    }
136
137    /**
138     * defines a default strategy for building docs
139     */
140    fun default(strategy: Strategy) {
141        rules.add(DocsRule(All, strategy))
142    }
143
144    /**
145     * docs for projects within [groupName] won't be built
146     */
147    fun ignore(groupName: String) {
148        rules.add(DocsRule(Group(groupName), Ignore))
149    }
150
151    /**
152     * docs for a specified project won't be built
153     */
154    fun ignore(groupName: String, name: String) {
155        rules.add(DocsRule(Exact(groupName, name), Ignore))
156    }
157
158    fun build() = PublishDocsRules(name, rules)
159}
160
161sealed class ArtifactsPredicate {
162    abstract fun apply(inGroup: String, inName: String): Boolean
163    object All : ArtifactsPredicate() {
164        override fun apply(inGroup: String, inName: String) = true
165    }
166    class Group(val group: String) : ArtifactsPredicate() {
167        override fun apply(inGroup: String, inName: String) = inGroup == group
168        override fun toString() = "\"$group\""
169    }
170    class Exact(val group: String, val name: String) : ArtifactsPredicate() {
171        override fun apply(inGroup: String, inName: String) = group == inGroup && name == inName
172        override fun toString() = "\"$group\", \"$name\""
173    }
174}
175
176data class DocsRule(val predicate: ArtifactsPredicate, val strategy: Strategy) {
177    override fun toString(): String {
178        if (predicate is All) {
179            return "default($strategy)"
180        }
181        return when (strategy) {
182            is Prebuilts -> "prebuilts($predicate, \"${strategy.version}\")"
183            is Ignore -> "ignore($predicate)"
184            is TipOfTree -> "tipOfTree($predicate)"
185        }
186    }
187}
188
189sealed class Strategy {
190    object TipOfTree : Strategy()
191    object Ignore : Strategy()
192    class Prebuilts(val version: Version) : Strategy() {
193        var stubs: MutableList<String>? = null
194        fun addStubs(path: String) {
195            if (stubs == null) {
196                stubs = mutableListOf()
197            }
198            stubs!!.add(path)
199        }
200
201        override fun toString() = "Prebuilts(\"$version\")"
202    }
203}
204
205class PublishDocsRules(val name: String, private val rules: List<DocsRule>) {
206    fun resolve(groupName: String, moduleName: String): DocsRule {
207        return rules.find { it.predicate.apply(groupName, moduleName) } ?: throw Error()
208    }
209}