diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index c449202..4ad5523 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -336,6 +336,40 @@ gitRepositories { } ---- +== Performing actions before the build is included + +It is possible to perform actions right after a project has been cloned and before it is included. +This can be useful, for example, if the project needs to be analyzed in order to properly configure the included builds. + +The action will always be called, even if sources are already available locally. +It is **not** recommended to mutate sources as part of this callback, since this will likely break updating the sources later. + +.Executing code before the build is included +[source,groovy,role="multi-language-sample",subs="attributes+"] +---- +gitRepositories { + include('my-project') { + // ... + codeReady { event -> + println("Project cloned in ${event.checkoutDirectory}") + } + } +} +---- + +[source,kotlin,role="multi-language-sample",subs="attributes+"] +---- +gitRepositories { + include("my-project") { + // ... + codeReady { + println("Project cloned in ${checkoutDirectory}") + } + } +} +---- + + [[comparison]] == Comparison of solutions diff --git a/plugin/src/functionalTest/groovy/me/champeau/gradle/igp/BasicFunctionalTest.groovy b/plugin/src/functionalTest/groovy/me/champeau/gradle/igp/BasicFunctionalTest.groovy index d8cbdad..6ed3802 100644 --- a/plugin/src/functionalTest/groovy/me/champeau/gradle/igp/BasicFunctionalTest.groovy +++ b/plugin/src/functionalTest/groovy/me/champeau/gradle/igp/BasicFunctionalTest.groovy @@ -23,6 +23,8 @@ class BasicFunctionalTest extends AbstractFunctionalTest { \\--- com.acme.somelib:somelib1:0.0 -> project :testlib0 ''' + outputContains 'Code ready' + where: useCommit << [false, true] } diff --git a/plugin/src/main/java/me/champeau/gradle/igp/IncludedGitRepo.java b/plugin/src/main/java/me/champeau/gradle/igp/IncludedGitRepo.java index 5dd8d75..942f333 100644 --- a/plugin/src/main/java/me/champeau/gradle/igp/IncludedGitRepo.java +++ b/plugin/src/main/java/me/champeau/gradle/igp/IncludedGitRepo.java @@ -21,6 +21,8 @@ import org.gradle.api.initialization.ConfigurableIncludedBuild; import org.gradle.api.provider.Property; +import java.io.File; + /** * Configures an included Git repository. */ @@ -94,4 +96,35 @@ default void includeBuild(String relativePath) { * @param config the authentication configuration */ void authentication(Action config); + + /** + * Allows executing some code right after a repository has been checked out, typically + * before the directory is included in a composite build. + * @param configuration the configuration action + */ + void codeReady(Action configuration); + + /** + * Base interface for events. + */ + interface Event { + /** + * The git repository for which the event was called + * @return the git repository + */ + IncludedGitRepo getIncludedGitRepo(); + } + + /** + * Event triggered when the code of an included repository + * is ready (e.g checked out). It is _not_ recommended to alter + * the contents of the directory as it will likely break updates. + */ + interface CodeReadyEvent extends Event { + /** + * The directory where the project is checked out. + * @return the directory + */ + File getCheckoutDirectory(); + } } diff --git a/plugin/src/main/java/me/champeau/gradle/igp/internal/DefaultIncludedGitRepo.java b/plugin/src/main/java/me/champeau/gradle/igp/internal/DefaultIncludedGitRepo.java index ea536f7..14ab329 100644 --- a/plugin/src/main/java/me/champeau/gradle/igp/internal/DefaultIncludedGitRepo.java +++ b/plugin/src/main/java/me/champeau/gradle/igp/internal/DefaultIncludedGitRepo.java @@ -33,6 +33,7 @@ public abstract class DefaultIncludedGitRepo implements IncludedGitRepo { private final ObjectFactory objects; private final Action rootSpec; private final List includes = new ArrayList<>(); + private final List> codeReadyEvents = new ArrayList<>(); private DefaultAuthentication auth; @Inject @@ -56,6 +57,11 @@ public void includeBuild(Action spec) { }); } + @Override + public void codeReady(Action configuration) { + codeReadyEvents.add(configuration); + } + /** * If this method is called, then the auto-include property will * automatically be set to false. @@ -86,6 +92,9 @@ Optional getAuth() { } void configure(Settings settings, File checkoutDirectory) { + if (!codeReadyEvents.isEmpty()) { + fireCodeReadyEvents(checkoutDirectory); + } if (getAutoInclude().get()) { settings.includeBuild(checkoutDirectory, rootSpec); } else { @@ -97,6 +106,23 @@ void configure(Settings settings, File checkoutDirectory) { } } + private void fireCodeReadyEvents(File checkoutDirectory) { + CodeReadyEvent codeReadyEvent = new CodeReadyEvent() { + @Override + public IncludedGitRepo getIncludedGitRepo() { + return DefaultIncludedGitRepo.this; + } + + @Override + public File getCheckoutDirectory() { + return checkoutDirectory; + } + }; + for (Action action : codeReadyEvents) { + action.execute(codeReadyEvent); + } + } + private static class IncludedBuild { private final String directory; private final Action spec; diff --git a/samples/basic/groovy/settings.gradle b/samples/basic/groovy/settings.gradle index a91feb3..b84076d 100644 --- a/samples/basic/groovy/settings.gradle +++ b/samples/basic/groovy/settings.gradle @@ -17,5 +17,9 @@ gitRepositories { if (gradle.startParameter.projectProperties.containsKey('checkoutDir')) { checkoutDirectory.set(file(gradle.startParameter.projectProperties.get('checkoutDir'))) } + codeReady { event -> + println "Code ready" + println "Checkout directory: ${event.checkoutDirectory}" + } } } diff --git a/samples/basic/kotlin/settings.gradle.kts b/samples/basic/kotlin/settings.gradle.kts index 3e1c49e..e8efb4b 100644 --- a/samples/basic/kotlin/settings.gradle.kts +++ b/samples/basic/kotlin/settings.gradle.kts @@ -20,5 +20,9 @@ gitRepositories { if (gradle.startParameter.projectProperties.containsKey("checkoutDir")) { checkoutDirectory.set(file(gradle.startParameter.projectProperties.get("checkoutDir")!!)) } + codeReady { + println("Code ready") + println("Checkout directory: ${checkoutDirectory}") + } } }