Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: fortify/fcli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.6.0
Choose a base ref
...
head repository: fortify/fcli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.7.0
Choose a head ref

Commits on Sep 12, 2024

  1. Copy the full SHA
    e3a273c View commit details

Commits on Sep 16, 2024

  1. chore: SSC appversion refresh improvements

    feat: `fcli ssc appversion create`: Add `--refresh-timeout` option
    
    feat: `fcli ssc appversion copy-state`: Add `--refresh-timeout` option
    
    fix: `fcli ssc appversion refresh-metrics`: Allow for `fcli state wait-for-job ::var::` to be invoked without errors even if no refresh was required
    rsenden committed Sep 16, 2024
    Copy the full SHA
    89cf435 View commit details
  2. Copy the full SHA
    388981a View commit details
  3. Copy the full SHA
    ae795c5 View commit details
  4. Copy the full SHA
    b7a1705 View commit details
  5. Copy the full SHA
    7378c00 View commit details
  6. Copy the full SHA
    4ab86c0 View commit details
  7. Copy the full SHA
    26bcabc View commit details
  8. Copy the full SHA
    e1c257d View commit details
  9. Copy the full SHA
    edcece5 View commit details
  10. feat: fcli fod sast-scan setup: Set --technology-stack to `Auto D…

    …etect` by default (fixes #595)
    rsenden committed Sep 16, 2024
    Copy the full SHA
    852d7bf View commit details
  11. Copy the full SHA
    757b3ad View commit details
  12. Copy the full SHA
    3a2d489 View commit details

Commits on Sep 17, 2024

  1. feat: fcli fod sast-scan setup: Add --use-aviator option (fixes #594

    )
    
    chore: `fcli fod sast-setup` partial fix for incorrect output
    kadraman committed Sep 17, 2024
    Copy the full SHA
    013af6f View commit details
  2. Copy the full SHA
    0aabeaf View commit details
  3. Copy the full SHA
    3727329 View commit details
  4. docs: Improve action synopsis

    rsenden committed Sep 17, 2024
    Copy the full SHA
    3321113 View commit details
  5. docs: Improve action synopsis

    rsenden committed Sep 17, 2024
    Copy the full SHA
    21ddf53 View commit details
  6. Merge pull request #599 from kadraman/fod-2403-updates

    Updates for Fortify Aviator in SAST scan setup and Release Attributes
    rsenden authored Sep 17, 2024
    Copy the full SHA
    312323e View commit details

Commits on Sep 19, 2024

  1. feat: FoD & SSC: Add aws-sast-report actions to enable integrating Fo…

    …rtify results with AWS Security Hub (#559)
    rohitbaryha1 authored Sep 19, 2024
    Copy the full SHA
    dc79095 View commit details

Commits on Sep 20, 2024

  1. chore: Update attribute handling and setup-release action (#605)

    fix: `fcli fod release create`: Ignore application attributes if included in `--attrs` option (fixes #604)
    
    fix: `fcli fod release update`: Ignore application attributes if included in `--attrs` option (fixes #604)
    
    fix: `fcli fod app update`: Ignore release attributes if included in `--attrs` option (fixes #604)
    
    chore: `fcli fod app create`: Allow both app & release attributes to be specified in `--attrs` option
    
    chore: `setup-release` action: Add support for attributes & Aviator
    kadraman authored Sep 20, 2024
    Copy the full SHA
    e2077b9 View commit details

Commits on Sep 23, 2024

  1. chore: Update actions

    rsenden committed Sep 23, 2024
    Copy the full SHA
    14626d7 View commit details

Commits on Sep 24, 2024

  1. Copy the full SHA
    77fcc1c View commit details

Commits on Sep 25, 2024

  1. Copy the full SHA
    d071d25 View commit details
  2. Copy the full SHA
    52a7821 View commit details
  3. Copy the full SHA
    c3670cc View commit details
  4. Merge pull request #609 from fortify/develop

    chore: Prepare for new release
    rsenden authored Sep 25, 2024
    Copy the full SHA
    5241640 View commit details
  5. Copy the full SHA
    2440cc1 View commit details
  6. Merge pull request #610 from fortify/release-please--branches--v2.x

    chore(v2.x): release 2.7.0
    rsenden authored Sep 25, 2024
    Copy the full SHA
    9981ead View commit details
Showing with 1,317 additions and 166 deletions.
  1. +1 −1 .release-please-manifest.json
  2. +26 −0 CHANGELOG.md
  3. +146 −0 ...cli-common/src/main/java/com/fortify/cli/common/action/cli/cmd/AbstractActionAsciidocCommand.java
  4. +10 −5 fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/helper/ActionLoaderHelper.java
  5. +3 −0 fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/model/ActionParameter.java
  6. +28 −0 fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/runner/ActionRunner.java
  7. +2 −2 fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/JsonHelper.java
  8. +1 −1 fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/wait/WaitHelper.java
  9. +10 −7 fcli-core/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties
  10. +51 −0 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/util/FoDEnums.java
  11. +25 −0 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/action/cli/cmd/FoDActionAsciidocCommand.java
  12. +1 −0 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/action/cli/cmd/FoDActionCommands.java
  13. +5 −0 ...core/fcli-fod/src/main/java/com/fortify/cli/fod/app/attr/cli/mixin/FoDAttributeUpdateOptions.java
  14. +23 −10 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/attr/helper/FoDAttributeHelper.java
  15. +4 −2 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppCreateCommand.java
  16. +4 −2 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppUpdateCommand.java
  17. +10 −1 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseCreateCommand.java
  18. +22 −2 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseUpdateCommand.java
  19. +3 −0 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseCreateRequest.java
  20. +14 −1 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseDescriptor.java
  21. +2 −0 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/helper/FoDReleaseUpdateRequest.java
  22. +101 −72 fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/sast_scan/cli/cmd/FoDSastScanSetupCommand.java
  23. +1 −0 ...re/fcli-fod/src/main/java/com/fortify/cli/fod/sast_scan/helper/FoDScanConfigSastSetupRequest.java
  24. +111 −0 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/aws-sast-report.yaml
  25. +6 −6 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/check-policy.yaml
  26. +21 −12 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/github-pr-comment.yaml
  27. +2 −2 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/github-sast-report.yaml
  28. +116 −0 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/setup-release.yaml
  29. +24 −7 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/i18n/FoDMessages.properties
  30. +2 −0 fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/_main/cli/cmd/SCSastCommands.java
  31. +13 −4 ...-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastControllerScanStartCommand.java
  32. +27 −0 ...i-sc-sast/src/main/java/com/fortify/cli/sc_sast/sensor_pool/cli/cmd/SCSastSensorPoolCommands.java
  33. +38 −0 ...c-sast/src/main/java/com/fortify/cli/sc_sast/sensor_pool/cli/cmd/SCSastSensorPoolListCommand.java
  34. +32 −0 ...sast/src/main/java/com/fortify/cli/sc_sast/sensor_pool/cli/helper/SCSastSensorPoolDescriptor.java
  35. +55 −0 ...-sc-sast/src/main/java/com/fortify/cli/sc_sast/sensor_pool/cli/helper/SCSastSensorPoolHelper.java
  36. +55 −0 ...st/src/main/java/com/fortify/cli/sc_sast/sensor_pool/cli/mixin/SCSastSensorPoolResolverMixin.java
  37. +8 −2 fcli-core/fcli-sc-sast/src/main/resources/com/fortify/cli/sc_sast/i18n/SCSastMessages.properties
  38. +25 −0 fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/action/cli/cmd/SSCActionAsciidocCommand.java
  39. +1 −0 fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/action/cli/cmd/SSCActionCommands.java
  40. +1 −1 .../fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCopyStateCommand.java
  41. +3 −1 ...-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionRefreshMetricsCommand.java
  42. +1 −1 ...e/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionCopyFromMixin.java
  43. +3 −0 .../fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionRefreshOptions.java
  44. +3 −1 fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/mixin/SSCJobResolverMixin.java
  45. +6 −3 fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/helper/SSCJobHelper.java
  46. +129 −0 fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/aws-sast-report.yaml
  47. +23 −15 fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/github-pr-comment.yaml
  48. +2 −2 fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/github-sast-report.yaml
  49. +88 −0 fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/setup-appversion.yaml
  50. +3 −0 fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties
  51. +19 −1 fcli-other/fcli-doc/build.gradle
  52. +5 −0 fcli-other/fcli-doc/src/docs/asciidoc/versioned/index.adoc
  53. +1 −1 gradle.properties
  54. +1 −1 version.txt
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.6.0"
".": "2.7.0"
}
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# Changelog

## [2.7.0](https://github.com/fortify/fcli/compare/v2.6.0...v2.7.0) (2024-09-25)


### Features

* `fcli fod release create`: Support release attributes (fixes fortify[#592](https://github.com/fortify/fcli/issues/592)) ([3727329](https://github.com/fortify/fcli/commit/37273298d007a15c552ae308b77f59d5e744798a))
* `fcli fod sast-scan setup`: Add `--skip-if-exists` option ([edcece5](https://github.com/fortify/fcli/commit/edcece5bf8b13aa5e79fd39ffa23ab7e03132781))
* `fcli fod sast-scan setup`: Add `--use-aviator` option (fixes fortify[#594](https://github.com/fortify/fcli/issues/594)) ([013af6f](https://github.com/fortify/fcli/commit/013af6ff7d4a0f1a140764447a34556960b51df7))
* `fcli fod sast-scan setup`: Set `--technology-stack` to `Auto Detect` by default (fixes [#595](https://github.com/fortify/fcli/issues/595)) ([852d7bf](https://github.com/fortify/fcli/commit/852d7bfa36af8a34c7eec768e2ddc6e81e33b2b1))
* `fcli sc-sast scan start`: Add option to select sensor pool for the scan ([d071d25](https://github.com/fortify/fcli/commit/d071d25944fbd06b79bc622d323fa6d42b5d75ba))
* `fcli ssc appversion copy-state`: Add `--refresh-timeout` option ([89cf435](https://github.com/fortify/fcli/commit/89cf4351ec3eb8fe9dfbdd682b8d485ee9bff07b))
* `fcli ssc appversion create`: Add `--refresh-timeout` option ([89cf435](https://github.com/fortify/fcli/commit/89cf4351ec3eb8fe9dfbdd682b8d485ee9bff07b))
* Add `fcli sc-sast sensor-pool list` command ([77fcc1c](https://github.com/fortify/fcli/commit/77fcc1c57f044aa99ba49e77710b98fd062593c0))
* Add FoD setup-release action ([4ab86c0](https://github.com/fortify/fcli/commit/4ab86c066a730fa10c29d4ab18f4838e322c1327))
* Add SSC setup-appversion action ([e3a273c](https://github.com/fortify/fcli/commit/e3a273c5ce489311f19f2355fde3f383bfac43a2))
* FoD & SSC: Add aws-sast-report actions to enable integrating Fortify results with AWS Security Hub ([#559](https://github.com/fortify/fcli/issues/559)) ([dc79095](https://github.com/fortify/fcli/commit/dc790950794c976c5242fc44fffd2ad5c0f1c081))


### Bug Fixes

* `fcli fod app update`: Ignore release attributes if included in `--attrs` option (fixes fortify[#604](https://github.com/fortify/fcli/issues/604)) ([e2077b9](https://github.com/fortify/fcli/commit/e2077b942e413083707893cad9b2aff562b391c6))
* `fcli fod release create`: Ignore application attributes if included in `--attrs` option (fixes fortify[#604](https://github.com/fortify/fcli/issues/604)) ([e2077b9](https://github.com/fortify/fcli/commit/e2077b942e413083707893cad9b2aff562b391c6))
* `fcli fod release update`: Ignore application attributes if included in `--attrs` option (fixes fortify[#604](https://github.com/fortify/fcli/issues/604)) ([e2077b9](https://github.com/fortify/fcli/commit/e2077b942e413083707893cad9b2aff562b391c6))
* `fcli ssc appversion refresh-metrics`: Allow for `fcli state wait-for-job ::var::` to be invoked without errors even if no refresh was required ([89cf435](https://github.com/fortify/fcli/commit/89cf4351ec3eb8fe9dfbdd682b8d485ee9bff07b))
* Increase issue limit for `github-sast-report` to match current GitHub limits ([3a2d489](https://github.com/fortify/fcli/commit/3a2d48929a9978ab71f0e02d2d669b47686556ce))

## [2.6.0](https://github.com/fortify/fcli/compare/v2.5.3...v2.6.0) (2024-09-09)


Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*******************************************************************************
* Copyright 2021, 2023 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.common.action.cli.cmd;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.fortify.cli.common.action.cli.mixin.ActionSourceResolverMixin;
import com.fortify.cli.common.action.helper.ActionLoaderHelper;
import com.fortify.cli.common.action.helper.ActionLoaderHelper.ActionValidationHandler;
import com.fortify.cli.common.action.model.Action;
import com.fortify.cli.common.action.runner.ActionParameterHelper;
import com.fortify.cli.common.cli.cmd.AbstractRunnableCommand;
import com.fortify.cli.common.cli.mixin.CommonOptionMixins;
import com.fortify.cli.common.cli.util.SimpleOptionsParser.IOptionDescriptor;
import com.fortify.cli.common.util.FcliBuildPropertiesHelper;
import com.fortify.cli.common.util.StringUtils;

import lombok.SneakyThrows;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;

public abstract class AbstractActionAsciidocCommand extends AbstractRunnableCommand {
@Mixin private ActionSourceResolverMixin.OptionalOption actionSourceResolver;
@Mixin private CommonOptionMixins.OptionalFile outputFileMixin;
@Option(names= {"--manpage-dir", "-d"}, required = false, descriptionKey="fcli.action.asciidoc.manpage-dir")
private Path manpageDir;

@Override @SneakyThrows
public final Integer call() {
initMixins();
var contents = generateHeader();
contents += ActionLoaderHelper
.streamAsActions(actionSourceResolver.getActionSources(getType()), ActionValidationHandler.IGNORE)
.map(this::generateActionSection)
.collect(Collectors.joining("\n\n"));
contents = addLinks(contents);
var outputFile = outputFileMixin.getFile();
if ( outputFile==null ) {
System.out.println(contents);
} else {
// TODO Should we require confirmation is file already exists?
Files.writeString(outputFile.toPath(), contents, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
}
return 0;
}

private final String replaceVariables(String s) {
return s.replace("${version}", FcliBuildPropertiesHelper.getFcliBuildInfo().replace(':', ' '))
.replace("${type}", getType())
.replace("${typeLower}", getType().toLowerCase());
}

private final String generateHeader() {
return replaceVariables("""
= Fcli ${type} Actions
This manual page describes built-in fcli ${type} actions that can be run through
the `fcli ${typeLower} action run <action-name>` command.
""");
}

private final String generateActionSection(Action action) {
// TODO Generate proper options list in synopsis. We should have a re-usable method in
// ActionParameterHelper or other class for generating this, such that we can also
// show synopsis in `fcli * action help` output.
String name = action.getMetadata().getName();
return replaceVariables(String.format("""
== %s
%s
=== Synopsis
*fcli ${typeLower} action run %s [fcli ${typeLower} action run options] [action options, see below]*
=== Description
%s
=== Options
%s
""", name, action.getUsage().getHeader(), name, action.getUsage().getDescription(), generateOptionsSection(action)));
}

private final String generateOptionsSection(Action action) {
return ActionParameterHelper.getOptionDescriptors(action)
.stream().map(this::generateOptionDescription).collect(Collectors.joining("\n\n"));
}

private final String generateOptionDescription(IOptionDescriptor descriptor) {
return String.format("%s::\n%s",
descriptor.getOptionNamesAndAliasesString(", "),
StringUtils.indent(descriptor.getDescription(), " "));
}

private final String addLinks(String contents) {
if ( manpageDir==null ) { return contents; }
var manPages = listDir(manpageDir).stream().filter(s->s.matches("fcli-[\\w-]+-[\\w-]+-[\\w-]+.adoc"))
.map(s->s.replaceAll("\\.adoc", ""))
.collect(Collectors.toSet());
for ( var manPage : manPages ) {
var pattern = manPage.replace("-", "[ -]");
var replacement = String.format("link:manpage/%s.html[$1]", manPage);
contents = contents.replaceAll("(?<!`)("+pattern+")", replacement);
contents = contents.replaceAll("(`"+pattern+".*`)", replacement);
}
return contents;
}

private Set<String> listDir(Path dir) {
try (Stream<Path> stream = Files.list(dir)) {
return stream
.filter(file -> !Files.isDirectory(file))
.map(Path::getFileName)
.map(Path::toString)
.collect(Collectors.toSet());
} catch ( IOException e ) {
return new HashSet<>();
}
}

protected abstract String getType();


}
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Stream;
@@ -73,19 +74,23 @@ public static final ActionLoadResult load(List<ActionSource> sources, String nam
return new ActionLoader(sources, actionValidationHandler).load(name);
}

public static final Stream<Action> streamAsActions(List<ActionSource> sources, ActionValidationHandler actionValidationHandler) {
return _stream(sources, actionValidationHandler, ActionLoadResult::getAction, a->a.getMetadata().getName());
}

public static final Stream<ObjectNode> streamAsJson(List<ActionSource> sources, ActionValidationHandler actionValidationHandler) {
return _streamAsJson(sources, actionValidationHandler);
return _stream(sources, actionValidationHandler, ActionLoadResult::getSummaryObjectNode, o->o.get("name").asText());
}

private static final Stream<ObjectNode> _streamAsJson(List<ActionSource> sources, ActionValidationHandler actionValidationHandler) {
Map<String, ObjectNode> result = new HashMap<>();
private static final <T> Stream<T> _stream(List<ActionSource> sources, ActionValidationHandler actionValidationHandler, Function<ActionLoadResult, T> asTypeFunction, Function<T, String> nameFunction) {
Map<String, T> result = new HashMap<>();
new ActionLoader(sources, actionValidationHandler)
.processActions(loadResult->{
result.putIfAbsent(loadResult.getMetadata().getName(), loadResult.getSummaryObjectNode());
result.putIfAbsent(loadResult.getMetadata().getName(), asTypeFunction.apply(loadResult));
return Break.FALSE;
});
return result.values().stream()
.sorted((a,b)->a.get("name").asText().compareTo(b.get("name").asText()));
.sorted((a,b)->nameFunction.apply(a).compareTo(nameFunction.apply(b)));
}

public static final String getSignatureStatusMessage(ActionMetadata metadata, SignatureStatus signatureStatus) {
Original file line number Diff line number Diff line change
@@ -50,6 +50,9 @@ public final class ActionParameter implements IActionElement {
@JsonPropertyDescription("Optional boolean: All parameters are required by default, unless this property is set to false.")
@JsonProperty(required = false, defaultValue = "true") private boolean required = true;

@JsonPropertyDescription("Optional string: Allows for defining groups of parameters")
@JsonProperty(required = false) private String group;

public final void postLoad(Action action) {
Action.checkNotBlank("parameter name", name, this);
Action.checkNotNull("parameter description", getDescription(), this);
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@
import com.fasterxml.jackson.databind.node.TextNode;
import com.fasterxml.jackson.databind.node.ValueNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.formkiq.graalvm.annotations.Reflectable;
import com.fortify.cli.common.action.model.AbstractActionStepForEach;
import com.fortify.cli.common.action.model.Action;
import com.fortify.cli.common.action.model.ActionParameter;
@@ -207,6 +208,29 @@ public final void close() {

private final void configureSpelEvaluator(SimpleEvaluationContext context) {
SpelHelper.registerFunctions(context, ActionSpelFunctions.class);
context.setVariable("action", new ActionUtil());
}

@Reflectable
private final class ActionUtil {
@SuppressWarnings("unused")
public final String copyParametersFromGroup(String group) {
StringBuilder result = new StringBuilder();
for ( var p : action.getParameters() ) {
if ( group==null || group.equals(p.getGroup()) ) {
var val = parameters.get(p.getName());
if ( val!=null && StringUtils.isNotBlank(val.asText()) ) {
result
.append("\"--")
.append(p.getName())
.append("=")
.append(val.asText())
.append("\" ");
}
}
}
return result.toString();
}
}

public final ActionRunner addParameterConverter(String type, BiFunction<String, ParameterTypeConverterArgs, JsonNode> converter) {
@@ -956,12 +980,16 @@ public static final class ParameterTypeConverterArgs {

private static final Map<String, BiFunction<String, ParameterTypeConverterArgs, JsonNode>> createDefaultParameterConverters() {
Map<String, BiFunction<String, ParameterTypeConverterArgs, JsonNode>> result = new HashMap<>();
// TODO Most of these will likely fail in case value is null or empty
result.put("string", (v,a)->new TextNode(v));
result.put("boolean", (v,a)->BooleanNode.valueOf(Boolean.parseBoolean(v)));
result.put("int", (v,a)->IntNode.valueOf(Integer.parseInt(v)));
result.put("long", (v,a)->LongNode.valueOf(Long.parseLong(v)));
result.put("double", (v,a)->DoubleNode.valueOf(Double.parseDouble(v)));
result.put("float", (v,a)->FloatNode.valueOf(Float.parseFloat(v)));
result.put("array", (v,a)->StringUtils.isBlank(v)
? JsonHelper.toArrayNode(new String[] {})
: JsonHelper.toArrayNode(v.split(",")));
// TODO Add BigIntegerNode/DecimalNode/ShortNode support?
// TODO Add array support?
return result;
Original file line number Diff line number Diff line change
@@ -86,8 +86,8 @@ public static final ArrayNodeCollector arrayNodeCollector() {
return new ArrayNodeCollector();
}

public static final ArrayNode toArrayNode(String... objects) {
return Stream.of(objects).map(TextNode::new).collect(arrayNodeCollector());
public static final ArrayNode toArrayNode(String... strings) {
return Stream.of(strings).map(TextNode::new).collect(arrayNodeCollector());
}

public static final ArrayNode toArrayNode(JsonNode... objects) {
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ private final void addNodeWithStatus(Map<ObjectNode, String> nodesWithStatus, Js
}

private final void updateProgress(Map<ObjectNode, WaitStatus> recordsWithWaitStatus) {
if ( progressMonitor!=null ) {
if ( progressMonitor!=null && !recordsWithWaitStatus.isEmpty() ) {
progressMonitor.updateProgress(recordsWithWaitStatus);
}
}
Original file line number Diff line number Diff line change
@@ -14,11 +14,11 @@ usage.footer.0 = %nCommands/options marked as PREVIEW are subject to change; pip
usage.footer.1 = %nFull command list: fcli util all-commands list
usage.footer.2 = Documentation: https://fortify.github.io/fcli
usage.footer.3 = %n(c) Copyright 2021-2024 Open Text
usage.parameterListHeading = %nCommand parameters:%n
usage.optionListHeading = %nCommand options:%n
usage.parameterListHeading = %nCommand parameters%n
usage.optionListHeading = %nCommand options%n

# Generic, non command-specific options
fcli.genericOptions.heading = Generic fcli options:%n
fcli.genericOptions.heading = Generic fcli options%n
help = Show this help message and exit. Use 'fcli <command> -h' to display help for subcommands.
version = Print version information and exit.
env-prefix = Environment variable prefix for resolving default option and parameter values. \
@@ -31,6 +31,9 @@ log-file = File where logging data will be written. Defaults to fcli.log in curr
fcli.action.nameOrLocation = The action to load; either simple name or local or remote action \
YAML file location. Note that custom actions are currently considered PREVIEW functionality, \
as explained in the 'fcli ${module} action -h' help output.
fcli.action.asciidoc.manpage-dir = Optional directory to write output. If directory contains fcli \
manual pages, any (full) fcli commands in the generated documentation will link to the corresponding \
fcli manual page.

fcli.action.run.action-parameter = Action parameter(s); see 'help' command output to \
list supported parameters.
@@ -53,8 +56,8 @@ fcli.action.sign.pubout = Public key output file. This option is required when g
new key pair (if given private key doesn't exist), and may optionally be used for outputting \
the public key if an already existing private key is being used.
fcli.action.resolver.from-zip = Optional local or remote zip-file from which to load the action if \
the action is specified as a simple name. This option will be ignored if action is specified as \
local or remote action YAML file location.
the action is specified as a simple name. For commands that take an action as input (like get, help \
or run), this option will be ignored if action is specified as local or remote action YAML file location.
fcli.action.resolver.pubkey = Optional public key to use for verifying action signature. Can \
be specified as one of: \
%n file:<local file>%n url:<url>%n string:<string value>%n env:<env-var name>\
@@ -74,7 +77,7 @@ fcli.action.on-invalid-version = Action to take if action schema version is not
output.header.signatureStatus = Signature\nStatus

# Generic, non command-specific output and query options
arggroup.output.heading = Output options:%n
arggroup.output.heading = Output options%n
output = Specify output format and options. Available output formats: ${COMPLETION-CANDIDATES}. \
The 'expr' output format takes a string containing '{property}' placeholders, other output \
formats take an optional, comma-separated list of properties to include in the output. Use \
@@ -132,7 +135,7 @@ progress=Configure progress output. Allowed values: ${COMPLETION-CANDIDATES}. De
${DEFAULT-VALUE}. Proper output of single-line and ansi depends on console capabilities.

# Login and connection options
arggroup.optional.session-name.heading = Session options:%n
arggroup.optional.session-name.heading = Session options%n
login.session = Name for this ${product} session. Default value: ${DEFAULT-VALUE}.
logout.session = Name of the ${product} session to be terminated. Default value: ${DEFAULT-VALUE}.
session = Name of the ${product} session to use for executing this command. Default value: ${DEFAULT-VALUE}.
Loading