From 33c52f001ec1124df36d508b924b8d8b0dd0c4ce Mon Sep 17 00:00:00 2001 From: Anishkumar N Date: Wed, 14 Oct 2026 11:31:31 +0530 Subject: [PATCH] feat(aviator): add usage examples and required-option info to command help Add an Examples section and a required-option sentence to the help of all non-deprecated Aviator commands. AviatorHelpExamplesTest (fcli-app) parses every example against the real command tree, enforces the 80-column help width and checks that required options are documented. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../fortify/cli/AviatorHelpExamplesTest.java | 144 +++++++++++++ .../aviator/i18n/AviatorMessages.properties | 194 ++++++++++++++++-- 2 files changed, 316 insertions(+), 22 deletions(-) create mode 100644 fcli-core/fcli-app/src/test/java/com/fortify/cli/AviatorHelpExamplesTest.java diff --git a/fcli-core/fcli-app/src/test/java/com/fortify/cli/AviatorHelpExamplesTest.java b/fcli-core/fcli-app/src/test/java/com/fortify/cli/AviatorHelpExamplesTest.java new file mode 100644 index 00000000000..9c671d19ca4 --- /dev/null +++ b/fcli-core/fcli-app/src/test/java/com/fortify/cli/AviatorHelpExamplesTest.java @@ -0,0 +1,144 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.fortify.cli.app._main.cli.cmd.FCLIRootCommands; +import com.fortify.cli.common.output.writer.CommandSpecMessageResolver; + +import picocli.CommandLine; +import picocli.CommandLine.Model.CommandSpec; + +/** + * Verifies that the help of every non-deprecated, runnable Fortify Aviator command contains + * usable examples: each example must parse successfully against the actual command definition, + * must fit the help output width (so that it doesn't get wrapped), and every required option + * must be mentioned in the command description. + */ +public class AviatorHelpExamplesTest { + // Picocli wraps help text at 80 columns; wrapped examples lose their indentation + private static final int MAX_LINE_LENGTH = 79; + + // TODO Remove once examples have been added for these commands (pending name-or-ID support for app commands) + private static final Set COMMANDS_WITHOUT_EXAMPLES = Set.of( + "fcli aviator app get", "fcli aviator app update", + "fcli aviator app delete", "fcli aviator app add-entitlement"); + + @Test + public void testAviatorCommandHelpExamples() { + var root = new CommandLine(FCLIRootCommands.class); + var failures = new ArrayList(); + var aviator = root.getSubcommands().get("aviator"); + Assertions.assertNotNull(aviator, "aviator command not found"); + leafCommands(aviator).distinct().forEach(cl -> checkCommand(root, cl, failures)); + Assertions.assertTrue(failures.isEmpty(), "Help example problems:\n" + String.join("\n", failures)); + } + + private static Stream leafCommands(CommandLine cl) { + var subs = cl.getSubcommands(); + return subs.isEmpty() ? Stream.of(cl) : subs.values().stream().flatMap(AviatorHelpExamplesTest::leafCommands); + } + + private void checkCommand(CommandLine root, CommandLine cl, List failures) { + var spec = cl.getCommandSpec(); + var name = spec.qualifiedName(" "); + if ( isDeprecated(spec) || COMMANDS_WITHOUT_EXAMPLES.contains(name) ) { return; } + var description = new CommandSpecMessageResolver(spec).getMessageString("usage.description").replace("%n", "\n"); + var lines = Arrays.asList(description.split("\n")).stream().map(String::stripTrailing).collect(Collectors.toList()); + var examplesIdx = lines.indexOf("Examples:"); + if ( examplesIdx < 0 ) { + failures.add(name + ": no 'Examples:' section in description"); + return; + } + var exampleLines = exampleSection(lines.subList(examplesIdx + 1, lines.size())); + exampleLines.stream().filter(l -> l.length() > MAX_LINE_LENGTH).forEach( + l -> failures.add(name + ": example line exceeds " + MAX_LINE_LENGTH + " characters: " + l.trim())); + var commands = exampleCommands(exampleLines); + if ( commands.stream().noneMatch(c -> c.startsWith(name + " ") || c.equals(name)) ) { + failures.add(name + ": no example found for this command"); + } + commands.forEach(c -> checkExampleCommand(root, name, c, failures)); + checkRequiredOptionsDocumented(spec, name, description, failures); + } + + // The examples section ends at the first non-blank line that isn't indented, like a trailing NOTE paragraph + private static List exampleSection(List lines) { + var result = new ArrayList(); + for ( var line : lines ) { + if ( !line.isBlank() && !line.startsWith(" ") ) { break; } + result.add(line); + } + return result; + } + + // Commands start with 'fcli' on a line indented by 3 spaces; commands that don't fit on a single + // line continue on following lines indented by 5 spaces, which are joined here before parsing. + private static List exampleCommands(List exampleLines) { + var commands = new ArrayList(); + for ( var line : exampleLines ) { + if ( line.startsWith(" fcli ") ) { commands.add(line.trim()); } + else if ( line.startsWith(" ") && !commands.isEmpty() && line.trim().startsWith("-") ) { + commands.set(commands.size()-1, commands.get(commands.size()-1) + " " + line.trim()); + } + } + return commands; + } + + private static boolean isDeprecated(CommandSpec spec) { + return String.join(" ", spec.usageMessage().header()).startsWith("(DEPRECATED)"); + } + + private void checkExampleCommand(CommandLine root, String name, String command, List failures) { + var args = tokenize(command); + try { + // Parsing validates option names, required options, mutually exclusive options, and value conversion + root.parseArgs(args.subList(1, args.size()).toArray(String[]::new)); + } catch ( Exception e ) { + failures.add(name + ": example fails to parse: " + command + " -> " + e.getMessage()); + } + } + + // Options that are part of an argument group (for example mutually exclusive options) are not + // unconditionally required, so these are not checked. + private void checkRequiredOptionsDocumented(CommandSpec spec, String name, String description, List failures) { + spec.options().stream().filter(o -> o.required() && o.group() == null).forEach(o -> { + if ( Stream.of(o.names()).noneMatch(n -> n.startsWith("--") && description.contains(n)) ) { + failures.add(name + ": required option " + o.longestName() + " isn't mentioned in the description"); + } + }); + } + + // Minimal shell-like tokenizer, supporting double-quoted values containing whitespace + private static List tokenize(String command) { + var tokens = new ArrayList(); + var current = new StringBuilder(); + var inQuotes = false; + for ( char c : command.toCharArray() ) { + if ( c == '"' ) { inQuotes = !inQuotes; } + else if ( Character.isWhitespace(c) && !inQuotes ) { + if ( current.length() > 0 ) { tokens.add(current.toString()); current.setLength(0); } + } else { current.append(c); } + } + if ( current.length() > 0 ) { tokens.add(current.toString()); } + return tokens; + } +} diff --git a/fcli-core/fcli-aviator/src/main/resources/com/fortify/cli/aviator/i18n/AviatorMessages.properties b/fcli-core/fcli-aviator/src/main/resources/com/fortify/cli/aviator/i18n/AviatorMessages.properties index 53db9c72176..f6e37212379 100644 --- a/fcli-core/fcli-aviator/src/main/resources/com/fortify/cli/aviator/i18n/AviatorMessages.properties +++ b/fcli-core/fcli-aviator/src/main/resources/com/fortify/cli/aviator/i18n/AviatorMessages.properties @@ -17,6 +17,16 @@ fcli.aviator.usage.header = Interact with Fortify Aviator. fcli.aviator.admin-config.usage.header = Manage Fortify Aviator administrator configurations (start here). fcli.aviator.admin-config.admin-config = Name of the Fortify Aviator administrator configuration to use. Default value: ${DEFAULT-VALUE}. fcli.aviator.admin-config.create.usage.header = Create an administrator configuration for interacting with Fortify Aviator. +fcli.aviator.admin-config.create.usage.description = Stores the Fortify Aviator URL, tenant and RSA private key that are used by administrator commands like 'fcli aviator app' and 'fcli aviator token'. \ + Required options: --url, --tenant, --private-key. \ + %n%nExamples: \ + %n%n Create the default administrator configuration: \ + %n fcli aviator admin-config create --url https://av.example.com \ + %n --tenant MyTenant --private-key private.pem \ + %n%n Create a named configuration, reading the private key from an env var: \ + %n fcli aviator admin-config create --admin-config prod \ + %n --url https://av.example.com --tenant MyTenant \ + %n --private-key env:AVIATOR_PRIVATE_KEY fcli.aviator.admin-config.create.url = Fortify Aviator URL. fcli.aviator.admin-config.create.tenant = Fortify Aviator tenant. fcli.aviator.admin-config.create.private-key = RSA private key. Can be specified as one of:\ @@ -27,13 +37,36 @@ fcli.aviator.admin-config.create.private-key = RSA private key. Can be specified \n Key must be in PEM format. fcli.aviator.admin-config.create.admin-config = Name for this Fortify Aviator administrator configuration. Default value: ${DEFAULT-VALUE}. fcli.aviator.admin-config.delete.usage.header = Delete a Fortify Aviator administrator configuration. +fcli.aviator.admin-config.delete.usage.description = Deletes the specified administrator configuration; the default configuration is deleted if --admin-config isn't specified. \ + %n%nExamples: \ + %n%n Delete the default administrator configuration: \ + %n fcli aviator admin-config delete \ + %n%n Delete a named administrator configuration: \ + %n fcli aviator admin-config delete --admin-config prod fcli.aviator.admin-config.delete.admin-config = Name of the Fortify Aviator administrator configuration to be deleted. Default value: ${DEFAULT-VALUE}. fcli.aviator.admin-config.list.usage.header = List available Fortify Aviator administrator configurations. +fcli.aviator.admin-config.list.usage.description = Lists all stored administrator configurations. \ + %n%nExamples: \ + %n%n List all administrator configurations: \ + %n fcli aviator admin-config list \ + %n%n List administrator configurations as JSON: \ + %n fcli aviator admin-config list -o json # fcli aviator session fcli.aviator.session.usage.header = Manage Fortify Aviator user sessions (start here). fcli.aviator.session.option.aviator-session = Name of the Fortify Aviator user session to use. Default value: ${DEFAULT-VALUE}. fcli.aviator.session.login.usage.header = Create a user session for interacting with Fortify Aviator. +fcli.aviator.session.login.usage.description = Creates a Fortify Aviator user session that is used by commands like 'fcli aviator ssc audit-sast'. \ + Required options: --url, --token. \ + %n%nExamples: \ + %n%n Log in using a token stored in a file: \ + %n fcli aviator session login --url https://av.example.com --token token.txt \ + %n%n Log in using a token stored in an environment variable: \ + %n fcli aviator session login --url https://av.example.com \ + %n --token env:AVIATOR_TOKEN \ + %n%n Log in using a named session: \ + %n fcli aviator session login --av-session prod \ + %n --url https://av.example.com --token env:AVIATOR_TOKEN fcli.aviator.session.login.url = Fortify Aviator URL. fcli.aviator.session.login.token = Fortify Aviator user access token. Can be specified as one of:\ \n file:\ @@ -43,14 +76,30 @@ fcli.aviator.session.login.token = Fortify Aviator user access token. Can be spe \n For security reasons, avoid specifying sensitive tokens directly\ \n on the command line (using string:). Prefer using files or env:. fcli.aviator.session.logout.usage.header = Terminate a Fortify Aviator user session. +fcli.aviator.session.logout.usage.description = Terminates the specified user session; the default session is terminated if --av-session isn't specified. \ + %n%nExamples: \ + %n%n Log out of the default session: \ + %n fcli aviator session logout \ + %n%n Log out of a named session: \ + %n fcli aviator session logout --av-session prod fcli.aviator.session.list.usage.header = List active and expired Fortify Aviator user sessions. +fcli.aviator.session.list.usage.description = Lists all Fortify Aviator user sessions, including expired sessions. \ + %n%nExamples: \ + %n%n List all sessions: \ + %n fcli aviator session list # fcli aviator app fcli.aviator.app.usage.header = Manage Fortify Aviator applications. fcli.aviator.app.usage.description = Commands for managing Fortify Aviator applications. These commands require an administrator configuration. Use 'fcli aviator admin-config create' to create a configuration. fcli.aviator.app.create.usage.header = Create a new Fortify Aviator application. -fcli.aviator.app.create.usage.description = Creates a new Fortify Aviator application within the tenant specified in the admin configuration. +fcli.aviator.app.create.usage.description = Creates a new Fortify Aviator application within the tenant specified in the admin configuration. \ + Required parameter: the application name. \ + %n%nExamples: \ + %n%n Create an application: \ + %n fcli aviator app create MyApp \ + %n%n Create an application using a named administrator configuration: \ + %n fcli aviator app create MyApp --admin-config prod fcli.aviator.app.create.name = Name of the application to create. fcli.aviator.app.add-entitlement.usage.header = Add one entitlement to an existing Fortify Aviator application. @@ -66,7 +115,12 @@ fcli.aviator.app.get.usage.description = Retrieves details for a specific Fortif fcli.aviator.app.get.applicationId = ID of the application to retrieve. fcli.aviator.app.list.usage.header = List Fortify Aviator applications. -fcli.aviator.app.list.usage.description = Lists all Fortify Aviator applications for the tenant specified in the admin configuration. +fcli.aviator.app.list.usage.description = Lists all Fortify Aviator applications for the tenant specified in the admin configuration. \ + %n%nExamples: \ + %n%n List all applications: \ + %n fcli aviator app list \ + %n%n List applications as JSON: \ + %n fcli aviator app list -o json fcli.aviator.app.update.usage.header = Update a Fortify Aviator application. fcli.aviator.app.update.usage.description = Updates an existing Fortify Aviator application, identified by its ID. Currently, this only supports renaming the application. @@ -77,7 +131,17 @@ fcli.aviator.app.update.name = The new name for the application. fcli.aviator.connection.usage.header = Diagnose Fortify Aviator connectivity. fcli.aviator.connection.usage.description = Commands for diagnosing Fortify Aviator endpoint and credential connectivity. fcli.aviator.connection.diagnose.usage.header = Run Fortify Aviator connectivity diagnostics. -fcli.aviator.connection.diagnose.usage.description = Runs ordered connectivity checks for Fortify Aviator endpoint configuration, DNS, TCP, optional HTTP proxy CONNECT (when a proxy is configured), TLS, gRPC reachability, and optional credential validation. Use --url with optional --token, or a saved --aviator-session / --admin-config. +fcli.aviator.connection.diagnose.usage.description = Runs ordered connectivity checks for Fortify Aviator endpoint configuration, DNS, TCP, optional HTTP proxy CONNECT (when a proxy is configured), TLS, gRPC reachability, and optional credential validation. Use --url with optional --token, or a saved --av-session / --admin-config. \ +%n%nExamples: \ +%n%n Diagnose connectivity to a Fortify Aviator URL: \ +%n fcli aviator connection diagnose --url https://av.example.com \ +%n%n Diagnose connectivity and validate a user token: \ +%n fcli aviator connection diagnose --url https://av.example.com \ +%n --token env:AVIATOR_TOKEN \ +%n%n Diagnose connectivity using an existing user session: \ +%n fcli aviator connection diagnose --av-session default \ +%n%n Diagnose connectivity using an administrator configuration: \ +%n fcli aviator connection diagnose --admin-config default aviator.connection.diagnose.source.arggroup = Fortify Aviator diagnostics source options%n fcli.aviator.connection.diagnose.url = Fortify Aviator URL to diagnose. Optionally pair with --token to validate a user token without a saved session. fcli.aviator.connection.diagnose.token = Fortify Aviator user access token. Can be specified as one of:\ @@ -98,26 +162,56 @@ fcli.aviator.token.usage.header = Manage Fortify Aviator access tokens. fcli.aviator.token.usage.description = Commands for creating, deleting, revoking, listing, and validating Fortify Aviator access tokens. These commands require an administrator configuration. fcli.aviator.token.create.usage.header = Create a user access token. -fcli.aviator.token.create.usage.description = Creates a new access token for a user within the tenant specified in the admin configuration. +fcli.aviator.token.create.usage.description = Creates a new access token for a user within the tenant specified in the admin configuration. \ + Required option: --email. \ + %n%nExamples: \ + %n%n Create a token for a user, saving the token to a file: \ + %n fcli aviator token create --email user@example.com --save-token token.txt \ + %n%n Create a named token with an explicit expiration date: \ + %n fcli aviator token create --email user@example.com --name ci-token \ + %n --end-date 2027-01-31 --save-token token.txt fcli.aviator.token.create.email = User's email address for whom the token will be generated. fcli.aviator.token.create.name = Optional custom name for the token. fcli.aviator.token.create.end-date = Optional token expiration date in YYYY-MM-DD format. Defaults to one month from creation. fcli.aviator.token.create.save-token = Save the generated raw token string to the specified file. fcli.aviator.token.delete.usage.header = Delete a user access token. -fcli.aviator.token.delete.usage.description = Deletes a user's access token. Requires the token to be deleted. +fcli.aviator.token.delete.usage.description = Deletes a user's access token. Requires the token to be deleted. \ + Required option: --token. \ + %n%nExamples: \ + %n%n Delete a token stored in a file: \ + %n fcli aviator token delete --token token.txt \ + %n%n Delete a token stored in an environment variable: \ + %n fcli aviator token delete --token env:AVIATOR_TOKEN fcli.aviator.token.delete.email = Deprecated option no longer used. fcli.aviator.token.revoke.usage.header = Revoke a user access token. -fcli.aviator.token.revoke.usage.description = Revokes a user's access token, rendering it invalid. Requires the token to be revoked. +fcli.aviator.token.revoke.usage.description = Revokes a user's access token, rendering it invalid. Requires the token to be revoked. \ + Required option: --token. \ + %n%nExamples: \ + %n%n Revoke a token stored in a file: \ + %n fcli aviator token revoke --token token.txt \ + %n%n Revoke a token stored in an environment variable: \ + %n fcli aviator token revoke --token env:AVIATOR_TOKEN fcli.aviator.token.revoke.email = Deprecated option no longer used. fcli.aviator.token.list.usage.header = List user access tokens. -fcli.aviator.token.list.usage.description = Retrieves a list of access tokens. Can be filtered by a user's email address. +fcli.aviator.token.list.usage.description = Retrieves a list of access tokens. Can be filtered by a user's email address. \ + %n%nExamples: \ + %n%n List all tokens: \ + %n fcli aviator token list \ + %n%n List the tokens of a specific user: \ + %n fcli aviator token list --email user@example.com fcli.aviator.token.list.email = User's email address to Filter the list for tokens associated with this email address (optional). fcli.aviator.token.validate.usage.header = Validate a user access token. -fcli.aviator.token.validate.usage.description = Validates an access token, checking its authenticity and status against the Fortify Aviator service. +fcli.aviator.token.validate.usage.description = Validates an access token, checking its authenticity and status against the Fortify Aviator service. \ + Required option: --token. \ + %n%nExamples: \ + %n%n Validate a token stored in a file: \ + %n fcli aviator token validate --token token.txt \ + %n%n Validate a token stored in an environment variable: \ + %n fcli aviator token validate --token env:AVIATOR_TOKEN # fcli aviator entitlement fcli.aviator.entitlement.usage.header = Manage Fortify Aviator entitlements. @@ -128,10 +222,16 @@ fcli.aviator.entitlement.list.usage.description = This command is deprecated, pl Retrieves a list of Fortify Remediation Aviator entitlements for the tenant specified in the admin configuration. fcli.aviator.entitlement.list-sast.usage.header = List Fortify Remediation Aviator entitlements for a tenant. -fcli.aviator.entitlement.list-sast.usage.description = Retrieves a list of Fortify Remediation Aviator entitlements for the tenant specified in the admin configuration. +fcli.aviator.entitlement.list-sast.usage.description = Retrieves a list of Fortify Remediation Aviator entitlements for the tenant specified in the admin configuration. \ + %n%nExamples: \ + %n%n List all Fortify Remediation Aviator entitlements: \ + %n fcli aviator entitlement list-sast fcli.aviator.entitlement.list-dast.usage.header = List Fortify DAST Aviator entitlements for a tenant. -fcli.aviator.entitlement.list-dast.usage.description = Retrieves a list of Fortify DAST Aviator entitlements with credit balance details for the tenant specified in the admin configuration. +fcli.aviator.entitlement.list-dast.usage.description = Retrieves a list of Fortify DAST Aviator entitlements with credit balance details for the tenant specified in the admin configuration. \ + %n%nExamples: \ + %n%n List all Fortify DAST Aviator entitlements: \ + %n fcli aviator entitlement list-dast # fcli aviator ssc fcli.aviator.ssc.usage.header = Use Fortify Remediation Aviator with SSC. @@ -145,8 +245,21 @@ fcli.aviator.ssc.audit-sast.usage.header = Audit SAST findings in an SSC applica fcli.aviator.ssc.audit-sast.usage.description = Downloads the FPR from an SSC application version, audits it with Fortify Remediation Aviator, and uploads the result back to SSC. \ This command requires an active user session. Use 'fcli aviator session login' to create a session. \ This command doesn't wait for SSC to finish processing the audited FPR file; please use the 'fcli ssc artifact wait-for' \ - command to wait until the audited FPR file has been processed by SSC. -fcli.aviator.ssc.audit.app = Fortify Aviator application name to associate with the audit. If not provided, the SAST/FPR Build ID of the SSC application is used. + command to wait until the audited FPR file has been processed by SSC. \ + Required option: --av. \ + %n%nExamples: \ + %n%n Audit an application version: \ + %n fcli aviator ssc audit-sast --av "MyApp:1.0" \ + %n%n Audit using a specific Fortify Aviator application: \ + %n fcli aviator ssc audit-sast --av "MyApp:1.0" --app MyAviatorApp \ + %n%n Check whether the open issues exceed the available quota: \ + %n fcli aviator ssc audit-sast --av "MyApp:1.0" --test-exceeding-quota \ + %n%n Skip the audit if the open issues exceed the available quota: \ + %n fcli aviator ssc audit-sast --av "MyApp:1.0" --skip-if-exceeding-quota \ + %n%n Audit only issues in specific folders of a filter set: \ + %n fcli aviator ssc audit-sast --av "MyApp:1.0" \ + %n --fs "Security Auditor View" --folder Critical,High +fcli.aviator.ssc.audit.app = Fortify Aviator application name to associate with the audit. If not provided, the SAST/FPR Build ID of the SSC application is used. fcli.aviator.ssc.audit.tag-mapping = Custom tag mapping for audit results. fcli.aviator.ssc.audit-dast.tag-mapping = Custom tag mapping for DAST audit results. fcli.aviator.ssc.audit.filterset = Name or ID of the FilterSet to apply. @@ -183,7 +296,15 @@ fcli.ssc.appversion.create.refresh-timeout = Time-out for refreshing application fcli.aviator.ssc.audit-dast.usage.header = Audit DAST findings in an SSC application version using Fortify Aviator. fcli.aviator.ssc.audit-dast.usage.description = Downloads the current application version FPR from SSC, audits eligible WebInspect findings, \ - writes decisions to audit.xml, and uploads the changed DAST FPR. This command requires an active Fortify Aviator user session. + writes decisions to audit.xml, and uploads the changed DAST FPR. This command requires an active Fortify Aviator user session. \ + Required option: --av. \ + %n%nExamples: \ + %n%n Audit the DAST findings of an application version: \ + %n fcli aviator ssc audit-dast --av "MyApp:1.0" \ + %n%n Audit using a specific Fortify Aviator application: \ + %n fcli aviator ssc audit-dast --av "MyApp:1.0" --app MyAviatorApp \ + %n%n Audit without refreshing application version metrics first: \ + %n fcli aviator ssc audit-dast --av "MyApp:1.0" --no-refresh fcli.aviator.ssc.audit-dast.app = Fortify Aviator application name to associate with the DAST audit. \ If omitted, the SSC application name is used. @@ -194,19 +315,21 @@ fcli.aviator.ssc.apply-remediations.usage.description = Downloads FPR artifact(s %n%n Apply remediations from a remediations cache zip: \ %n fcli aviator ssc apply-remediations --from-cache ./remediations.zip \ %n%n Apply selected issue IDs from a cache zip: \ - %n fcli aviator ssc apply-remediations --from-cache ./remediations.zip --issue-ids id1,id2 \ + %n fcli aviator ssc apply-remediations --from-cache ./remediations.zip \ + %n --issue-ids id1,id2 \ %n%n Apply remediations from a known artifact by ID: \ %n fcli aviator ssc apply-remediations --artifact-id 12345 \ - %n%n Apply remediations from the latest Fortify Remediation Aviator-processed artifact for an application version: \ + %n%n Apply remediations from the latest artifact of an application version: \ %n fcli aviator ssc apply-remediations --av "MyApp:1.0" --latest \ - %n%n Apply remediations from the latest artifact, restricting to those uploaded in the last 7 days: \ + %n%n Apply remediations from the latest artifact uploaded in the last 7 days: \ %n fcli aviator ssc apply-remediations --av "MyApp:1.0" --latest --since 7d \ - %n%n Apply remediations across all Fortify Remediation Aviator-processed artifacts for an application version: \ + %n%n Apply remediations across all artifacts of an application version: \ %n fcli aviator ssc apply-remediations --av "MyApp:1.0" --all \ %n%n Apply remediations across all artifacts uploaded in the last 2 weeks: \ %n fcli aviator ssc apply-remediations --av "MyApp:1.0" --all --since 2w \ - %n%n Apply remediations from the latest artifact using a custom source directory: \ - %n fcli aviator ssc apply-remediations --av "MyApp:1.0" --latest --source-dir /path/to/src + %n%n Apply remediations from the latest artifact to a custom source directory: \ + %n fcli aviator ssc apply-remediations --av "MyApp:1.0" --latest \ + %n --source-dir /path/to/src fcli.aviator.ssc.apply-remediations.from-cache = Local remediations cache zip produced by download-remediations-cache. Mutually exclusive with online selection options. Does not require an SSC session. fcli.aviator.ssc.apply-remediations.source-dir = Source code directory where remediations will be applied. Defaults to current directory. fcli.aviator.ssc.apply-remediations.preview = Shows available remediations and their proposed changes without modifying source files. \ @@ -221,7 +344,20 @@ fcli.aviator.ssc.remediations-cache.since = Filter artifacts by upload date. Sup fcli.aviator.ssc.download-remediations-cache.usage.header = Download a remediations cache zip containing Fortify Remediation Aviator audited FPR(s) from SSC. fcli.aviator.ssc.download-remediations-cache.usage.description = Downloads audited FPR file(s) from SSC into a single remediations cache zip (manifest.json + ordered FPR entries) for use with apply-remediations --from-cache. \ - Exactly one of --artifact-id, --latest, or --all must be specified. Requires -f/--file. Overwriting an existing file requires confirmation (-y/--confirm). + Exactly one of --artifact-id, --latest, or --all must be specified. Requires -f/--file. Overwriting an existing file requires confirmation (-y/--confirm). \ + %n%nExamples: \ + %n%n Download the latest artifact of an application version: \ + %n fcli aviator ssc download-remediations-cache --av "MyApp:1.0" --latest \ + %n -f remediations.zip \ + %n%n Download all artifacts uploaded in the last 2 weeks, overwriting the file: \ + %n fcli aviator ssc download-remediations-cache --av "MyApp:1.0" --all \ + %n --since 2w -f remediations.zip -y \ + %n%n Download a specific artifact by ID: \ + %n fcli aviator ssc download-remediations-cache --artifact-id 12345 \ + %n -f remediations.zip \ + %n%n Apply the downloaded cache to local source code: \ + %n fcli aviator ssc apply-remediations --from-cache remediations.zip \ + %n --source-dir /path/to/src fcli.aviator.ssc.download-remediations-cache.file = Destination remediations cache zip path. Required. Existing files require confirmation (-y/--confirm) before overwrite. fcli.aviator.ssc.download-remediations-cache.confirm = Confirm overwriting existing remediations cache file. fcli.aviator.ssc.download-remediations-cache.confirmPrompt = Overwrite existing remediations cache file %s? @@ -235,7 +371,14 @@ fcli.aviator.ssc.prepare.usage.description = This command ensures that the Forti associated with all issue templates and application versions, and this command will detect them and skip \ manual association. For older SSC versions, the tags are created as custom tags and must be manually associated. \ %n%nAt least one update option must be specified. \ - %n%nNOTE\: This command is considered preview functionality as it will likely change in a future fcli version \ + %n%nExamples: \ + %n%n Prepare a single application version: \ + %n fcli aviator ssc prepare --av "MyApp:1.0" \ + %n%n Prepare a single issue template: \ + %n fcli aviator ssc prepare --issue-template MyIssueTemplate \ + %n%n Prepare all issue templates and all application versions: \ + %n fcli aviator ssc prepare --all-issue-templates --all-avs \ + %n%nNOTE\: This command is considered preview functionality as it will likely change in a future fcli version \ to re-use generic tag update functionality that is planned for the fcli ssc module. fcli.aviator.ssc.prepare.issue-template = Update a single issue template by its name or ID. fcli.aviator.ssc.prepare.all-issue-templates = Update all issue templates on the SSC instance. @@ -247,7 +390,14 @@ fcli.aviator.ssc.correlate-sast-dast.usage.header = Correlate SAST and DAST find fcli.aviator.ssc.correlate-sast-dast.usage.description = Downloads the latest SAST and DAST FPR artifacts from an SSC application version, \ groups findings by category, streams mixed-category SAST findings to the Fortify Aviator server \ for correlation via gRPC, injects correlation results into the DAST FPR as ExternalFindings, \ - and uploads it back to SSC. Requires an active SSC session and Fortify Aviator user session. + and uploads it back to SSC. Required option: --av. \ + %n%nExamples: \ + %n%n Correlate the latest SAST and DAST results of an application version: \ + %n fcli aviator ssc correlate-sast-dast --av "MyApp:1.0" \ + %n%n Correlate using a specific Fortify Aviator application: \ + %n fcli aviator ssc correlate-sast-dast --av "MyApp:1.0" --app MyAviatorApp \ + %n%n Correlate without refreshing application version metrics first: \ + %n fcli aviator ssc correlate-sast-dast --av "MyApp:1.0" --no-refresh fcli.aviator.ssc.correlate-sast-dast.app = Fortify Aviator application name to associate with the correlation. If not provided, the SAST/FPR Build ID of the SSC application is used. #################################################################################################################