Gradle ソース解析

# Gradle ソース解析

Gradleが内部的にどのように構成されているか確認するためにソースコードリーディングしています。
その際のメモです。バージョンは 4.1.0。

From https://github.com/gradle/gradle (tag: v4.1.0)

## task
* [org.gradle.api.Task](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/Task.java#L143)
    * [org.gradle.api.internal.AbstractTask](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/AbstractTask.java#L85)
        * [org.gradle.api.DefaultTask](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/DefaultTask.java)
* [org.gradle.api.internal.project.DefaultProject#task()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/project/DefaultProject.java#L1165)
    * [org.gradle.api.internal.tasks.DefaultTaskContainer#create()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/tasks/DefaultTaskContainer.java#L71)
        * [org.gradle.api.internal.project.taskfactory.TaskFactory#createTask()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/project/taskfactory/TaskFactory.java#L67)
* [org.gradle.api.internal.ClassGenerator#generate()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/ClassGenerator.java#L22)
    * [org.gradle.api.internal.AbstractClassGenerator#generate()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/AbstractClassGenerator.java#L75)

※ [leftShift ( &lt;&lt; ) でのタスク定義は非推奨となり v5.0 で削除予定](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/AbstractTask.java#L584)

## repositories

* [org.gradle.api.Project#repositories()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/Project.java#L1492)
    * [DefaultProject#repositories](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/project/DefaultProject.java#L1145)
    * [ConfigureUtil#configure()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/util/ConfigureUtil.java#L98)
        * [org.gradle.api.artifacts.dsl.RepositoryHandler](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/artifacts/dsl/RepositoryHandler.java#L31)

## 拡張プロパティ、プロジェクトプロパティ
* なぜ ext で設定することができる？
    * [DefaultConvention.java#L69](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/plugins/DefaultConvention.java#L69)
* [ProjectPropertySettingBuildLoader#CachingPropertyApplicator](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/initialization/ProjectPropertySettingBuildLoader.java#L85)

```java:
    private static class CachingPropertyApplicator {
        private final Map<Pair<String, ? extends Class<?>>, PropertyMutator> mutators = Maps.newHashMap();
        private Class<? extends Project> projectClazz;

        void configureProperty(Project project, String name, Object value) {
            Class<? extends Project> clazz = project.getClass();
            if (clazz != projectClazz) {
                mutators.clear();
                projectClazz = clazz;
            }
            Class<?> valueType = value == null ? null : value.getClass();
            Pair<String, ? extends Class<?>> key = Pair.of(name, valueType);
            PropertyMutator propertyMutator = mutators.get(key);
            if (propertyMutator != null) {
                propertyMutator.setValue(project, value);
            } else {
                if (!mutators.containsKey(key)) {
                    propertyMutator = JavaReflectionUtil.writeablePropertyIfExists(clazz, name, valueType);
                    mutators.put(key, propertyMutator);
                    if (propertyMutator != null) {
                        propertyMutator.setValue(project, value);
                        return;
                    }
                }
                ExtraPropertiesExtension extraProperties = project.getExtensions().getExtraProperties();
                extraProperties.set(name, value);
            }
        }
    }
```

* [org.gradle.api.Project#getExtensions()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/Project.java#L1700)
* [org.gradle.api.internal.project.DefaultProject#getExtensions()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/project/DefaultProject.java#L1280)
    * [ExtensionContainer#getExtraProperties()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/plugins/ExtensionContainer.java#L249)
    * [DefaultConvention#getExtraProperties()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/plugins/DefaultConvention.java#L156)
        * [ExtraPropertiesExtension#set()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/plugins/ExtraPropertiesExtension.java#L142)
        * [DefaultExtraPropertiesExtension#set()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/plugins/DefaultExtraPropertiesExtension.java#L44)

## Configurations

* [org/gradle/api/internal/project/DefaultProject#configurations()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/project/DefaultProject.java#L1135)
    * [org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer.java#L48)
        * [org/gradle/api/internal/AbstractNamedDomainObjectContainer#configure()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/AbstractNamedDomainObjectContainer.java#L77)

なぜ configurations スコープに記述するだけでコンフィグレーションが生成される？

* [org/gradle/api/internal/NamedDomainObjectContainerConfigureDelegate#_configure()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/NamedDomainObjectContainerConfigureDelegate.java#L33)
    * [org/gradle/api/internal/AbstractNamedDomainObjectContainer#create()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/AbstractNamedDomainObjectContainer.java#L49)
        * [org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer#doCreate()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfigurationContainer.java#L99)
            * [org/gradle/api/internal/ClassGeneratorBackedInstantiator#newInstance()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/core/src/main/java/org/gradle/api/internal/ClassGeneratorBackedInstantiator.java#L29)
                * [org/gradle/internal/reflect/DirectInstantiator#newInstance()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/base-services/src/main/java/org/gradle/internal/reflect/DirectInstantiator.java#L40)


↓ DefaultConfiguration が生成される

[org/gradle/api/internal/artifacts/configurations/DefaultConfiguration.](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfiguration.java#L175)

↓ dependencies スコープ側の delegate で動的にメソッド追加される

* [org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler#DynamicMethods](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java#L200)
    * [org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler#doAdd()](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/dsl/dependencies/DefaultDependencyHandler.java#L100)

## JavaPlugin

* [org.gradle.api.plugins.JavaPlugin](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/plugins/src/main/java/org/gradle/api/plugins/JavaPlugin.java)

# MavenPlugin

* [org/gradle/api/plugins/MavenPlugin](https://github.com/gradle/gradle/blob/v4.1.0/subprojects/maven/src/main/java/org/gradle/api/plugins/MavenPlugin.java)

# 内部情報確認

## repositories

```groovy:build.gradle
def closure = {
  mavenCentral()
}

this.repositories(closure)
this.repositories.each { println it instanceof org.gradle.api.internal.artifacts.repositories.DefaultMavenArtifactRepository }
//-> true
```