Coder Social home page Coder Social logo

stable-plugins-dsl's Introduction

Project Summary

The Stable Plugins DSL project is sponsored work to reduce the burden of configuring, resolving, and publishing plugins (especially, for enterprise users.)

Background

Currently, we have several competing ways to declare plugins to be used by a project, each with their own limitations:

  • apply from: 'some/path/foo.gradle' - Allows applying script plugins

  • apply plugin : 'aplugin' - Applies a plugin which is already on the buildscript.configurations.classpath. It is either a core plugin like 'java', a plugin from the buildSrc directory or it has been added as a dependency using the repositories {} and dependencies {} blocks.

  • plugins { id 'some.plugin' version '2.3' } - resolves the plugin using the https://plugins.gradle.org to map from the plugin id and version to the implementing jar file and its dependencies which are then downloaded and added to the buildscript.configurations.classpath.

Some larger enterprise users invest a lot of time and energy into setting up internal plugins and using them on all of their projects to standardize their development and make the lives of their developers easier. These plugins are often not published to https://plugins.gradle.org. Asking these users to configure the same buildscript repositories and dependencies blocks for each of their projects is a nuisance.

Solution

The key milestones are:

  1. Resolve plugins from a maven/ivy repository based on the plugin id

    1. Specify which repositories to look in for plugins

    2. Publish plugins to a maven/ivy repository complete with metadata needed to map from the plugin id to a maven/ivy artifact and its dependencies

  2. Specify plugins to be used on multiple projects in a multi-project build in a single block

  3. Support dynamic versions for plugins

  4. Support locking versions of plugins in version control to increase build reproducibility

We are currently committed to delivering #1 and #2. #3 and #4 are still being prioritized.

Gradle Team

Technical Leadership: Luke Daley @alkemist

Engineering Coordination: Piotr Jagielski ([email protected])

Engineers: Pepper Lebeck-Jobe @eljobe, Stefan Oehme @oehme

Development Process

  • ZenHub on top of GitHub issues to track progress

  • Design documents are iterated on in Google Docs and then checked into gradle/gradle

  • Weekly team meeting

  • Weekly stream update on discourse

  • Time tracking using the engineering spreadsheet

stable-plugins-dsl's People

Contributors

eskatos avatar jmcgarr avatar oehme avatar pioterj avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stable-plugins-dsl's Issues

Publish pluginRepositories API and add user documentation

Motivation

We want to release this feature as part of Gradle 2.14. To do that, it needs to be public and documented.

Proposed Change

  • Move PluginRepositoryHandler and friends to public package
  • Mark all classes as incubating if not yet done
  • Add DSL Reference documentation (both consumption and publishing)
  • Add User guide documentation (both consumption and publishing)
  • Mention in release notes

Lock down pluginRepositories block

Motivation

Method calls inside the pluginRepositories block should not fall back to the SettingsScript instance. Otherwise nonsensical code like this would be valid:

pluginRepositories {
  include 'foo'
}

Proposed Change

Don't use ConfigureUtil#configure (which falls back to the owner of the closure if a method/property is not found). Use DELEGATE_ONLY strategy instead.

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Can resolve from a single Maven repository defined in the pluginRepositories block

Motivation

Using a single Maven plugin repository will be sufficient for many users. It is thus a great first step for wiring up the repository declaration with the resolver.

Proposed Change

Replace the org.gradle.plugin.repoUrl system property with the URL of the single Maven repository defined in the pluginRepositories block.

