/*
* Copyright 2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.api;
import groovy.lang.Closure;
import groovy.lang.MissingPropertyException;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.dsl.ArtifactHandler;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.component.SoftwareComponentContainer;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.ConfigurableFileTree;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.DeleteSpec;
import org.gradle.api.file.FileTree;
import org.gradle.api.file.ProjectLayout;
import org.gradle.api.initialization.dsl.ScriptHandler;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.LoggingManager;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.plugins.Convention;
import org.gradle.api.plugins.ExtensionAware;
import org.gradle.api.plugins.ExtensionContainer;
import org.gradle.api.plugins.PluginAware;
import org.gradle.api.provider.PropertyState;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.resources.ResourceHandler;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.WorkResult;
import org.gradle.internal.HasInternalProtocol;
import org.gradle.normalization.InputNormalizationHandler;
import org.gradle.process.ExecResult;
import org.gradle.process.ExecSpec;
import org.gradle.process.JavaExecSpec;
import javax.annotation.Nullable;
import java.io.File;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* <p>This interface is the main API you use to interact with Gradle from your build file. From a <code>Project</code>,
* you have programmatic access to all of Gradle's features.</p>
*
* <h3>Lifecycle</h3>
*
* <p>There is a one-to-one relationship between a <code>Project</code> and a <code>{@value #DEFAULT_BUILD_FILE}</code>
* file. During build initialisation, Gradle assembles a <code>Project</code> object for each project which is to
* participate in the build, as follows:</p>
*
* <ul>
*
* <li>Create a {@link org.gradle.api.initialization.Settings} instance for the build.</li>
*
* <li>Evaluate the <code>{@value org.gradle.api.initialization.Settings#DEFAULT_SETTINGS_FILE}</code> script, if
* present, against the {@link org.gradle.api.initialization.Settings} object to configure it.</li>
*
* <li>Use the configured {@link org.gradle.api.initialization.Settings} object to create the hierarchy of
* <code>Project</code> instances.</li>
*
* <li>Finally, evaluate each <code>Project</code> by executing its <code>{@value #DEFAULT_BUILD_FILE}</code> file, if
* present, against the project. The projects are evaluated in breadth-wise order, such that a project is evaluated
* before its child projects. This order can be overridden by calling <code>{@link #evaluationDependsOnChildren()}</code> or by adding an
* explicit evaluation dependency using <code>{@link #evaluationDependsOn(String)}</code>.</li>
*
* </ul>
*
* <h3>Tasks</h3>
*
* <p>A project is essentially a collection of {@link Task} objects. Each task performs some basic piece of work, such
* as compiling classes, or running unit tests, or zipping up a WAR file. You add tasks to a project using one of the
* {@code create()} methods on {@link TaskContainer}, such as {@link TaskContainer#create(String)}. You can locate existing
* tasks using one of the lookup methods on {@link TaskContainer}, such as {@link org.gradle.api.tasks.TaskCollection#getByName(String)}.</p>
*
* <h3>Dependencies</h3>
*
* <p>A project generally has a number of dependencies it needs in order to do its work. Also, a project generally
* produces a number of artifacts, which other projects can use. Those dependencies are grouped in configurations, and
* can be retrieved and uploaded from repositories. You use the {@link org.gradle.api.artifacts.ConfigurationContainer}
* returned by {@link #getConfigurations()} method to manage the configurations. The {@link
* org.gradle.api.artifacts.dsl.DependencyHandler} returned by {@link #getDependencies()} method to manage the
* dependencies. The {@link org.gradle.api.artifacts.dsl.ArtifactHandler} returned by {@link #getArtifacts()} method to
* manage the artifacts. The {@link org.gradle.api.artifacts.dsl.RepositoryHandler} returned by {@link
* #getRepositories()} method to manage the repositories.</p>
*
* <h3>Multi-project Builds</h3>
*
* <p>Projects are arranged into a hierarchy of projects. A project has a name, and a fully qualified path which
* uniquely identifies it in the hierarchy.</p>
*
* <h3>Plugins</h3>
*
* <p>
* Plugins can be used to modularise and reuse project configuration.
* Plugins can be applied using the {@link PluginAware#apply(java.util.Map)} method, or by using the {@link org.gradle.plugin.use.PluginDependenciesSpec} plugins script block.
* </p>
*
* <a name="properties"></a> <h3>Properties</h3>
*
* <p>Gradle executes the project's build file against the <code>Project</code> instance to configure the project. Any
* property or method which your script uses is delegated through to the associated <code>Project</code> object. This
* means, that you can use any of the methods and properties on the <code>Project</code> interface directly in your script.
* </p><p>For example:
* <pre>
* defaultTasks('some-task') // Delegates to Project.defaultTasks()
* reportsDir = file('reports') // Delegates to Project.file() and the Java Plugin
* </pre>
* <p>You can also access the <code>Project</code> instance using the <code>project</code> property. This can make the
* script clearer in some cases. For example, you could use <code>project.name</code> rather than <code>name</code> to
* access the project's name.</p>
*
* <p>A project has 5 property 'scopes', which it searches for properties. You can access these properties by name in
* your build file, or by calling the project's {@link #property(String)} method. The scopes are:</p>
*
* <ul>
*
* <li>The <code>Project</code> object itself. This scope includes any property getters and setters declared by the
* <code>Project</code> implementation class. For example, {@link #getRootProject()} is accessible as the
* <code>rootProject</code> property. The properties of this scope are readable or writable depending on the presence
* of the corresponding getter or setter method.</li>
*
* <li>The <em>extra</em> properties of the project. Each project maintains a map of extra properties, which
* can contain any arbitrary name -> value pair. Once defined, the properties of this scope are readable and writable.
* See <a href="#extraproperties">extra properties</a> for more details.</li>
*
* <li>The <em>extensions</em> added to the project by the plugins. Each extension is available as a read-only property with the same name as the extension.</li>
*
* <li>The <em>convention</em> properties added to the project by the plugins. A plugin can add properties and methods
* to a project through the project's {@link Convention} object. The properties of this scope may be readable or writable, depending on the convention objects.</li>
*
* <li>The tasks of the project. A task is