diff --git a/README.md b/README.md index a1287baa..cd783f98 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,13 @@ If you are making changes to the plugins, please see the [internal docs](https:/ on how to do that, including how to develop and test locally and the versioning information. ## Release Notes -### 8.2.0-SNAPSHOT -*Released*: TBD + +### 8.2.0 +*Released*: 11 May 2026 (Earliest compatible LabKey version: 26.5.0) +- Add `BuildUtils.hasArtifactoryProperties` method for brevity +- Add cacheability annotations to tasks so they work with stricter plugin validation +- Update to Gradle 9.5.0 ### 8.1.0 *Released*: 22 April 2026 diff --git a/build.gradle b/build.gradle index 668425e5..91477b5b 100644 --- a/build.gradle +++ b/build.gradle @@ -43,12 +43,7 @@ dependencies { } group = 'org.labkey.build' -project.version = "8.2.0-SNAPSHOT" - -// Stricter plugin validation was added in 9.4.0. Disable it for now. TODO: Address complaints and remove. -tasks.validatePlugins { - enableStricterValidation = false -} +project.version = "8.2.0-pluginValidation-SNAPSHOT" gradlePlugin { plugins { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f8e1ee31..d997cfc6 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew index adff685a..739907df 100755 --- a/gradlew +++ b/gradlew @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. diff --git a/src/main/groovy/org/labkey/gradle/task/Bootstrap.groovy b/src/main/groovy/org/labkey/gradle/task/Bootstrap.groovy index 572e1173..a482a717 100644 --- a/src/main/groovy/org/labkey/gradle/task/Bootstrap.groovy +++ b/src/main/groovy/org/labkey/gradle/task/Bootstrap.groovy @@ -15,8 +15,10 @@ */ package org.labkey.gradle.task +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.util.DatabaseProperties +@UntrackedTask(because="Should always be run") abstract class Bootstrap extends DoThenSetup { @Override diff --git a/src/main/groovy/org/labkey/gradle/task/CheckForVersionConflicts.groovy b/src/main/groovy/org/labkey/gradle/task/CheckForVersionConflicts.groovy index 53fa7c44..e076a4ac 100644 --- a/src/main/groovy/org/labkey/gradle/task/CheckForVersionConflicts.groovy +++ b/src/main/groovy/org/labkey/gradle/task/CheckForVersionConflicts.groovy @@ -21,7 +21,10 @@ import org.gradle.api.file.FileCollection import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.util.BuildUtils import java.util.regex.Matcher @@ -29,7 +32,8 @@ import java.util.regex.Matcher /** * Checks for conflicts that may exist between a file collection and the files in an existing directory */ -class CheckForVersionConflicts extends DefaultTask +@UntrackedTask(because="Should always be run") +class CheckForVersionConflicts extends DefaultTask { // GH Issue 1015: We are using milestone versions of spring-ai jars, which use classifiers like -M2 to distinguish the different versions. // We want to have the later milestones replace the earlier ones, so we want to exclude the milestone classifier from the name when @@ -64,7 +68,7 @@ class CheckForVersionConflicts extends DefaultTask project.hasProperty('versionConflictAction') ? ConflictAction.valueOf((String) project.property('versionConflictAction')) : ConflictAction.fail) /** The collection of files to check for. Usually this will come from a configuration. **/ - @InputFiles + @InputFiles @PathSensitive(PathSensitivity.RELATIVE) FileCollection collection /** The name of a task to run if conflicts are found that will resolve the conflict (presumably by cleaning out the directory) **/ diff --git a/src/main/groovy/org/labkey/gradle/task/ClientLibsCompress.groovy b/src/main/groovy/org/labkey/gradle/task/ClientLibsCompress.groovy index 816af2c1..0de7ea1c 100644 --- a/src/main/groovy/org/labkey/gradle/task/ClientLibsCompress.groovy +++ b/src/main/groovy/org/labkey/gradle/task/ClientLibsCompress.groovy @@ -23,10 +23,13 @@ import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.file.FileTree +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputDirectories import org.gradle.api.tasks.OutputFiles +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.labkey.gradle.plugin.NpmRun import org.labkey.gradle.plugin.extension.LabKeyExtension @@ -43,19 +46,24 @@ import java.util.stream.Collectors /** * Class for compressing javascript and css files using the yuicompressor classes. */ +@CacheableTask class ClientLibsCompress extends DefaultTask { public static final String LIB_XML_EXTENSION = ".lib.xml" - protected File workingDir = new File((String) project.labkey.explodedModuleWebDir) - // This returns the libXml files from the project directory (the actual input files) @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) FileTree xmlFiles private List inputFiles = null private List outputFiles = null private List outputDirs = null + @Internal + String getWorkingDirPath() { + return new File((String) project.labkey.explodedModuleWebDir).getAbsolutePath() + } + /** * Creates a map between the individual .lib.xml files and the importers used to parse these files and * extract the css and javascript files that are referenced. @@ -103,6 +111,7 @@ class ClientLibsCompress extends DefaultTask * @return list of all the .lib.xml files and the (internal) files referenced in the .lib.xml files */ @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) List getInputFiles() { if (inputFiles == null) @@ -139,7 +148,7 @@ class ClientLibsCompress extends DefaultTask getImporterMap().entrySet().each { Map.Entry entry -> // The output file will be in the working directory not in the source directory used when parsing the file. String fileName = entry.key.getAbsolutePath() - fileName = fileName.replace(entry.value.sourceDir.getAbsolutePath(), workingDir.getAbsolutePath()) + fileName = fileName.replace(entry.value.sourceDir.getAbsolutePath(), getWorkingDirPath()) File workingFile = project.file(fileName) if (entry.value.getCssFiles().size() > 0) { @@ -306,7 +315,7 @@ class ClientLibsCompress extends DefaultTask File cssMinFile = null File sourceDir = getSourceDir(xmlFile) - File workingFile = new File(xmlFile.getAbsolutePath().replace(sourceDir.getAbsolutePath(), workingDir.getAbsolutePath())) + File workingFile = new File(xmlFile.getAbsolutePath().replace(sourceDir.getAbsolutePath(), getWorkingDirPath())) File packageJson = new File(getMinificationWorkingDir(xmlFile), "package.json") project.logger.info("Creating ${packageJson} for ${xmlFile.getAbsolutePath()}") diff --git a/src/main/groovy/org/labkey/gradle/task/CopyAndInstallRPackage.groovy b/src/main/groovy/org/labkey/gradle/task/CopyAndInstallRPackage.groovy index f231447d..28682d16 100644 --- a/src/main/groovy/org/labkey/gradle/task/CopyAndInstallRPackage.groovy +++ b/src/main/groovy/org/labkey/gradle/task/CopyAndInstallRPackage.groovy @@ -4,16 +4,21 @@ import org.gradle.api.file.CopySpec import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileSystemOperations import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskExecutionException +import org.gradle.work.DisableCachingByDefault import javax.inject.Inject +@DisableCachingByDefault(because="Does only file copying") abstract class CopyAndInstallRPackage extends InstallRPackage { @Inject abstract FileSystemOperations getFs() @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) File packageLocation @TaskAction diff --git a/src/main/groovy/org/labkey/gradle/task/CopyJsp.groovy b/src/main/groovy/org/labkey/gradle/task/CopyJsp.groovy index 6fff9e0b..6a61eaff 100644 --- a/src/main/groovy/org/labkey/gradle/task/CopyJsp.groovy +++ b/src/main/groovy/org/labkey/gradle/task/CopyJsp.groovy @@ -3,12 +3,16 @@ package org.labkey.gradle.task import org.gradle.api.DefaultTask import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileSystemOperations +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import javax.inject.Inject +@CacheableTask abstract class CopyJsp extends DefaultTask { public static final String WEBAPP_DIR = "jspWebappDir/webapp" @@ -16,6 +20,7 @@ abstract class CopyJsp extends DefaultTask @Inject abstract FileSystemOperations getFs() @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty srcDir = project.objects.directoryProperty().convention(project.layout.projectDirectory.dir('src')) @OutputDirectory diff --git a/src/main/groovy/org/labkey/gradle/task/CreateJsDocs.groovy b/src/main/groovy/org/labkey/gradle/task/CreateJsDocs.groovy index a84c52a7..44fd6504 100644 --- a/src/main/groovy/org/labkey/gradle/task/CreateJsDocs.groovy +++ b/src/main/groovy/org/labkey/gradle/task/CreateJsDocs.groovy @@ -21,20 +21,26 @@ import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.gradle.process.ExecOperations import org.labkey.gradle.plugin.XsdDoc import javax.inject.Inject +@CacheableTask abstract class CreateJsDocs extends DefaultTask { @Inject abstract ExecOperations getExec() @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty templateDir = project.objects.directoryProperty().convention( project.rootProject.layout.projectDirectory.dir("tools/jsdoc-toolkit/templates/jsdoc_substituted") ) diff --git a/src/main/groovy/org/labkey/gradle/task/CreateModule.groovy b/src/main/groovy/org/labkey/gradle/task/CreateModule.groovy index 8ca8fe23..01f4cd06 100644 --- a/src/main/groovy/org/labkey/gradle/task/CreateModule.groovy +++ b/src/main/groovy/org/labkey/gradle/task/CreateModule.groovy @@ -22,6 +22,7 @@ import org.gradle.api.file.CopySpec import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileTree import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.util.BuildUtils import java.util.regex.Matcher @@ -32,6 +33,7 @@ import java.util.regex.Pattern * user input based on the prompt flag. * Documented at labkey.org */ +@UntrackedTask(because="Has user interaction and side effects") class CreateModule extends DefaultTask { @TaskAction diff --git a/src/main/groovy/org/labkey/gradle/task/CreateXsdDocs.groovy b/src/main/groovy/org/labkey/gradle/task/CreateXsdDocs.groovy index 6777d7c5..75be6f97 100644 --- a/src/main/groovy/org/labkey/gradle/task/CreateXsdDocs.groovy +++ b/src/main/groovy/org/labkey/gradle/task/CreateXsdDocs.groovy @@ -20,6 +20,7 @@ import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles @@ -30,6 +31,7 @@ import org.labkey.gradle.plugin.XsdDoc import javax.inject.Inject +@CacheableTask abstract class CreateXsdDocs extends DefaultTask { @Inject abstract ExecOperations getExec() diff --git a/src/main/groovy/org/labkey/gradle/task/DeployApp.groovy b/src/main/groovy/org/labkey/gradle/task/DeployApp.groovy index c6cd1dc9..63c4f5bc 100644 --- a/src/main/groovy/org/labkey/gradle/task/DeployApp.groovy +++ b/src/main/groovy/org/labkey/gradle/task/DeployApp.groovy @@ -26,17 +26,22 @@ import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.plugin.ServerDeploy import org.labkey.gradle.plugin.extension.ServerDeployExtension import org.labkey.gradle.util.BuildUtils +@DisableCachingByDefault(because="Outputs are in the deploy directory") abstract class DeployApp extends DeployAppBase { - @InputDirectory + @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty stagingModulesDir = BuildUtils.getRootBuildDirectoryProperty(project, ServerDeploy.STAGING_MODULES_DIR) @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty stagingPipelineJarDir = BuildUtils.getRootBuildDirectoryProperty(project, ServerDeploy.STAGING_PIPELINE_DIR) @OutputDirectory @@ -62,6 +67,7 @@ abstract class DeployApp extends DeployAppBase final abstract DirectoryProperty embeddedDir = project.objects.directoryProperty().convention(ServerDeployExtension.getEmbeddedServerDeployDirectory(project)) @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) abstract ConfigurableFileCollection getBootJar() @TaskAction diff --git a/src/main/groovy/org/labkey/gradle/task/DeployAppBase.groovy b/src/main/groovy/org/labkey/gradle/task/DeployAppBase.groovy index 2f2d86d8..c1149b0d 100644 --- a/src/main/groovy/org/labkey/gradle/task/DeployAppBase.groovy +++ b/src/main/groovy/org/labkey/gradle/task/DeployAppBase.groovy @@ -8,15 +8,20 @@ import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileSystemOperations import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.util.BuildUtils import javax.inject.Inject +@DisableCachingByDefault(because="Outputs are in the deploy directory") abstract class DeployAppBase extends SetUpProperties { @Inject abstract FileSystemOperations getFs() @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) abstract ConfigurableFileCollection getBinaries() @OutputDirectory diff --git a/src/main/groovy/org/labkey/gradle/task/DeployDistribution.groovy b/src/main/groovy/org/labkey/gradle/task/DeployDistribution.groovy index 216a0ce1..30616981 100644 --- a/src/main/groovy/org/labkey/gradle/task/DeployDistribution.groovy +++ b/src/main/groovy/org/labkey/gradle/task/DeployDistribution.groovy @@ -11,12 +11,16 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.Optional import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.plugin.extension.DistributionExtension import org.labkey.gradle.plugin.extension.ServerDeployExtension import javax.inject.Inject +@DisableCachingByDefault(because="Outputs are in the deploy directory") abstract class DeployDistribution extends DeployAppBase { @Inject abstract ArchiveOperations getArchiveOps() @@ -31,6 +35,7 @@ abstract class DeployDistribution extends DeployAppBase final abstract DirectoryProperty deployBinDir = project.objects.directoryProperty().convention(ServerDeployExtension.getEmbeddedBinDir(project)) @InputFile @Optional + @PathSensitive(PathSensitivity.RELATIVE) final abstract RegularFileProperty distributionFile = project.objects.fileProperty().fileValue(DistributionExtension.getDistributionFile(project, distDir.get())) @TaskAction diff --git a/src/main/groovy/org/labkey/gradle/task/DoThenSetup.groovy b/src/main/groovy/org/labkey/gradle/task/DoThenSetup.groovy index 565069dc..00f62c9a 100644 --- a/src/main/groovy/org/labkey/gradle/task/DoThenSetup.groovy +++ b/src/main/groovy/org/labkey/gradle/task/DoThenSetup.groovy @@ -16,7 +16,9 @@ package org.labkey.gradle.task import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask +@UntrackedTask(because="No trackable file outputs") abstract class DoThenSetup extends SetUpProperties { protected void doDatabaseTask() diff --git a/src/main/groovy/org/labkey/gradle/task/InstallRPackage.groovy b/src/main/groovy/org/labkey/gradle/task/InstallRPackage.groovy index f3674b67..58fca9cd 100644 --- a/src/main/groovy/org/labkey/gradle/task/InstallRPackage.groovy +++ b/src/main/groovy/org/labkey/gradle/task/InstallRPackage.groovy @@ -22,8 +22,10 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.extension.TeamCityExtension +@UntrackedTask(because="Does only file copying outside the build directory") class InstallRPackage extends DefaultTask { @Optional @Input diff --git a/src/main/groovy/org/labkey/gradle/task/JspCompile2Java.groovy b/src/main/groovy/org/labkey/gradle/task/JspCompile2Java.groovy index 7a316189..2fb5e262 100644 --- a/src/main/groovy/org/labkey/gradle/task/JspCompile2Java.groovy +++ b/src/main/groovy/org/labkey/gradle/task/JspCompile2Java.groovy @@ -47,8 +47,7 @@ abstract class JspCompile2Java extends DefaultTask @Input final abstract Property sourceCompatibility = project.objects.property(String).convention((String) project.property('sourceCompatibility')) - @PathSensitive(PathSensitivity.RELATIVE) - @InputDirectory + @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) File webappDirectory @OutputDirectory diff --git a/src/main/groovy/org/labkey/gradle/task/ModuleDistribution.groovy b/src/main/groovy/org/labkey/gradle/task/ModuleDistribution.groovy index b9283249..e4530bda 100644 --- a/src/main/groovy/org/labkey/gradle/task/ModuleDistribution.groovy +++ b/src/main/groovy/org/labkey/gradle/task/ModuleDistribution.groovy @@ -23,6 +23,7 @@ import org.gradle.api.file.CopySpec import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileSystemOperations import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.OutputDirectory @@ -37,6 +38,7 @@ import org.labkey.gradle.util.GroupNames import javax.inject.Inject +@CacheableTask abstract class ModuleDistribution extends DefaultTask { @Inject abstract FileSystemOperations getFs() diff --git a/src/main/groovy/org/labkey/gradle/task/ModuleXmlFile.groovy b/src/main/groovy/org/labkey/gradle/task/ModuleXmlFile.groovy index 635ba319..422b3346 100644 --- a/src/main/groovy/org/labkey/gradle/task/ModuleXmlFile.groovy +++ b/src/main/groovy/org/labkey/gradle/task/ModuleXmlFile.groovy @@ -4,6 +4,7 @@ import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.MapProperty +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction @@ -12,6 +13,7 @@ import org.labkey.gradle.util.PropertiesUtils import java.util.regex.Matcher +@CacheableTask abstract class ModuleXmlFile extends DefaultTask { @Input diff --git a/src/main/groovy/org/labkey/gradle/task/PickDb.groovy b/src/main/groovy/org/labkey/gradle/task/PickDb.groovy index 03972edd..4a4c9d2d 100644 --- a/src/main/groovy/org/labkey/gradle/task/PickDb.groovy +++ b/src/main/groovy/org/labkey/gradle/task/PickDb.groovy @@ -20,10 +20,14 @@ import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileSystemOperations import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.util.BuildUtils import javax.inject.Inject +@UntrackedTask(because="Does only file copying and should always be run") abstract class PickDb extends DoThenSetup { @Inject abstract FileSystemOperations getFs() @@ -31,7 +35,7 @@ abstract class PickDb extends DoThenSetup @Input String dbType - @InputDirectory + @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) File configsDir = new File(BuildUtils.getConfigsProject(project).projectDir, "configs") @Override diff --git a/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy b/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy index cdadfae1..ee0bef22 100644 --- a/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy +++ b/src/main/groovy/org/labkey/gradle/task/PurgeArtifacts.groovy @@ -1,6 +1,6 @@ package org.labkey.gradle.task -import org.apache.commons.io.IOUtils + import org.apache.commons.lang3.StringUtils import org.apache.hc.client5.http.classic.methods.HttpDelete import org.apache.hc.client5.http.impl.classic.CloseableHttpClient @@ -13,17 +13,19 @@ import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask +import org.gradle.work.DisableCachingByDefault +import org.labkey.gradle.util.BuildUtils import org.labkey.gradle.util.TaskUtils -import java.nio.file.Paths - +@UntrackedTask(because="External side effects only") class PurgeArtifacts extends DefaultTask { public static final String SNAPSHOT_REPOSITORY_NAME = 'libs-snapshot-local' public static final String RELEASE_REPOSITORY_NAME = 'libs-release-local' public static final String VERSION_PROPERTY = 'purgeVersion' public static final String VERSIONS_FILE_PROPERTY = 'purgeVersions' - public static final String PURGE_LIST_FILE_PROPERTY = 'purgeList'; + public static final String PURGE_LIST_FILE_PROPERTY = 'purgeList' public static final String DRY_RUN_PROPERTY = 'dryRun'; @Input @Optional @@ -36,11 +38,11 @@ class PurgeArtifacts extends DefaultTask final abstract Property isDryRun = project.objects.property(Boolean).convention(project.hasProperty(DRY_RUN_PROPERTY)) @Input - final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property('artifactory_contextUrl')) + final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property(BuildUtils.ARTIFACTORY_CONTEXT_URL_PROP)) @Input - final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property('artifactory_user')) + final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property(BuildUtils.ARTIFACTORY_USER_PROP)) @Input - final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property('artifactory_password')) + final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property(BuildUtils.ARTIFACTORY_PASSWORD_PROP)) enum Response { SUCCESS, @@ -66,6 +68,7 @@ class PurgeArtifacts extends DefaultTask else { Map overallStats = new HashMap<>() + List inactiveModules = new ArrayList<>() overallStats.put(NUM_NOT_FOUND, 0) overallStats.put(NUM_DELETED, 0) String purgeVersionsFileName = purgeVersions.get() @@ -77,11 +80,16 @@ class PurgeArtifacts extends DefaultTask if (versions.size() > 1) { for (String moduleName : moduleNames) { Map deleteStats = purgeModuleVersions(moduleName, versions) + if (deleteStats.get(NUM_DELETED) == 0) // if none of the versions in question were deleted, we may have removed all versions of this module and can remove it from consideration + inactiveModules.add(moduleName) overallStats.put(NUM_NOT_FOUND, overallStats.get(NUM_NOT_FOUND) + (Integer) deleteStats.get(NUM_NOT_FOUND)) overallStats.put(NUM_DELETED, overallStats.get(NUM_DELETED) + (Integer) deleteStats.get(NUM_DELETED)) } - if (moduleNames.size() > 1) + if (moduleNames.size() > 1) { logger.quiet("\nSummary:\n\tDeleted ${overallStats.get(NUM_DELETED)} artifacts.\n\t${overallStats.get(NUM_NOT_FOUND)} artifacts not found.") + if (!inactiveModules.isEmpty()) + logger.quiet("\n\tModules with no artifacts deleted: " + inactiveModules.join(", ")) + } } else { for (String v : versions) { diff --git a/src/main/groovy/org/labkey/gradle/task/PurgeNpmAlphaVersions.groovy b/src/main/groovy/org/labkey/gradle/task/PurgeNpmAlphaVersions.groovy index 10ca1ced..76aa5d7d 100644 --- a/src/main/groovy/org/labkey/gradle/task/PurgeNpmAlphaVersions.groovy +++ b/src/main/groovy/org/labkey/gradle/task/PurgeNpmAlphaVersions.groovy @@ -7,20 +7,20 @@ import org.apache.hc.client5.http.impl.classic.CloseableHttpClient import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse import org.apache.hc.client5.http.impl.classic.HttpClients import org.apache.hc.core5.http.HttpStatus -import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.NpmRun import java.util.stream.Collectors +@UntrackedTask(because="External side effects only") abstract class PurgeNpmAlphaVersions extends PurgeNpmVersions { private static final String REPOSITORY_NAME = 'libs-client-local' public static final String ALPHA_PREFIX_PROPERTY = 'alphaPrefix' - public static final String DRY_RUN_PROPERTY = 'dryRun' public static final String[] PACKAGE_NAMES = [ '@labkey/api', '@labkey/assayreport', diff --git a/src/main/groovy/org/labkey/gradle/task/PurgeNpmVersions.groovy b/src/main/groovy/org/labkey/gradle/task/PurgeNpmVersions.groovy index d8eaa75d..83c6f033 100644 --- a/src/main/groovy/org/labkey/gradle/task/PurgeNpmVersions.groovy +++ b/src/main/groovy/org/labkey/gradle/task/PurgeNpmVersions.groovy @@ -1,6 +1,5 @@ package org.labkey.gradle.task - import org.apache.commons.lang3.StringUtils import org.apache.hc.client5.http.classic.methods.HttpDelete import org.apache.hc.client5.http.impl.classic.CloseableHttpClient @@ -13,8 +12,11 @@ import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask +import org.labkey.gradle.util.BuildUtils import org.labkey.gradle.util.TaskUtils +@UntrackedTask(because="External side effects only") abstract class PurgeNpmVersions extends DefaultTask { private static final String REPOSITORY_NAME = 'libs-client-local' @@ -33,11 +35,11 @@ abstract class PurgeNpmVersions extends DefaultTask @Input final abstract Property isDryRun = project.objects.property(Boolean).convention(project.hasProperty(DRY_RUN_PROPERTY)) @Input - final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property('artifactory_contextUrl')) + final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property(BuildUtils.ARTIFACTORY_CONTEXT_URL_PROP)) @Input - final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property('artifactory_user')) + final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property(BuildUtils.ARTIFACTORY_USER_PROP)) @Input - final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property('artifactory_password')) + final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property(BuildUtils.ARTIFACTORY_PASSWORD_PROP)) @TaskAction void purgeVersions() diff --git a/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy b/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy index c7c87b3f..bd907930 100644 --- a/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy +++ b/src/main/groovy/org/labkey/gradle/task/RestoreFromTrash.groovy @@ -12,10 +12,13 @@ import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask +import org.labkey.gradle.util.BuildUtils import org.labkey.gradle.util.TaskUtils import static org.labkey.gradle.task.PurgeArtifacts.Response +@UntrackedTask(because="External side effects only") class RestoreFromTrash extends DefaultTask { public static final String VERSION_PROPERTY = "restoreVersion" @@ -33,11 +36,11 @@ class RestoreFromTrash extends DefaultTask final abstract Property isDryRun = project.objects.property(Boolean).convention(project.hasProperty(PurgeArtifacts.DRY_RUN_PROPERTY)) @Input - final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property('artifactory_contextUrl')) + final abstract Property artifactoryUrl = project.objects.property(String).convention((String) project.property(ARTIFACTORY_CONTEXT_URL_PROP)) @Input - final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property('artifactory_user')) + final abstract Property artifactoryUser = project.objects.property(String).convention((String) project.property(ARTIFACTORY_USER_PROP)) @Input - final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property('artifactory_password')) + final abstract Property artifactoryPassword = project.objects.property(String).convention((String) project.property(ARTIFACTORY_PASSWORD_PROP)) private static final String NUM_NOT_FOUND = "numNotFound" private static final String NUM_RESTORED = "numRestored" @@ -163,7 +166,7 @@ class RestoreFromTrash extends DefaultTask } CloseableHttpClient httpClient = HttpClients.createDefault() - String endpoint = project.property('artifactory_contextUrl') + String endpoint = project.property(BuildUtils.ARTIFACTORY_CONTEXT_URL_PROP) Response responseStatus = Response.SUCCESS if (!endpoint.endsWith("/")) endpoint += "/" @@ -178,7 +181,7 @@ class RestoreFromTrash extends DefaultTask { HttpPost httpPost = new HttpPost(endpoint) // N.B. Using Authorization Bearer with an API token does not currently work - httpPost.setHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("${project.property('artifactory_user')}:${project.property('artifactory_password')}".getBytes())) + httpPost.setHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("${project.property(BuildUtils.ARTIFACTORY_USER_PROP)}:${project.property(BuildUtils.ARTIFACTORY_PASSWORD_PROP)}".getBytes())) CloseableHttpResponse response = httpClient.execute(httpPost) int statusCode = response.getCode() diff --git a/src/main/groovy/org/labkey/gradle/task/RunTestSuite.groovy b/src/main/groovy/org/labkey/gradle/task/RunTestSuite.groovy index 9d259663..eb87ea18 100644 --- a/src/main/groovy/org/labkey/gradle/task/RunTestSuite.groovy +++ b/src/main/groovy/org/labkey/gradle/task/RunTestSuite.groovy @@ -17,6 +17,7 @@ package org.labkey.gradle.task import org.apache.commons.lang3.StringUtils import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.TeamCity import org.labkey.gradle.plugin.extension.TeamCityExtension import org.labkey.gradle.util.DatabaseProperties @@ -25,6 +26,7 @@ import org.labkey.gradle.util.DatabaseProperties * Class that sets our test/Runner.class as the junit test suite and configures a bunch of system properties for * running these suites of tests. */ +@UntrackedTask(because="Runs tests") abstract class RunTestSuite extends RunUiTest { // Designated as @Internal instead of @Input to avoid this error in TeamCity (dbProperties is not used for running local tests). diff --git a/src/main/groovy/org/labkey/gradle/task/RunUiTest.groovy b/src/main/groovy/org/labkey/gradle/task/RunUiTest.groovy index 8b1edffe..e47a566c 100644 --- a/src/main/groovy/org/labkey/gradle/task/RunUiTest.groovy +++ b/src/main/groovy/org/labkey/gradle/task/RunUiTest.groovy @@ -16,7 +16,9 @@ package org.labkey.gradle.task import org.apache.commons.lang3.StringUtils +import org.gradle.api.tasks.UntrackedTask import org.gradle.api.tasks.testing.Test +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.plugin.extension.LabKeyExtension import org.labkey.gradle.plugin.extension.TomcatExtension import org.labkey.gradle.plugin.extension.UiTestExtension @@ -25,6 +27,7 @@ import org.labkey.gradle.util.BuildUtils /** * Class that sets up jvmArgs and our standard output options */ +@UntrackedTask(because="Runs tests") abstract class RunUiTest extends Test { public static final String LOG_DIR = "test/logs" diff --git a/src/main/groovy/org/labkey/gradle/task/ServerSideJS.groovy b/src/main/groovy/org/labkey/gradle/task/ServerSideJS.groovy index 77637574..d424f124 100644 --- a/src/main/groovy/org/labkey/gradle/task/ServerSideJS.groovy +++ b/src/main/groovy/org/labkey/gradle/task/ServerSideJS.groovy @@ -18,8 +18,11 @@ package org.labkey.gradle.task import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.file.DirectoryProperty +import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.labkey.gradle.plugin.extension.LabKeyExtension import org.labkey.gradle.util.BuildUtils @@ -27,19 +30,23 @@ import org.labkey.gradle.util.BuildUtils /** * N.B. This task requires that you have the platform/api project source as it needs access to directories in that project */ +@CacheableTask abstract class ServerSideJS extends DefaultTask { @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) File scriptFragmentsDir = project.file("script-fragments") @OutputDirectory File scriptsDir = project.file("resources/scripts") @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty ext3SrcDir = project.objects.directoryProperty() .convention(project.project(BuildUtils.getApiProjectPath(project.gradle)).layout.projectDirectory.dir("webapp/${LabKeyExtension.ext3Dir}/src")) @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty ext4SrcDir = project.objects.directoryProperty() .convention(project.project(BuildUtils.getApiProjectPath(project.gradle)).layout.projectDirectory.dir("webapp/${LabKeyExtension.ext4Dir}/src")) @@ -101,6 +108,5 @@ abstract class ServerSideJS extends DefaultTask File destFile = new File("${scriptsDir}/Ext4.js") if (!destFile.exists()) throw new GradleException("Output file ${destFile} not created") - } } diff --git a/src/main/groovy/org/labkey/gradle/task/SetUpProperties.groovy b/src/main/groovy/org/labkey/gradle/task/SetUpProperties.groovy index b7b9e71a..214e5311 100644 --- a/src/main/groovy/org/labkey/gradle/task/SetUpProperties.groovy +++ b/src/main/groovy/org/labkey/gradle/task/SetUpProperties.groovy @@ -23,11 +23,16 @@ import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property +import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.UntrackedTask +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.plugin.extension.TeamCityExtension import org.labkey.gradle.util.BuildUtils import org.labkey.gradle.util.DatabaseProperties @@ -35,12 +40,13 @@ import org.labkey.gradle.util.PropertiesUtils import javax.inject.Inject +@DisableCachingByDefault(because="Outputs are not in the build directory") abstract class SetUpProperties extends TeamCityPropertiesTask { @Internal private DatabaseProperties databaseProperties - @InputFiles + @InputFiles @Classpath abstract ConfigurableFileCollection getDriverFiles() @Input @@ -65,7 +71,7 @@ abstract class SetUpProperties extends TeamCityPropertiesTask @Input final abstract Property embeddedConfigDir = project.objects.property(String).convention(BuildUtils.getEmbeddedConfigPath(project)) - @InputDirectory + @InputDirectory @PathSensitive(PathSensitivity.ABSOLUTE) File configsDir = new File(BuildUtils.getConfigsProject(project).projectDir, "configs") @OutputFile diff --git a/src/main/groovy/org/labkey/gradle/task/ShowDiscrepancies.groovy b/src/main/groovy/org/labkey/gradle/task/ShowDiscrepancies.groovy index e9a97d5f..23667726 100644 --- a/src/main/groovy/org/labkey/gradle/task/ShowDiscrepancies.groovy +++ b/src/main/groovy/org/labkey/gradle/task/ShowDiscrepancies.groovy @@ -21,11 +21,13 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ModuleVersionIdentifier import org.gradle.api.artifacts.ResolvedArtifact import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask /** * This task will collect all the resolved dependencies from each project and print a report * that shows the external dependencies with more than one version referenced within the build. */ +@UntrackedTask(because="Output is logging") class ShowDiscrepancies extends DefaultTask { diff --git a/src/main/groovy/org/labkey/gradle/task/StageDistribution.groovy b/src/main/groovy/org/labkey/gradle/task/StageDistribution.groovy index 13362e6f..f286aaca 100644 --- a/src/main/groovy/org/labkey/gradle/task/StageDistribution.groovy +++ b/src/main/groovy/org/labkey/gradle/task/StageDistribution.groovy @@ -29,13 +29,17 @@ import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.plugin.ServerDeploy import org.labkey.gradle.plugin.extension.DistributionExtension import org.labkey.gradle.util.BuildUtils import javax.inject.Inject +@DisableCachingByDefault(because="Outputs are in the staging directory") abstract class StageDistribution extends DefaultTask { @Inject abstract FileSystemOperations getFs() @@ -54,6 +58,7 @@ abstract class StageDistribution extends DefaultTask final abstract DirectoryProperty pipelineJarStagingDir = BuildUtils.getRootBuildDirectoryProperty(project, ServerDeploy.STAGING_PIPELINE_DIR) @InputFile + @PathSensitive(PathSensitivity.RELATIVE) final abstract RegularFileProperty distributionFileProp = project.objects.fileProperty().fileValue(DistributionExtension.getDistributionFile(project, distDir.get())) @TaskAction diff --git a/src/main/groovy/org/labkey/gradle/task/StageModules.groovy b/src/main/groovy/org/labkey/gradle/task/StageModules.groovy index 0bb8a50b..a085a97a 100644 --- a/src/main/groovy/org/labkey/gradle/task/StageModules.groovy +++ b/src/main/groovy/org/labkey/gradle/task/StageModules.groovy @@ -7,12 +7,16 @@ import org.gradle.api.file.FileCollection import org.gradle.api.file.FileSystemOperations import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault import org.labkey.gradle.plugin.ServerDeploy import org.labkey.gradle.util.BuildUtils import javax.inject.Inject +@DisableCachingByDefault(because="Outputs are in the staging directory") abstract class StageModules extends DefaultTask { @Inject abstract FileSystemOperations getFs() @@ -21,9 +25,11 @@ abstract class StageModules extends DefaultTask final abstract DirectoryProperty stagingModulesDir = BuildUtils.getRootBuildDirectoryProperty(project, ServerDeploy.STAGING_MODULES_DIR) @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) abstract ConfigurableFileCollection getDownloadedModules() @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) abstract ConfigurableFileCollection getBuiltModules() @TaskAction diff --git a/src/main/groovy/org/labkey/gradle/task/StartLabKey.groovy b/src/main/groovy/org/labkey/gradle/task/StartLabKey.groovy index acd2b5e2..b26ba740 100644 --- a/src/main/groovy/org/labkey/gradle/task/StartLabKey.groovy +++ b/src/main/groovy/org/labkey/gradle/task/StartLabKey.groovy @@ -23,7 +23,10 @@ import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.Tomcat import org.labkey.gradle.plugin.extension.LabKeyExtension import org.labkey.gradle.plugin.extension.ServerDeployExtension @@ -32,6 +35,7 @@ import org.labkey.gradle.util.BuildUtils import java.util.stream.Collectors +@UntrackedTask(because="Output is a running process") abstract class StartLabKey extends TeamCityPropertiesTask { private static final String EMBEDDED_REFLECTION_PARAM = "embeddedReflectionArgs" @@ -45,6 +49,7 @@ abstract class StartLabKey extends TeamCityPropertiesTask ] @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) final abstract DirectoryProperty deployDir = project.objects.directoryProperty().convention(ServerDeployExtension.getEmbeddedServerDeployDirectory(project)) @OutputFile diff --git a/src/main/groovy/org/labkey/gradle/task/StopLabKey.groovy b/src/main/groovy/org/labkey/gradle/task/StopLabKey.groovy index d9613c97..c7109303 100644 --- a/src/main/groovy/org/labkey/gradle/task/StopLabKey.groovy +++ b/src/main/groovy/org/labkey/gradle/task/StopLabKey.groovy @@ -18,7 +18,10 @@ package org.labkey.gradle.task import org.gradle.api.DefaultTask import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.extension.ServerDeployExtension import java.nio.charset.StandardCharsets @@ -28,10 +31,11 @@ import java.util.concurrent.TimeUnit /** * Task for stopping a running LabKey instance */ +@UntrackedTask(because="Output is a stopped process") class StopLabKey extends DefaultTask { - @InputFile @Optional + @InputFile @Optional @PathSensitive(PathSensitivity.RELATIVE) final abstract File pidFile = ServerDeployExtension.getEmbeddedDir(project).file("labkey.pid").asFile .with { it.exists() ? it : null } // "Optional" means that the property may be null, not refer to something nonexistent @@ -68,4 +72,4 @@ class StopLabKey extends DefaultTask } }, { () -> logger.warn("No process found with PID {}", pid)} ) } -} \ No newline at end of file +} diff --git a/src/main/groovy/org/labkey/gradle/task/TeamCityDbSetup.groovy b/src/main/groovy/org/labkey/gradle/task/TeamCityDbSetup.groovy index 88f2d300..85f75649 100644 --- a/src/main/groovy/org/labkey/gradle/task/TeamCityDbSetup.groovy +++ b/src/main/groovy/org/labkey/gradle/task/TeamCityDbSetup.groovy @@ -16,8 +16,10 @@ package org.labkey.gradle.task import org.gradle.api.tasks.Input +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.util.DatabaseProperties +@UntrackedTask(because="External side effects are not cacheable") abstract class TeamCityDbSetup extends DoThenSetup { @Input diff --git a/src/main/groovy/org/labkey/gradle/task/TeamCityPropertiesTask.groovy b/src/main/groovy/org/labkey/gradle/task/TeamCityPropertiesTask.groovy index dbd28b0b..b4b94f63 100644 --- a/src/main/groovy/org/labkey/gradle/task/TeamCityPropertiesTask.groovy +++ b/src/main/groovy/org/labkey/gradle/task/TeamCityPropertiesTask.groovy @@ -5,10 +5,12 @@ import org.gradle.api.Project import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.extension.TeamCityExtension import java.util.function.Function +@UntrackedTask(because="No tracked output") abstract class TeamCityPropertiesTask extends DefaultTask { @Input diff --git a/src/main/groovy/org/labkey/gradle/task/UndeployModules.groovy b/src/main/groovy/org/labkey/gradle/task/UndeployModules.groovy index bac165f7..0a91efdf 100644 --- a/src/main/groovy/org/labkey/gradle/task/UndeployModules.groovy +++ b/src/main/groovy/org/labkey/gradle/task/UndeployModules.groovy @@ -20,6 +20,7 @@ import org.gradle.api.Project import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask import org.labkey.gradle.plugin.FileModule import org.labkey.gradle.plugin.JavaModule import org.labkey.gradle.plugin.Module @@ -29,6 +30,7 @@ import org.labkey.gradle.plugin.Module * it removes those not supporting the given dbType. If dbType is null, removes all modules from * the current set of projects. */ +@UntrackedTask(because="Does only file removal") class UndeployModules extends DefaultTask { @Input @Optional diff --git a/src/main/groovy/org/labkey/gradle/task/WriteDependenciesFile.groovy b/src/main/groovy/org/labkey/gradle/task/WriteDependenciesFile.groovy index 4b32a59b..55ce3222 100644 --- a/src/main/groovy/org/labkey/gradle/task/WriteDependenciesFile.groovy +++ b/src/main/groovy/org/labkey/gradle/task/WriteDependenciesFile.groovy @@ -31,6 +31,7 @@ import org.labkey.gradle.util.ExternalDependency import java.nio.charset.StandardCharsets import java.util.stream.Collectors +@CacheableTask abstract class WriteDependenciesFile extends DefaultTask { // we assume that if a version number has changed, we should generate a new dependencies file diff --git a/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy b/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy index 08a1755c..0befe6b2 100644 --- a/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy +++ b/src/main/groovy/org/labkey/gradle/util/BuildUtils.groovy @@ -21,16 +21,12 @@ import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.SystemUtils import org.gradle.api.GradleException import org.gradle.api.Project -import org.gradle.api.UnknownDomainObjectException -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.DependencySubstitutions import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.initialization.Settings import org.gradle.api.invocation.Gradle import org.gradle.api.provider.Provider -import org.labkey.gradle.plugin.FileModule import org.labkey.gradle.plugin.extension.LabKeyExtension import org.labkey.gradle.plugin.extension.ModuleExtension import org.labkey.gradle.plugin.extension.ServerDeployExtension @@ -99,6 +95,9 @@ class BuildUtils public static final int ARTIFACT_EXTENSION_INDEX = 8 public static final String BOOTSTRAP_JAR_BASE_NAME = "labkeyBootstrap" public static final String RESTART_FILE_NAME = ".restartTrigger" + public static final String ARTIFACTORY_CONTEXT_URL_PROP = 'artifactory_contextUrl' + public static final String ARTIFACTORY_USER_PROP = 'artifactory_user' + public static final String ARTIFACTORY_PASSWORD_PROP = 'artifactory_password' // the set of modules required for minimal LabKey server functionality static List getBaseModules(Gradle gradle) @@ -985,4 +984,11 @@ class BuildUtils return Boolean.valueOf(propertyValue) ? _TRUE : _FALSE } } + + static boolean hasArtifactoryProperties(Project project) + { + return project.hasProperty(ARTIFACTORY_CONTEXT_URL_PROP) && + project.hasProperty(ARTIFACTORY_USER_PROP) && + project.hasProperty(ARTIFACTORY_PASSWORD_PROP) + } }