Introduce DefaultPluginRepositoryHandler, MavenPluginRepository (this overlaps with #17) and PluginRepositoryInternal. These will form the back-end for the DSL introduced by #17.

PluginRepositoryInternal {
  PluginResolver asResolver()
}

The resolvers derived from these repositories are added before the Plugin Portal resolver. This replaces the single "CustomRepositoryResolver". The name mentioned in resolution failure messages should equal the name that the user set on the plugin repository.

Test cases

  • after #17 is implemented, all tests from #5 must pass when supplying the repository URL via the new pluginRepositories block instead of a system property
  • the name of the repository are mentioned in the description of resolution failures

Code Review

  • [] Does the change work?
    • [] Try out the feature, executing it like a end-user would.
    • [] Check corner cases and try to break it in various ways.
    • [] Are the error messages informative?
  • [] Is the change sufficiently tested?
    • [] Are there appropriate levels of unit & integration tests?
    • [] Do the tests indicate what they are actually testing?
    • [] Are the tests in the right location?
    • [] Can new tests be consolidated with any existing tests?
  • [] Does it change the public API?
    • [] Has @Incubating been used appropriately?
    • [] Does it preserve backward compatibility?
  • [] Is it sufficiently documented?
    • [] Is the user guide documentation in the best location?
    • [] Is the user guide documentation clear and informative?
    • [] If there should be samples, are they helpful and tested appropriately?
    • [] Is there sufficient API/DSL documentation?
    • [] Is the API/DSL documentation clear and informative?
    • [] Do the release notes clearly convey the value of the feature?
    • [] Do the release notes explain the feature and link to more documentation?
  • [] Is it implemented well?
    • [] Does it minimize surface area (particularly public)?
    • [] Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • [] Does it use appropriate data structures?
    • [] Does it minimize potential for invalid states?
    • [] Does it suitably reuse existing infrastructure?
    • [] Does it suitably consider concurrency?
    • [] Does it suitably consider failure modes?
    • [] Does it suitably consider performance?
    • [] Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Can parse Plugin Repository declarations in settings.gradle

Motivation

To allow users to specify their custom repositories, Gradle first of all needs to be able to parse the new pluginRepositories DSL.

Proposed Change

Add a pluginRepositories {} block to the DSL of settings.gradle. The pluginRepositories block is parsed in the same phase as the buildScript block, before the remaining instructions in the settings file are parsed. A pluginRepositories block is only allowed as a top-level element. It introduces new PluginRepositoriesHandler and PluginRepository interfaces which work similarly to the RepositoryHandler and ArtifactRepository interfaces.

The InitialPassStatementTransformer and BuildScriptTransformer classes will be updated to be aware of the special handling needed to deal with the pluginRepositories DSL block.

Test Cases

  • pluginRepositories block can be read from settings.gradle
  • pluginRepositories block supports defining a maven plugin repository
  • pluginRepositories block is not supported in ProjectScripts
  • pluginRepositories block must come before other blocks in the settings.gradle script
  • pluginRepositories block must be a top-level block (not nested)
  • Only one pluginRepositores block is allowed in each script

Code Review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Collect Deep Thoughts on Applying Plugins

Motivation

There are lots of proposals floating around for how we might be able to support conveniently applying plugins and configuring their tasks and consuming the APIs they expose across multiple projects in a multi-project build. We need to collect the proposals and evaluate their relative merits in a single place to more clearly understand how we want applying plugins to work for the future of Gradle.

Proposed Change

We will write a document capturing several different possible ways to proceed and invite the larger engineering team to provide feedback on the document to make sure we have all our bases covered.

Auto-generate plugin descriptor files

Motivation

With the new explicit DSL in the java-gradle-plugin, the build script could be the single source of truth and the plugin descriptor files auto-generated.

Proposed Change

  • add the implementationClass attribute to the plugin declarations in the DSL
  • auto-generate the corresponding .properties files
  • fail the build if there already is a hand-written .properties file

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Can apply plugin to all subprojects of a project

Motivation

In many cases, all sub-projects of a project share some common conventions that are captured in plugins. It should be possible to apply those plugins in the parent project using the following syntax:

plugins {
  subprojects {
    id 'our.great.plugin' version '1.0.0'
  }
}

Proposed Change

Replace the AST-Transformation-based plugin request collection with a handler interface, much like ScriptHandler or PluginRepositorySpec. Collect plugin requests including their desired target. Change the PluginRequestApplicator to resolve the plugin once in the parent, but apply it to all target projects instead of applying it to the parent. The parent itself may of course be a target itself.

For now, forbid calling any other methods except id, version and subprojects

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Allow accessing classes from the plugin artifact inside the build script

Try referring to the org.example.hello.HelloPlugin class from the example build script and you’ll see that it fails. This is because we are using an isolated classloader to load that plugin. We should instead be using the PluginResolveContext#addLegacy() method to add the artifact to the buildscript classpath.

The following steps should fix this problem without loosing the correct "notFound" behavior:

  • resolve the marker non-transitively (to check if it’s there and report „notFound“ if it isn't)
  • if it’s there, return a resolution that calls addLegacy(), passing in the repoUrl and marker coordinates
  • add a test case that verifies we can access classes from an applied plugin

Resolve plugins from Ivy Repositories

We have added the concept of a POM-only marker artifact to the Maven repositories to provide a stable mapping from a pluginid and version to the artifact that actually contains the plugin. We need to introduce a similar concept for Ivy repositories and confirm that we can resolve plugin artifacts from those as well.

Can specify plugin repositories in an init script

Motivation

An organization might want to standardize which plugin repositories to use by providing an init script that configures them. They might also want to prohibit adding additional repositories, at least when building publishable artifacts (doing some local experiments with a different repo might be okay though).

Proposed Change

Add a pluginRepositories block to init scripts, backed by the same global repository handler which is also used for evaluating settings.gradle.

Code Review

  • [] Does the change work?
    • [] Try out the feature, executing it like a end-user would.
    • [] Check corner cases and try to break it in various ways.
    • [] Are the error messages informative?
  • [] Is the change sufficiently tested?
    • [] Are there appropriate levels of unit & integration tests?
    • [] Do the tests indicate what they are actually testing?
    • [] Are the tests in the right location?
    • [] Can new tests be consolidated with any existing tests?
  • [] Does it change the public API?
    • [] Has @Incubating been used appropriately?
    • [] Does it preserve backward compatibility?
  • [] Is it sufficiently documented?
    • [] Is the user guide documentation in the best location?
    • [] Is the user guide documentation clear and informative?
    • [] If there should be samples, are they helpful and tested appropriately?
    • [] Is there sufficient API/DSL documentation?
    • [] Is the API/DSL documentation clear and informative?
    • [] Do the release notes clearly convey the value of the feature?
    • [] Do the release notes explain the feature and link to more documentation?
  • [] Is it implemented well?
    • [] Does it minimize surface area (particularly public)?
    • [] Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • [] Does it use appropriate data structures?
    • [] Does it minimize potential for invalid states?
    • [] Does it suitably reuse existing infrastructure?
    • [] Does it suitably consider concurrency?
    • [] Does it suitably consider failure modes?
    • [] Does it suitably consider performance?
    • [] Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Can add Gradle Plugin Portal at any point in the repository list

Motivation

When the user defines the list of plugin repositories, he expects them to be queried in the given order. This should also apply to the Gradle Plugin Portal.

Proposed Change

Instead of always adding the Plugin Portal as the last resolver in the list, add a gradePluginPortal() method to the pluginRepositories block which allows users to add the Plugin Portal resolver at any point between their custom repositories.

Code Review

  • [] Does the change work?
    • [] Try out the feature, executing it like a end-user would.
    • [] Check corner cases and try to break it in various ways.
    • [] Are the error messages informative?
  • [] Is the change sufficiently tested?
    • [] Are there appropriate levels of unit & integration tests?
    • [] Do the tests indicate what they are actually testing?
    • [] Are the tests in the right location?
    • [] Can new tests be consolidated with any existing tests?
  • [] Does it change the public API?
    • [] Has @Incubating been used appropriately?
    • [] Does it preserve backward compatibility?
  • [] Is it sufficiently documented?
    • [] Is the user guide documentation in the best location?
    • [] Is the user guide documentation clear and informative?
    • [] If there should be samples, are they helpful and tested appropriately?
    • [] Is there sufficient API/DSL documentation?
    • [] Is the API/DSL documentation clear and informative?
    • [] Do the release notes clearly convey the value of the feature?
    • [] Do the release notes explain the feature and link to more documentation?
  • [] Is it implemented well?
    • [] Does it minimize surface area (particularly public)?
    • [] Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • [] Does it use appropriate data structures?
    • [] Does it minimize potential for invalid states?
    • [] Does it suitably reuse existing infrastructure?
    • [] Does it suitably consider concurrency?
    • [] Does it suitably consider failure modes?
    • [] Does it suitably consider performance?
    • [] Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Add `apply false` option to `plugins` block

Motivation

The new plugins block currently does not handle two important use cases:

  • applying plugins to subprojects
  • only resolving a plugin for its classes, but not applying it

Proposed Change

Add a apply false option which resolves a plugin and puts it on the current buildscript's classloader without applying it.

plugins {
  id 'com.foo.bar' version '1.0' apply false
}

subprojects {
  if(someProperty) {
    apply plugin: 'com.foo.bar'
  }
}

Code review

https://code-review.gradle.org/cru/REVIEW-6036

  • Does the change work?
  • Is the change sufficiently tested?
  • Does it change the public API?
  • Is it sufficiently documented?
  • Is it implemented well?

Can resolve from multiple Maven repository defined in the pluginRepositories block

Motivation

Some organizations might have multiple plugin repositories are a developer might want to try out a plugin deployed to mavenLocal() before pushing a change. Allowing multiple Maven repositories will solve these use cases.

Proposed Change

Instead of passing a single repository URL to the ScriptHandler of the current build script, we need to globally add the declared plugin repositories to the locations from where plugin jars are resolved. The current idea is to prepend them to the repositories of each initScript/buildScript block.

Each repository will be added to the list of plugin resolvers as a separate resolver. This will give the user better diagnostic messages and will later enable us to insert the Gradle Plugin Portal at any location between other repositories, see #22.

Code Review

  • [] Does the change work?
    • [] Try out the feature, executing it like a end-user would.
    • [] Check corner cases and try to break it in various ways.
    • [] Are the error messages informative?
  • [] Is the change sufficiently tested?
    • [] Are there appropriate levels of unit & integration tests?
    • [] Do the tests indicate what they are actually testing?
    • [] Are the tests in the right location?
    • [] Can new tests be consolidated with any existing tests?
  • [] Does it change the public API?
    • [] Has @Incubating been used appropriately?
    • [] Does it preserve backward compatibility?
  • [] Is it sufficiently documented?
    • [] Is the user guide documentation in the best location?
    • [] Is the user guide documentation clear and informative?
    • [] If there should be samples, are they helpful and tested appropriately?
    • [] Is there sufficient API/DSL documentation?
    • [] Is the API/DSL documentation clear and informative?
    • [] Do the release notes clearly convey the value of the feature?
    • [] Do the release notes explain the feature and link to more documentation?
  • [] Is it implemented well?
    • [] Does it minimize surface area (particularly public)?
    • [] Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • [] Does it use appropriate data structures?
    • [] Does it minimize potential for invalid states?
    • [] Does it suitably reuse existing infrastructure?
    • [] Does it suitably consider concurrency?
    • [] Does it suitably consider failure modes?
    • [] Does it suitably consider performance?
    • [] Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Can inspect plugin repositories of a build

Motivation

Highly regulated organizations might want to ensure that only approved repositories are used. They need to be able to inspect the plugin repositories used by the current build.

Proposed Change

Add a getPluginRepositories() method to the Gradle API. Forbid any modifications after settings.gradle has been evaluated.

Code Review

  • [] Does the change work?
    • [] Try out the feature, executing it like a end-user would.
    • [] Check corner cases and try to break it in various ways.
    • [] Are the error messages informative?
  • [] Is the change sufficiently tested?
    • [] Are there appropriate levels of unit & integration tests?
    • [] Do the tests indicate what they are actually testing?
    • [] Are the tests in the right location?
    • [] Can new tests be consolidated with any existing tests?
  • [] Does it change the public API?
    • [] Has @Incubating been used appropriately?
    • [] Does it preserve backward compatibility?
  • [] Is it sufficiently documented?
    • [] Is the user guide documentation in the best location?
    • [] Is the user guide documentation clear and informative?
    • [] If there should be samples, are they helpful and tested appropriately?
    • [] Is there sufficient API/DSL documentation?
    • [] Is the API/DSL documentation clear and informative?
    • [] Do the release notes clearly convey the value of the feature?
    • [] Do the release notes explain the feature and link to more documentation?
  • [] Is it implemented well?
    • [] Does it minimize surface area (particularly public)?
    • [] Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • [] Does it use appropriate data structures?
    • [] Does it minimize potential for invalid states?
    • [] Does it suitably reuse existing infrastructure?
    • [] Does it suitably consider concurrency?
    • [] Does it suitably consider failure modes?
    • [] Does it suitably consider performance?
    • [] Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Can add autorization settings to plugin repositories

Motivation

Users might want to add authentication information to their plugin repository declaration.

Proposed Change

Once #19 is implemented, this will most likely just work out of the box. Still, it needs to be tested and reviewed.

Code Review

  • [] Does the change work?
    • [] Try out the feature, executing it like a end-user would.
    • [] Check corner cases and try to break it in various ways.
    • [] Are the error messages informative?
  • [] Is the change sufficiently tested?
    • [] Are there appropriate levels of unit & integration tests?
    • [] Do the tests indicate what they are actually testing?
    • [] Are the tests in the right location?
    • [] Can new tests be consolidated with any existing tests?
  • [] Does it change the public API?
    • [] Has @Incubating been used appropriately?
    • [] Does it preserve backward compatibility?
  • [] Is it sufficiently documented?
    • [] Is the user guide documentation in the best location?
    • [] Is the user guide documentation clear and informative?
    • [] If there should be samples, are they helpful and tested appropriately?
    • [] Is there sufficient API/DSL documentation?
    • [] Is the API/DSL documentation clear and informative?
    • [] Do the release notes clearly convey the value of the feature?
    • [] Do the release notes explain the feature and link to more documentation?
  • [] Is it implemented well?
    • [] Does it minimize surface area (particularly public)?
    • [] Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • [] Does it use appropriate data structures?
    • [] Does it minimize potential for invalid states?
    • [] Does it suitably reuse existing infrastructure?
    • [] Does it suitably consider concurrency?
    • [] Does it suitably consider failure modes?
    • [] Does it suitably consider performance?
    • [] Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Resolve from custom repositories before plugin portal

The initial prototype consults the custom repositories last in order to minimize its impact on the production code. However, for performance reasons, the custom repositories should be consulted first.

The main issue is that we currently use a system property to define the repository. The system properties are synchronized, so we might potentially slow down plugin resolution. We could either:

  • verify that there is no such slowdown
  • cache the value (although we need to be careful whether resolvers are used from different threads or not)
  • wait with the swapping of the order until we have the real repository declaration syntax, so we no longer need the system property lookup

Create dummy plugins and automated repository creation

Instead of checking in a hand-made repository, we should have one or a few dummy plugins that are automatically published to a well-known location. The build scripts of these dummy plugins will also serve as a reminder that publishing of plugin marker POMs needs to be automated.

Handle resolution failure gracefully

The current custom repository resolver fails the build with a dependency resolution exception if it cannot find a plugin. This is wrong for two reasons:

  • the error message is not helpful, because it does not contain the requested plugin ID
  • the plugin portal is never considered

We need to catch dependency resolution exceptions and report the plugin as notFound instead.

Revise plugin use documentation

Motivation

With the ability to apply plugins to sub-projects, the most important roadblock for using the plugins block is removed.

Proposed Change

We should update the user documentation to show these new features. Possibly we should recommend the use of the plugins block over the buildscript block. We also need to update the usage notes on the plugin portal.

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Create a sample Plugins Maven Repository

We want to have a Maven repository we can play with which houses plugin artifacts and whatever metadata we want to allow resolving those artifacts from plugin ids and versions.

Initially, this can just be a local maven repository that we either generate (like we do with Gradle's own performance:lotDependencies task) or just check into the stable-plugins-dsl github project somewhere.

Search gradlePluginsPortal for dependencies

Problem

When using the pluginRepositories {} block, and resolving a plugin from a custom repository which has dependencies on another plugin which is available in the gradlePluginsPortal the dependency is not found.

Originally reported in the Gradle Forum.

Proposed Change

We need to fix this. One thing we could do is to make the DefaultGradlePluginPortal implement BackedByArtifactRepository and provide the maven ree

Code review

  • Does the change work?
  • Is the change sufficiently tested?
  • Does it change the public API?
  • Is it sufficiently documented?
  • Is it implemented well?

Add Performance Test for Many Plugins on Subprojects

Motivation

We know there will be users which apply several plugins to a whole mess of subprojects with the addition of support for the allprojects {} and subprojects {} support for plugin application in M2. We should ensure that using the plugins {} block in this way doesn't incur an unreasonable performance hit.

Proposed Change

Add a performance test template for a project with 500 or so subprojects each of which has about 10 plugins applied to them. Make sure that all of the plugin resolution happens efficiently.

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Integrate marker publishing into java-gradle-plugin

Motivation

In order to resolve plugins from a custom plugin repository, this repository needs to contain plugin markers. Since missing or malformed markers will lead to plugin resolution failures, the marker publishing should be automated for our users.

Proposed Change

Change to java-gradle-plugin DSL to explicitly declare the plugins to build and publish:

gradlePlugin {
  //existing stuff like testkit integration here

  plugins {
    helloPlugin {
      id = 'org.example.hello'
    }
  }
}

If the maven-publish and/or ivy-publish plugin are applied, the main plugin artifact is published automatically under "project.group:project.name:project.version", while each plugin marker is published under "plugin.id:plugin.id:project.version"

Future enhancements include:

  • auto-generating the plugin .properties file
  • specifying different versions for each plugin
  • setting a description that will be added to the plugin marker publication

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Revise plugin use documentation

Motivation

With the ability to apply plugins to sub-projects, the most important roadblock for using the plugins block is removed.

Proposed Change

We should update the user documentation to show these new features. Possibly we should recommend the use of the plugins block over the buildscript block. We also need to update the usage notes on the plugin portal.

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Allow accessing immutable project properties in plugins block

Motivation

Often a plugin should not be applied to all projects, but only to those that match certain criteria, e.g. name, location, existence of some file or some property being set in gradle.properties. The plugins block should allow access to these immutable properties of a project, e.g.:

plugins {
  subprojects {
    if (findProperty('openSource')) {
      id 'oss.publishing.plugin' version '1.0'
    }
    if (file('build.properties')) {
      id 'eclipse.plugin' version '1.0'
    }
    if (name.endsWith('test')) {
      id 'testing.plugin' version '1.0'
    }
  }
}

Proposed Change

Allow access to the name, location and properties of the projects in the plugins block. Do not allow any other method or property access. Do not allow mutation of the name/location/properties.

Code review

  • Does the change work?
    • Try out the feature, executing it like a end-user would.
    • Check corner cases and try to break it in various ways.
    • Are the error messages informative?
  • Is the change sufficiently tested?
    • Are there appropriate levels of unit & integration tests?
    • Do the tests indicate what they are actually testing?
    • Are the tests in the right location?
    • Can new tests be consolidated with any existing tests?
  • Does it change the public API?
    • Has @Incubating been used appropriately?
    • Does it preserve backward compatibility?
  • Is it sufficiently documented?
    • Is the user guide documentation in the best location?
    • Is the user guide documentation clear and informative?
    • If there should be samples, are they helpful and tested appropriately?
    • Is there sufficient API/DSL documentation?
    • Is the API/DSL documentation clear and informative?
    • Do the release notes clearly convey the value of the feature?
    • Do the release notes explain the feature and link to more documentation?
  • Is it implemented well?
    • Does it minimize surface area (particularly public)?
    • Does it follow our coding conventions? (note that we don't have coding conventions formalized but it's something to keep in mind)
    • Does it use appropriate data structures?
    • Does it minimize potential for invalid states?
    • Does it suitably reuse existing infrastructure?
    • Does it suitably consider concurrency?
    • Does it suitably consider failure modes?
    • Does it suitably consider performance?
    • Does it introduce new types or move existing ones? Are they located in the appropriate package? (e.g. internal classes in internal packages)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.