diff --git a/src/main/java/org/hypertrace/gradle/dependency/DeleteSettingsLockfileAction.java b/src/main/java/org/hypertrace/gradle/dependency/DeleteSettingsLockfileAction.java new file mode 100644 index 0000000..a05ca26 --- /dev/null +++ b/src/main/java/org/hypertrace/gradle/dependency/DeleteSettingsLockfileAction.java @@ -0,0 +1,26 @@ +package org.hypertrace.gradle.dependency; + +import java.io.File; +import javax.annotation.Nonnull; +import javax.inject.Inject; +import org.gradle.api.file.FileSystemOperations; +import org.gradle.api.flow.FlowAction; +import org.gradle.api.flow.FlowParameters; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.hypertrace.gradle.dependency.DeleteSettingsLockfileAction.Parameters; + +public abstract class DeleteSettingsLockfileAction implements FlowAction { + interface Parameters extends FlowParameters { + @Input + Property getDeleteTarget(); + } + + @Inject + protected abstract FileSystemOperations getFileSystemOperations(); + + @Override + public void execute(@Nonnull Parameters parameters) { + getFileSystemOperations().delete(spec -> spec.delete(parameters.getDeleteTarget())); + } +} diff --git a/src/main/java/org/hypertrace/gradle/dependency/DependencyPluginSettingExtension.java b/src/main/java/org/hypertrace/gradle/dependency/DependencyPluginSettingExtension.java index 90ccdad..a55f433 100644 --- a/src/main/java/org/hypertrace/gradle/dependency/DependencyPluginSettingExtension.java +++ b/src/main/java/org/hypertrace/gradle/dependency/DependencyPluginSettingExtension.java @@ -13,13 +13,12 @@ public class DependencyPluginSettingExtension { private static final String DEFAULT_BOM_ARTIFACT_NAME = "hypertrace.bom"; private static final String DEFAULT_BOM_VERSION_NAME = "hypertrace.bom"; private static final String DEFAULT_BOM_VERSION = "+"; - private static final boolean DEFAULT_USE_DEPENDENCY_LOCKING = true; public final Property catalogGroup; public final Property catalogArtifact; public final Property catalogVersion; public final Property catalogName; - public final Property useDependencyLocking; + public final Property dependencyLockMode; public final Property bomArtifactName; public final Property bomVersionName; public final Property bomVersion; @@ -35,9 +34,11 @@ public DependencyPluginSettingExtension(ObjectFactory objectFactory) { this.catalogVersion.disallowUnsafeRead(); this.catalogName = objectFactory.property(String.class).convention(DEFAULT_CATALOG_NAME); this.catalogName.disallowUnsafeRead(); - this.useDependencyLocking = - objectFactory.property(Boolean.class).convention(DEFAULT_USE_DEPENDENCY_LOCKING); - this.useDependencyLocking.disallowUnsafeRead(); + this.dependencyLockMode = + objectFactory + .property(DependencyLockingMode.class) + .convention(DependencyLockingMode.PROJECTS_ONLY); + this.dependencyLockMode.disallowUnsafeRead(); this.bomArtifactName = objectFactory.property(String.class).convention(DEFAULT_BOM_ARTIFACT_NAME); this.bomArtifactName.disallowUnsafeRead(); @@ -57,4 +58,10 @@ Provider getCatalogArtifactNotation() { String.format( "%s:%s:%s", groupString, artifactString, versionString)))); } + + public enum DependencyLockingMode { + DISABLED, + PROJECTS_ONLY, // Default + PROJECTS_AND_SETTINGS // Typically not desired due to bugs in the settings lock. + } } diff --git a/src/main/java/org/hypertrace/gradle/dependency/HypertraceDependencySettingsPlugin.java b/src/main/java/org/hypertrace/gradle/dependency/HypertraceDependencySettingsPlugin.java index 6e42937..8db2d18 100644 --- a/src/main/java/org/hypertrace/gradle/dependency/HypertraceDependencySettingsPlugin.java +++ b/src/main/java/org/hypertrace/gradle/dependency/HypertraceDependencySettingsPlugin.java @@ -1,5 +1,8 @@ package org.hypertrace.gradle.dependency; +import java.io.File; +import java.util.Optional; +import javax.inject.Inject; import org.gradle.api.GradleException; import org.gradle.api.Plugin; import org.gradle.api.Project; @@ -9,19 +12,26 @@ import org.gradle.api.artifacts.VersionCatalogsExtension; import org.gradle.api.artifacts.dsl.LockMode; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; +import org.gradle.api.flow.FlowProviders; +import org.gradle.api.flow.FlowScope; import org.gradle.api.initialization.Settings; import org.gradle.api.initialization.dsl.VersionCatalogBuilder; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.provider.Provider; +import org.hypertrace.gradle.dependency.DependencyPluginSettingExtension.DependencyLockingMode; import org.jetbrains.annotations.NotNull; -import java.util.Optional; - -public class HypertraceDependencySettingsPlugin implements Plugin { +public abstract class HypertraceDependencySettingsPlugin implements Plugin { private static final String HYPERTRACE_REPOSITORY_URL = "https://hypertrace.jfrog.io/artifactory/maven"; private static final String CONFLUENT_REPOSITORY_URL = "https://packages.confluent.io/maven"; + @Inject + protected abstract FlowScope getFlowScope(); + + @Inject + protected abstract FlowProviders getFlowProviders(); + @Override public void apply(@NotNull Settings settings) { DependencyPluginSettingExtension settingExtension = this.createSettingsExtension(settings); @@ -47,11 +57,16 @@ public void apply(@NotNull Settings settings) { this.addProjectExtension(project); this.addBomDependencyIfRequested( project, settingExtension, projectExtension); - if (settingExtension.useDependencyLocking.get()) { + if (settingExtension + .dependencyLockMode + .map(this::shouldEnableProjectLocking) + .get()) { this.addDependencyLocking(project, projectExtension); this.addLockTask(project, projectExtension); } })); + + this.addSettingsLockDeletionIfNeeded(settings, settingExtension); } private DependencyPluginSettingExtension createSettingsExtension(Settings target) { @@ -70,6 +85,31 @@ private DependencyPluginProjectExtension addProjectExtension(Project project) { DependencyPluginProjectExtension.class); } + private void addSettingsLockDeletionIfNeeded( + Settings settings, DependencyPluginSettingExtension settingExtension) { + // This is confusing. Based off https://docs.gradle.org/current/userguide/dataflow_actions.html + + // We only get the build work result to make sure this isn't available until after build is + // complete + getFlowScope() + .always( + DeleteSettingsLockfileAction.class, + spec -> + spec.getParameters() + .getDeleteTarget() + .set( + getFlowProviders() + .getBuildWorkResult() + .zip( + settingExtension.dependencyLockMode, + (result, lockMode) -> + shouldEnableSettingsLocking(lockMode) + ? null // No file to delete if locking enabled + : new File( + settings.getSettingsDir(), + "settings-gradle.lockfile")))); + } + private void updateLocalCatalogNameConvention(Settings settings) { // Update convention to make it clear which libs are local and which come from common catalog settings @@ -78,6 +118,32 @@ private void updateLocalCatalogNameConvention(Settings settings) { .convention("localLibs"); } + private boolean shouldEnableProjectLocking(DependencyLockingMode mode) { + switch (mode) { + case PROJECTS_ONLY: + case PROJECTS_AND_SETTINGS: + return true; + case DISABLED: + return false; + default: + throw new UnsupportedOperationException( + String.format("Unrecognized locking mode: %s", mode)); + } + } + + private boolean shouldEnableSettingsLocking(DependencyLockingMode mode) { + switch (mode) { + case PROJECTS_AND_SETTINGS: + return true; + case PROJECTS_ONLY: + case DISABLED: + return false; + default: + throw new UnsupportedOperationException( + String.format("Unrecognized locking mode: %s", mode)); + } + } + /** * If autoApplyBom is true, this adds a BOM automatically to the target project. Configuration is * determined by {@link #resolveBomHostConfigurationName(Project)}