Skip to content

Commit

Permalink
chore: Add/update issue list commands
Browse files Browse the repository at this point in the history
fix: `fcli ssc issue list`: Add `--include` option to allow for retrieving `hidden`, `fixed` and/or `suppressed` issues

chore: Update behavior of `fcli fod issue list --include` option to allow retrieval of only fixed/suppressed issues, without `visible` issues
  • Loading branch information
rsenden committed May 27, 2024
1 parent 833c607 commit 318ca98
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.fortify.cli.fod.issue.cli.mixin;

import java.util.List;
import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.json.JsonHelper;
import com.fortify.cli.common.output.transform.IRecordTransformer;
import com.fortify.cli.common.rest.unirest.IHttpRequestUpdater;
import com.fortify.cli.common.util.DisableTest;
import com.fortify.cli.common.util.DisableTest.TestType;
Expand All @@ -11,23 +14,51 @@
import lombok.RequiredArgsConstructor;
import picocli.CommandLine.Option;

public class FoDIssueIncludeMixin implements IHttpRequestUpdater {
public class FoDIssueIncludeMixin implements IHttpRequestUpdater, IRecordTransformer {
@DisableTest(TestType.MULTI_OPT_PLURAL_NAME)
@Option(names = {"--include", "-i"}, split = ",", descriptionKey = "fcli.fod.issue.list.includeIssue", paramLabel="<status>")
private List<FoDIssueInclude> includes;
@Option(names = {"--include", "-i"}, split = ",", defaultValue = "visible", descriptionKey = "fcli.fod.issue.list.includeIssue", paramLabel="<status>")
private Set<FoDIssueInclude> includes;

public HttpRequest<?> updateRequest(HttpRequest<?> request) {
// TODO Potentially if 'includes' contains ONLY suppressed, we could also
// add filters=isSuppressed:true to perform server-side filtering
// (note that FoD doesn't allow for server-side filtering on closedStatus,
// so we can't do the same for fixed issues).
// However, we'd need to check how to integrate this with any
// FoDFiltersParamGenerator defined on the command, i.e., how FoD
// reacts if there are multiple 'filters' parameters, and/or do
// some refactoring to generate only a single 'filters' parameter
// from multiple sources. Alternatively, instead of directly generating
// a 'filters' parameter, we could potentially amend the client-side
// query, which would then be picked up by any FoDFiltersParamGenerator,
// and also remove the need for having an explicit transformRecord()
// method to perform client-side filtering.
if ( includes!=null ) {
for ( var include : includes) {
request = request.queryString(include.getRequestParameterName(), "true");
var queryParameterName = include.getRequestParameterName();
if ( queryParameterName!=null ) {
request = request.queryString(queryParameterName, "true");
}
}
}
return request;
}

@Override
public JsonNode transformRecord(JsonNode record) {
// If includes doesn't include 'visible', we return null for any visible (non-suppressed
// & non-fixed) issues. We don't need explicit handling for other cases, as suppressed or
// fixed issues won't be returned by FoD if not explicitly specified through the --include
// option.
return !includes.contains(FoDIssueInclude.visible)
&& JsonHelper.evaluateSpelExpression(record, "!isSuppressed && !closedStatus", Boolean.class)
? null
: record;
}

@RequiredArgsConstructor
public static enum FoDIssueInclude {
fixed("includeFixed"), suppressed("includeSuppressed");
visible(null), fixed("includeFixed"), suppressed("includeSuppressed");

@Getter
private final String requestParameterName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -755,9 +755,10 @@ fcli.fod.issue.embed = Embed extra issue data. Due to FoD rate limits, this may
Using the --output option, this extra data can be included in the output. Using the --query option, \
this extra data can be queried upon. To get an understanding of the structure and contents of the \
embedded data, use the --output json or --output yaml options.
fcli.fod.issue.list.includeIssue = By default, fixed or suppressed issues will not be included. \
This option accepts 'fixed', 'suppressed' or 'fixed,suppressed' to include such issues in the \
output.
fcli.fod.issue.list.includeIssue = By default, only visible issues will be returned. This option \
accepts a comma-separated list to allow (also) fixed and/or suppressed issues to be returned, \
for example `--include visible,fixed` (to return both visible and fixed issues) or `--include \
fixed` (to return only fixed issues). Allowed values: ${COMPLETION-CANDIDATES}.

# fcli fod report
fcli.fod.report.usage.header = Manage FoD reports.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionResolverMixin;
import com.fortify.cli.ssc.issue.cli.mixin.SSCIssueBulkEmbedMixin;
import com.fortify.cli.ssc.issue.cli.mixin.SSCIssueFilterSetResolverMixin;
import com.fortify.cli.ssc.issue.cli.mixin.SSCIssueIncludeMixin;
import com.fortify.cli.ssc.issue.helper.SSCIssueFilterHelper;
import com.fortify.cli.ssc.issue.helper.SSCIssueFilterSetDescriptor;

Expand All @@ -41,6 +42,7 @@ public class SSCIssueListCommand extends AbstractSSCBaseRequestOutputCommand imp
@Mixin private SSCQParamMixin qParamMixin;
@Mixin private SSCIssueBulkEmbedMixin bulkEmbedMixin;
@Option(names="--filter", required=false) private String filter;
@Mixin private SSCIssueIncludeMixin includeMixin;

// For some reason, SSC q param doesn't use same property names as returned by SSC,
// so we list the proper mappings below. TODO Any other useful server-side queries?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.fortify.cli.ssc.issue.cli.mixin;

import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.json.JsonHelper;
import com.fortify.cli.common.output.transform.IRecordTransformer;
import com.fortify.cli.common.rest.unirest.IHttpRequestUpdater;
import com.fortify.cli.common.util.DisableTest;
import com.fortify.cli.common.util.DisableTest.TestType;

import kong.unirest.HttpRequest;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import picocli.CommandLine.Option;

public class SSCIssueIncludeMixin implements IHttpRequestUpdater, IRecordTransformer {
@DisableTest(TestType.MULTI_OPT_PLURAL_NAME)
@Option(names = {"--include", "-i"}, split = ",", defaultValue = "visible", descriptionKey = "fcli.ssc.issue.list.includeIssue", paramLabel="<status>")
private Set<SSCIssueInclude> includes;

public HttpRequest<?> updateRequest(HttpRequest<?> request) {
// TODO Check whether we can potentially perform any server-side filtering
// to retrieve ONLY suppressed/fixed/hidden issues, although SSC doesn't
// seem to allow server-side filtering on the respective boolean fields.
// See FoDIssueIncludeMixin for additional details.
if ( includes!=null ) {
for ( var include : includes) {
var queryParameterName = include.getRequestParameterName();
if ( queryParameterName!=null ) {
request = request.queryString(queryParameterName, "true");
}
}
}
return request;
}

@Override
public JsonNode transformRecord(JsonNode record) {
// If includes doesn't include 'visible', we return null for any visible (non-suppressed
// & non-fixed) issues. We don't need explicit handling for other cases, as suppressed or
// fixed issues won't be returned by FoD if not explicitly specified through the --include
// option.
return !includes.contains(SSCIssueInclude.visible)
&& JsonHelper.evaluateSpelExpression(record, "!hidden && !removed && !suppressed", Boolean.class)
? null
: record;
}

@RequiredArgsConstructor
public static enum SSCIssueInclude {
visible(null), hidden("showhidden"), fixed("showremoved"), suppressed("showsuppressed");

@Getter
private final String requestParameterName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ fcli.ssc.issue.list.embed = Embed extra application version data. Allowed values
Using the --output option, this extra data can be included in the output. Using the --query option, \
this extra data can be queried upon. To get an understanding of the structure and contents of the \
embedded data, use the --output json or --output yaml options.
fcli.ssc.issue.list.includeIssue = By default, only visible issues will be returned. This option \
accepts a comma-separated list to allow (also) fixed, suppressed and/or hidden issues to be returned, \
for example `--include visible,fixed` (to return both visible and fixed issues) or `--include \
fixed` (to return only fixed issues). Allowed values: ${COMPLETION-CANDIDATES}.
fcli.ssc.issue.get-filter.usage.header = Get issue filter details.
fcli.ssc.issue.filter = Technical or friendly filter as returned by the 'fcli ssc issue list-filters' command.
fcli.ssc.issue.list-filters.usage.header = List application version issue filters.
Expand Down

0 comments on commit 318ca98

Please sign in to comment.