Class DetectDoppelgangerApisTask
- All Implemented Interfaces:
Comparable<org.gradle.api.Task>,org.gradle.api.internal.DynamicObjectAware,org.gradle.api.internal.TaskInternal,org.gradle.api.Named,org.gradle.api.plugins.ExtensionAware,org.gradle.api.Task,org.gradle.util.Configurable<org.gradle.api.Task>
@RestController classes against verification evidence collected
from the enabled ContractVerificationSources, and writes an AsciiDoc report of every
endpoint with no such evidence - the "doppelganger APIs".
Registered automatically by DoppelgangerApiDetectorPlugin under the name
detectDoppelgangerApis.
-
Nested Class Summary
Nested classes/interfaces inherited from interface org.gradle.api.Named
org.gradle.api.Named.Namer -
Field Summary
Fields inherited from interface org.gradle.api.Task
TASK_ACTION, TASK_CONSTRUCTOR_ARGS, TASK_DEPENDS_ON, TASK_DESCRIPTION, TASK_GROUP, TASK_NAME, TASK_OVERWRITE, TASK_TYPE -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidgenerate()Task action: scans the configured controller directories and OpenAPI documentation to find endpoints both declared and implemented, scans the enabled verification sources, writes the doppelganger API report, and - whengetFailOnDoppelganger()istrue- fails the build if any doppelganger API was found.abstract org.gradle.api.file.RegularFilePropertyFile that the persisted contract progress history is read from and, whengetUpdateContractHistory()istrue, written back to.The absolute path ofgetContractHistoryFile(), tracked as a plain@Inputvalue - not the file's content, whichgetContractHistoryFile()itself is deliberately excluded from up-to-date checking for.abstract org.gradle.api.file.DirectoryPropertyDirectory searched for Spring Cloud Contract DSL files whengetUseSpringCloudContract()istrue.abstract org.gradle.api.file.ConfigurableFileCollectionDirectories to search recursively for@RestControllerclasses.abstract org.gradle.api.file.ConfigurableFileCollectionExternal exclusion rule files - seeDoppelgangerApiDetectorExtension.getExcludeFiles().abstract org.gradle.api.provider.ListProperty<String> Exclusion rule strings - seeDoppelgangerApiDetectorExtension.getExcludePaths().abstract org.gradle.api.provider.ListProperty<String> Bundled well-known exclusion set names - seeDoppelgangerApiDetectorExtension.getExcludeWellKnown().abstract org.gradle.api.provider.Property<Boolean> Whether the build should fail when doppelganger APIs are found.abstract org.gradle.api.file.DirectoryPropertyDirectory where OpenAPI descriptions are stored, tracked so that changes to any document reachable fromgetRootDocument()invalidate the task's cached result.abstract org.gradle.api.file.DirectoryPropertyDirectory the AsciiDoc report is written to.abstract org.gradle.api.provider.Property<String> Name of the generated AsciiDoc report file (without path).abstract org.gradle.api.file.RegularFilePropertyThe root OpenAPI document describing the API.abstract org.gradle.api.provider.Property<String> Version of the system under test whose@RestControllerclasses were scanned, printed in the generated report as e.g.abstract org.gradle.api.file.ConfigurableFileCollectionDirectories to search recursively for test classes, scanned by the Spring RestDocs and OpenAPI request validator verification sources when enabled.abstract org.gradle.api.provider.Property<Boolean> WhethergetTestDirs()holds directories the user actually configured, as opposed to onlyDoppelgangerApiDetectorExtension.DEFAULT_TEST_DIRapplied byDoppelgangerApiDetectorPluginbecause the user configured none.abstract org.gradle.api.provider.Property<Boolean> Whether to persist, across builds, a history of when each endpoint first reached each stage of its contract lifecycle - declared, implemented, verified.abstract org.gradle.api.provider.Property<Boolean> WhethergetContractHistoryFile()is written back to disk after being updated with the current run's endpoints.abstract org.gradle.api.provider.Property<Boolean> Whether to treat Atlassian OpenAPI request validator usage as verification evidence.abstract org.gradle.api.provider.Property<Boolean> Whether to treat Spring RestDocs test methods as verification evidence.abstract org.gradle.api.provider.Property<Boolean> Whether to treat Spring Cloud Contract DSL files as verification evidence.Methods inherited from class org.gradle.api.DefaultTask
compareTo, configure, dependsOn, doFirst, doFirst, doFirst, doLast, doLast, doLast, finalizedBy, getActions, getAnt, getDependsOn, getDescription, getDestroyables, getDidWork, getEnabled, getExtensions, getFinalizedBy, getGroup, getInputs, getLocalState, getLogger, getLogging, getMustRunAfter, getName, getOutputs, getPath, getProject, getShouldRunAfter, getState, getTaskDependencies, getTemporaryDir, getTimeout, hasProperty, mustRunAfter, onlyIf, onlyIf, onlyIf, property, setActions, setDependsOn, setDescription, setDidWork, setEnabled, setFinalizedBy, setGroup, setMustRunAfter, setOnlyIf, setOnlyIf, setOnlyIf, setProperty, setShouldRunAfter, shouldRunAfter, usesServiceMethods inherited from class org.gradle.api.internal.AbstractTask
acceptServiceReferences, appendParallelSafeAction, doNotTrackState, doNotTrackStateIf, getAsDynamicObject, getIdentityPath, getImpliesSubProjects, getLifecycleDependencies, getOnlyIf, getReasonNotToTrackState, getReasonsNotToTrackState, getReasonTaskIsIncompatibleWithConfigurationCache, getRequiredServices, getServices, getSharedResources, getStandardOutputCapture, getTaskActions, getTaskIdentity, getTemporaryDirFactory, hasTaskActions, injectIntoNewInstance, isCompatibleWithConfigurationCache, isEnabled, isHasCustomActions, notCompatibleWithConfigurationCache, prependParallelSafeAction, restoreOnlyIf, restoreTaskActions, setImpliesSubProjectsMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.gradle.api.Task
doNotTrackState, notCompatibleWithConfigurationCache
-
Constructor Details
-
DetectDoppelgangerApisTask
@Inject public DetectDoppelgangerApisTask()Creates the task. Instantiated by Gradle infrastructure viaInject.
-
-
Method Details
-
getControllerDirs
@InputFiles @PathSensitive(RELATIVE) public abstract org.gradle.api.file.ConfigurableFileCollection getControllerDirs()Directories to search recursively for@RestControllerclasses.- Returns:
- mutable file collection of controller source directories
-
getTestDirs
@InputFiles @PathSensitive(RELATIVE) public abstract org.gradle.api.file.ConfigurableFileCollection getTestDirs()Directories to search recursively for test classes, scanned by the Spring RestDocs and OpenAPI request validator verification sources when enabled.- Returns:
- mutable file collection of test source directories
-
getTestDirsUserConfigured
WhethergetTestDirs()holds directories the user actually configured, as opposed to onlyDoppelgangerApiDetectorExtension.DEFAULT_TEST_DIRapplied byDoppelgangerApiDetectorPluginbecause the user configured none. Set by the plugin; defaults totruefor tasks created without it (e.g. directly in a test), which keeps the conservative, pre-existing behavior of treating a missinggetTestDirs()entry as a bootstrapping gap.This distinction matters because a missing
testDirsentry means two very different things depending on where it came from. A user-configured path that doesn't exist yet is genuinely a bootstrapping gap - the team is going to add that test directory once the corresponding tests are written - andgenerate()correctly suppresses detection for it, the same as a missinggetContractsDir(). The plugin's own default, by contrast, is applied whether or not the project will ever have asrc/testContract/java- a project that deliberately has no Spring RestDocs or OpenAPI request validator evidence at all looks, on disk, identical to one that simply hasn't been bootstrapped yet. Suppressing detection in that case defeats the entire plugin for exactly the projects it exists to catch: one with zero verification evidence would never be flagged, because the absence of evidence is misread as "not built yet" rather than "genuinely absent".- Returns:
- mutable boolean property,
truewhengetTestDirs()reflects the user's own configuration rather than only the plugin's default
-
getRootDocument
@Optional @InputFiles @PathSensitive(RELATIVE) public abstract org.gradle.api.file.RegularFileProperty getRootDocument()The root OpenAPI document describing the API.Validated as
@InputFilesrather than@InputFile, and@Optional: unlike@InputFile, neither requires a value to be present nor the configured file to actually exist. A team bootstrapping a build script for a project whose OpenAPI documentation doesn't exist yet - or hasn't been configured yet - should get a report with aWARNINGadmonition explaining that fromgenerate(), not an opaque Gradle input-validation failure before the task action ever runs; seedescribeMissingRootDocument().- Returns:
- mutable file property for the root OpenAPI document
-
getOpenApiDir
@Optional @InputFiles @PathSensitive(RELATIVE) public abstract org.gradle.api.file.DirectoryProperty getOpenApiDir()Directory where OpenAPI descriptions are stored, tracked so that changes to any document reachable fromgetRootDocument()invalidate the task's cached result.Validated as
@InputFilesrather than@InputDirectoryfor the same reason asgetRootDocument(): it defaults to that file's own parent directory, which does not exist either when the file itself does not.- Returns:
- mutable directory property for the OpenAPI description directory
-
getContractsDir
@Optional @InputFiles @PathSensitive(RELATIVE) public abstract org.gradle.api.file.DirectoryProperty getContractsDir()Directory searched for Spring Cloud Contract DSL files whengetUseSpringCloudContract()istrue.Validated as
@InputFilesrather than@InputDirectory: most projects have nocontractsdirectory at all, and unlike@InputDirectory,@InputFilesdoes not require the configured directory to actually exist.- Returns:
- mutable directory property for the Spring Cloud Contract directory
-
getUseRestDocs
Whether to treat Spring RestDocs test methods as verification evidence.- Returns:
- mutable boolean property controlling whether the Spring RestDocs source is enabled
-
getUseOpenApiRequestValidator
Whether to treat Atlassian OpenAPI request validator usage as verification evidence.- Returns:
- mutable boolean property controlling whether the OpenAPI request validator source is enabled
-
getUseSpringCloudContract
Whether to treat Spring Cloud Contract DSL files as verification evidence.- Returns:
- mutable boolean property controlling whether the Spring Cloud Contract source is enabled
-
getFailOnDoppelganger
Whether the build should fail when doppelganger APIs are found.- Returns:
- mutable boolean property controlling whether the build fails on doppelganger APIs
-
getReportDir
@OutputDirectory public abstract org.gradle.api.file.DirectoryProperty getReportDir()Directory the AsciiDoc report is written to.- Returns:
- mutable directory property for the report output directory
-
getReportFileName
Name of the generated AsciiDoc report file (without path).- Returns:
- mutable string property for the report file name
-
getSystemUnderTestVersion
Version of the system under test whose@RestControllerclasses were scanned, printed in the generated report as e.g.System Under Test version: v1.0.0.- Returns:
- mutable string property for the system-under-test version
-
getTrackContractHistory
Whether to persist, across builds, a history of when each endpoint first reached each stage of its contract lifecycle - declared, implemented, verified.- Returns:
- mutable boolean property controlling whether contract progress history is tracked
-
getContractHistoryFile
@Internal public abstract org.gradle.api.file.RegularFileProperty getContractHistoryFile()File that the persisted contract progress history is read from and, whengetUpdateContractHistory()istrue, written back to. Deliberately not declared as an@InputFile/@OutputFile: the file legitimately may not exist yet (treated as an empty history, not an error) and is only conditionally written back, so it's read and written directly ingenerate()instead of through Gradle's file-content-based up-to-date checking. Its configured path - as opposed to the file's content - is still tracked as a plain input viagetContractHistoryFilePath(), so that renaming or relocating it is itself enough to invalidate this task's up-to-date state.- Returns:
- mutable file property for the contract history file
-
getContractHistoryFilePath
The absolute path ofgetContractHistoryFile(), tracked as a plain@Inputvalue - not the file's content, whichgetContractHistoryFile()itself is deliberately excluded from up-to-date checking for. Without this, renaming or relocatingcontractHistoryFilein the build script - with no other configured input having changed - would leave this taskUP-TO-DATEand silently skip writing history to the newly configured location.- Returns:
- the contract history file's absolute path, or
nullif unset
-
getUpdateContractHistory
WhethergetContractHistoryFile()is written back to disk after being updated with the current run's endpoints. Only consulted whengetTrackContractHistory()istrue; the history file is always read regardless.- Returns:
- mutable boolean property controlling whether the contract history file is written back
-
getExcludePaths
Exclusion rule strings - seeDoppelgangerApiDetectorExtension.getExcludePaths().- Returns:
- mutable list property of exclusion rule strings
-
getExcludeFiles
@InputFiles @PathSensitive(RELATIVE) public abstract org.gradle.api.file.ConfigurableFileCollection getExcludeFiles()External exclusion rule files - seeDoppelgangerApiDetectorExtension.getExcludeFiles().- Returns:
- mutable file collection of exclusion rule files
-
getExcludeWellKnown
Bundled well-known exclusion set names - seeDoppelgangerApiDetectorExtension.getExcludeWellKnown().- Returns:
- mutable list property of well-known exclusion set names
-
generate
public void generate()Task action: scans the configured controller directories and OpenAPI documentation to find endpoints both declared and implemented, scans the enabled verification sources, writes the doppelganger API report, and - whengetFailOnDoppelganger()istrue- fails the build if any doppelganger API was found.A missing
getRootDocument(), emptygetControllerDirs(), or - for an enabled verification source - a user-configuredgetTestDirs()/getContractsDir()it depends on with none of its currently-enabled sources able to gather any evidence at all - e.g. a build script bootstrapped for a project whose OpenAPI documentation, controllers, or test evidence don't exist yet - is not a build failure: it is recorded as aWARNINGadmonition in the generated report instead, and doppelganger API detection (and, deliberately, contract history advancement - seeloadContractHistoryForDisplay()) is skipped for this run rather than computed from incomplete input and risking a false positive. A missing directory for a source that is not enabled,getContractsDir()left unset entirely whilegetUseSpringCloudContract()is enabled, orgetTestDirs()missing only because it was never configured by the user (seegetTestDirsUserConfigured()) is a deliberate, complete configuration rather than a gap, and neither warns nor suppresses detection.The build still fails when a doppelganger API is genuinely found and
getFailOnDoppelganger()istrue- the one failure condition this task ever raises on its own initiative, per this plugin's design: fail only on a real finding the DSL asked to fail on, never on merely incomplete input.Two DSL configurations are rejected eagerly, before anything is scanned, regardless of
getFailOnDoppelganger()and regardless of what currently exists on disk - unlike every gap above, these are not bootstrapping gaps that resolve themselves as a project fills in, but property combinations that can never yield a meaningful result no matter what: everygetUseRestDocs()/getUseOpenApiRequestValidator()/getUseSpringCloudContract()source disabled at once, andgetUseSpringCloudContract()enabled withgetContractsDir()left unconfigured.
-