├── .github └── workflows │ └── main.yml ├── .gitignore ├── CONTRIBUTING.md ├── ConfigCompact.json ├── ConfigFull.json ├── DEPENDENCYVISUALIZATION.md ├── DESIGN.md ├── LICENSE ├── README.md ├── aspoet-input ├── build.gradle └── src │ └── main │ └── kotlin │ └── com │ └── google │ └── androidstudiopoet │ └── input │ ├── AndroidBuildConfig.kt │ ├── AndroidModuleConfig.kt │ ├── BuildSystemConfig.kt │ ├── BuildTypeConfig.kt │ ├── CodeComplexityConfig.kt │ ├── CodeConfig.kt │ ├── ComposeConfig.kt │ ├── DataBindingConfig.kt │ ├── FlavorConfig.kt │ ├── GenerationConfig.kt │ ├── ModuleConfig.kt │ ├── ModuleDependencyConfig.kt │ ├── PluginConfig.kt │ ├── ProjectConfig.kt │ ├── PureModuleConfig.kt │ ├── RepositoryConfig.kt │ └── ResourcesConfig.kt ├── aspoet ├── build.gradle └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── google │ │ └── androidstudiopoet │ │ ├── AndroidStudioPoet.kt │ │ ├── Defaults.kt │ │ ├── DependencyValidator.kt │ │ ├── Injector.kt │ │ ├── JsonConfigGenerator.kt │ │ ├── ModuleBlueprintFactory.kt │ │ ├── converters │ │ ├── ConfigPojoToAndroidModuleConfigConverter.kt │ │ ├── ConfigPojoToBuildSystemConfigConverter.kt │ │ ├── ConfigPojoToBuildTypeConfigsConverter.kt │ │ ├── ConfigPojoToFlavourConfigsConverter.kt │ │ ├── ConfigPojoToModuleConfigConverter.kt │ │ └── ConfigPojoToProjectConfigConverter.kt │ │ ├── core.kt │ │ ├── deserializers │ │ ├── DependencyConfigDeserializer.kt │ │ └── ModuleConfigDeserializer.kt │ │ ├── generators │ │ ├── BazelWorkspaceGenerator.kt │ │ ├── DependencyGraphGenerator.kt │ │ ├── DependencyImageGenerator.kt │ │ ├── GradleUtils.kt │ │ ├── ModuleBuildBazelGenerator.kt │ │ ├── ModuleBuildGradleGenerator.kt │ │ ├── PackagesGenerator.kt │ │ ├── SourceModuleGenerator.kt │ │ ├── android_modules │ │ │ ├── ActivityGenerator.kt │ │ │ ├── AndroidModuleBuildBazelGenerator.kt │ │ │ ├── AndroidModuleBuildGradleGenerator.kt │ │ │ ├── AndroidModuleGenerator.kt │ │ │ ├── JavaActivityGenerator.kt │ │ │ ├── KotlinActivityGenerator.kt │ │ │ ├── ManifestGenerator.kt │ │ │ ├── ProguardGenerator.kt │ │ │ └── resources │ │ │ │ ├── ImagesGenerator.kt │ │ │ │ ├── LayoutResourcesGenerator.kt │ │ │ │ ├── ResourcesGenerator.kt │ │ │ │ └── StringResourcesGenerator.kt │ │ ├── bazel │ │ │ └── BazelLang.kt │ │ ├── packages │ │ │ ├── JavaGenerator.kt │ │ │ ├── KotlinGenerator.kt │ │ │ └── PackageGenerator.kt │ │ └── project │ │ │ ├── GradlePropertiesGenerator.kt │ │ │ ├── GradleSettingsGenerator.kt │ │ │ ├── GradlewGenerator.kt │ │ │ └── ProjectBuildGradleGenerator.kt │ │ ├── gradle │ │ └── GradleLang.kt │ │ ├── input │ │ └── ConfigPOJO.kt │ │ ├── models │ │ ├── AbstractModuleBlueprint.kt │ │ ├── ActivityBlueprint.kt │ │ ├── AndroidBuildBazelBlueprint.kt │ │ ├── AndroidBuildGradleBlueprint.kt │ │ ├── AndroidModuleBlueprint.kt │ │ ├── AnnotationBlueprint.kt │ │ ├── BazelWorkspaceBlueprint.kt │ │ ├── BuildType.kt │ │ ├── ClassBlueprint.kt │ │ ├── ClassComplexity.kt │ │ ├── DataBindingBlueprint.kt │ │ ├── Dependencies.kt │ │ ├── FieldBlueprint.kt │ │ ├── Flavor.kt │ │ ├── FromToDependencyConfig.kt │ │ ├── GradlePropertiesBlueprint.kt │ │ ├── GradleTask.kt │ │ ├── ImageViewBlueprint.kt │ │ ├── JavaClassBlueprint.kt │ │ ├── JavaTestClassBlueprint.kt │ │ ├── KotlinClassBlueprint.kt │ │ ├── KotlinTestClassBlueprint.kt │ │ ├── Language.kt │ │ ├── LayoutBlueprint.kt │ │ ├── MethodBlueprint.kt │ │ ├── MethodToCall.kt │ │ ├── ModuleBlueprint.kt │ │ ├── ModuleBuildBazelBlueprint.kt │ │ ├── ModuleBuildGradleBlueprint.kt │ │ ├── NonTestClassBlueprint.kt │ │ ├── PackageBlueprint.kt │ │ ├── PackagesBlueprint.kt │ │ ├── ProjectBlueprint.kt │ │ ├── ProjectBuildGradleBlueprint.kt │ │ ├── Repositories.kt │ │ ├── ResourcesBlueprint.kt │ │ ├── ResourcesToRefer.kt │ │ ├── TextViewBlueprint.kt │ │ └── Topologies.kt │ │ ├── utils │ │ ├── collections.kt │ │ ├── fold.kt │ │ └── joinPath.kt │ │ └── writers │ │ ├── AbstractWriter.kt │ │ ├── FileWriter.kt │ │ ├── GithubDownloader.kt │ │ └── ImageWriter.kt │ └── test │ ├── kotlin │ └── com │ │ └── google │ │ └── androidstudiopoet │ │ ├── DependencyValidatorTest.kt │ │ ├── converters │ │ ├── ConfigPojoToAndroidModuleConfigConverterTest.kt │ │ ├── ConfigPojoToBuildSystemConfigConverterTest.kt │ │ ├── ConfigPojoToFlavorConfigsConverterTest.kt │ │ ├── ConfigPojoToModuleConfigConverterTest.kt │ │ └── ConfigPojoToProjectConfigConverterTest.kt │ │ ├── generators │ │ ├── BazelWorkspaceGeneratorTest.kt │ │ ├── DependencyGraphBase.kt │ │ ├── DependencyGraphGeneratorTest.kt │ │ ├── DependencyImageGeneratorTest.kt │ │ ├── ModuleBuildBazelGeneratorTest.kt │ │ ├── ModuleBuildGradleGeneratorTest.kt │ │ ├── android_modules │ │ │ ├── AndroidModuleBuildBazelGeneratorTest.kt │ │ │ └── AndroidModuleBuildGradleGeneratorTest.kt │ │ ├── bazel │ │ │ └── BazelLangTest.kt │ │ └── project │ │ │ ├── GradlePropertiesGeneratorTest.kt │ │ │ └── ProjectBuildGradleGeneratorTest.kt │ │ ├── models │ │ ├── AndroidBuildBazelBlueprintTest.kt │ │ ├── AndroidBuildGradleBlueprintTest.kt │ │ ├── AndroidModuleBlueprintTest.kt │ │ ├── BazelWorkspaceBlueprintTest.kt │ │ ├── DependencyTest.kt │ │ ├── GradlePropertiesBlueprintTest.kt │ │ ├── ModuleBuildBazelBlueprintTest.kt │ │ ├── ModuleBuildGradleBlueprintTest.kt │ │ └── ProjectBuildGradleBlueprintTest.kt │ │ └── testutils │ │ ├── assert.kt │ │ └── mock.kt │ └── resources │ └── com │ └── google │ └── androidstudiopoet │ └── generators │ └── dependencyGraphTest.png ├── build.gradle ├── configs ├── build-tool-versions │ ├── ConfigFull_G4-3-1_AGP3-0-1_Kotlin1-1-60.json │ ├── ConfigFull_G4-5_AGP3-0-1_Kotlin1-2-20.json │ ├── ConfigFull_G4-6_AGP3-1-0_Kotlin1-2-30.json │ ├── ConfigFull_G4-6_AGP3-1-0_Kotlin1-2-41.json │ ├── ConfigFull_G4-6_AGP3-1-2_Kotlin1-2-41.json │ ├── ConfigFull_G4-7_AGP3-1-2_Kotlin1-2-41.json │ ├── ConfigFull_G4-8_AGP3-1-2_Kotlin1-2-41.json │ ├── gradle-profiler-commands.txt │ ├── gradle-profiler.scenarios │ └── result.md ├── compose │ ├── compose.json │ ├── databinding-kapt.json │ ├── databinding.json │ ├── gradle-profiler-commands.sh │ ├── gradle-profiler.scenarios │ ├── plain.json │ └── viewbinding.json ├── desugaring │ ├── ConfigFull_JavaWithLambdas.json │ ├── ConfigFull_JavaWithLambdasApi21.json │ ├── ConfigFull_JavaWithoutLambdas.json │ ├── ConfigFull_JavaWithoutLambdasApi21.json │ ├── ConfigFull_JavaWithoutLambdasApi21_ReducedClassCount.json │ ├── ConfigFull_JavaWithoutLambdas_ReducedClassCount.json │ ├── ConfigFull_KotlinWithLambdas.json │ ├── ConfigFull_KotlinWithLambdasApi21.json │ ├── desugaring-research-v1 │ ├── gradle-profiler-commands.txt │ ├── gradle-profiler.scenarios │ └── result.md ├── examples │ └── plugins │ │ ├── ConfigWithAppliedButterknifePlugin.json │ │ └── ConfigWithAppliedFabricPlugin.json ├── kapt │ ├── v1 │ │ ├── ConfigFull_KaptProblem_JavaKotlin_DataBinding.json │ │ ├── ConfigFull_KaptProblem_JavaKotlin_NoDataBinding.json │ │ ├── ConfigFull_KaptProblem_JavaOnly_DataBinding.json │ │ ├── ConfigFull_KaptProblem_JavaOnly_NoDataBinding.json │ │ ├── ConfigFull_KaptProblem_KotlinOnly_DataBinding.json │ │ ├── ConfigFull_KaptProblem_KotlinOnly_NoDataBinding.json │ │ └── kapt-research-v1.md │ └── v2 │ │ ├── ConfigFull_KaptProblem_JavaKotlin_DataBinding.json │ │ ├── ConfigFull_KaptProblem_JavaOnly_DataBinding.json │ │ ├── ConfigFull_KaptProblem_KotlinOnly_DataBinding.json │ │ ├── gradle-profiler.scenarios │ │ └── kapt-reseach-v2.md └── modularization │ └── v1 │ ├── ConfigFull_20k_classes_10modules.json │ ├── ConfigFull_20k_classes_1module.json │ ├── ConfigFull_20k_classes_2modules.json │ ├── ConfigFull_20k_classes_3modules.json │ ├── ConfigFull_20k_classes_4modules.json │ ├── ConfigFull_20k_classes_5modules.json │ ├── ConfigFull_20k_classes_6modules.json │ ├── ConfigFull_20k_classes_7modules.json │ ├── ConfigFull_20k_classes_8modules.json │ ├── ConfigFull_20k_classes_9modules.json │ ├── gradle-profiler-commands.txt │ ├── gradle-profiler.scenarios │ └── result.md ├── extend └── Extending.md ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── img ├── dependencies.dot.png ├── dependencies.png └── generator.png ├── resources └── gradle-assets │ ├── gradle │ └── wrapper │ │ └── gradle-wrapper.jar │ ├── gradlew │ └── gradlew.bat └── settings.gradle /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Set up JDK 11 12 | uses: actions/setup-java@v1 13 | with: 14 | java-version: 11 15 | - name: Build with Gradle 16 | uses: eskatos/gradle-command-action@v1 17 | with: 18 | arguments: check 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | 14 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 15 | hs_err_pid* 16 | 17 | *.xml 18 | 19 | src/pack*/* 20 | 21 | out/production/java-generator/json/sample.json 22 | 23 | out/production/java-generator/META-INF/MANIFEST.MF 24 | 25 | src/META-INF/MANIFEST.MF 26 | 27 | *.iml 28 | .gradle/ 29 | /build 30 | */build 31 | 32 | 33 | modules/** 34 | 35 | out/** 36 | */out/** 37 | local.properties 38 | 39 | **.DS_Store -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. -------------------------------------------------------------------------------- /ConfigCompact.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "GeneratedASProject", 3 | "root": "./../", 4 | "gradleVersion": "7.2", 5 | "androidGradlePluginVersion": "7.0.3", 6 | "kotlinVersion": "1.5.31", 7 | "numModules": "2", 8 | "allMethods": "40", 9 | "javaPackageCount": "1", 10 | "javaClassCount": "4", 11 | "javaMethodCount": "20", 12 | "kotlinPackageCount": "1", 13 | "kotlinClassCount": "4", 14 | "androidModules": "2", 15 | "numActivitiesPerAndroidModule": "2", 16 | "productFlavors": [ 17 | 2, 3 18 | ], 19 | "topologies": [ 20 | {"type": "star", "seed": "2"} 21 | ], 22 | "dependencies": [ 23 | {"from": "module1", "to": "module0"} 24 | ], 25 | "buildTypes": 2, 26 | "generateTests": true, 27 | "generateBazelFiles": false 28 | } -------------------------------------------------------------------------------- /DEPENDENCYVISUALIZATION.md: -------------------------------------------------------------------------------- 1 | # Visualization of Dependencies 2 | 3 | During the generation stage, a pair of auxiliary files is created to help visualizing dependencies 4 | between modules. The information they contain is similar but they are presented in a different way. 5 | The files are generated in the root of the project folder. 6 | 7 | ## Dependency Graph 8 | 9 | This representation shows all modules and its dependencies as a directed graph in which 10 | modules are represented by nodes and dependencies by edges between them. It is stored in the 11 | dependencies.dot file and can be can be used with [Graphviz](https://www.graphviz.org/). This is an 12 | example of the generated graph: 13 | 14 | ![Dependency Graph](https://github.com/borisf/java-generator/blob/master/img/dependencies.dot.png) 15 | 16 | ## Adjacency Matrix 17 | 18 | For projects with many inter module dependencies it can be difficult to visualize the dependencies 19 | as a graph and it can be convenient to use an 20 | [adjacency matrix](https://en.wikipedia.org/wiki/Adjacency_matrix). The file dependencies.png 21 | contains an image with it. The colors on the header indicates what type of module it is: 22 | 23 | - Blue: App. 24 | - Green: Android module. 25 | - Yellow: Non-android module. 26 | 27 | The cells in a particular row indicates the dependencies for that module, while the cell in a column 28 | indicate what other modules depoend on it. The type of dependency is also encoded using a color, 29 | based on [Gradle documentation](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph): 30 | - Black: No dependency. 31 | - Green: user declared dependencies. 32 | - Pink: used when a component compiles, or runs against the library. 33 | - Blue: internal to the component, for its own use. 34 | - White: inherited from the Java plugin. 35 | - Purple: two or more configurations from the [Java library plugin configurations](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph). 36 | - Red: one or more configurations, with at least one not from the Java library plugin. 37 | 38 | This is the generated image for the project in the example graph: 39 | 40 | ![Adjacency Matrix](https://github.com/borisf/java-generator/blob/master/img/dependencies.png) 41 | 42 | 43 | -------------------------------------------------------------------------------- /DESIGN.md: -------------------------------------------------------------------------------- 1 | This is document that explains design, contracts and responsibilities of different classes. 2 | If you see that something is misaligned between this document and actual code, feel free to file an issue. 3 | 4 | ##Global architecture 5 | 6 | There are mainly three big pieces in the puzzle: 7 | 8 | * Input - this includes UI design, input format and reading input from the file(latter is not done yet). 9 | * Processing - main goal of this layer is to generate blueprints for the generation. 10 | That includes but not limited: 11 | 1. Decisions about what modules should be generated and how bee should they be, 12 | 2. Is there "main" module or not, is it an android module or not. 13 | 3. Is input valid? For example, is there cycle dependencies between module graph. 14 | * Generation - at this stage code gets generated according to information in blueprints. 15 | 16 | ##Generator's contract 17 | Generator are used to turn blueprint into a different pieces of result project. 18 | In short `Generator` takes a `Blueprint` as input, generate the code/files and returns a `GenerationResult`. 19 | 20 | Important notice: `Generator` shouldn't interact with file system directly(aka shouldn't have dependency on `File` class), 21 | instead it should calls proper methods on `FileWriter`. When it needs to combine file paths, 22 | it shouldn't do it directly, instead it should use `joinPath` extension function. 23 | 24 | Using `Blueprint` as input allows us to easier combine different generators together. 25 | In some cases it is ok to pass parent's blueprint to the child. 26 | 27 | `GenerationResult` makes "sibling" dependencies between generators clearer and 28 | let us easier pass information from one generator to another. For example, 29 | having passing `StringResourceGenerationResult` instead of `List` 30 | makes code easier to understand. Plus it will later allows us to do better error handling. 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /aspoet-input/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | 3 | dependencies { 4 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" 5 | testImplementation 'junit:junit:4.13.2' 6 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/AndroidBuildConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | data class AndroidBuildConfig(val minSdkVersion: Int = 24, val targetSdkVersion: Int = 30, val compileSdkVersion: Int = 30) -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/AndroidModuleConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | class AndroidModuleConfig : ModuleConfig() { 20 | 21 | var androidBuildConfig: AndroidBuildConfig = AndroidBuildConfig() 22 | 23 | var activityCount: Int = 0 24 | var productFlavorConfigs: List? = null 25 | var buildTypes: List? = null 26 | var hasLaunchActivity: Boolean = false 27 | 28 | var resourcesConfig: ResourcesConfig? = null 29 | var dataBindingConfig: DataBindingConfig? = null 30 | var composeConfig: ComposeConfig? = null 31 | var viewBinding: Boolean = false 32 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/BuildSystemConfig.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.input 2 | 3 | data class BuildSystemConfig( 4 | var buildSystemVersion: String?, 5 | var agpVersion: String?, 6 | var kotlinVersion: String?, 7 | var generateBazelFiles: Boolean?, 8 | 9 | /** 10 | * Allows to set different properties in "gradle.properties" file. 11 | * Defaults: 12 | * org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError 13 | * org.gradle.daemon=true 14 | * org.gradle.parallel=true 15 | * org.gradle.caching=true 16 | */ 17 | var properties: Map?) -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/BuildTypeConfig.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.input 2 | 3 | data class BuildTypeConfig(val name: String, val body: String? = null) -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/CodeComplexityConfig.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.input 2 | 3 | class CodeComplexityConfig { 4 | var lambdaCount = 0 5 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/CodeConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | class CodeConfig { 20 | var packages = 0 21 | var classesPerPackage = 0 22 | var methodsPerClass = 0 23 | var fieldsPerClass = 0 24 | var complexity: CodeComplexityConfig? = null 25 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/ComposeConfig.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.input 2 | 3 | class ComposeConfig(val actionCount: Int = 0) 4 | -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/DataBindingConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | class DataBindingConfig(val listenerCount: Int? = 0, val kapt: Boolean = false) -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/FlavorConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | data class FlavorConfig(val name: String, val dimension: String?, val count: Int? = 1) -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/GenerationConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package com.google.androidstudiopoet.input 16 | 17 | class GenerationConfig { 18 | lateinit var inputVersion: String 19 | lateinit var projectConfig: ProjectConfig 20 | } 21 | -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/ModuleConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | open class ModuleConfig { 20 | lateinit var moduleName: String 21 | var java: CodeConfig? = null 22 | var kotlin: CodeConfig? = null 23 | var useKotlin: Boolean = false 24 | var extraLines: List? = null 25 | var dependencies: List? = null 26 | var plugins: List? = null 27 | var generateTests: Boolean = true 28 | } 29 | -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/ModuleDependencyConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | sealed class DependencyConfig { 20 | data class ModuleDependencyConfig(val moduleName: String, val method: String? = null) : DependencyConfig() 21 | data class LibraryDependencyConfig(val library: String, val method: String? = null) : DependencyConfig() 22 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/PluginConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | /** 20 | * Configuration of a plugin applied to a module. 21 | * 22 | * @param id Id of the plugin that will be used in the gradle script to apply it 23 | * @param taskName Name of the gradle task that is used to customize plugin 24 | * @param taskBody Body of the gradle task that is used to customize plugin 25 | */ 26 | data class PluginConfig(val id: String, val taskName: String? = null, val taskBody: List? = null) -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/ProjectConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | class ProjectConfig { 20 | lateinit var projectName: String 21 | lateinit var root: String 22 | var buildSystemConfig: BuildSystemConfig? = null 23 | lateinit var moduleConfigs: List 24 | var repositories: List? = null 25 | var classpathDependencies: List? = null 26 | 27 | val pureModuleConfigs : List by lazy { moduleConfigs.filter { it !is AndroidModuleConfig } } 28 | val androidModuleConfigs: List by lazy { moduleConfigs.filterIsInstance() } 29 | 30 | var jsonText: String = "" 31 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/PureModuleConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | class PureModuleConfig : ModuleConfig() -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/RepositoryConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | class RepositoryConfig() { 20 | lateinit var url: String 21 | } -------------------------------------------------------------------------------- /aspoet-input/src/main/kotlin/com/google/androidstudiopoet/input/ResourcesConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.input 18 | 19 | data class ResourcesConfig(val stringCount: Int?, 20 | val imageCount: Int?, 21 | val layoutCount: Int?) -------------------------------------------------------------------------------- /aspoet/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'kotlin' 2 | 3 | dependencies { 4 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" 5 | implementation 'com.google.code.gson:gson:2.8.8' 6 | implementation 'com.squareup:javapoet:1.13.0' 7 | implementation 'com.squareup:kotlinpoet:1.10.1' 8 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt' 9 | implementation 'junit:junit:4.13.2' 10 | implementation 'commons-io:commons-io:20030203.000550' 11 | implementation project(':aspoet-input') 12 | 13 | testImplementation 'junit:junit:4.13.2' 14 | testImplementation 'org.mockito:mockito-inline:3.7.7' 15 | testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0' 16 | testImplementation "org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}" 17 | testImplementation 'com.google.truth:truth:1.1.3' 18 | } 19 | 20 | // java -jar aspoet/build/libs/aspoet-all.jar 21 | task fatJar(type: Jar) { 22 | manifest { 23 | attributes ( 24 | 'Main-Class': 'com.google.androidstudiopoet.AndroidStudioPoet', 25 | ) 26 | } 27 | archiveBaseName = project.name + '-all' 28 | from { configurations.runtimeClasspath.collect { it.directory ? it : zipTree(it) } } 29 | with jar 30 | duplicatesStrategy = 'include' 31 | } 32 | 33 | task runGenerator(type: JavaExec) { 34 | mainClass = 'com.google.androidstudiopoet.AndroidStudioPoet' 35 | classpath = sourceSets.main.runtimeClasspath 36 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/Defaults.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet 18 | 19 | const val DEFAULT_KOTLIN_VERSION = "1.5.31" 20 | const val DEFAULT_AGP_VERSION = "7.0.3" 21 | const val DEFAULT_GRADLE_VERSION = "7.2" 22 | const val DEFAULT_DEPENDENCY_METHOD = "implementation" 23 | 24 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/JsonConfigGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package com.google.androidstudiopoet 16 | 17 | import com.google.androidstudiopoet.models.ProjectBlueprint 18 | import com.google.androidstudiopoet.utils.joinPath 19 | import com.google.androidstudiopoet.writers.FileWriter 20 | 21 | class JsonConfigGenerator(val fileWriter: FileWriter) { 22 | 23 | fun generate(projectBlueprint: ProjectBlueprint) { 24 | val where = projectBlueprint.projectRoot.joinPath("as_poet_config.json") 25 | fileWriter.writeToFile(projectBlueprint.jsonText, where) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToAndroidModuleConfigConverter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.converters 18 | 19 | import com.google.androidstudiopoet.input.* 20 | import com.google.androidstudiopoet.input.ConfigPOJO 21 | 22 | class ConfigPojoToAndroidModuleConfigConverter { 23 | fun convert(config: ConfigPOJO, index: Int, productFlavorConfigs: List, 24 | buildTypes: List): AndroidModuleConfig { 25 | return AndroidModuleConfig().apply { 26 | moduleName = config.getAndroidModuleName(index) 27 | 28 | java = CodeConfig().apply { 29 | packages = config.javaPackageCount?.toInt() ?: 0 30 | classesPerPackage = config.javaClassCount?.toInt() ?: 0 31 | methodsPerClass = config.javaMethodsPerClass 32 | } 33 | 34 | kotlin = CodeConfig().apply { 35 | packages = config.kotlinPackageCount?.toInt() ?: 0 36 | classesPerPackage = config.kotlinClassCount?.toInt() ?: 0 37 | methodsPerClass = config.kotlinMethodsPerClass 38 | } 39 | 40 | useKotlin = config.useKotlin 41 | 42 | activityCount = config.numActivitiesPerAndroidModule?.toInt() ?: 0 43 | 44 | generateTests = config.generateTests 45 | hasLaunchActivity = index == 0 46 | 47 | val resolvedDependencies = config.resolvedDependencies[moduleName]?.sortedBy { it.to } 48 | ?.map { dependency -> DependencyConfig.ModuleDependencyConfig(dependency.to, dependency.method) } ?: emptyList() 49 | dependencies = config.libraries?.let { resolvedDependencies + it } ?: resolvedDependencies 50 | 51 | this.buildTypes = buildTypes 52 | this.productFlavorConfigs = productFlavorConfigs 53 | extraLines = config.extraAndroidBuildFileLines 54 | resourcesConfig = ResourcesConfig(activityCount + 2, activityCount + 5, activityCount) 55 | dataBindingConfig = config.dataBindingConfig 56 | composeConfig = config.composeConfig 57 | viewBinding = config.viewBinding 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToBuildSystemConfigConverter.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.converters 2 | 3 | import com.google.androidstudiopoet.input.BuildSystemConfig 4 | import com.google.androidstudiopoet.input.ConfigPOJO 5 | 6 | class ConfigPojoToBuildSystemConfigConverter { 7 | fun convert(configPojo: ConfigPOJO): BuildSystemConfig { 8 | return BuildSystemConfig(configPojo.gradleVersion, configPojo.androidGradlePluginVersion, 9 | configPojo.kotlinVersion, configPojo.generateBazelFiles, configPojo.gradleProperties) 10 | } 11 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToBuildTypeConfigsConverter.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.converters 2 | 3 | import com.google.androidstudiopoet.input.BuildTypeConfig 4 | import com.google.androidstudiopoet.input.ConfigPOJO 5 | 6 | class ConfigPojoToBuildTypeConfigsConverter { 7 | fun convert(configPOJO: ConfigPOJO): List { 8 | val buildTypes = configPOJO.buildTypes 9 | if (buildTypes == null || buildTypes <= 0) { 10 | return listOf() 11 | } 12 | 13 | return (0 until buildTypes).map { index -> BuildTypeConfig("buildType$index") } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToFlavourConfigsConverter.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.converters 2 | 3 | import com.google.androidstudiopoet.input.FlavorConfig 4 | import com.google.androidstudiopoet.input.ConfigPOJO 5 | 6 | class ConfigPojoToFlavourConfigsConverter { 7 | fun convert(configPOJO: ConfigPOJO): List { 8 | val productFlavors = configPOJO.productFlavors 9 | if (productFlavors == null || productFlavors.isEmpty()) { 10 | return listOf() 11 | } 12 | 13 | return productFlavors.withIndex().flatMap { (dimension, size) -> 14 | (0 until size) 15 | .map { flavourIndex -> "dim${dimension}flav$flavourIndex" } 16 | .map { FlavorConfig(it, "dim$dimension") } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToModuleConfigConverter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.converters 18 | 19 | import com.google.androidstudiopoet.input.CodeConfig 20 | import com.google.androidstudiopoet.input.ModuleConfig 21 | import com.google.androidstudiopoet.input.ConfigPOJO 22 | import com.google.androidstudiopoet.input.DependencyConfig 23 | 24 | class ConfigPojoToModuleConfigConverter { 25 | fun convert(config: ConfigPOJO, index: Int): ModuleConfig { 26 | return ModuleConfig().apply { 27 | java = CodeConfig().apply { 28 | packages = config.javaPackageCount?.toInt() ?: 0 29 | classesPerPackage = config.javaClassCount?.toInt() ?: 0 30 | methodsPerClass = config.javaMethodsPerClass 31 | } 32 | 33 | kotlin = CodeConfig().apply { 34 | packages = config.kotlinPackageCount?.toInt() ?: 0 35 | classesPerPackage = config.kotlinClassCount?.toInt() ?: 0 36 | methodsPerClass = config.kotlinMethodsPerClass 37 | } 38 | 39 | useKotlin = config.useKotlin 40 | 41 | extraLines = config.extraBuildFileLines 42 | 43 | generateTests = config.generateTests 44 | 45 | moduleName = config.getModuleName(index) 46 | dependencies = config.resolvedDependencies[moduleName]?.map { DependencyConfig.ModuleDependencyConfig(it.to, it.method) } ?: listOf() 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToProjectConfigConverter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.converters 18 | 19 | import com.google.androidstudiopoet.input.ProjectConfig 20 | import com.google.androidstudiopoet.input.ConfigPOJO 21 | 22 | class ConfigPojoToProjectConfigConverter(private val configPojoToModuleConfigConverter: ConfigPojoToModuleConfigConverter, 23 | private val configPojoToFlavourConfigsConverter: ConfigPojoToFlavourConfigsConverter, 24 | private val configPojoToBuildTypeConfigsConverter: ConfigPojoToBuildTypeConfigsConverter, 25 | private val configPojoToAndroidModuleConfigConverter: ConfigPojoToAndroidModuleConfigConverter, 26 | private val configPojoToBuildSystemConfigConverter: ConfigPojoToBuildSystemConfigConverter) { 27 | fun convert(configPojo: ConfigPOJO): ProjectConfig { 28 | val pureModulesConfigs = (0 until configPojo.numModules) 29 | .map { configPojoToModuleConfigConverter.convert(configPojo, it) } 30 | 31 | val productFlavors = configPojoToFlavourConfigsConverter.convert(configPojo) 32 | val buildTypes = configPojoToBuildTypeConfigsConverter.convert(configPojo) 33 | 34 | val androidModulesConfigs = (0 until configPojo.androidModules) 35 | .map { 36 | configPojoToAndroidModuleConfigConverter.convert(configPojo, it, productFlavors, buildTypes) 37 | } 38 | 39 | val buildSystemConfig = configPojoToBuildSystemConfigConverter.convert(configPojo) 40 | return ProjectConfig().apply { 41 | projectName = configPojo.projectName 42 | root = configPojo.root 43 | this.buildSystemConfig = buildSystemConfig 44 | moduleConfigs = pureModulesConfigs + androidModulesConfigs 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/core.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet 18 | 19 | interface Blueprint 20 | 21 | interface GenerationResult 22 | 23 | interface Generator { 24 | fun generate(blueprint: T): K 25 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/deserializers/DependencyConfigDeserializer.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.deserializers 2 | 3 | import com.google.androidstudiopoet.input.DependencyConfig 4 | import com.google.gson.JsonDeserializationContext 5 | import com.google.gson.JsonDeserializer 6 | import com.google.gson.JsonElement 7 | import java.lang.reflect.Type 8 | 9 | private const val MODULE_NAME = "moduleName" 10 | 11 | class DependencyConfigDeserializer: JsonDeserializer { 12 | override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): DependencyConfig = 13 | when (json.asJsonObject?.get(MODULE_NAME)?.asString) { 14 | null -> context.deserialize(json, 15 | DependencyConfig.LibraryDependencyConfig::class.java) 16 | else -> context.deserialize(json, 17 | DependencyConfig.ModuleDependencyConfig::class.java) 18 | } 19 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/deserializers/ModuleConfigDeserializer.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.deserializers 2 | 3 | import com.google.androidstudiopoet.input.AndroidModuleConfig 4 | import com.google.androidstudiopoet.input.ModuleConfig 5 | import com.google.androidstudiopoet.input.PureModuleConfig 6 | import com.google.gson.JsonDeserializationContext 7 | import com.google.gson.JsonDeserializer 8 | import com.google.gson.JsonElement 9 | import java.lang.reflect.Type 10 | 11 | private const val MODULE_TYPE = "moduleType" 12 | private const val ANDROID = "android" 13 | 14 | class ModuleConfigDeserializer: JsonDeserializer { 15 | override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ModuleConfig = 16 | when (json.asJsonObject?.get(MODULE_TYPE)?.asString) { 17 | ANDROID -> context.deserialize(json, AndroidModuleConfig::class.java) 18 | else -> context.deserialize(json, PureModuleConfig::class.java) 19 | } 20 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/BazelWorkspaceGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.generators.bazel.AssignmentStatement 20 | import com.google.androidstudiopoet.generators.bazel.Comment 21 | import com.google.androidstudiopoet.generators.bazel.LoadStatement 22 | import com.google.androidstudiopoet.generators.bazel.RawAttribute 23 | import com.google.androidstudiopoet.generators.bazel.StringAttribute 24 | import com.google.androidstudiopoet.generators.bazel.Target 25 | import com.google.androidstudiopoet.models.BazelWorkspaceBlueprint 26 | import com.google.androidstudiopoet.writers.FileWriter 27 | 28 | class BazelWorkspaceGenerator(private val fileWriter: FileWriter) { 29 | 30 | fun generate(bazelWorkspaceBlueprint: BazelWorkspaceBlueprint) { 31 | fileWriter.writeToFile( 32 | getBazelWorkspaceContent(bazelWorkspaceBlueprint), 33 | bazelWorkspaceBlueprint.workspacePath) 34 | } 35 | 36 | fun getBazelWorkspaceContent(blueprint: BazelWorkspaceBlueprint) = 37 | """${Target( 38 | "android_sdk_repository", 39 | listOf(StringAttribute("name", "androidsdk")))} 40 | 41 | ${Comment("Google Maven Repository")} 42 | ${LoadStatement("@bazel_tools//tools/build_defs/repo:http.bzl", listOf("http_archive"))} 43 | ${AssignmentStatement("GMAVEN_TAG", "\"${blueprint.gmavenRulesTag}\"")} 44 | ${Target( 45 | "http_archive", 46 | listOf( 47 | StringAttribute("name", "gmaven_rules"), 48 | RawAttribute("strip_prefix", "\"gmaven_rules-%s\" % GMAVEN_TAG"), 49 | RawAttribute("urls", "[\"https://github.com/bazelbuild/gmaven_rules/archive/%s.tar.gz\" % GMAVEN_TAG]") 50 | ))} 51 | ${LoadStatement("@gmaven_rules//:gmaven.bzl", listOf("gmaven_rules"))} 52 | ${Target("gmaven_rules", listOf())} 53 | """ 54 | 55 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/DependencyGraphGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | 16 | package com.google.androidstudiopoet.generators 17 | 18 | import com.google.androidstudiopoet.models.ModuleDependency 19 | import com.google.androidstudiopoet.models.ProjectBlueprint 20 | import com.google.androidstudiopoet.utils.joinPath 21 | import com.google.androidstudiopoet.writers.FileWriter 22 | 23 | class DependencyGraphGenerator(private val fileWriter: FileWriter, private val dependencyImageGenerator: DependencyImageGenerator) { 24 | 25 | fun generate(projectBlueprint: ProjectBlueprint) { 26 | val dependenciesGraphFileName = projectBlueprint.projectRoot.joinPath("dependencies.dot") 27 | fileWriter.writeToFile(dependenciesGraphString(projectBlueprint), dependenciesGraphFileName) 28 | println("Dependency graph written to $dependenciesGraphFileName") 29 | dependencyImageGenerator.generate(projectBlueprint) 30 | } 31 | 32 | private fun dependenciesGraphString(projectBlueprint: ProjectBlueprint) = projectBlueprint.allModuleBlueprints.joinToString("\n", "digraph ${projectBlueprint.projectName} {\n", "\n}") { 33 | getDependencyForModuleAsString(it.name, projectBlueprint.allDependencies[it.name]?: listOf()) 34 | } 35 | 36 | private fun getDependencyForModuleAsString(name: String, dependencies: List): String { 37 | var list = "" 38 | if (dependencies.isNotEmpty()) { 39 | list = " -> ${dependencies.map { it.name }.sorted().joinToString()}" 40 | } 41 | 42 | return " $name$list;" 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/GradleUtils.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.gradle.Closure 20 | import com.google.androidstudiopoet.gradle.Expression 21 | import com.google.androidstudiopoet.gradle.StringStatement 22 | import com.google.androidstudiopoet.models.Dependency 23 | import com.google.androidstudiopoet.models.LibraryDependency 24 | import com.google.androidstudiopoet.models.ModuleDependency 25 | import com.google.androidstudiopoet.models.Repository 26 | 27 | fun ModuleDependency.toExpression() = Expression(this.method, "project(':${this.name}')") 28 | 29 | fun LibraryDependency.toExpression() = Expression(this.method, "\"${this.name}\"") 30 | 31 | fun String.toApplyPluginExpression() = Expression("apply plugin:", "'$this'") 32 | 33 | fun String.toClasspathExpression() = Expression("classpath", "\"$this\"") 34 | 35 | fun Repository.toExpression() = when (this) { 36 | is Repository.Named -> this.toExpression() 37 | is Repository.Remote -> this.toExpression() 38 | } 39 | 40 | fun Repository.Named.toExpression() = StringStatement("${this.name}()") 41 | 42 | fun Repository.Remote.toExpression() = Closure("maven", listOf(Expression("url", "\"${this.url}\""))) 43 | 44 | fun Dependency.toExpression() = when (this) { 45 | is ModuleDependency -> this.toExpression() 46 | is LibraryDependency -> this.toExpression() 47 | else -> null 48 | } 49 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/ModuleBuildBazelGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.models.ModuleBuildBazelBlueprint 20 | import com.google.androidstudiopoet.models.ModuleDependency 21 | import com.google.androidstudiopoet.writers.FileWriter 22 | 23 | class ModuleBuildBazelGenerator(private val fileWriter: FileWriter) { 24 | fun generate(blueprint: ModuleBuildBazelBlueprint) { 25 | val deps: Set = blueprint.dependencies.map { 26 | when (it) { 27 | is ModuleDependency -> "\"//${it.name}\"" 28 | else -> "" 29 | } 30 | }.toSet() 31 | val depsString = """ 32 | deps = [ 33 | ${deps.joinToString(separator = ",\n ") { it }} 34 | ],""" 35 | val ruleClass = "java_library" 36 | val targetName = blueprint.targetName 37 | val ruleDefinition = """$ruleClass( 38 | name = "$targetName", 39 | srcs = glob(["src/main/java/**/*.java"]), 40 | visibility = ["//visibility:public"],${if (deps.isNotEmpty()) depsString else ""} 41 | )""" 42 | 43 | fileWriter.writeToFile(ruleDefinition, blueprint.path) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/ModuleBuildGradleGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.gradle.Closure 20 | import com.google.androidstudiopoet.gradle.Expression 21 | import com.google.androidstudiopoet.gradle.Statement 22 | import com.google.androidstudiopoet.gradle.StringStatement 23 | import com.google.androidstudiopoet.models.ModuleBuildGradleBlueprint 24 | import com.google.androidstudiopoet.writers.FileWriter 25 | 26 | class ModuleBuildGradleGenerator(private val fileWriter: FileWriter) { 27 | fun generate(blueprint: ModuleBuildGradleBlueprint) { 28 | val statements = applyPlugins(blueprint.plugins) + 29 | dependenciesClosure(blueprint) + 30 | codeCompatibilityStatements() + 31 | (blueprint.extraLines?.map { StringStatement(it) } ?: listOf()) 32 | 33 | val gradleText = statements.joinToString(separator = "\n") { it.toGroovy(0) } 34 | 35 | fileWriter.writeToFile(gradleText, blueprint.path) 36 | } 37 | 38 | private fun applyPlugins(plugins: Set): List { 39 | return plugins.map { it.toApplyPluginExpression() } 40 | } 41 | 42 | private fun dependenciesClosure(blueprint: ModuleBuildGradleBlueprint): Closure { 43 | val dependencyExpressions: Set = blueprint.dependencies.mapNotNull { it.toExpression() }.toSet() 44 | 45 | val statements = dependencyExpressions.toList() 46 | return Closure("dependencies", statements) 47 | } 48 | 49 | private fun codeCompatibilityStatements(): List { 50 | return listOf( 51 | StringStatement("sourceCompatibility = \"1.8\""), 52 | StringStatement("targetCompatibility = \"1.8\"") 53 | ) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/PackagesGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package com.google.androidstudiopoet.generators 16 | 17 | import com.google.androidstudiopoet.generators.packages.JavaGenerator 18 | import com.google.androidstudiopoet.generators.packages.KotlinGenerator 19 | import com.google.androidstudiopoet.models.PackagesBlueprint 20 | import java.io.File 21 | 22 | class PackagesGenerator(private val javaGenerator: JavaGenerator, 23 | private val kotlinGenerator: KotlinGenerator) { 24 | 25 | fun writePackages(blueprint: PackagesBlueprint) { 26 | val packagesRoot = File(blueprint.where) 27 | packagesRoot.mkdirs() 28 | blueprint.javaPackageBlueprints.forEach({javaGenerator.generatePackage(it) }) 29 | blueprint.kotlinPackageBlueprints.forEach({ kotlinGenerator.generatePackage(it) }) 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/android_modules/ActivityGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.android_modules 18 | 19 | import com.google.androidstudiopoet.models.ActivityBlueprint 20 | 21 | interface ActivityGenerator { 22 | fun generate(blueprint: ActivityBlueprint) 23 | } 24 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/android_modules/AndroidModuleBuildBazelGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.android_modules 18 | 19 | import com.google.androidstudiopoet.models.* 20 | import com.google.androidstudiopoet.writers.FileWriter 21 | 22 | class AndroidModuleBuildBazelGenerator(val fileWriter: FileWriter) { 23 | fun generate(bazelBlueprint: AndroidBuildBazelBlueprint) { 24 | 25 | val deps: Set = bazelBlueprint.dependencies.map { 26 | when (it) { 27 | is ModuleDependency -> "\"//${it.name}\"" 28 | is GmavenBazelDependency -> "gmaven_artifact(\"${it.name}\")" 29 | else -> "" 30 | } 31 | }.toSet() 32 | val depsString = """ 33 | deps = [ 34 | ${deps.joinToString(separator = ",\n ") { it }} 35 | ],""" 36 | val multidexString = """ 37 | multidex = "native",""" 38 | 39 | val ruleClass = if (bazelBlueprint.isApplication) "android_binary" else "android_library" 40 | val targetName = bazelBlueprint.name 41 | val ruleDefinition = """load("@gmaven_rules//:defs.bzl", "gmaven_artifact") 42 | 43 | $ruleClass( 44 | name = "$targetName", 45 | srcs = glob(["src/main/java/**/*.java"]),${if (bazelBlueprint.isApplication) multidexString else ""} 46 | resource_files = glob(["src/main/res/**/*"]), 47 | manifest = "src/main/AndroidManifest.xml", 48 | custom_package = "${bazelBlueprint.packageName}", 49 | visibility = ["//visibility:public"],${if (deps.isNotEmpty()) depsString else ""} 50 | )""" 51 | 52 | fileWriter.writeToFile(ruleDefinition, bazelBlueprint.path) 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/android_modules/ProguardGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.android_modules 18 | 19 | import com.google.androidstudiopoet.models.AndroidModuleBlueprint 20 | import com.google.androidstudiopoet.utils.joinPath 21 | import com.google.androidstudiopoet.writers.FileWriter 22 | 23 | class ProguardGenerator(val fileWriter: FileWriter) { 24 | fun generate(blueprint: AndroidModuleBlueprint) { 25 | val moduleRoot = blueprint.moduleRoot 26 | 27 | val proguardText = "# Add project specific ProGuard rules here.\n" + 28 | "# You can control the set of applied configuration files using the\n" + 29 | "# proguardFiles setting in build.gradle.\n" + 30 | "#\n" + 31 | "# For more details, see\n" + 32 | "# http://developer.android.com/guide/developing/tools/proguard.html\n" + 33 | "\n" + 34 | "# If your project uses WebView with JS, uncomment the following\n" + 35 | "# and specify the fully qualified class name to the JavaScript interface\n" + 36 | "# class:\n" + 37 | "#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n" + 38 | "# public *;\n" + 39 | "#}\n" + 40 | "\n" + 41 | "# Uncomment this to preserve the line number information for\n" + 42 | "# debugging stack traces.\n" + 43 | "#-keepattributes SourceFile,LineNumberTable\n" + 44 | "\n" + 45 | "# If you keep the line number information, uncomment this to\n" + 46 | "# hide the original source file name.\n" + 47 | "#-renamesourcefileattribute SourceFile" 48 | 49 | 50 | fileWriter.writeToFile(proguardText, moduleRoot.joinPath("proguard-rules.pro")) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/android_modules/resources/ImagesGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | 16 | package com.google.androidstudiopoet.generators.android_modules.resources 17 | 18 | import com.google.androidstudiopoet.models.ResourcesBlueprint 19 | import com.google.androidstudiopoet.utils.joinPath 20 | import com.google.androidstudiopoet.writers.FileWriter 21 | import java.awt.image.BufferedImage 22 | import java.io.File 23 | import java.util.* 24 | import javax.imageio.ImageIO 25 | 26 | class ImagesGenerator(val fileWriter: FileWriter) { 27 | 28 | /** 29 | * generates image resources by blueprint, returns list of image names to refer later. 30 | */ 31 | fun generate(blueprint: ResourcesBlueprint, random: Random) { 32 | 33 | val imagesDir = blueprint.resDirPath.joinPath("drawable") 34 | 35 | fileWriter.mkdir(imagesDir) 36 | 37 | blueprint.imageNames.forEach { imageName -> 38 | val image = generateRandomImage(random) 39 | 40 | ImageIO.write(image, 41 | "png", 42 | File(imagesDir, "$imageName.png")) 43 | } 44 | } 45 | 46 | private fun generateRandomImage(random: Random): BufferedImage { 47 | // Create buffered image object 48 | val img = BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB) 49 | 50 | // create random values pixel by pixel 51 | for (y in 0 until 100) { 52 | for (x in 0 until 100) { 53 | val a = random.nextInt(256) //generating 54 | val r = random.nextInt(256) //values 55 | val g = random.nextInt(256) //less than 56 | val b = random.nextInt(256) //256 57 | 58 | val p = a shl 24 or (r shl 16) or (g shl 8) or b //pixel 59 | 60 | img.setRGB(x, y, p) 61 | } 62 | } 63 | 64 | return img 65 | } 66 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/android_modules/resources/ResourcesGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.android_modules.resources 18 | 19 | import com.google.androidstudiopoet.models.ResourcesBlueprint 20 | import com.google.androidstudiopoet.writers.FileWriter 21 | import java.util.* 22 | 23 | class ResourcesGenerator(private val stringResourcesGenerator: StringResourcesGenerator, 24 | private val imageResourcesGenerator: ImagesGenerator, 25 | private val layoutResourcesGenerator: LayoutResourcesGenerator, 26 | private val fileWriter: FileWriter) { 27 | fun generate(blueprint: ResourcesBlueprint, random: Random) { 28 | stringResourcesGenerator.generate(blueprint) 29 | imageResourcesGenerator.generate(blueprint, random) 30 | fileWriter.mkdir(blueprint.layoutsDir) 31 | blueprint.layoutBlueprints.forEach { layoutResourcesGenerator.generate(it) } 32 | } 33 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/android_modules/resources/StringResourcesGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.android_modules.resources 18 | 19 | import com.google.androidstudiopoet.GenerationResult 20 | import com.google.androidstudiopoet.Generator 21 | import com.google.androidstudiopoet.models.ResourcesBlueprint 22 | import com.google.androidstudiopoet.utils.fold 23 | import com.google.androidstudiopoet.utils.joinPath 24 | import com.google.androidstudiopoet.writers.FileWriter 25 | 26 | class StringResourcesGenerator(private val fileWriter: FileWriter): Generator { 27 | 28 | /** 29 | * generates string resources by blueprint, returns list of string names to refer later. 30 | * Precondition: resources package is generated 31 | */ 32 | override fun generate(blueprint: ResourcesBlueprint): StringResourceGenerationResult { 33 | val valuesDirPath = blueprint.resDirPath.joinPath("values") 34 | fileWriter.mkdir(valuesDirPath) 35 | val stringsFileContent = getFileContent(blueprint.stringNames) 36 | 37 | fileWriter.writeToFile(stringsFileContent, valuesDirPath.joinPath("strings.xml")) 38 | return StringResourceGenerationResult(blueprint.stringNames) 39 | } 40 | 41 | private fun getFileContent(stringNames: List): String { 42 | val stringsFileContent = "" + 43 | stringNames.map { "$it\n" }.fold() + 44 | "" 45 | return stringsFileContent 46 | } 47 | } 48 | 49 | // TODO remove the class below after refactoring the generators 50 | 51 | data class StringResourceGenerationResult(val stringNames: List): GenerationResult -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/packages/KotlinGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.packages 18 | 19 | import com.google.androidstudiopoet.models.ClassBlueprint 20 | import com.google.androidstudiopoet.models.MethodBlueprint 21 | import com.google.androidstudiopoet.models.MethodToCall 22 | import com.google.androidstudiopoet.writers.FileWriter 23 | 24 | class KotlinGenerator constructor(fileWriter: FileWriter) : PackageGenerator(fileWriter) { 25 | 26 | override fun generateClass(blueprint: ClassBlueprint) { 27 | val buff = StringBuilder() 28 | 29 | buff.append("package ${blueprint.packageName};\n\n") 30 | 31 | val annotName = blueprint.className + "Fancy" 32 | buff.append("annotation class " + annotName + "\n") 33 | buff.append("@" + annotName + "\n") 34 | 35 | buff.append("class ${blueprint.className} {\n") 36 | 37 | blueprint.getFieldBlueprints() 38 | .joinToString(separator = "\n", postfix = "\n") { it -> "val ${it.name}: ${it.typeName}? = null"} 39 | .let { buff.append(it) } 40 | 41 | blueprint.getMethodBlueprints() 42 | .withIndex().map { (if (it.index != 0) "\n" else "") + generateMethod(it.value) } 43 | .fold(buff) { acc, method -> acc.append(method) } 44 | 45 | buff.append("}") 46 | 47 | writeFile(blueprint.getClassPath(), buff.toString()) 48 | } 49 | 50 | private fun generateMethod(blueprint: MethodBlueprint): String { 51 | val buff = StringBuilder() 52 | blueprint.annotationBlueprints.forEach { it -> buff.append(" @${it.className}\n") } 53 | buff.append(" fun ${blueprint.methodName}(){\n") 54 | blueprint.statements.forEach { statement -> statement?.let { buff.append(" $it\n") } } 55 | buff.append(" }\n") 56 | return buff.toString() 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/packages/PackageGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.packages 18 | 19 | import com.google.androidstudiopoet.models.ClassBlueprint 20 | import com.google.androidstudiopoet.models.MethodToCall 21 | import com.google.androidstudiopoet.models.PackageBlueprint 22 | import com.google.androidstudiopoet.writers.FileWriter 23 | import java.io.File 24 | 25 | abstract class PackageGenerator(private val fileWriter: FileWriter) { 26 | 27 | fun generatePackage(blueprint: PackageBlueprint): MethodToCall? { 28 | 29 | val srcFolder = File(blueprint.srcFolder, blueprint.packageName) 30 | if (srcFolder.exists()) { 31 | srcFolder.delete() 32 | } 33 | 34 | srcFolder.mkdirs() 35 | 36 | if (blueprint.generateTests) { 37 | val testFolder = File(blueprint.testFolder, blueprint.packageName) 38 | if (testFolder.exists()) { 39 | testFolder.delete() 40 | } 41 | testFolder.mkdirs() 42 | } 43 | 44 | blueprint.classBlueprints.forEach({ generateClass(it) }) 45 | 46 | return blueprint.methodToCallFromOutside 47 | } 48 | 49 | abstract fun generateClass(blueprint: ClassBlueprint) 50 | 51 | protected fun writeFile(path: String, content: String) { 52 | fileWriter.writeToFile(content, path) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/project/GradlePropertiesGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.project 18 | 19 | import com.google.androidstudiopoet.models.GradlePropertiesBlueprint 20 | import com.google.androidstudiopoet.writers.FileWriter 21 | 22 | class GradlePropertiesGenerator(private val fileWriter: FileWriter) { 23 | fun generate(blueprint: GradlePropertiesBlueprint) { 24 | val fileBody = blueprint.properties?.entries 25 | ?.joinToString("\n") { it.key + "=" + it.value } 26 | 27 | fileBody?.let { fileWriter.writeToFile(fileBody, blueprint.path) } 28 | } 29 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/generators/project/GradleSettingsGenerator.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.project 18 | 19 | import com.google.androidstudiopoet.utils.joinPath 20 | import com.google.androidstudiopoet.writers.FileWriter 21 | 22 | private const val INCLUDE_LENGTH_LIMIT = 250 23 | class GradleSettingsGenerator(private val fileWriter: FileWriter) { 24 | 25 | fun generate(projectName: String, allModulesNames: List, projectRoot: String) { 26 | val settingsGradleContent = buildString { 27 | appendLine(""" 28 | plugins { 29 | id "com.gradle.enterprise" version "3.7" 30 | } 31 | gradleEnterprise { 32 | buildScan { 33 | termsOfServiceUrl = "https://gradle.com/terms-of-service" 34 | termsOfServiceAgree = "yes" 35 | } 36 | } 37 | """.trimIndent()) 38 | appendLine() 39 | appendLine("rootProject.name = \'$projectName\'") 40 | append(generateIncludeStatements(allModulesNames)) 41 | } 42 | fileWriter.writeToFile(settingsGradleContent, projectRoot.joinPath("settings.gradle")) 43 | } 44 | 45 | private fun generateIncludeStatements(moduleBlueprints: List) = 46 | moduleBlueprints.asSequence() 47 | .map { "\'$it\'" } 48 | .foldIndexed("", { index, acc, next -> 49 | acc + getIncludeStatementOrComma(index) + next 50 | }) 51 | 52 | private fun getIncludeStatementOrComma(index: Int): String { 53 | return if (index.rem(INCLUDE_LENGTH_LIMIT) == 0) { 54 | "\ninclude " 55 | } else "," 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/gradle/GradleLang.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.gradle 18 | 19 | interface Statement { 20 | fun toGroovy(indentNumber: Int): String 21 | } 22 | 23 | data class StringStatement(val value: String) : Statement { 24 | override fun toGroovy(indentNumber: Int): String = INDENT.repeat(indentNumber) + value 25 | } 26 | 27 | data class Expression(val left: String, val right: String) : Statement { 28 | override fun toGroovy(indentNumber: Int): String = "${INDENT.repeat(indentNumber)}$left $right" 29 | } 30 | 31 | class Closure(val name: String, val statements: List) : Statement { 32 | override fun toGroovy(indentNumber: Int): String { 33 | val indent = INDENT.repeat(indentNumber) 34 | return """$indent$name { 35 | ${statements.joinToString(separator = "\n") { it.toGroovy(indentNumber + 1) }} 36 | $indent}""" 37 | } 38 | } 39 | 40 | data class Task(val name: String, val arguments: List, val statements: List) : Statement { 41 | override fun toGroovy(indentNumber: Int): String { 42 | val indent = INDENT.repeat(indentNumber) 43 | return """${indent}task $name(${arguments.joinToString { "${it.name}: ${it.value}" }}) { 44 | ${statements.joinToString(separator = "\n") { it.toGroovy(indentNumber + 1) }} 45 | $indent}""" 46 | } 47 | 48 | } 49 | 50 | data class TaskParameter(val name: String, val value: String) 51 | 52 | private const val INDENT = " " -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/AbstractModuleBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.input.CodeConfig 20 | import com.google.androidstudiopoet.utils.joinPath 21 | 22 | abstract class AbstractModuleBlueprint(val name: String, 23 | root: String, 24 | val useKotlin: Boolean, 25 | val dependencies: Set, 26 | javaConfig: CodeConfig?, 27 | kotlinConfig: CodeConfig?, 28 | val extraLines: List?, 29 | val generateTests : Boolean) { 30 | 31 | val moduleRoot = root.joinPath(name) 32 | val moduleDependencies by lazy{ dependencies.filterIsInstance()} 33 | private val methodsToCallWithIn by lazy { moduleDependencies.map { it.methodToCall } } 34 | 35 | val packagesBlueprint by lazy { 36 | PackagesBlueprint(javaConfig, kotlinConfig, moduleRoot, name, methodsToCallWithIn, generateTests) 37 | } 38 | 39 | val methodToCallFromOutside by lazy { 40 | packagesBlueprint.methodToCallFromOutside 41 | } 42 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ActivityBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | import com.google.androidstudiopoet.utils.fold 4 | 5 | data class ActivityBlueprint(val className: String, 6 | val enableCompose: Boolean, 7 | val enableViewBinding: Boolean, 8 | val layout: LayoutBlueprint, 9 | val where: String, 10 | val packageName: String, 11 | val classToReferFromActivity: ClassBlueprint, 12 | val listenerClassesForDataBinding: List, 13 | private val useButterknife: Boolean) { 14 | val enableDataBinding = listenerClassesForDataBinding.isNotEmpty() 15 | val dataBindingClassName = "$packageName.databinding.${layout.name.toDataBindingShortClassName()}" 16 | 17 | val fields: Set = 18 | layout.imageViewsBlueprints.mapIndexed { index, it -> 19 | FieldBlueprint("imageView$index", "android.widget.ImageView", it.getAnnotations()) }.toSet() 20 | 21 | private fun ImageViewBlueprint.getAnnotations(): List { 22 | if (useButterknife) { 23 | return listOf(AnnotationBlueprint("butterknife.BindView", mapOf("value" to "R2.id.$id"))) 24 | } 25 | return listOf() 26 | } 27 | } 28 | 29 | 30 | 31 | private fun String.toDataBindingShortClassName(): String = this.split("_").map { it.capitalize() }.fold() + "Binding" 32 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/AndroidBuildBazelBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.utils.joinPath 20 | 21 | class AndroidBuildBazelBlueprint(val isApplication: Boolean, 22 | moduleRoot: String, 23 | val packageName: String, 24 | additionalDependencies: Set, 25 | val name: String) { 26 | val libraries: Set = createSetOfLibraries() 27 | 28 | val dependencies = additionalDependencies + libraries 29 | 30 | val path = moduleRoot.joinPath("BUILD.bazel") 31 | 32 | private fun createSetOfLibraries(): Set { 33 | return mutableSetOf( 34 | GmavenBazelDependency("com.android.support:appcompat-v7:aar:28.0.0"), 35 | GmavenBazelDependency("com.android.support.constraint:constraint-layout:aar:1.1.3"), 36 | GmavenBazelDependency("com.android.support:multidex:aar:1.0.3"), 37 | GmavenBazelDependency("com.android.support.test:runner:aar:1.0.2"), 38 | GmavenBazelDependency("com.android.support.test.espresso:espresso-core:aar:3.0.2")) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/AnnotationBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class AnnotationBlueprint(val className: String, val params: Map = mapOf()) -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/BazelWorkspaceBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | package com.google.androidstudiopoet.models 15 | 16 | import com.google.androidstudiopoet.generators.bazel.* 17 | import com.google.androidstudiopoet.utils.joinPath 18 | 19 | class BazelWorkspaceBlueprint(val projectRoot: String) { 20 | 21 | val workspacePath = projectRoot.joinPath("WORKSPACE") 22 | 23 | val gmavenRulesTag = "20181212-2" 24 | 25 | } 26 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/BuildType.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class BuildType(val name: String, val body: String? = null) -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ClassBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | abstract class ClassBlueprint(val packageName: String, val className: String) { 20 | val fullClassName = "$packageName.$className" 21 | abstract fun getFieldBlueprints(): List 22 | abstract fun getMethodBlueprints(): List 23 | abstract fun getClassPath(): String 24 | abstract fun getMethodToCallFromOutside(): MethodToCall? 25 | } 26 | 27 | internal fun ClassBlueprint.toDataBindingOnClickAction(): String = 28 | "(view) -> ${className.decapitalize()}.${getMethodToCallFromOutside()!!.methodName}()" 29 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ClassComplexity.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | class ClassComplexity(val lambdaCount: Int = 0) 4 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/DataBindingBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | class DataBindingBlueprint { 4 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/Dependencies.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | open class ModuleDependency(val name: String, val methodToCall: MethodToCall, val method: String) : Dependency 20 | 21 | class AndroidModuleDependency(name: String, methodToCall: MethodToCall, method: String, val resourcesToRefer: ResourcesToRefer) 22 | : ModuleDependency(name, methodToCall, method) 23 | 24 | data class LibraryDependency(val method: String, val name: String) : Dependency 25 | 26 | data class GmavenBazelDependency(val name: String) : Dependency 27 | 28 | interface Dependency 29 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/FieldBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class FieldBlueprint(val name: String, val typeName: String, val annotations: List) { 4 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/Flavor.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class Flavor(val name: String, val dimension: String? = null) -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/FromToDependencyConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | data class FromToDependencyConfig(val from: String, val to: String, val method: String? = null) 20 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/GradlePropertiesBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.utils.joinPath 20 | 21 | class GradlePropertiesBlueprint(projectRoot: String, overrideProperties: Map?) { 22 | private val defaultProperties = mapOf( 23 | "org.gradle.jvmargs" to "-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError", 24 | "org.gradle.daemon" to "true", 25 | "org.gradle.parallel" to "true", 26 | "org.gradle.caching" to "true", 27 | "android.useAndroidX" to "true" 28 | ) 29 | 30 | val path = projectRoot.joinPath("gradle.properties") 31 | val properties: Map = defaultProperties + (overrideProperties ?: mapOf()) 32 | 33 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/GradleTask.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class GradleTask(val name: String, val body: List?) -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ImageViewBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class ImageViewBlueprint(val id: String, val imageName: String, val actionClass: ClassBlueprint?) 4 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/JavaClassBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | class JavaClassBlueprint(packageName: String, classNumber: Int, methodsPerClass: Int, fieldsPerClass: Int, 20 | private val where: String, private val methodsToCallWithinClass: List, classComplexity: ClassComplexity) : 21 | NonTestClassBlueprint(packageName, "Foo" + classNumber, methodsPerClass, fieldsPerClass, classComplexity) { 22 | override fun getFieldBlueprints(): List { 23 | return (0 until fieldsPerClass) 24 | .map { i -> FieldBlueprint("int$i", "java.lang.Integer", listOf()) } 25 | } 26 | 27 | override fun getMethodBlueprints(): List { 28 | return (0 until methodsPerClass) 29 | .map { i -> 30 | val statements = ArrayList() 31 | 32 | // adding lambdas 33 | for (j in 0 until lambdaCountInMethod(i)) { 34 | statements += getLambda(j) 35 | } 36 | if (i > 0) { 37 | statements += "foo" + (i - 1) + "()" 38 | } else if (!methodsToCallWithinClass.isEmpty()) { 39 | methodsToCallWithinClass.forEach({ statements += "new ${it.className}().${it.methodName}()" }) 40 | 41 | } 42 | 43 | MethodBlueprint("foo$i", statements) 44 | } 45 | } 46 | 47 | override fun getClassPath(): String = "$where/$packageName/$className.java" 48 | 49 | private fun getLambda(lambdaNumber: Int) = "final Runnable anything$lambdaNumber = () -> System.out.println(\"anything\")" 50 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/JavaTestClassBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | import org.junit.Test 4 | 5 | class JavaTestClassBlueprint(packageName: String, private val classNumber: Int, private val methodsPerClass: Int, 6 | private val where: String) : 7 | ClassBlueprint(packageName, "Foo${classNumber}Test") { 8 | 9 | override fun getFieldBlueprints(): List = listOf() 10 | 11 | override fun getMethodBlueprints(): List { 12 | return (0 until methodsPerClass) 13 | .map { i -> 14 | val statements = listOf("new Foo$classNumber().foo$i()") 15 | MethodBlueprint("testFoo$i", statements, listOf(Test::class.java.name)) 16 | } 17 | } 18 | 19 | override fun getClassPath(): String = "$where/$packageName/$className.java" 20 | 21 | override fun getMethodToCallFromOutside(): MethodToCall? = null 22 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/KotlinClassBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | class KotlinClassBlueprint(packageName: String, classNumber: Int, methodsPerClass: Int, fieldsPerClass: Int, 20 | private val mainPackage: String, private val methodsToCallWithinClass: List, 21 | classComplexity: ClassComplexity) : 22 | NonTestClassBlueprint(packageName, "Foo" + classNumber, methodsPerClass, fieldsPerClass, classComplexity) { 23 | override fun getFieldBlueprints(): List { 24 | return (0 until fieldsPerClass) 25 | .map { i -> FieldBlueprint("int$i", "Int", listOf()) } 26 | } 27 | 28 | override fun getMethodBlueprints(): List { 29 | return (0 until methodsPerClass) 30 | .map { i -> 31 | val statements = ArrayList() 32 | 33 | // adding lambdas 34 | for (j in 0 until lambdaCountInMethod(i)) { 35 | statements += getLambda(j) 36 | } 37 | 38 | if (i > 0) { 39 | statements += "foo" + (i - 1) + "()" 40 | } else if (!methodsToCallWithinClass.isEmpty()) { 41 | methodsToCallWithinClass.forEach { statements += "${it.className}().${it.methodName}()" } 42 | 43 | } 44 | 45 | MethodBlueprint("foo$i", statements) 46 | } 47 | } 48 | 49 | private fun getLambda(lambdaNumber: Int) = "var anything$lambdaNumber = { System.out.print(\"anything\")}" 50 | 51 | override fun getClassPath(): String = "$mainPackage/$packageName/$className.kt" 52 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/KotlinTestClassBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | import org.junit.Test 4 | 5 | class KotlinTestClassBlueprint(packageName: String, private val classNumber: Int, private val methodsPerClass: Int, 6 | private val mainPackage: String) : 7 | ClassBlueprint(packageName, "Foo${classNumber}Test") { 8 | 9 | override fun getFieldBlueprints(): List = listOf() 10 | 11 | override fun getMethodBlueprints(): List { 12 | return (0 until methodsPerClass) 13 | .map { i -> 14 | val statements = listOf("Foo$classNumber().foo$i()") 15 | MethodBlueprint("testFoo$i", statements, listOf(Test::class.java.name)) 16 | } 17 | } 18 | 19 | override fun getClassPath(): String = "$mainPackage/$packageName/$className.kt" 20 | 21 | override fun getMethodToCallFromOutside(): MethodToCall? = null 22 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/Language.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | enum class Language(val postfix: kotlin.String) { 20 | 21 | JAVA("Java"), 22 | KOTLIN("Kt") 23 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/LayoutBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.utils.joinPath 20 | 21 | class LayoutBlueprint(val name: String, 22 | layoutsDir: String, 23 | val enableCompose: Boolean, 24 | textsWithActions: List>, 25 | imagesWithActions: List>, 26 | val layoutsToInclude: List) { 27 | 28 | val filePath = layoutsDir.joinPath(name) + ".xml" 29 | val textViewsBlueprints = textsWithActions.mapIndexed { index, it -> 30 | TextViewBlueprint("$name${it.first}$index", it.first, it.second) 31 | } 32 | 33 | val imageViewsBlueprints = imagesWithActions.mapIndexed { index, it -> 34 | ImageViewBlueprint("$name${it.first}$index", it.first, it.second) 35 | } 36 | 37 | val classesToBind 38 | = (textsWithActions + imagesWithActions).mapNotNull { it.second } 39 | 40 | val hasLayoutTag = classesToBind.isNotEmpty() 41 | } 42 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/MethodBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | data class MethodBlueprint(val methodName: String, val statements: List, val annotations: List = listOf()) { 20 | val annotationBlueprints = annotations.map { AnnotationBlueprint(it) } 21 | } 22 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/MethodToCall.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | data class MethodToCall(val methodName: String, val className: String) 20 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ModuleBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.input.CodeConfig 20 | import com.google.androidstudiopoet.input.PluginConfig 21 | 22 | class ModuleBlueprint(name: String, 23 | root: String, 24 | useKotlin: Boolean, 25 | dependencies: Set, 26 | javaConfig: CodeConfig?, 27 | kotlinConfig: CodeConfig?, 28 | extraLines: List?, 29 | generateTests: Boolean, 30 | pluginConfigs: List?, 31 | generateBazelFiles: Boolean?) 32 | : AbstractModuleBlueprint(name, root, useKotlin, dependencies, javaConfig, kotlinConfig, extraLines, 33 | generateTests) { 34 | 35 | val buildGradleBlueprint by lazy { 36 | ModuleBuildGradleBlueprint(dependencies.toSet(), useKotlin, generateTests, extraLines, moduleRoot, 37 | pluginConfigs) 38 | } 39 | 40 | val buildBazelBlueprint by lazy { 41 | when (generateBazelFiles) { 42 | true -> ModuleBuildBazelBlueprint(dependencies.toSet(), moduleRoot, name) 43 | else -> null 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ModuleBuildBazelBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.utils.joinPath 20 | 21 | class ModuleBuildBazelBlueprint( 22 | additionalDependencies: Set, 23 | moduleRoot: String, 24 | name: String 25 | ) { 26 | 27 | val targetName = name 28 | 29 | val path = moduleRoot.joinPath("BUILD.bazel") 30 | 31 | val dependencies = additionalDependencies 32 | 33 | } 34 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ModuleBuildGradleBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.input.PluginConfig 20 | import com.google.androidstudiopoet.utils.joinPath 21 | 22 | class ModuleBuildGradleBlueprint( 23 | additionalDependencies: Set, 24 | private val enableKotlin: Boolean, 25 | private val generateTests: Boolean, 26 | val extraLines: List? = null, 27 | moduleRoot: String, 28 | pluginConfigs: List? 29 | ) { 30 | 31 | val path = moduleRoot.joinPath("build.gradle") 32 | 33 | val plugins: Set = createSetOfPlugins(pluginConfigs) 34 | 35 | val dependencies = additionalDependencies + createSetOfMandatoryLibraries() 36 | 37 | private fun createSetOfMandatoryLibraries(): Set { 38 | val result = mutableSetOf() 39 | 40 | if (enableKotlin) { 41 | result += LibraryDependency("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${'$'}kotlin_version") 42 | } 43 | 44 | if (generateTests) { 45 | result += LibraryDependency("testImplementation", "junit:junit:4.12") 46 | } 47 | 48 | return result 49 | } 50 | 51 | private fun createSetOfPlugins(pluginConfigs: List?): Set { 52 | val result = mutableSetOf("java-library") 53 | if (enableKotlin) { 54 | result += listOf("kotlin") 55 | } 56 | 57 | pluginConfigs?.map { it.id }?.forEach { result.add(it) } 58 | 59 | return result 60 | } 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/NonTestClassBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | abstract class NonTestClassBlueprint(packageName: String, className: String, val methodsPerClass: Int, val fieldsPerClass: Int, 20 | private val classComplexity: ClassComplexity) : ClassBlueprint(packageName, className) { 21 | 22 | override fun getMethodToCallFromOutside(): MethodToCall? = 23 | MethodToCall(getMethodBlueprints().last().methodName, fullClassName) 24 | 25 | fun lambdaCountInMethod(methodNumber: Int) = classComplexity.lambdaCount / methodsPerClass + 26 | if (((classComplexity.lambdaCount % methodsPerClass) - methodNumber) > 0) 1 else 0 27 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ProjectBuildGradleBlueprint.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.input.RepositoryConfig 20 | import com.google.androidstudiopoet.utils.joinPath 21 | 22 | class ProjectBuildGradleBlueprint(root: String, enableKotlin: Boolean, androidGradlePluginVersion: String, 23 | kotlinVersion: String, additionalRepositories: List?, 24 | additionalClasspaths: List?) { 25 | 26 | val path = root.joinPath("build.gradle") 27 | val kotlinExtStatement = if (enableKotlin) "ext.kotlin_version = '$kotlinVersion'" else null 28 | 29 | val classpaths: Set by lazy { 30 | listOfNotNull( 31 | "com.android.tools.build:gradle:$androidGradlePluginVersion", 32 | if (enableKotlin) "org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}kotlin_version" else null, 33 | *additionalClasspaths?.toTypedArray().orEmpty() 34 | ).toSet() 35 | } 36 | 37 | val buildScriptRepositories = setOf( 38 | Repository.Named("google"), 39 | Repository.Named("mavenCentral"), 40 | Repository.Named("gradlePluginPortal") 41 | ) + additionalRepositories.orEmpty().map { Repository.Remote(it.url) }.toSet() 42 | 43 | val repositories = setOf( 44 | Repository.Named("google"), 45 | Repository.Named("mavenCentral") 46 | ) + additionalRepositories.orEmpty().map { Repository.Remote(it.url) }.toSet() 47 | } 48 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/Repositories.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | sealed class Repository { 20 | data class Named(val name: String): Repository() 21 | data class Remote(val url: String): Repository() 22 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/ResourcesToRefer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | data class ResourcesToRefer(val strings: List, val images: List, val layouts: List) { 20 | fun combine(moreResourcesToRefer: ResourcesToRefer) = 21 | ResourcesToRefer(strings + moreResourcesToRefer.strings, 22 | images + moreResourcesToRefer.images, 23 | layouts + moreResourcesToRefer.layouts) 24 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/models/TextViewBlueprint.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | data class TextViewBlueprint(val id: String, val stringName: String, val actionClass: ClassBlueprint?) 4 | -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/utils/collections.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | * except in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the 10 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 | * KIND, either express or implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package com.google.androidstudiopoet.utils 16 | 17 | fun Collection?.isNullOrEmpty() = this == null || this.isEmpty() 18 | 19 | fun Collection?.joinLines(separator: CharSequence = "\n") : String { 20 | if (this == null) { 21 | return "" 22 | } 23 | return this.joinToString(separator = separator) 24 | } 25 | 26 | fun MutableMap.increase(key : T) : Int { 27 | val newValue = this.getOrDefault(key, 0) + 1 28 | this.put(key, newValue) 29 | return newValue 30 | } 31 | 32 | fun MutableMap.decrease(key : T) : Int { 33 | val newValue = this.getOrDefault(key, 0) - 1 34 | this.put(key, newValue) 35 | return newValue 36 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/utils/fold.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.utils 18 | 19 | fun Iterable.fold() = this.fold("") { acc, next -> acc + next } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/utils/joinPath.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.utils 18 | 19 | fun String.joinPath(addition: String) = this + "/" + addition 20 | fun String.joinPaths(additions: List) = this.joinPath(additions.joinToString("/")) -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/writers/AbstractWriter.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.writers 2 | 3 | import java.io.File 4 | import java.nio.file.Files 5 | 6 | interface AbstractWriter { 7 | 8 | fun mkdir(path: String) { 9 | val file = File(path) 10 | if (file.parentFile != null && !file.parentFile.exists()) { 11 | mkdir(file.parent) 12 | } 13 | File(path).mkdir() 14 | } 15 | 16 | fun delete(path: String) { 17 | val file = File(path) 18 | if (!Files.isSymbolicLink(file.toPath())) { 19 | file.listFiles()?.forEach { delete(it.absolutePath) } 20 | } 21 | file.delete() 22 | } 23 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/writers/FileWriter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.writers 18 | 19 | import java.io.BufferedWriter 20 | import java.io.File 21 | import java.io.FileWriter 22 | import java.io.IOException 23 | 24 | class FileWriter : AbstractWriter { 25 | fun writeToFile(content: String, path: String) { 26 | var writer: BufferedWriter? = null 27 | try { 28 | val file = File(path) 29 | file.createNewFile() 30 | 31 | writer = BufferedWriter(FileWriter(file)) 32 | 33 | writer.write(content) 34 | 35 | } catch (e: IOException) { 36 | e.printStackTrace() 37 | } finally { 38 | try { 39 | writer?.close() 40 | } catch (e: IOException) { 41 | e.printStackTrace() 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/writers/GithubDownloader.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.writers 18 | 19 | import com.google.gson.Gson 20 | import com.google.gson.reflect.TypeToken 21 | import org.apache.commons.io.FileUtils 22 | import java.io.File 23 | import java.io.IOException 24 | import java.net.URL 25 | import java.util.* 26 | 27 | class GithubDownloader { 28 | 29 | private data class GithubItem( 30 | val name: String? = null, 31 | val path: String? = null, 32 | val sha: String? = null, 33 | val size: Long = 0, 34 | val url: String? = null, 35 | val html_url: String? = null, 36 | val git_url: String? = null, 37 | val download_url: String? = null, 38 | val type: String? = null) 39 | 40 | fun downloadDir(githubPath: String, to: String): Boolean { 41 | 42 | FileUtils.deleteDirectory(File(to)) 43 | File(to).mkdirs() 44 | 45 | val list = listUrl(githubPath) 46 | val result = ArrayList() 47 | list?.forEach { item -> 48 | if ("dir" == item.type) { 49 | val newDir = File(to, item.name) 50 | result.add(downloadDir(item.url!!, newDir.absolutePath)) 51 | } else { 52 | val file = File(to, item.name) 53 | file.createNewFile() 54 | result.add(downloadFile(item.download_url!!, file)) 55 | } 56 | } 57 | return !result.contains(java.lang.Boolean.FALSE) 58 | } 59 | 60 | private fun listUrl(url: String): List? { 61 | val json = getStringFromUrl(url) 62 | val listType = object : TypeToken>() {}.type 63 | return Gson().fromJson>(json, listType) 64 | } 65 | 66 | private fun getStringFromUrl(url: String): String? { 67 | var out: String? = null 68 | try { 69 | Scanner(URL(url).openStream(), "UTF-8"). 70 | use({ scanner -> out = scanner.useDelimiter("\\A").next() }) 71 | } catch (ex: IOException) { 72 | } 73 | 74 | return out 75 | } 76 | 77 | private fun downloadFile(url: String, file: File): Boolean { 78 | var success = true 79 | try { 80 | FileUtils.copyURLToFile(URL(url), file) 81 | } catch (ioex: IOException) { 82 | success = false 83 | } 84 | 85 | return success 86 | } 87 | } -------------------------------------------------------------------------------- /aspoet/src/main/kotlin/com/google/androidstudiopoet/writers/ImageWriter.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.writers 2 | 3 | import java.awt.image.BufferedImage 4 | import java.io.File 5 | import javax.imageio.ImageIO 6 | 7 | class ImageWriter : AbstractWriter { 8 | fun writeToFile(content: BufferedImage, path: String) { 9 | ImageIO.write(content, "png", File(path)) 10 | } 11 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToBuildSystemConfigConverterTest.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.converters 2 | 3 | import com.google.androidstudiopoet.input.ConfigPOJO 4 | import com.google.androidstudiopoet.testutils.assertEquals 5 | import com.google.androidstudiopoet.testutils.assertOn 6 | import org.junit.Test 7 | 8 | private const val KOTLIN_VERSION = "kotlin version" 9 | private const val AGP_VERSION = "agp version" 10 | private const val GRADLE_VERSION = "gradle version" 11 | private val GRADLE_PROPERTIES = mapOf("property1" to "value1", "property2" to "value2") 12 | private const val GENERATE_BAZEL_FILES = true 13 | 14 | class ConfigPojoToBuildSystemConfigConverterTest { 15 | private val configPojo = ConfigPOJO().apply { 16 | kotlinVersion = KOTLIN_VERSION 17 | androidGradlePluginVersion = AGP_VERSION 18 | gradleVersion = GRADLE_VERSION 19 | gradleProperties = GRADLE_PROPERTIES 20 | generateBazelFiles = GENERATE_BAZEL_FILES 21 | } 22 | 23 | private val converter = ConfigPojoToBuildSystemConfigConverter() 24 | 25 | @Test 26 | fun `convert should pass gradle, AGP and kotlin versions to BuildSystemConfig`() { 27 | val buildSystemConfig = converter.convert(configPojo) 28 | assertOn(buildSystemConfig) { 29 | kotlinVersion!!.assertEquals(KOTLIN_VERSION) 30 | agpVersion!!.assertEquals(AGP_VERSION) 31 | buildSystemVersion!!.assertEquals(GRADLE_VERSION) 32 | properties!!.assertEquals(GRADLE_PROPERTIES) 33 | generateBazelFiles!!.assertEquals(GENERATE_BAZEL_FILES) 34 | } 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/converters/ConfigPojoToFlavorConfigsConverterTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.converters 18 | 19 | import com.google.androidstudiopoet.input.FlavorConfig 20 | import com.google.androidstudiopoet.input.ConfigPOJO 21 | import com.google.androidstudiopoet.testutils.assertEmpty 22 | import com.google.androidstudiopoet.testutils.assertEquals 23 | import com.google.androidstudiopoet.testutils.mock 24 | import com.nhaarman.mockitokotlin2.whenever 25 | import org.junit.Test 26 | 27 | class ConfigPojoToFlavorConfigsConverterTest { 28 | private val configPojo: ConfigPOJO = mock() 29 | 30 | private val converter = ConfigPojoToFlavourConfigsConverter() 31 | 32 | @Test 33 | fun `convert returns empty list when configPojo#productFlavors is null`() { 34 | converter.convert(configPojo).assertEmpty() 35 | } 36 | 37 | @Test 38 | fun `convert returns empty list when configPojo#productFlavors is empty`() { 39 | whenever(configPojo.productFlavors).thenReturn(listOf()) 40 | converter.convert(configPojo).assertEmpty() 41 | } 42 | 43 | @Test 44 | fun `convert returns two flavours when configPojo#productFlavors has one element equal to two`() { 45 | whenever(configPojo.productFlavors).thenReturn(listOf(2)) 46 | converter.convert(configPojo).assertEquals(listOf( 47 | FlavorConfig("dim0flav0", "dim0"), 48 | FlavorConfig("dim0flav1", "dim0") 49 | )) 50 | } 51 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/generators/BazelWorkspaceGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.generators 2 | 3 | import com.google.androidstudiopoet.models.BazelWorkspaceBlueprint 4 | import com.google.androidstudiopoet.testutils.mock 5 | import com.google.androidstudiopoet.writers.FileWriter 6 | import com.nhaarman.mockitokotlin2.verify 7 | import com.nhaarman.mockitokotlin2.whenever 8 | import org.junit.Test 9 | 10 | class BazelWorkspaceGeneratorTest { 11 | 12 | private val fileWriter: FileWriter = mock() 13 | private val bazelWorkspaceGenerator= BazelWorkspaceGenerator(fileWriter) 14 | 15 | @Test 16 | fun `generator generates workspace file with correct base content`() { 17 | val blueprint = getBazelWorkspaceBlueprint() 18 | bazelWorkspaceGenerator.generate(blueprint) 19 | val expected = """android_sdk_repository( 20 | name = "androidsdk", 21 | ) 22 | 23 | # Google Maven Repository 24 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 25 | GMAVEN_TAG = "19700101-1" 26 | http_archive( 27 | name = "gmaven_rules", 28 | strip_prefix = "gmaven_rules-%s" % GMAVEN_TAG, 29 | urls = ["https://github.com/bazelbuild/gmaven_rules/archive/%s.tar.gz" % GMAVEN_TAG], 30 | ) 31 | load("@gmaven_rules//:gmaven.bzl", "gmaven_rules") 32 | gmaven_rules() 33 | """ 34 | verify(fileWriter).writeToFile(expected, "WORKSPACE") 35 | } 36 | 37 | @Test 38 | fun `generator generates workspace file with correct gmaven rules tag`() { 39 | val blueprint = getBazelWorkspaceBlueprint("20001212-42") 40 | bazelWorkspaceGenerator.generate(blueprint) 41 | val expected = """android_sdk_repository( 42 | name = "androidsdk", 43 | ) 44 | 45 | # Google Maven Repository 46 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 47 | GMAVEN_TAG = "20001212-42" 48 | http_archive( 49 | name = "gmaven_rules", 50 | strip_prefix = "gmaven_rules-%s" % GMAVEN_TAG, 51 | urls = ["https://github.com/bazelbuild/gmaven_rules/archive/%s.tar.gz" % GMAVEN_TAG], 52 | ) 53 | load("@gmaven_rules//:gmaven.bzl", "gmaven_rules") 54 | gmaven_rules() 55 | """ 56 | verify(fileWriter).writeToFile(expected, "WORKSPACE") 57 | } 58 | 59 | private fun getBazelWorkspaceBlueprint(gmavenRulesTag: String = "19700101-1"): BazelWorkspaceBlueprint { 60 | val blueprint = mock() 61 | whenever(blueprint.workspacePath).thenReturn("WORKSPACE") 62 | whenever(blueprint.gmavenRulesTag).thenReturn(gmavenRulesTag) 63 | return blueprint 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/generators/DependencyGraphGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.testutils.mock 20 | import com.google.androidstudiopoet.utils.joinPath 21 | import com.google.androidstudiopoet.writers.FileWriter 22 | import com.nhaarman.mockitokotlin2.verify 23 | import org.junit.Test 24 | 25 | class DependencyGraphGeneratorTest: DependencyGraphBase() { 26 | private val fileWriter: FileWriter = mock() 27 | private val dependencyImageGenerator: DependencyImageGenerator = mock() 28 | private val dependencyGraphGenerator = DependencyGraphGenerator(fileWriter, dependencyImageGenerator) 29 | 30 | @Test 31 | fun `generator dot file is correct`() { 32 | val blueprint = getProjectBlueprint() 33 | dependencyGraphGenerator.generate(blueprint) 34 | val expectedPath = "projectRoot".joinPath("dependencies.dot") 35 | verify(fileWriter).writeToFile(expectedGraphText, expectedPath) 36 | } 37 | 38 | @Test 39 | fun `generator image is called`() { 40 | val blueprint = getProjectBlueprint() 41 | dependencyGraphGenerator.generate(blueprint) 42 | verify(dependencyImageGenerator).generate(blueprint) 43 | } 44 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/generators/DependencyImageGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.testutils.* 20 | import com.google.androidstudiopoet.utils.joinPath 21 | import com.google.androidstudiopoet.writers.ImageWriter 22 | import com.nhaarman.mockitokotlin2.argumentCaptor 23 | import com.nhaarman.mockitokotlin2.eq 24 | import org.junit.Test 25 | import com.nhaarman.mockitokotlin2.verify 26 | import java.awt.image.BufferedImage 27 | import javax.imageio.ImageIO 28 | 29 | class DependencyImageGeneratorTest: DependencyGraphBase() { 30 | private val imageWriter: ImageWriter = mock() 31 | private val dependencyImageGenerator = DependencyImageGenerator(imageWriter) 32 | 33 | @Test 34 | fun `generated image content is what is expected`() { 35 | val blueprint = getProjectBlueprint() 36 | dependencyImageGenerator.generate(blueprint) 37 | val expectedPath = "projectRoot".joinPath("dependencies.png") 38 | val stream = this.javaClass.getResourceAsStream("dependencyGraphTest.png") 39 | val expectedImage = ImageIO.read(stream) 40 | val imgCaptor = argumentCaptor() 41 | verify(imageWriter).writeToFile(imgCaptor.capture(), eq(expectedPath)) 42 | assertOn(imgCaptor) { 43 | allValues.assertSize(1) 44 | allValues[0].assertEqualImage(expectedImage) 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/generators/ModuleBuildBazelGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators 18 | 19 | import com.google.androidstudiopoet.models.* 20 | import com.google.androidstudiopoet.testutils.mock 21 | import com.google.androidstudiopoet.writers.FileWriter 22 | import com.nhaarman.mockitokotlin2.verify 23 | import com.nhaarman.mockitokotlin2.whenever 24 | import org.junit.Test 25 | 26 | class ModuleBuildBazelGeneratorTest { 27 | private val fileWriter: FileWriter = mock() 28 | private val buildBazelGenerator = ModuleBuildBazelGenerator(fileWriter) 29 | 30 | @Test 31 | fun `generator applies dependencies from the blueprint`() { 32 | val blueprint = getModuleBuildBazelBlueprint(dependencies = setOf( 33 | ModuleDependency("library1", mock(),"unused"), 34 | ModuleDependency("library2", mock(),"unused") 35 | )) 36 | buildBazelGenerator.generate(blueprint) 37 | val expected = """java_library( 38 | name = "target_name", 39 | srcs = glob(["src/main/java/**/*.java"]), 40 | visibility = ["//visibility:public"], 41 | deps = [ 42 | "//library1", 43 | "//library2" 44 | ], 45 | )""" 46 | verify(fileWriter).writeToFile(expected, "BUILD.bazel") 47 | } 48 | 49 | private fun getModuleBuildBazelBlueprint(dependencies: Set = setOf()): ModuleBuildBazelBlueprint { 50 | return mock().apply { 51 | whenever(this.targetName).thenReturn("target_name") 52 | whenever(this.dependencies).thenReturn(dependencies) 53 | whenever(this.path).thenReturn("BUILD.bazel") 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/generators/bazel/BazelLangTest.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.generators.bazel 2 | 3 | import com.google.androidstudiopoet.testutils.assertEquals 4 | import org.junit.Test 5 | 6 | class BazelLangTest { 7 | 8 | @Test 9 | fun `assignment statement is converted to string correctly`() { 10 | val stmt = AssignmentStatement("foo", "\"bar\"") 11 | stmt.toString().assertEquals("foo = \"bar\"") 12 | } 13 | 14 | @Test 15 | fun `load statement is converted to string correctly`() { 16 | val stmt = LoadStatement("@foo//bar:baz.bzl", listOf("foo", "bar")) 17 | stmt.toString().assertEquals("""load("@foo//bar:baz.bzl", "foo", "bar")""") 18 | } 19 | 20 | @Test 21 | fun `comment is converted to string correctly`() { 22 | val comment = Comment("Foo bar baz") 23 | comment.toString().assertEquals("# Foo bar baz") 24 | } 25 | 26 | @Test 27 | fun `raw attribute is converted to string correctly`() { 28 | val attr = RawAttribute("foo", "[1, 2, 3]") 29 | attr.toString().assertEquals("foo = [1, 2, 3]") 30 | } 31 | 32 | @Test 33 | fun `string attribute is converted to string correctly`() { 34 | val attr = StringAttribute("foo", "bar") 35 | attr.toString().assertEquals("foo = \"bar\"") 36 | } 37 | 38 | @Test 39 | fun `target without attributes is converted to string correctly`() { 40 | val target = Target("foo_bar", listOf()) 41 | target.toString().assertEquals("foo_bar()") 42 | } 43 | 44 | @Test 45 | fun `target with one attribute is converted to string correctly`() { 46 | val target = Target("foo_bar", listOf(RawAttribute("baz", "42"))) 47 | target.toString().assertEquals("""foo_bar( 48 | baz = 42, 49 | )""") 50 | } 51 | 52 | @Test 53 | fun `target with two attributes is converted to string correctly`() { 54 | val target = Target( 55 | "foo_bar", 56 | listOf( 57 | RawAttribute("baz", "42"), 58 | StringAttribute("qux", "foo") 59 | )) 60 | target.toString().assertEquals("""foo_bar( 61 | baz = 42, 62 | qux = "foo", 63 | )""") 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/generators/project/GradlePropertiesGeneratorTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.generators.project 18 | 19 | import com.google.androidstudiopoet.models.GradlePropertiesBlueprint 20 | import com.google.androidstudiopoet.testutils.mock 21 | import com.google.androidstudiopoet.writers.FileWriter 22 | import com.nhaarman.mockitokotlin2.verify 23 | import com.nhaarman.mockitokotlin2.verifyZeroInteractions 24 | import com.nhaarman.mockitokotlin2.whenever 25 | import org.junit.Test 26 | 27 | class GradlePropertiesGeneratorTest { 28 | 29 | private val fileWriter: FileWriter = mock() 30 | 31 | private val generator = GradlePropertiesGenerator(fileWriter) 32 | 33 | @Test 34 | fun `generate should write properties into the file`() { 35 | val key1 = "randomKey1" 36 | val value1 = "randomValue1" 37 | 38 | val key2 = "randomKey2" 39 | val value2 = "randomValue2" 40 | generator.generate(getGradlePropertiesBlueprint( 41 | path = "path", 42 | properties = mapOf( 43 | key1 to value1, 44 | key2 to value2 45 | ) 46 | )) 47 | 48 | verify(fileWriter).writeToFile("$key1=$value1\n$key2=$value2", "path") 49 | } 50 | 51 | @Test 52 | fun `generate should not create a file if properties are absent`() { 53 | generator.generate(getGradlePropertiesBlueprint( 54 | properties = null 55 | )) 56 | 57 | verifyZeroInteractions(fileWriter) 58 | } 59 | 60 | private fun getGradlePropertiesBlueprint( 61 | path: String = "path", 62 | properties: Map? = mapOf() 63 | ): GradlePropertiesBlueprint { 64 | return mock().apply { 65 | whenever(this.path).thenReturn(path) 66 | whenever(this.properties).thenReturn(properties) 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/models/AndroidBuildBazelBlueprintTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.testutils.assertEquals 20 | import com.google.androidstudiopoet.testutils.assertOn 21 | import com.google.androidstudiopoet.utils.joinPath 22 | import org.junit.Test 23 | 24 | class AndroidBuildBazelBlueprintTest { 25 | 26 | @Test 27 | fun `libraries contain default set of libraries`() { 28 | val blueprint = createAndroidBuildBazelBlueprint() 29 | 30 | assertOn(blueprint) { 31 | libraries.assertEquals(setOf( 32 | GmavenBazelDependency("com.android.support:appcompat-v7:aar:28.0.0"), 33 | GmavenBazelDependency("com.android.support.constraint:constraint-layout:aar:1.1.3"), 34 | GmavenBazelDependency("com.android.support:multidex:aar:1.0.3"), 35 | GmavenBazelDependency("com.android.support.test:runner:aar:1.0.2"), 36 | GmavenBazelDependency("com.android.support.test.espresso:espresso-core:aar:3.0.2"))) 37 | } 38 | } 39 | 40 | @Test 41 | fun `path is module root joined with bazel build file`() { 42 | val blueprint = createAndroidBuildBazelBlueprint(moduleRoot = "moduleRoot") 43 | 44 | assertOn(blueprint) { 45 | path.assertEquals("moduleRoot".joinPath("BUILD.bazel")) 46 | } 47 | } 48 | 49 | private fun createAndroidBuildBazelBlueprint(isApplication: Boolean = false, 50 | moduleRoot: String = "", 51 | packageName: String = "com.example", 52 | dependencies: Set = setOf(), 53 | name: String = "targetName" 54 | ) = AndroidBuildBazelBlueprint(isApplication, moduleRoot, packageName, dependencies, name) 55 | 56 | } 57 | -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/models/BazelWorkspaceBlueprintTest.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | import com.google.androidstudiopoet.testutils.assertEquals 4 | import com.google.androidstudiopoet.utils.joinPath 5 | import org.junit.Test 6 | 7 | class BazelWorkspaceBlueprintTest { 8 | 9 | @Test 10 | fun `workspace path is at the root of the project`() { 11 | val blueprint = getBazelWorkspaceBlueprint("rootPath") 12 | blueprint.workspacePath.assertEquals("rootPath".joinPath("WORKSPACE")) 13 | } 14 | 15 | @Test 16 | fun `blueprint stores GMAVEN_TAG in YYYYMMDD-{snapshot num} form`() { 17 | val blueprint = getBazelWorkspaceBlueprint() 18 | assert(blueprint.gmavenRulesTag.contains(Regex("\\d{8}-\\d+"))) 19 | } 20 | 21 | private fun getBazelWorkspaceBlueprint(projectRoot: String = "foo") = BazelWorkspaceBlueprint(projectRoot) 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/models/DependencyTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.gson.Gson 20 | 21 | import org.intellij.lang.annotations.Language 22 | import org.junit.Assert.assertEquals 23 | import org.junit.Test 24 | 25 | class DependencyTest { 26 | @Test 27 | fun `Dependency deserialized correctly`() { 28 | @Language("JSON") val dependencyString = "{\n \"from\": \"module2\",\n \"to\": \"module1\",\n \"method\": \"api\"\n}" 29 | val dependency = Gson().fromJson(dependencyString, FromToDependencyConfig::class.java) 30 | assertEquals("module2", dependency.from) 31 | assertEquals("module1", dependency.to) 32 | assertEquals("api", dependency.method) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/models/GradlePropertiesBlueprintTest.kt: -------------------------------------------------------------------------------- 1 | package com.google.androidstudiopoet.models 2 | 3 | import com.google.androidstudiopoet.testutils.assertEquals 4 | import com.google.androidstudiopoet.utils.joinPath 5 | 6 | import org.junit.Test 7 | 8 | class GradlePropertiesBlueprintTest { 9 | 10 | @Test 11 | fun `properties contains default settings when no overrideProperties is passed`() { 12 | GradlePropertiesBlueprint("root", null).properties!! 13 | .assertEquals(mapOf( 14 | "org.gradle.jvmargs" to "-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError", 15 | "org.gradle.daemon" to "true", 16 | "org.gradle.parallel" to "true", 17 | "org.gradle.caching" to "true", 18 | "android.useAndroidX" to "true" 19 | )) 20 | 21 | } 22 | 23 | @Test 24 | fun `properties contains default values when not overriden`() { 25 | GradlePropertiesBlueprint("root", mapOf( 26 | "org.gradle.daemon" to "false", 27 | "randomKey" to "randomValue" 28 | )).properties!! 29 | .assertEquals(mapOf( 30 | "org.gradle.jvmargs" to "-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError", 31 | "org.gradle.daemon" to "false", 32 | "org.gradle.parallel" to "true", 33 | "org.gradle.caching" to "true", 34 | "android.useAndroidX" to "true", 35 | "randomKey" to "randomValue" 36 | )) 37 | } 38 | 39 | @Test 40 | fun `path is root with gradle properties`() { 41 | GradlePropertiesBlueprint("root", null).path 42 | .assertEquals("root".joinPath("gradle.properties")) 43 | } 44 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/models/ModuleBuildBazelBlueprintTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.models 18 | 19 | import com.google.androidstudiopoet.testutils.assertEquals 20 | import com.google.androidstudiopoet.testutils.assertOn 21 | import com.google.androidstudiopoet.utils.joinPath 22 | import org.junit.Test 23 | 24 | class ModuleBuildBazelBlueprintTest { 25 | 26 | @Test 27 | fun `path is module root joined with bazel build file`() { 28 | val blueprint = createModuleBuildBazelBlueprint(moduleRoot = "moduleRoot") 29 | 30 | assertOn(blueprint) { 31 | path.assertEquals("moduleRoot".joinPath("BUILD.bazel")) 32 | } 33 | } 34 | 35 | private fun createModuleBuildBazelBlueprint(dependencies: Set = setOf(), 36 | moduleRoot: String = "", 37 | name: String = "target_name" 38 | ) = ModuleBuildBazelBlueprint(dependencies, moduleRoot, name) 39 | 40 | } 41 | -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/testutils/assert.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.testutils 18 | 19 | import org.junit.Assert.assertEquals 20 | import org.junit.Assert.assertTrue 21 | import org.junit.Assert.assertFalse 22 | import java.awt.image.BufferedImage 23 | 24 | fun Collection.assertEmpty() { 25 | assertTrue(this.isEmpty()) 26 | } 27 | 28 | fun Collection.assertSize(expectedSize: Int) { 29 | assertEquals(expectedSize, size) 30 | } 31 | 32 | fun Collection.assertContains(item: T) { 33 | assertTrue(this.contains(item)) 34 | } 35 | 36 | fun Collection.assertNotContains(item: T) { 37 | assertFalse(this.contains(item)) 38 | } 39 | 40 | fun Any.assertEquals(expected: Any) { 41 | assertEquals(expected, this) 42 | } 43 | 44 | inline fun assertOn(receiver: T, block: T.() -> R): R = receiver.block() 45 | 46 | fun Boolean.assertTrue() { 47 | assertTrue(this) 48 | } 49 | 50 | fun Boolean.assertFalse() { 51 | assertFalse(this) 52 | } 53 | 54 | fun Any?.assertNull() { 55 | assertEquals(null, this) 56 | } 57 | 58 | fun BufferedImage.assertEqualImage(bufferedImage: BufferedImage) { 59 | this.height.assertEquals(bufferedImage.height) 60 | this.width.assertEquals(bufferedImage.width) 61 | for (y in 0..(this.height - 1)) { 62 | for (x in 0..(this.width - 1)){ 63 | this.getRGB(x, y).assertEquals(bufferedImage.getRGB(x, y)) 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /aspoet/src/test/kotlin/com/google/androidstudiopoet/testutils/mock.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 Google Inc. 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 | https://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 | package com.google.androidstudiopoet.testutils 18 | 19 | import org.mockito.Mockito 20 | 21 | inline fun mock() = Mockito.mock(T::class.java) 22 | -------------------------------------------------------------------------------- /aspoet/src/test/resources/com/google/androidstudiopoet/generators/dependencyGraphTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android/android-studio-poet/f820e9cc0e5d7db4de9a7e31b818277143546f73/aspoet/src/test/resources/com/google/androidstudiopoet/generators/dependencyGraphTest.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.google.androidstudio.poet' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.5.31' 6 | 7 | repositories { 8 | mavenCentral() 9 | gradlePluginPortal() 10 | } 11 | 12 | dependencies { 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}" 14 | } 15 | } 16 | 17 | apply plugin: 'kotlin' 18 | 19 | dependencies { 20 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" 21 | implementation 'com.google.code.gson:gson:2.8.8' 22 | implementation 'com.squareup:javapoet:1.13.0' 23 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2' 24 | implementation 'junit:junit:4.13.2' 25 | implementation 'commons-io:commons-io:2.6' 26 | implementation project(':aspoet-input') 27 | } 28 | 29 | sourceSets { 30 | main { 31 | resources { 32 | srcDirs = ['src/main/assets', 'src/main/assets/gradle.wrapper'] 33 | } 34 | } 35 | } 36 | 37 | repositories { 38 | mavenCentral() 39 | } 40 | -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-3-1_AGP3-0-1_Kotlin1-1-60.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-3-1_AGP3-0-1_Kotlin1-1-60", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1", 8 | "agpVersion": "3.0.1", 9 | "kotlinVersion": "1.1.60" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-5_AGP3-0-1_Kotlin1-2-20.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-5_AGP3-0-1_Kotlin1-2-20", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.5", 8 | "agpVersion": "3.0.1", 9 | "kotlinVersion": "1.2.20" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-6_AGP3-1-0_Kotlin1-2-30.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-6_AGP3-1-0_Kotlin1-2-30", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.6", 8 | "agpVersion": "3.1.0", 9 | "kotlinVersion": "1.2.30" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-6_AGP3-1-0_Kotlin1-2-41.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-6_AGP3-1-0_Kotlin1-2-41", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.6", 8 | "agpVersion": "3.1.0", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-6_AGP3-1-2_Kotlin1-2-41.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-6_AGP3-1-2_Kotlin1-2-41", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.6", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-7_AGP3-1-2_Kotlin1-2-41.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-7_AGP3-1-2_Kotlin1-2-41", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.7", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/ConfigFull_G4-8_AGP3-1-2_Kotlin1-2-41.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_G4-8_AGP3-1-2_Kotlin1-2-41", 5 | "root": "../generated_projects/build-tools-versions", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 250, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 250, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 10, 49 | "classesPerPackage": 250, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 10, 54 | "classesPerPackage": 250, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/build-tool-versions/gradle-profiler-commands.txt: -------------------------------------------------------------------------------- 1 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios clean_build 2 | 3 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios inc_build 4 | -------------------------------------------------------------------------------- /configs/build-tool-versions/gradle-profiler.scenarios: -------------------------------------------------------------------------------- 1 | clean_build { 2 | tasks = ["assembleDebug"] 3 | cleanup-tasks = ["clean", "cleanBuildCache"] 4 | warm-ups = 6 5 | } 6 | 7 | inc_build { 8 | tasks = ["assembleDebug"] 9 | 10 | apply-abi-change-to = "libraryModule/src/main/java/libraryModulepackageJava0/Foo0.java" 11 | apply-non-abi-change-to = "libraryModule/src/main/java/libraryModulepackageJava0/Foo0.java" 12 | apply-kotlin-change-to = "libraryModule/src/main/java/libraryModulepackageKt3/Foo2.kt" 13 | 14 | warm-ups = 6 15 | } 16 | -------------------------------------------------------------------------------- /configs/build-tool-versions/result.md: -------------------------------------------------------------------------------- 1 | 2 | ## Comparison between different build tools versions 3 | 4 | Date - 7th July 2018 5 | 6 | ### Setup 7 | 8 | Profiling is done with gradle-profiler. Profiling scenarios could be found [here](https://github.com/android/android-studio-poet/blob/master/configs/build-tool-versions/gradle-profiler.scenarios). 9 | Commands that were used to profile can be found [here](https://github.com/android/android-studio-poet/blob/master/configs/build-tool-versions/gradle-profiler-commands.txt). 10 | 11 | Please note, that gradle-profiler was modified to support incremental Kotlin profiling. 12 | 13 | ### Variants 14 | All variants have 2 modules with 2500 Kotlin classes and 2500 Java classes 10 methods each. All variant has 15 | `minSdkVersion=21`. 16 | The only difference is version of Gradle(G), Android Gradle Plugin(AGP), Kotlin(K). 17 | The following combinations were profiled: 18 | * G:4.3.1, AGP 3.0.1, Kotlin 1.1.60 19 | * G:4.5, AGP 3.0.1, Kotlin 1.2.20 20 | * G:4.6, AGP 3.1.0, Kotlin 1.2.30 21 | * G:4.6, AGP 3.1.0, Kotlin 1.2.41 22 | * G:4.6, AGP 3.1.2, Kotlin 1.2.41 23 | * G:4.7, AGP 3.1.2, Kotlin 1.2.41 24 | * G:4.8, AGP 3.1.2, Kotlin 1.2.41 25 | 26 | ### Summary of the results 27 | 28 | | | Clean build | Incremental build | 29 | |-------------|-------------| ----------------- | 30 | |G:4.3.1 AGP 3.0.1 Kotlin 1.1.60 | 1m 57s [buildscan](https://scans.gradle.com/s/bvdlmqauv4vfi) | 1m 22s [buildscan](https://scans.gradle.com/s/tsesvbvtmhqzi) | 31 | |G:4.5, AGP 3.0.1, Kotlin 1.2.20 | 1m 17s [buildscan](https://scans.gradle.com/s/ek2vtboirtgpc) | 1m 19s [buildscan](https://scans.gradle.com/s/pghes2tsukg7s) | 32 | |G:4.6, AGP 3.1.0, Kotlin 1.2.30 | 1m 31s [buildscan](https://scans.gradle.com/s/momm25atli64q) | 1m 1s [buildscan](https://scans.gradle.com/s/uxmkl46swvefu) | 33 | |G:4.6, AGP 3.1.0, Kotlin 1.2.41 | 1m 31s [buildscan](https://scans.gradle.com/s/unrlpbrwzaa3g) | 53s [buildscan](https://scans.gradle.com/s/f2lxmcbwglth4) | 34 | |G:4.6, AGP 3.1.2, Kotlin 1.2.41 | 1m 7s [buildscan](https://scans.gradle.com/s/h4gqgwb4al4mu)| 56s [buildscan](https://scans.gradle.com/s/a2ufhihk2mmpi) | 35 | |G:4.7, AGP 3.1.2, Kotlin 1.2.41 | 1m 10s [buildscan](https://scans.gradle.com/s/ulf32prjxbkny)| 55s [buildscan](https://scans.gradle.com/s/zvbhbskzpd6be) | 36 | |G:4.8, AGP 3.1.2, Kotlin 1.2.41 | 1m 12s [buildscan](https://scans.gradle.com/s/2jbjvjhapt7pa)| 1m 11s [buildscan](https://scans.gradle.com/s/nmrtqbgq3yya6) | 37 | 38 | Notes: 39 | * Time for incremental build is constantly decrease for all the versions, but Gradle 4.8. 40 | * Clean build for AGP 3.1.2 is significantly faster then AGP 3.1.0. -------------------------------------------------------------------------------- /configs/compose/gradle-profiler.scenarios: -------------------------------------------------------------------------------- 1 | clean_build { 2 | tasks = ["assembleDebug"] 3 | cleanup-tasks = ["clean"] 4 | gradle-args = ["--no-build-cache"] 5 | } 6 | 7 | ui_inc_build { 8 | tasks = ["assembleDebug"] 9 | apply-android-layout-change-to = "libraryModule/src/main/res/layout/librarymoduleactivity_main4.xml" 10 | clear-build-cache-before = SCENARIO 11 | } 12 | 13 | compose_inc_build { 14 | tasks = ["assembleDebug"] 15 | apply-kotlin-composable-change-to = "libraryModule/src/main/java/com/libraryModule/Activity4.kt" 16 | clear-build-cache-before = SCENARIO 17 | } 18 | -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_JavaWithLambdas.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaWithLambdas", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 19, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": "10", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "10", 23 | "complexity": { 24 | "lambdaCount": 1 25 | } 26 | }, 27 | "moduleName": "applicationModule", 28 | "activityCount": 5, 29 | "hasLaunchActivity": true, 30 | "resourcesConfig": { 31 | "stringCount": 5, 32 | "imageCount": 5, 33 | "layoutCount": 5 34 | } 35 | } 36 | ] 37 | } 38 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_JavaWithLambdasApi21.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaWithLambdasApi21", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": "10", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "10", 23 | "complexity": { 24 | "lambdaCount": 1 25 | } 26 | }, 27 | "moduleName": "applicationModule", 28 | "activityCount": 5, 29 | "hasLaunchActivity": true, 30 | "resourcesConfig": { 31 | "stringCount": 5, 32 | "imageCount": 5, 33 | "layoutCount": 5 34 | } 35 | } 36 | ] 37 | } 38 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_JavaWithoutLambdas.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaWithoutLambdas", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 19, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": "20", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "6" 23 | }, 24 | "moduleName": "applicationModule", 25 | "activityCount": 5, 26 | "hasLaunchActivity": true, 27 | "resourcesConfig": { 28 | "stringCount": 5, 29 | "imageCount": 5, 30 | "layoutCount": 5 31 | } 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_JavaWithoutLambdasApi21.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaWithoutLambdasApi21", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": "20", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "6" 23 | }, 24 | "moduleName": "applicationModule", 25 | "activityCount": 5, 26 | "hasLaunchActivity": true, 27 | "resourcesConfig": { 28 | "stringCount": 5, 29 | "imageCount": 5, 30 | "layoutCount": 5 31 | } 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_JavaWithoutLambdasApi21_ReducedClassCount.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaWithoutLambdasApi21_ReducedClassCount", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": "10", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "10" 23 | }, 24 | "moduleName": "applicationModule", 25 | "activityCount": 5, 26 | "hasLaunchActivity": true, 27 | "resourcesConfig": { 28 | "stringCount": 5, 29 | "imageCount": 5, 30 | "layoutCount": 5 31 | } 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_JavaWithoutLambdas_ReducedClassCount.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaWithoutLambdas_ReducedClassCount", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 19, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": "10", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "10" 23 | }, 24 | "moduleName": "applicationModule", 25 | "activityCount": 5, 26 | "hasLaunchActivity": true, 27 | "resourcesConfig": { 28 | "stringCount": 5, 29 | "imageCount": 5, 30 | "layoutCount": 5 31 | } 32 | } 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_KotlinWithLambdas.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_KotlinWithLambdas", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 19, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "kotlin": { 20 | "packages": "10", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "10", 23 | "complexity": { 24 | "lambdaCount": 1 25 | } 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | } 36 | } 37 | ] 38 | } 39 | } -------------------------------------------------------------------------------- /configs/desugaring/ConfigFull_KotlinWithLambdasApi21.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_KotlinWithLambdasApi21", 5 | "root": "../generated_projects/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "kotlin": { 20 | "packages": "10", 21 | "classesPerPackage": "1000", 22 | "methodsPerClass": "10", 23 | "complexity": { 24 | "lambdaCount": 1 25 | } 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | } 36 | } 37 | ] 38 | } 39 | } -------------------------------------------------------------------------------- /configs/desugaring/desugaring-research-v1: -------------------------------------------------------------------------------- 1 | "Java vs Java with Lambdas vs Kotlin with Lambdas" 2 | 3 | In total there were six configurations: 4 | - Java with 20k classes with 6 methods each and `minSdkVersion=19` 5 | - Java with 20k classes with 6 methods each and `minSdkVersion=21` 6 | - Java with 10k classes with 10 methods and 1 lambda each and `minSdkVersion=19` 7 | - Java with 10k classes with 10 methods and 1 lambda each and `minSdkVersion=21` 8 | - Kotlin with 10k classes with 10 methods and 1 lambda each and `minSdkVersion=19` 9 | - Kotlin with 10k classes with 10 methods and 1 lambda each and `minSdkVersion=21` -------------------------------------------------------------------------------- /configs/desugaring/gradle-profiler-commands.txt: -------------------------------------------------------------------------------- 1 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios clean_build 2 | 3 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios java_inc_build 4 | 5 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios kotlin_inc_build 6 | -------------------------------------------------------------------------------- /configs/desugaring/gradle-profiler.scenarios: -------------------------------------------------------------------------------- 1 | clean_build { 2 | tasks = ["assembleDebug"] 3 | cleanup-tasks = ["clean", "cleanBuildCache"] 4 | warm-ups = 6 5 | } 6 | 7 | java_inc_build { 8 | tasks = ["assembleDebug"] 9 | 10 | apply-abi-change-to = "applicationModule/src/main/java/applicationModulepackageJava0/Foo0.java" 11 | apply-non-abi-change-to = "applicationModule/src/main/java/applicationModulepackageJava0/Foo0.java" 12 | 13 | warm-ups = 6 14 | } 15 | 16 | kotlin_inc_build { 17 | tasks = ["assembleDebug"] 18 | 19 | apply-kotlin-change-to = "applicationModule/src/main/java/applicationModulepackageKt3/Foo2.kt" 20 | 21 | warm-ups = 6 22 | } 23 | -------------------------------------------------------------------------------- /configs/examples/plugins/ConfigWithAppliedButterknifePlugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_WithAppliedButterknifePlugin", 5 | "root": "./modules/", 6 | "classpathDependencies": [ 7 | "com.jakewharton:butterknife-gradle-plugin:9.0.0-SNAPSHOT" 8 | ], 9 | "moduleConfigs": [ 10 | { 11 | "moduleType": "android", 12 | "java": { 13 | "packages": 10, 14 | "classesPerPackage": 10, 15 | "methodsPerClass": 10 16 | }, 17 | "kotlin": { 18 | "packages": 10, 19 | "classesPerPackage": 10, 20 | "methodsPerClass": 10 21 | }, 22 | "useKotlin": true, 23 | "moduleName": "applicationModule", 24 | "activityCount": 5, 25 | "resourcesConfig": { 26 | "layoutCount": 5, 27 | "imageCount": 5, 28 | "stringCount": 5 29 | }, 30 | "hasLaunchActivity": true, 31 | "plugins": [ 32 | { 33 | "id": "kotlin-kapt" 34 | }, 35 | { 36 | "id": "com.jakewharton.butterknife" 37 | } 38 | ], 39 | "dependencies": [ 40 | { 41 | "library": "com.jakewharton:butterknife:9.0.0-SNAPSHOT", 42 | "method": "implementation" 43 | }, 44 | { 45 | "library": "com.jakewharton:butterknife-compiler:9.0.0-SNAPSHOT", 46 | "method": "kapt" 47 | } 48 | ] 49 | } 50 | ], 51 | "repositories": [ 52 | { 53 | "url": "https://oss.sonatype.org/content/repositories/snapshots" 54 | } 55 | ] 56 | } 57 | } -------------------------------------------------------------------------------- /configs/examples/plugins/ConfigWithAppliedFabricPlugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_WithAppliedFabricPlugin", 5 | "root": "./modules/", 6 | "classpathDependencies": [ 7 | "io.fabric.tools:gradle:1.24.1" 8 | ], 9 | "moduleConfigs": [ 10 | { 11 | "moduleType": "android", 12 | "kotlin": { 13 | "packages": 10, 14 | "classesPerPackage": 10, 15 | "methodsPerClass": 10 16 | }, 17 | "useKotlin": true, 18 | "moduleName": "applicationModule", 19 | "activityCount": 5, 20 | "resourcesConfig": { 21 | "layoutCount": 5 22 | }, 23 | "hasLaunchActivity": true, 24 | "plugins": [ 25 | { 26 | "id": "io.fabric" 27 | } 28 | ] 29 | } 30 | ], 31 | "repositories": [ 32 | { 33 | "url": "https://maven.fabric.io/public" 34 | } 35 | ] 36 | } 37 | } -------------------------------------------------------------------------------- /configs/kapt/v1/ConfigFull_KaptProblem_JavaKotlin_DataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaKotlin_DataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1" 8 | }, 9 | "moduleConfigs": [ 10 | { 11 | "moduleType": "android", 12 | "androidBuildConfig": { 13 | "minSdkVersion": 20, 14 | "targetSdkVersion": 27, 15 | "compileSdkVersion": 27 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 100, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 100, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dataBindingConfig": { 37 | "listenerCount": 10 38 | }, 39 | "dependencies": [ 40 | { 41 | "moduleName": "libraryModule" 42 | }, 43 | { 44 | "library": "org.mockito:mockito-inline:2.15.0", 45 | "method": "testCompile" 46 | } 47 | ] 48 | }, 49 | { 50 | "moduleType": "android", 51 | "javaPackageCount": 10, 52 | "javaClassCount": 100, 53 | "javaMethodsPerClass": 10, 54 | "kotlinPackageCount": 10, 55 | "kotlinClassCount": 100, 56 | "kotlinMethodsPerClass": 10, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | }, 65 | "dataBindingConfig": { 66 | "listenerCount": 10 67 | }, 68 | "flavors": [ 69 | { 70 | "name": "red", 71 | "dimension": "color", 72 | "count": 2 73 | } 74 | ] 75 | } 76 | ] 77 | } 78 | } -------------------------------------------------------------------------------- /configs/kapt/v1/ConfigFull_KaptProblem_JavaKotlin_NoDataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_Kotlin_NoDataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1" 8 | }, 9 | "moduleConfigs": [ 10 | { 11 | "moduleType": "android", 12 | "androidBuildConfig": { 13 | "minSdkVersion": 20, 14 | "targetSdkVersion": 27, 15 | "compileSdkVersion": 27 16 | }, 17 | "java": { 18 | "packages": 10, 19 | "classesPerPackage": 100, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 10, 24 | "classesPerPackage": 100, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | }, 40 | { 41 | "library": "org.mockito:mockito-inline:2.15.0", 42 | "method": "testCompile" 43 | } 44 | ] 45 | }, 46 | { 47 | "moduleType": "android", 48 | "javaPackageCount": 10, 49 | "javaClassCount": 100, 50 | "javaMethodsPerClass": 10, 51 | "kotlinPackageCount": 10, 52 | "kotlinClassCount": 100, 53 | "kotlinMethodsPerClass": 10, 54 | "useKotlin": true, 55 | "moduleName": "libraryModule", 56 | "activityCount": 5, 57 | "resourcesConfig": { 58 | "stringCount": 5, 59 | "imageCount": 5, 60 | "layoutCount": 5 61 | }, 62 | "flavors": [ 63 | { 64 | "name": "red", 65 | "dimension": "color", 66 | "count": 2 67 | } 68 | ] 69 | } 70 | ] 71 | } 72 | } -------------------------------------------------------------------------------- /configs/kapt/v1/ConfigFull_KaptProblem_JavaOnly_DataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaOnly_DataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1" 8 | }, 9 | "moduleConfigs": [ 10 | { 11 | "moduleType": "android", 12 | "androidBuildConfig": { 13 | "minSdkVersion": 20, 14 | "targetSdkVersion": 27, 15 | "compileSdkVersion": 27 16 | }, 17 | "java": { 18 | "packages": 20, 19 | "classesPerPackage": 100, 20 | "methodsPerClass": 10 21 | }, 22 | "moduleName": "applicationModule", 23 | "activityCount": 5, 24 | "hasLaunchActivity": true, 25 | "resourcesConfig": { 26 | "stringCount": 5, 27 | "imageCount": 5, 28 | "layoutCount": 5 29 | }, 30 | "dataBindingConfig": { 31 | "listenerCount": 10 32 | }, 33 | "dependencies": [ 34 | { 35 | "moduleName": "libraryModule" 36 | }, 37 | { 38 | "library": "org.mockito:mockito-inline:2.15.0", 39 | "method": "testCompile" 40 | } 41 | ] 42 | }, 43 | { 44 | "moduleType": "android", 45 | "java": { 46 | "packages": 20, 47 | "classesPerPackage": 100, 48 | "methodsPerClass": 10 49 | }, 50 | "moduleName": "libraryModule", 51 | "activityCount": 5, 52 | "resourcesConfig": { 53 | "stringCount": 5, 54 | "imageCount": 5, 55 | "layoutCount": 5 56 | }, 57 | "dataBindingConfig": { 58 | "listenerCount": 10 59 | }, 60 | "flavors": [ 61 | { 62 | "name": "red", 63 | "dimension": "color", 64 | "count": 2 65 | } 66 | ] 67 | } 68 | ] 69 | } 70 | } -------------------------------------------------------------------------------- /configs/kapt/v1/ConfigFull_KaptProblem_JavaOnly_NoDataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaOnly_NoDataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1" 8 | }, 9 | "moduleConfigs": [{ 10 | "moduleType": "android", 11 | "androidBuildConfig": { 12 | "minSdkVersion" : 20, 13 | "targetSdkVersion": 27, 14 | "compileSdkVersion" : 27 15 | }, 16 | "java": { 17 | "packages": 20, 18 | "classesPerPackage": 100, 19 | "methodsPerClass": 10 20 | }, 21 | "moduleName": "applicationModule", 22 | "activityCount": 5, 23 | "hasLaunchActivity": true, 24 | "resourcesConfig": { 25 | "stringCount": 5, 26 | "imageCount": 5, 27 | "layoutCount": 5 28 | }, 29 | "dependencies": [ 30 | { 31 | "moduleName": "libraryModule" 32 | }, 33 | { 34 | "library": "org.mockito:mockito-inline:2.15.0", 35 | "method": "testCompile" 36 | } 37 | ] 38 | }, 39 | { 40 | "moduleType": "android", 41 | "java": { 42 | "packages": 20, 43 | "classesPerPackage": 100, 44 | "methodsPerClass": 10 45 | }, 46 | "moduleName": "libraryModule", 47 | "activityCount": 5, 48 | "resourcesConfig": { 49 | "stringCount": 5, 50 | "imageCount": 5, 51 | "layoutCount": 5 52 | }, 53 | "flavors": [ 54 | { 55 | "name": "red", 56 | "dimension": "color", 57 | "count": 2 58 | } 59 | ] 60 | } 61 | ] 62 | } 63 | } -------------------------------------------------------------------------------- /configs/kapt/v1/ConfigFull_KaptProblem_KotlinOnly_DataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_KotlinOnly_DataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1" 8 | }, 9 | "moduleConfigs": [ 10 | { 11 | "moduleType": "android", 12 | "androidBuildConfig": { 13 | "minSdkVersion": 20, 14 | "targetSdkVersion": 27, 15 | "compileSdkVersion": 27 16 | }, 17 | "kotlin": { 18 | "packages": 20, 19 | "classesPerPackage": 100, 20 | "methodsPerClass": 10 21 | }, 22 | "useKotlin": true, 23 | "moduleName": "applicationModule", 24 | "activityCount": 5, 25 | "hasLaunchActivity": true, 26 | "resourcesConfig": { 27 | "stringCount": 5, 28 | "imageCount": 5, 29 | "layoutCount": 5 30 | }, 31 | "dataBindingConfig": { 32 | "listenerCount": 10 33 | }, 34 | "dependencies": [ 35 | { 36 | "moduleName": "libraryModule" 37 | }, 38 | { 39 | "library": "org.mockito:mockito-inline:2.15.0", 40 | "method": "testCompile" 41 | } 42 | ] 43 | }, 44 | { 45 | "moduleType": "android", 46 | "kotlin": { 47 | "packages": 20, 48 | "classesPerPackage": 100, 49 | "methodsPerClass": 10 50 | }, 51 | "useKotlin": true, 52 | "moduleName": "libraryModule", 53 | "activityCount": 5, 54 | "resourcesConfig": { 55 | "stringCount": 5, 56 | "imageCount": 5, 57 | "layoutCount": 5 58 | }, 59 | "dataBindingConfig": { 60 | "listenerCount": 10 61 | }, 62 | "flavors": [ 63 | { 64 | "name": "red", 65 | "dimension": "color", 66 | "count": 2 67 | } 68 | ] 69 | } 70 | ] 71 | } 72 | } -------------------------------------------------------------------------------- /configs/kapt/v1/ConfigFull_KaptProblem_KotlinOnly_NoDataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_KotlinOnly_NoDataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.3.1" 8 | }, 9 | "moduleConfigs": [{ 10 | "moduleType": "android", 11 | "androidBuildConfig": { 12 | "minSdkVersion" : 20, 13 | "targetSdkVersion": 27, 14 | "compileSdkVersion" : 27 15 | }, 16 | "kotlin": { 17 | "packages": 20, 18 | "classesPerPackage": 100, 19 | "methodsPerClass": 10 20 | }, 21 | "useKotlin": true, 22 | "moduleName": "applicationModule", 23 | "activityCount": 5, 24 | "hasLaunchActivity": true, 25 | "resourcesConfig": { 26 | "stringCount": 5, 27 | "imageCount": 5, 28 | "layoutCount": 5 29 | }, 30 | "dependencies": [ 31 | { 32 | "moduleName": "libraryModule" 33 | }, 34 | { 35 | "library": "org.mockito:mockito-inline:2.15.0", 36 | "method": "testCompile" 37 | } 38 | ] 39 | }, 40 | { 41 | "moduleType": "android", 42 | "kotlin": { 43 | "packages": 20, 44 | "classesPerPackage": 100, 45 | "methodsPerClass": 10 46 | }, 47 | "useKotlin": true, 48 | "moduleName": "libraryModule", 49 | "activityCount": 5, 50 | "resourcesConfig": { 51 | "stringCount": 5, 52 | "imageCount": 5, 53 | "layoutCount": 5 54 | }, 55 | "flavors": [ 56 | { 57 | "name": "red", 58 | "dimension": "color", 59 | "count": 2 60 | } 61 | ] 62 | } 63 | ] 64 | } 65 | } -------------------------------------------------------------------------------- /configs/kapt/v1/kapt-research-v1.md: -------------------------------------------------------------------------------- 1 | How kapt affects the performance 2 | Legend: 3 | KotlinOnly - no java code 4 | JavaOnly - no kotlin code 5 | JavaKotlin - mix java and kotlin code 6 | DataBinding - data binding enabled 7 | NoDataBinding - data binding disabled 8 | 9 | JavaKotlin_DataBinding: 10 | * Full: https://scans.gradle.com/s/a4gqljyjxzvqm (6m) 11 | * Incremental: https://scans.gradle.com/s/a4gqljyjxzvqm (4m 18s) 12 | 13 | JavaKotlin_NoDataBinding: 14 | * Full: https://scans.gradle.com/s/kdzpjmiky5yze (3m 21s) 15 | * Incremental: https://gradle.com/s/5dl6qskwekapy (3m 9ss) 16 | 17 | JavaOnly_DataBinding: 18 | * Full: https://scans.gradle.com/s/5evcrapewcyqm (7m 58s) 19 | * Incremental: https://scans.gradle.com/s/2q4uqgikwyfzq (5m 56s) 20 | 21 | JavaOnly_NoDataBinding: 22 | * Full: https://scans.gradle.com/s/7hcmjgrqcir7a (7m 17s) 23 | * Incremental: https://scans.gradle.com/s/imcnynoavdgay (3m 51s) 24 | 25 | KotlinOnly_DataBinding: 26 | * Full: https://scans.gradle.com/s/iwseu3574d3ga (4m 40s) 27 | * Incremental: https://scans.gradle.com/s/d72wi7k6p6tci (3m 59s) 28 | 29 | KotlinOnly_NoDataBinding: 30 | * Full: https://scans.gradle.com/s/jbjjqpgsuv5ei (1m 51s) 31 | * Incremental: https://scans.gradle.com/s/lm4sivh5n5lbu (43s) 32 | 33 | 34 | Hypothesyses: 35 | 1. Kapt slows down the build significantly (KotlinOnly_DataBinding vs KotlinOnly_NoDataBinding) 36 | 2. Annotaion Processing for Java slows down the build but less then kapt. (NoKotlin_DataBinding vs NoKotlin_NoDataBinding) 37 | 3. Generated Java code is more complex to process then Kotlin, probably because of lambdas. This conclusion is made because desugaring task takes very long to complete. 38 | -------------------------------------------------------------------------------- /configs/kapt/v2/ConfigFull_KaptProblem_JavaKotlin_DataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaKotlin_DataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.7", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 20, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "java": { 20 | "packages": 10, 21 | "classesPerPackage": 100, 22 | "methodsPerClass": 10 23 | }, 24 | "kotlin": { 25 | "packages": 10, 26 | "classesPerPackage": 100, 27 | "methodsPerClass": 10 28 | }, 29 | "useKotlin": true, 30 | "moduleName": "applicationModule", 31 | "activityCount": 5, 32 | "hasLaunchActivity": true, 33 | "resourcesConfig": { 34 | "stringCount": 5, 35 | "imageCount": 5, 36 | "layoutCount": 5 37 | }, 38 | "dataBindingConfig": { 39 | "listenerCount": 10 40 | }, 41 | "dependencies": [ 42 | { 43 | "moduleName": "libraryModule" 44 | }, 45 | { 46 | "library": "org.mockito:mockito-inline:2.15.0", 47 | "method": "testCompile" 48 | } 49 | ] 50 | }, 51 | { 52 | "moduleType": "android", 53 | "java": { 54 | "packages": 10, 55 | "classesPerPackage": 100, 56 | "methodsPerClass": 10 57 | }, 58 | "kotlin": { 59 | "packages": 10, 60 | "classesPerPackage": 100, 61 | "methodsPerClass": 10 62 | }, 63 | "useKotlin": true, 64 | "moduleName": "libraryModule", 65 | "activityCount": 5, 66 | "resourcesConfig": { 67 | "stringCount": 5, 68 | "imageCount": 5, 69 | "layoutCount": 5 70 | }, 71 | "dataBindingConfig": { 72 | "listenerCount": 10 73 | }, 74 | "flavors": [ 75 | { 76 | "name": "red", 77 | "dimension": "color", 78 | "count": 2 79 | } 80 | ] 81 | } 82 | ] 83 | } 84 | } -------------------------------------------------------------------------------- /configs/kapt/v2/ConfigFull_KaptProblem_JavaOnly_DataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_JavaOnly_DataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.7", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 20, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "kotlin": { 20 | "packages": 20, 21 | "classesPerPackage": 100, 22 | "methodsPerClass": 10 23 | }, 24 | "moduleName": "applicationModule", 25 | "activityCount": 5, 26 | "hasLaunchActivity": true, 27 | "resourcesConfig": { 28 | "stringCount": 5, 29 | "imageCount": 5, 30 | "layoutCount": 5 31 | }, 32 | "dataBindingConfig": { 33 | "listenerCount": 10 34 | }, 35 | "dependencies": [ 36 | { 37 | "moduleName": "libraryModule" 38 | }, 39 | { 40 | "library": "org.mockito:mockito-inline:2.15.0", 41 | "method": "testCompile" 42 | } 43 | ] 44 | }, 45 | { 46 | "moduleType": "android", 47 | "kotlin": { 48 | "packages": 20, 49 | "classesPerPackage": 100, 50 | "methodsPerClass": 10 51 | }, 52 | "moduleName": "libraryModule", 53 | "activityCount": 5, 54 | "resourcesConfig": { 55 | "stringCount": 5, 56 | "imageCount": 5, 57 | "layoutCount": 5 58 | }, 59 | "dataBindingConfig": { 60 | "listenerCount": 10 61 | }, 62 | "flavors": [ 63 | { 64 | "name": "red", 65 | "dimension": "color", 66 | "count": 2 67 | } 68 | ] 69 | } 70 | ] 71 | } 72 | } -------------------------------------------------------------------------------- /configs/kapt/v2/ConfigFull_KaptProblem_KotlinOnly_DataBinding.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_KotlinOnly_DataBinding", 5 | "root": "./modules/", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.7", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 20, 16 | "targetSdkVersion": 27, 17 | "compileSdkVersion": 27 18 | }, 19 | "kotlin": { 20 | "packages": 20, 21 | "classesPerPackage": 100, 22 | "methodsPerClass": 10 23 | }, 24 | "useKotlin": true, 25 | "moduleName": "applicationModule", 26 | "activityCount": 5, 27 | "hasLaunchActivity": true, 28 | "resourcesConfig": { 29 | "stringCount": 5, 30 | "imageCount": 5, 31 | "layoutCount": 5 32 | }, 33 | "dataBindingConfig": { 34 | "listenerCount": 10 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | }, 40 | { 41 | "library": "org.mockito:mockito-inline:2.15.0", 42 | "method": "testCompile" 43 | } 44 | ] 45 | }, 46 | { 47 | "moduleType": "android", 48 | "kotlin": { 49 | "packages": 20, 50 | "classesPerPackage": 100, 51 | "methodsPerClass": 10 52 | }, 53 | "useKotlin": true, 54 | "moduleName": "libraryModule", 55 | "activityCount": 5, 56 | "resourcesConfig": { 57 | "stringCount": 5, 58 | "imageCount": 5, 59 | "layoutCount": 5 60 | }, 61 | "dataBindingConfig": { 62 | "listenerCount": 10 63 | }, 64 | "flavors": [ 65 | { 66 | "name": "red", 67 | "dimension": "color", 68 | "count": 2 69 | } 70 | ] 71 | } 72 | ] 73 | } 74 | } -------------------------------------------------------------------------------- /configs/kapt/v2/gradle-profiler.scenarios: -------------------------------------------------------------------------------- 1 | clean_build { 2 | tasks = ["assembleDebug"] 3 | cleanup-tasks = ["clean", "cleanBuildCache"] 4 | } 5 | 6 | incremental_build { 7 | tasks = ["assembleDebug"] 8 | 9 | apply-abi-change-to = "applicationModule/src/main/java/applicationModulepackageJava0/Foo0.java" 10 | apply-non-abi-change-to = "applicationModule/src/main/java/applicationModulepackageJava0/Foo0.java" 11 | } -------------------------------------------------------------------------------- /configs/kapt/v2/kapt-reseach-v2.md: -------------------------------------------------------------------------------- 1 | 2 | ## KAPT Research with Java/Kotlin mix 3 | 4 | 5 | * Date - 2018 - 5 - 21 6 | * Tools Version 7 | * Gradle version - 4.7 8 | * Android Gradle Plugin (AGP) version - 3.1.2 9 | * KotlinVersion - 1.2.41 10 | 11 | #### Profiling 12 | The profiling was done with gradle-profiler. Each configuration, except `KotlinOnly`, 13 | was profiled 4 times. The `KotlinOnly` configuration was profiled twice, because 14 | the gradle-profiler does not support incremental build profiling for Kotlin. 15 | 16 | 17 | ##### Steps 18 | 1. Clean build with build scan profiler 19 | 2. Incremental build with build scan profiler 20 | 3. Clean build with `--benchmark` option (second for “KotlinOnly" configuration) 21 | 4. Incremental build with `--benchmark` option. 22 | 23 | * [Profiler scenarios](https://github.com/android/android-studio-poet/blob/master/configs/kapt/v2/gradle-profiler.scenarios) 24 | for clean and incremental builds. 25 | * [AS Poet configs](https://github.com/android/android-studio-poet/tree/master/configs/kapt/v2) 26 | * All projects have data binding, which means enabled annotation processing. 27 | * Each module has 200 classes with 10 methods each. Depending on configs 28 | it is 100% Java, 100% Kotlin or 50-50 Java Kotlin mix. 29 | * The tested "variable" is a mix of Java and Kotlin code 30 | * Branch with 31 | [results](https://github.com/NikitaKozlov/android-studio-poet/tree/kapt-problem-v2-with-results/generated_projects). 32 | 33 | #### Summary of the results 34 | * Only Java code 35 | * Clean: 2m 23s ± 19s (Build scan: https://scans.gradle.com/s/tixxvw4gbpmmi) 36 | * Incremental: 30s ± 3s (Build scan: https://scans.gradle.com/s/icieznrsm3u6k) 37 | * Mixed Java and Kotlin code 38 | * Clean: 2m 11s ± 16s (Build scan: https://scans.gradle.com/s/42gr5zacv5uxc) 39 | * Incremental: 26s ± 3s (Build scan: https://scans.gradle.com/s/sx3jz5iwzkq6c) 40 | * Only Kotlin code 41 | * Clean: 1m 44s ± 3s (Build scan: https://scans.gradle.com/s/qg4wpgnu774y4) 42 | -------------------------------------------------------------------------------- /configs/modularization/v1/ConfigFull_20k_classes_1module.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_20k_classes_1module", 5 | "root": "../generated_projects/modularization", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 50, 19 | "classesPerPackage": 200, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 50, 24 | "classesPerPackage": 200, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | } 36 | } 37 | ] 38 | } 39 | } -------------------------------------------------------------------------------- /configs/modularization/v1/ConfigFull_20k_classes_2modules.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_20k_classes_2modules", 5 | "root": "../generated_projects/modularization", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 25, 19 | "classesPerPackage": 200, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 25, 24 | "classesPerPackage": 200, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | } 40 | ] 41 | }, 42 | { 43 | "moduleType": "android", 44 | "androidBuildConfig": { 45 | "minSdkVersion": 21 46 | }, 47 | "java": { 48 | "packages": 25, 49 | "classesPerPackage": 200, 50 | "methodsPerClass": 10 51 | }, 52 | "kotlin": { 53 | "packages": 25, 54 | "classesPerPackage": 200, 55 | "methodsPerClass": 10 56 | }, 57 | "useKotlin": true, 58 | "moduleName": "libraryModule", 59 | "activityCount": 5, 60 | "resourcesConfig": { 61 | "stringCount": 5, 62 | "imageCount": 5, 63 | "layoutCount": 5 64 | } 65 | } 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /configs/modularization/v1/ConfigFull_20k_classes_3modules.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputVersion": "0.1", 3 | "projectConfig": { 4 | "projectName": "genny_20k_classes_3modules", 5 | "root": "../generated_projects/modularization", 6 | "buildSystemConfig": { 7 | "buildSystemVersion": "4.8", 8 | "agpVersion": "3.1.2", 9 | "kotlinVersion": "1.2.41" 10 | }, 11 | "moduleConfigs": [ 12 | { 13 | "moduleType": "android", 14 | "androidBuildConfig": { 15 | "minSdkVersion": 21 16 | }, 17 | "java": { 18 | "packages": 16, 19 | "classesPerPackage": 208, 20 | "methodsPerClass": 10 21 | }, 22 | "kotlin": { 23 | "packages": 16, 24 | "classesPerPackage": 208, 25 | "methodsPerClass": 10 26 | }, 27 | "useKotlin": true, 28 | "moduleName": "applicationModule", 29 | "activityCount": 5, 30 | "hasLaunchActivity": true, 31 | "resourcesConfig": { 32 | "stringCount": 5, 33 | "imageCount": 5, 34 | "layoutCount": 5 35 | }, 36 | "dependencies": [ 37 | { 38 | "moduleName": "libraryModule" 39 | }, 40 | { 41 | "moduleName": "libraryModule1" 42 | } 43 | ] 44 | }, 45 | { 46 | "moduleType": "android", 47 | "androidBuildConfig": { 48 | "minSdkVersion": 21 49 | }, 50 | "java": { 51 | "packages": 16, 52 | "classesPerPackage": 208, 53 | "methodsPerClass": 10 54 | }, 55 | "kotlin": { 56 | "packages": 16, 57 | "classesPerPackage": 208, 58 | "methodsPerClass": 10 59 | }, 60 | "useKotlin": true, 61 | "moduleName": "libraryModule", 62 | "activityCount": 5, 63 | "resourcesConfig": { 64 | "stringCount": 5, 65 | "imageCount": 5, 66 | "layoutCount": 5 67 | } 68 | }, 69 | { 70 | "moduleType": "android", 71 | "androidBuildConfig": { 72 | "minSdkVersion": 21 73 | }, 74 | "java": { 75 | "packages": 16, 76 | "classesPerPackage": 208, 77 | "methodsPerClass": 10 78 | }, 79 | "kotlin": { 80 | "packages": 16, 81 | "classesPerPackage": 208, 82 | "methodsPerClass": 10 83 | }, 84 | "useKotlin": true, 85 | "moduleName": "libraryModule1", 86 | "activityCount": 5, 87 | "resourcesConfig": { 88 | "stringCount": 5, 89 | "imageCount": 5, 90 | "layoutCount": 5 91 | } 92 | } 93 | ] 94 | } 95 | } -------------------------------------------------------------------------------- /configs/modularization/v1/gradle-profiler-commands.txt: -------------------------------------------------------------------------------- 1 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios clean_build 2 | 3 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios app_inc_build 4 | 5 | gradle-profiler --profile buildscan --project-dir . --scenario-file ../gradle-profiler.scenarios lib_inc_build 6 | -------------------------------------------------------------------------------- /configs/modularization/v1/gradle-profiler.scenarios: -------------------------------------------------------------------------------- 1 | clean_build { 2 | tasks = ["assembleDebug"] 3 | cleanup-tasks = ["clean", "cleanBuildCache"] 4 | warm-ups = 6 5 | } 6 | 7 | lib_inc_build { 8 | tasks = ["assembleDebug"] 9 | 10 | apply-abi-change-to = "libraryModule/src/main/java/libraryModulepackageJava0/Foo0.java" 11 | apply-non-abi-change-to = "libraryModule/src/main/java/libraryModulepackageJava0/Foo0.java" 12 | apply-kotlin-change-to = "libraryModule/src/main/java/libraryModulepackageKt3/Foo2.kt" 13 | 14 | warm-ups = 6 15 | } 16 | 17 | 18 | app_inc_build { 19 | tasks = ["assembleDebug"] 20 | 21 | apply-abi-change-to = "applicationModule/src/main/java/applicationModulepackageJava0/Foo0.java" 22 | apply-non-abi-change-to = "applicationModule/src/main/java/applicationModulepackageJava0/Foo0.java" 23 | apply-kotlin-change-to = "applicationModule/src/main/java/applicationModulepackageKt3/Foo2.kt" 24 | 25 | warm-ups = 6 26 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kapt.verbose=true 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android/android-studio-poet/f820e9cc0e5d7db4de9a7e31b818277143546f73/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /img/dependencies.dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android/android-studio-poet/f820e9cc0e5d7db4de9a7e31b818277143546f73/img/dependencies.dot.png -------------------------------------------------------------------------------- /img/dependencies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android/android-studio-poet/f820e9cc0e5d7db4de9a7e31b818277143546f73/img/dependencies.png -------------------------------------------------------------------------------- /img/generator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android/android-studio-poet/f820e9cc0e5d7db4de9a7e31b818277143546f73/img/generator.png -------------------------------------------------------------------------------- /resources/gradle-assets/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android/android-studio-poet/f820e9cc0e5d7db4de9a7e31b818277143546f73/resources/gradle-assets/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /resources/gradle-assets/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'android-studio-poet' 2 | 3 | include 'aspoet', 'aspoet-input' 4 | 5 | dependencyResolutionManagement { 6 | repositories { 7 | mavenCentral() 8 | } 9 | } --------------------------------------------------------------------------------