Class MigrateContractHistoryTask

java.lang.Object
org.gradle.api.internal.AbstractTask
org.gradle.api.DefaultTask
com.arc_e_tect.gradle.mirage.MigrateContractHistoryTask
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>

@DisableCachingByDefault(because="One-off, manually-invoked file migration; not part of the normal build graph") public abstract class MigrateContractHistoryTask extends org.gradle.api.DefaultTask
Gradle task that migrates getContractHistoryFile() from the pre-stubbedAt 9-field NDJSON format to the current 10-field format, by re-scanning the currently configured getControllerDirs() and getStubDirs() to work out, for every legacy record that has implementedAt set, whether that evidence should now count as a real implementation, a WireMock stub, both, or neither.

CAUTION

This migration is a best-effort reconstruction, not a lossless transformation. The legacy format's implementedAt never distinguished a real @RestController match from a WireMock stub match, so this task can only tell them apart by re-scanning the project's current source and stub directories - it has no way to know what those directories looked like back when each timestamp was first stamped. contractHistoryFile is backed up alongside itself (as <file>.bak) before being overwritten, but review the migrated file - or the version-controlled diff of it - before committing the result.

Per legacy record with a non-null implementedAt:

  • Already marked removedAt - both implementedAt and stubbedAt are cleared to null. The endpoint is already gone, so there is no current evidence left to re-derive either field from, and guessing would bake in a permanent, unverifiable assumption for a record that can never be re-scanned successfully.
  • Matches a currently-scanned controller only - implementedAt is kept as-is and declaringClass is refreshed from the match; stubbedAt stays null. No evidence a stub was ever involved.
  • Matches a currently-scanned stub only - implementedAt becomes null and stubbedAt takes the old implementedAt value; declaringClass becomes null. This is the case the whole migration exists to correct.
  • Matches both - both implementedAt and stubbedAt take the old implementedAt value, and declaringClass is refreshed from the controller match. Which of the two evidence types actually came first is lost, but the "first-seen" date itself is still accurate for whichever it turns out to be.
  • Matches neither, and removedAt was not already set - both implementedAt and stubbedAt take the old value (same reasoning as "matches both": preserve the ambiguous signal rather than discard it), and removedAt is stamped with this migration run's time, since the endpoint can no longer be found anywhere - the same outcome a normal detectMirageApis run would reach if it observed the same absence.

Registered automatically by MirageApiDetectorPlugin under the name migrateContractHistory. Running it against a file that is already in the current 10-field format fails - see DetectMirageApisTask for the exception guiding you here in the first place.

  • 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
    Constructor
    Description
    Creates the task.
  • Method Summary

    Modifier and Type
    Method
    Description
    abstract org.gradle.api.file.RegularFileProperty
    The legacy-format contract history file to migrate in place.
    abstract org.gradle.api.file.ConfigurableFileCollection
    Directories to search recursively for @RestController classes, used to determine which legacy records currently have real-implementation evidence.
    abstract org.gradle.api.file.ConfigurableFileCollection
    Directories to search recursively for WireMock stub mapping files, used to determine which legacy records currently have stub evidence.
    void
    Task action: loads getContractHistoryFile() as the legacy 9-field format, re-scans getControllerDirs() and getStubDirs(), reconstructs every record per the rules documented on this class, backs up the original file, and writes the migrated result back to the same path in the current 10-field format.

    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, usesService

    Methods 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, setImpliesSubProjects

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface org.gradle.api.Task

    doNotTrackState, notCompatibleWithConfigurationCache
  • Constructor Details

    • MigrateContractHistoryTask

      @Inject public MigrateContractHistoryTask()
      Creates the task. Instantiated by Gradle infrastructure via Inject.
  • Method Details

    • getControllerDirs

      @InputFiles @Optional @PathSensitive(RELATIVE) public abstract org.gradle.api.file.ConfigurableFileCollection getControllerDirs()
      Directories to search recursively for @RestController classes, used to determine which legacy records currently have real-implementation evidence.
      Returns:
      mutable file collection of controller source directories
    • getStubDirs

      @InputFiles @Optional @PathSensitive(RELATIVE) public abstract org.gradle.api.file.ConfigurableFileCollection getStubDirs()
      Directories to search recursively for WireMock stub mapping files, used to determine which legacy records currently have stub evidence.
      Returns:
      mutable file collection of WireMock stub directories
    • getContractHistoryFile

      @Internal public abstract org.gradle.api.file.RegularFileProperty getContractHistoryFile()
      The legacy-format contract history file to migrate in place. Deliberately not declared as an @InputFile/@OutputFile - see DetectMirageApisTask.getContractHistoryFile() for why this family of tasks reads and writes this file directly instead.
      Returns:
      mutable file property for the contract history file
    • migrate

      public void migrate()
      Task action: loads getContractHistoryFile() as the legacy 9-field format, re-scans getControllerDirs() and getStubDirs(), reconstructs every record per the rules documented on this class, backs up the original file, and writes the migrated result back to the same path in the current 10-field format.