From ca2f6e108adaadaf7d642367b96c72b2f3b57fa6 Mon Sep 17 00:00:00 2001 From: Kyle Moore Date: Mon, 22 Mar 2021 22:31:42 -0700 Subject: [PATCH] Fix #561 - cleanup task input/output issues - Consumers of the pegasus plugin must use Gradle 5.4+ - `@ReplacedBy` annotation requires Gradle 5.4+ - `o.g.w.InputChanges` API requires Gradle 5.4+ --- .../pegasus/gradle/PegasusPlugin.java | 11 +++ .../gradle/tasks/ChangedFileReportTask.java | 73 ++++++++++++------- .../pegasus/gradle/tasks/CheckIdlTask.java | 7 ++ .../gradle/tasks/CheckRestModelTask.java | 9 +++ .../gradle/tasks/CheckSnapshotTask.java | 10 +++ .../tasks/GenerateDataTemplateTask.java | 15 +++- .../gradle/tasks/GenerateRestClientTask.java | 20 ++++- .../gradle/tasks/GenerateRestModelTask.java | 1 - 8 files changed, 115 insertions(+), 31 deletions(-) diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/PegasusPlugin.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/PegasusPlugin.java index 9e9f2be94b..5a15147c2b 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/PegasusPlugin.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/PegasusPlugin.java @@ -76,6 +76,7 @@ import org.gradle.plugins.ide.eclipse.model.EclipseModel; import org.gradle.plugins.ide.idea.IdeaPlugin; import org.gradle.plugins.ide.idea.model.IdeaModule; +import org.gradle.util.GradleVersion; /** @@ -633,6 +634,11 @@ public void setJavadocJarTask(Task javadocJarTask) @Override public void apply(Project project) { + if (!isAtLeastGradle54()) + { + throw new GradleException("The pegasus plugin requires Gradle 5.4 or higher; please upgrade."); + } + project.getPlugins().apply(JavaPlugin.class); project.getPlugins().apply(IdeaPlugin.class); project.getPlugins().apply(EclipsePlugin.class); @@ -1407,6 +1413,7 @@ protected void configureRestModelGeneration(Project project, SourceSet sourceSet changedFileReportTask.setIdlFiles(SharedFileUtils.getSuffixedFiles(project, apiIdlDir, IDL_FILE_SUFFIX)); changedFileReportTask.setSnapshotFiles(SharedFileUtils.getSuffixedFiles(project, apiSnapshotDir, SNAPSHOT_FILE_SUFFIX)); + changedFileReportTask.getOutputFile().set(project.getLayout().getBuildDirectory().file("changedFilesReport.txt")); changedFileReportTask.mustRunAfter(publishRestliSnapshotTask, publishRestliIdlTask); changedFileReportTask.doLast(new CacheableAction<>(t -> { @@ -2224,4 +2231,8 @@ private Task publishPegasusSchemaSnapshot(Project project, SourceSet sourceSet, task.onlyIf(t -> !SharedFileUtils.getSuffixedFiles(project, inputDir, PDL_FILE_SUFFIX).isEmpty()); }); } + protected static boolean isAtLeastGradle54() { + return GradleVersion.current().getBaseVersion().compareTo(GradleVersion.version("5.4")) >= 0; + } + } diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/ChangedFileReportTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/ChangedFileReportTask.java index a7dd65f606..d3c0a55109 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/ChangedFileReportTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/ChangedFileReportTask.java @@ -5,14 +5,18 @@ import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; + +import com.linkedin.pegasus.gradle.IOUtil; import org.gradle.api.DefaultTask; import org.gradle.api.file.FileCollection; -import org.gradle.api.specs.Specs; +import org.gradle.api.file.FileType; +import org.gradle.api.file.RegularFileProperty; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Internal; +import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.SkipWhenEmpty; import org.gradle.api.tasks.TaskAction; -import org.gradle.api.tasks.incremental.IncrementalTaskInputs; +import org.gradle.work.InputChanges; public class ChangedFileReportTask extends DefaultTask @@ -21,15 +25,10 @@ public class ChangedFileReportTask extends DefaultTask private FileCollection _idlFiles = getProject().files(); private FileCollection _snapshotFiles = getProject().files(); - - public ChangedFileReportTask() - { - //with Gradle 6.0, Declaring an incremental task without outputs is not allowed. - getOutputs().upToDateWhen(Specs.satisfyNone()); - } + private RegularFileProperty _outputFile = getProject().getObjects().fileProperty(); @TaskAction - public void checkFilesForChanges(IncrementalTaskInputs inputs) + public void checkFilesForChanges(InputChanges inputs) { getLogger().lifecycle("Checking idl and snapshot files for changes..."); getLogger().info("idlFiles: " + _idlFiles.getAsPath()); @@ -41,46 +40,59 @@ public void checkFilesForChanges(IncrementalTaskInputs inputs) if (inputs.isIncremental()) { - inputs.outOfDate(inputFileDetails -> { - if (inputFileDetails.isAdded()) + inputs.getFileChanges(getSnapshotFiles()).forEach(change -> { + if (change.getFileType() != FileType.DIRECTORY) { - filesAdded.add(inputFileDetails.getFile().getAbsolutePath()); - } - - if (inputFileDetails.isRemoved()) - { - filesRemoved.add(inputFileDetails.getFile().getAbsolutePath()); - } - - if (inputFileDetails.isModified()) - { - filesChanged.add(inputFileDetails.getFile().getAbsolutePath()); + String path = change.getFile().getAbsolutePath(); + switch (change.getChangeType()) + { + case ADDED: + filesAdded.add(path); + break; + case REMOVED: + filesRemoved.add(path); + break; + case MODIFIED: + filesChanged.add(path); + break; + } } }); - inputs.removed(inputFileDetails -> filesRemoved.add(inputFileDetails.getFile().getAbsolutePath())); + StringBuilder sb = new StringBuilder(); if (!filesRemoved.isEmpty()) { String files = joinByComma(filesRemoved); _needCheckinFiles.add(files); - getLogger().lifecycle( - "The following files have been removed, be sure to remove them from source control: {}", files); + String removedFilesMsg = String.format("The following files have been removed, " + + "be sure to remove them from source control: %s\n", files); + sb.append(removedFilesMsg); } if (!filesAdded.isEmpty()) { String files = joinByComma(filesAdded); _needCheckinFiles.add(files); - getLogger().lifecycle("The following files have been added, be sure to add them to source control: {}", files); + String addedFilesMsg = String.format("The following files have been added, " + + "be sure to add them to source control: %s\n", files); + sb.append(addedFilesMsg); } if (!filesChanged.isEmpty()) { String files = joinByComma(filesChanged); _needCheckinFiles.add(files); - getLogger().lifecycle( - "The following files have been changed, be sure to commit the changes to source control: {}", files); + String modifiedFilesMsg = String.format("The following files have been changed, " + + "be sure to commit the changes to source control: %s\n", files); + sb.append(modifiedFilesMsg); + } + + String output = sb.toString(); + if (!output.isEmpty()) + { + getLogger().lifecycle(output); + IOUtil.writeText(getOutputFile().get().getAsFile(), output); } } } @@ -119,4 +131,9 @@ public Collection getNeedCheckinFiles() { return _needCheckinFiles; } + + @OutputFile + public RegularFileProperty getOutputFile() { + return _outputFile; + } } diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckIdlTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckIdlTask.java index 185c1dcf59..8baa28065e 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckIdlTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckIdlTask.java @@ -17,6 +17,7 @@ import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; +import org.gradle.api.model.ReplacedBy; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; @@ -175,6 +176,7 @@ public void setSummaryTarget(File summaryTarget) * @deprecated use {@link #isModelCompatible()} instead */ @Deprecated + @ReplacedBy("modelCompatible") public boolean getIsModelCompatible() { return isModelCompatible(); @@ -189,6 +191,7 @@ public boolean getIsModelCompatible() * @deprecated use {@link #isModelCompatible()} instead */ @Deprecated + @ReplacedBy("modelCompatible") public boolean isIsModelCompatible() { return isModelCompatible(); @@ -209,6 +212,7 @@ public boolean isModelCompatible() * @deprecated use {@link #isRestSpecCompatible()} instead */ @Deprecated + @ReplacedBy("restSpecCompatible") public boolean getIsRestSpecCompatible() { return isRestSpecCompatible(); @@ -223,6 +227,7 @@ public boolean getIsRestSpecCompatible() * @deprecated use {@link #isRestSpecCompatible()} instead */ @Deprecated + @ReplacedBy("restSpecCompatible") public boolean isIsRestSpecCompatible() { return isRestSpecCompatible(); @@ -243,6 +248,7 @@ public boolean isRestSpecCompatible() * @deprecated use {@link #isEquivalent()} instead */ @Deprecated + @ReplacedBy("equivalent") public boolean getIsEquivalent() { return _equivalent; @@ -257,6 +263,7 @@ public boolean getIsEquivalent() * @deprecated use {@link #isEquivalent()} instead */ @Deprecated + @ReplacedBy("equivalent") public boolean isIsEquivalent() { return _equivalent; diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckRestModelTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckRestModelTask.java index fff58ababe..8e800f9e22 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckRestModelTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckRestModelTask.java @@ -29,6 +29,7 @@ import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; +import org.gradle.api.model.ReplacedBy; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; @@ -210,6 +211,7 @@ public void setSummaryTarget(File summaryTarget) * @deprecated use {@link #isModelCompatible()} instead */ @Deprecated + @ReplacedBy("modelCompatible") public boolean getIsModelCompatible() { return isModelCompatible(); @@ -224,6 +226,7 @@ public boolean getIsModelCompatible() * @deprecated use {@link #isModelCompatible()} instead */ @Deprecated + @ReplacedBy("modelCompatible") public boolean isIsModelCompatible() { return isModelCompatible(); @@ -244,6 +247,7 @@ public boolean isModelCompatible() * @deprecated use {@link #isRestSpecCompatible()} instead */ @Deprecated + @ReplacedBy("restSpecCompatible") public boolean getIsRestSpecCompatible() { return isRestSpecCompatible(); @@ -258,6 +262,7 @@ public boolean getIsRestSpecCompatible() * @deprecated use {@link #isRestSpecCompatible()} instead */ @Deprecated + @ReplacedBy("restSpecCompatible") public boolean isIsRestSpecCompatible() { return isRestSpecCompatible(); @@ -278,6 +283,7 @@ public boolean isRestSpecCompatible() * @deprecated use {@link #isEquivalent()} instead */ @Deprecated + @ReplacedBy("equivalent") public boolean getIsEquivalent() { return isEquivalent(); @@ -292,6 +298,7 @@ public boolean getIsEquivalent() * @deprecated use {@link #isEquivalent()} instead */ @Deprecated + @ReplacedBy("equivalent") public boolean isIsEquivalent() { return isEquivalent(); @@ -312,6 +319,7 @@ public boolean isEquivalent() * @deprecated use {@link #isRestSpecEquivalent()} instead */ @Deprecated + @ReplacedBy("restSpecEquivalent") public boolean getIsRestSpecEquivalent() { return isRestSpecEquivalent(); @@ -326,6 +334,7 @@ public boolean getIsRestSpecEquivalent() * @deprecated use {@link #isRestSpecEquivalent()} instead */ @Deprecated + @ReplacedBy("restSpecEquivalent") public boolean isIsRestSpecEquivalent() { return isRestSpecEquivalent(); diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckSnapshotTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckSnapshotTask.java index f601ef67b3..c61ea77172 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckSnapshotTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/CheckSnapshotTask.java @@ -13,6 +13,7 @@ import org.gradle.api.GradleException; import org.gradle.api.Project; import org.gradle.api.file.FileCollection; +import org.gradle.api.model.ReplacedBy; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; @@ -105,6 +106,7 @@ public void setCurrentSnapshotFiles(FileCollection currentSnapshotFiles) } @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) public File getPreviousSnapshotDirectory() { return _previousSnapshotDirectory; @@ -157,6 +159,7 @@ public void setSummaryTarget(File summaryTarget) * @deprecated use {@link #isModelCompatible()} instead */ @Deprecated + @ReplacedBy("modelCompatible") public boolean getIsModelCompatible() { return isModelCompatible(); @@ -171,6 +174,7 @@ public boolean getIsModelCompatible() * @deprecated use {@link #isModelCompatible()} instead */ @Deprecated + @ReplacedBy("modelCompatible") public boolean isIsModelCompatible() { return isModelCompatible(); @@ -191,6 +195,7 @@ public boolean isModelCompatible() * @deprecated use {@link #isRestSpecCompatible()} instead */ @Deprecated + @ReplacedBy("restSpecCompatible") public boolean getIsRestSpecCompatible() { return isRestSpecCompatible(); @@ -205,6 +210,7 @@ public boolean getIsRestSpecCompatible() * @deprecated use {@link #isRestSpecCompatible()} instead */ @Deprecated + @ReplacedBy("restSpecCompatible") public boolean isIsRestSpecCompatible() { return isRestSpecCompatible(); @@ -225,6 +231,7 @@ public boolean isRestSpecCompatible() * @deprecated use {@link #isEquivalent()} instead */ @Deprecated + @ReplacedBy("equivalent") public boolean getIsEquivalent() { return isEquivalent(); @@ -239,6 +246,7 @@ public boolean getIsEquivalent() * @deprecated use {@link #isEquivalent()} instead */ @Deprecated + @ReplacedBy("equivalent") public boolean isIsEquivalent() { return isEquivalent(); @@ -259,6 +267,7 @@ public boolean isEquivalent() * @deprecated use {@link #isRestSpecEquivalent()} instead */ @Deprecated + @ReplacedBy("restSpecEquivalent") public boolean getIsRestSpecEquivalent() { return isRestSpecEquivalent(); @@ -273,6 +282,7 @@ public boolean getIsRestSpecEquivalent() * @deprecated use {@link #isRestSpecEquivalent()} instead */ @Deprecated + @ReplacedBy("restSpecEquivalent") public boolean isIsRestSpecEquivalent() { return isRestSpecEquivalent(); diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateDataTemplateTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateDataTemplateTask.java index db4aeab750..7922bc4437 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateDataTemplateTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateDataTemplateTask.java @@ -126,9 +126,22 @@ public void setEnableArgFile(boolean enable) _enableArgFile = enable; } + /** + * This method is kept for backwards compatibility. + *

+ * This non-property method was exposed. Property methods should begin with is or get. + * + * @deprecated use {@link #isGenerateLowercasePath()} instead + */ + @Deprecated + public Boolean generateLowercasePath() + { + return isGenerateLowercasePath(); + } + @Optional @Input - public Boolean generateLowercasePath() + public Boolean isGenerateLowercasePath() { return _generateLowercasePath; } diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestClientTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestClientTask.java index 557c631f91..94046eab59 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestClientTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestClientTask.java @@ -15,6 +15,7 @@ import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.file.FileCollection; +import org.gradle.api.model.ReplacedBy; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; @@ -290,9 +291,22 @@ public void setEnableArgFile(boolean enable) _enableArgFile = enable; } + /** + * This method is kept for backwards compatibility. + *

+ * This non-property method was exposed. Property methods should begin with is or get. + * + * @deprecated use {@link #isGenerateLowercasePath()} instead + */ + @Deprecated + public Boolean generateLowercasePath() + { + return isGenerateLowercasePath(); + } + @Optional @Input - public Boolean generateLowercasePath() + public Boolean isGenerateLowercasePath() { return _generateLowercasePath; } @@ -322,6 +336,7 @@ public void setDestinationDir(File destinationDir) * @deprecated use {@link #isRestli2FormatSuppressed()} instead */ @Deprecated + @ReplacedBy("restli2FormatSuppressed") public boolean getIsRestli2FormatSuppressed() { return isRestli2FormatSuppressed(); @@ -336,6 +351,7 @@ public boolean getIsRestli2FormatSuppressed() * @deprecated use {@link #isRestli2FormatSuppressed()} instead */ @Deprecated + @ReplacedBy("restli2FormatSuppressed") public boolean isIsRestli2FormatSuppressed() { return isRestli2FormatSuppressed(); @@ -397,6 +413,7 @@ public void setGenerateFluentApi(boolean generateFluentApi) * @deprecated use {@link #isRestli1BuildersDeprecated()} instead */ @Deprecated + @ReplacedBy("restli1BuildersDeprecated") public boolean get_isRestli1BuildersDeprecated() { return isRestli1BuildersDeprecated(); @@ -411,6 +428,7 @@ public boolean get_isRestli1BuildersDeprecated() * @deprecated use {@link #isRestli1BuildersDeprecated()} instead */ @Deprecated + @ReplacedBy("restli1BuildersDeprecated") public boolean is_isRestli1BuildersDeprecated() { return isRestli1BuildersDeprecated(); diff --git a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestModelTask.java b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestModelTask.java index 154f355863..6e1c0f1117 100644 --- a/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestModelTask.java +++ b/gradle-plugins/src/main/java/com/linkedin/pegasus/gradle/tasks/GenerateRestModelTask.java @@ -163,7 +163,6 @@ public void setResolverPath(FileCollection resolverPath) } @OutputDirectory - @PathSensitive(PathSensitivity.NAME_ONLY) public File getIdlDestinationDir() { return _idlDestinationDir;