Skip to content

feat: add --preview flag to preview aviator remediations before applying - #1076

Open
dhanwanthp wants to merge 4 commits into
feat/v3.x/aviator/26.4from
dhanwanthp/feat/auto_remediations_preview
Open

feat: add --preview flag to preview aviator remediations before applying#1076
dhanwanthp wants to merge 4 commits into
feat/v3.x/aviator/26.4from
dhanwanthp/feat/auto_remediations_preview

Conversation

@dhanwanthp

Copy link
Copy Markdown

This MR adds a new --preview flag to the fcli aviator ssc apply-remediations and fcli fod aviator apply-remediations commands, enabling users to preview what changes would be applied to their source code without actually modifying files.

Features:

  • Added --preview option to both SSC and FoD apply-remediations commands
  • When enabled, the tool performs full validation and processing without modifying source files
  • Returns detailed JSON output containing:
    • All proposed code changes per issue ID
    • File paths and encodings
    • Line numbers and code snippets (before/after)
    • Context metadata for fuzzy matching
    • Skip reasons for any failed remediations

Usage:

# Preview changes without applying them
fcli aviator ssc apply-remediations --appversion myapp --preview

# Preview specific issues only
fcli aviator ssc apply-remediations --appversion myapp --preview --issue-ids ISSUE-123,ISSUE-456

# Apply changes (existing behavior, no --preview flag)
fcli aviator ssc apply-remediations --appversion myapp

Output format:-

{
  "previewMode": true,
  "totalRemediation": 10,
  "appliedRemediation": 8,
  "previewDetails": [
    {
      "issueId": "ISSUE-123",
      "status": "available",
      "files": {
        "src/Example.java": {
          "filename": "src/Example.java",
          "path": "src/Example.java",
          "encoding": "UTF-8",
          "changes": [
            {
              "changeIndex": 1,
              "lineFrom": 42,
              "lineTo": 44,
              "originalCode": "...",
              "newCode": "...",
              "context": { "linesBefore": 2, "linesAfter": 2, "content": "..." },
              "fuzzyMatched": false
            }
          ]
        }
      }
    }
  ]
}

Dhanwanth Pratheep added 4 commits August 20, 2026 15:53
@dhanwanthp
dhanwanthp marked this pull request as ready for review August 24, 2026 08:21
@dhanwanthp
dhanwanthp requested a review from rsenden August 24, 2026 08:23
* Applies or previews remediations for each source entry until done or the issue-id filter is exhausted.
* Caller owns {@code source} lifecycle (try-with-resources).
*/
public static ApplyResult apply(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the number of parameters keep growing, maybe better to combine in a single object that implements builder pattern (through Lombok @Builder), i.e.,

  apply(ApplyArgs.builder()
              .source(source)
              .sourceCodeDirectory(sourceCodeDirectory)
              ...
              .build();

Same could potentially be applied to other methods in Aviator code to reduce number of parameters.

*/
@Reflectable
@JsonPropertyOrder({"changeIndex", "lineFrom", "lineTo", "originalCode", "newCode", "context", "fuzzyMatched"})
public record FileChange(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as before; maybe better to add Lombok @Builder instead of relying on constructor parameter order.

unirest, logger, progressWriter, resolved.artifacts())) {
ApplyResult applyResult = RemediationsApplyHelper.apply(
source, sourceCodeDirectory, logger, issueIdFilter, LOG);
source, sourceCodeDirectory, logger, issueIdFilter, LOG, previewMode);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the apply comment elsewhere, what about:

  • Move the various options that define method parameter values into a separate Picocli ArgGroup that can be shared between SSC and FoD commands
  • Have that ArgGroup implement some interface with getters for each of the option values (through Lombok @Getter annotations on the options/class)
  • Have the RemediationsApplyHelper::apply method take an instance of that interface

This way, the FoD & SSC apply-remediations commands can simply pass the ArgGroup to the apply method (together with the loggers, which remain separate method parameters), and due to interface abstraction, RemediationsApplyHelper doesn't have a compile-time dependency on CLI-specific code (like the ArgGroup).

unirest, logger, progressWriter, resolved.artifacts())) {
ApplyResult applyResult = RemediationsApplyHelper.apply(
source, sourceCodeDirectory, logger, issueIdFilter, LOG);
source, sourceCodeDirectory, logger, issueIdFilter, LOG, previewMode);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you passing LOG to a different class? Usually, each class has its own Slf4j logger, which also makes it much easier to identify which class generated a particular log message.

unirest, logger, progressWriter, resolved.artifacts())) {
ApplyResult applyResult = RemediationsApplyHelper.apply(
source, sourceCodeDirectory, logger, issueIdFilter, LOG);
source, sourceCodeDirectory, logger, issueIdFilter, LOG, previewMode);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's some overlap between FoD and SSC implementations of the apply-remediations command; please check whether it makes sense to introduce a common AbstractAviatorApplyRemediationsCommand base class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants