Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions cmd/kosli/listFlows.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import (
const listFlowsDesc = `List flows for an org.`

type listFlowsOptions struct {
output string
output string
name string
ignoreCase bool
}

func newListFlowsCmd(out io.Writer) *cobra.Command {
Expand All @@ -39,19 +41,34 @@ func newListFlowsCmd(out io.Writer) *cobra.Command {
}

cmd.Flags().StringVarP(&o.output, "output", "o", "table", outputFlag)
cmd.Flags().StringVarP(&o.name, "name", "n", "", searchByNameFlag)
cmd.Flags().BoolVarP(&o.ignoreCase, "ignore-case", "i", false, ignoreCaseFlag)

return cmd
}

func (o *listFlowsOptions) run(out io.Writer) error {
url, err := url.JoinPath(global.Host, "api/v2/flows", global.Org)
base, err := url.JoinPath(global.Host, "api/v2/flows", global.Org)
if err != nil {
return err
}

params := url.Values{}
if o.name != "" {
params.Set("search_by_name", o.name)
// case_sensitive only affects search, so only send it alongside a search term
if o.ignoreCase {
params.Set("case_sensitive", "false")
}
}
Comment thread
mbevc1 marked this conversation as resolved.
reqURL := base
if encoded := params.Encode(); encoded != "" {
reqURL = base + "?" + encoded
}

reqParams := &requests.RequestParams{
Method: http.MethodGet,
URL: url,
URL: reqURL,
Token: global.ApiToken,
}
response, err := kosliClient.Do(reqParams)
Expand Down
29 changes: 29 additions & 0 deletions cmd/kosli/listFlows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func (suite *ListFlowsCommandTestSuite) SetupTest() {
}
suite.defaultKosliArguments = fmt.Sprintf(" --host %s --org %s --api-token %s", global.Host, global.Org, global.ApiToken)

// create flows with deterministic names so the --name / --case-sensitive tests
// can assert match / no-match behaviour reliably
CreateFlow("list-flows-search-target", suite.T())

global.Org = "acme-org"
global.ApiToken = "v3OWZiYWu9G2IMQStYg9BcPQUQ88lJNNnTJTNq8jfvmkR1C5wVpHSs7F00JcB5i6OGeUzrKt3CwRq7ndcN4TTfMeo8ASVJ5NdHpZT7DkfRfiFvm8s7GbsIHh2PtiQJYs2UoN13T8DblV5C4oKb6-yWH73h67OhotPlKfVKazR-c"
suite.acmeOrgKosliArguments = fmt.Sprintf(" --host %s --org %s --api-token %s", global.Host, global.Org, global.ApiToken)
Expand Down Expand Up @@ -51,6 +55,31 @@ func (suite *ListFlowsCommandTestSuite) TestListFlowsCmd() {
cmd: fmt.Sprintf(`list flows --output json %s`, suite.acmeOrgKosliArguments),
goldenJson: []jsonCheck{{"", "[]"}},
},
{
name: "--name matches flows whose name contains the substring",
cmd: fmt.Sprintf(`list flows --name list-flows-search-target --output json %s`, suite.defaultKosliArguments),
goldenJson: []jsonCheck{{"", "non-empty"}, {"[0].name", "list-flows-search-target"}},
},
{
name: "--name with no matching substring returns an empty list",
cmd: fmt.Sprintf(`list flows --name no-such-flow-substring-xyz --output json %s`, suite.defaultKosliArguments),
goldenJson: []jsonCheck{{"", "[]"}},
},
{
name: "--name matching is case sensitive by default so a wrong-case substring does not match",
cmd: fmt.Sprintf(`list flows --name LIST-FLOWS-SEARCH-TARGET --output json %s`, suite.defaultKosliArguments),
goldenJson: []jsonCheck{{"", "[]"}},
},
{
name: "--ignore-case makes a wrong-case substring match",
cmd: fmt.Sprintf(`list flows --name LIST-FLOWS-SEARCH-TARGET --ignore-case --output json %s`, suite.defaultKosliArguments),
goldenJson: []jsonCheck{{"", "non-empty"}, {"[0].name", "list-flows-search-target"}},
},
{
name: "short flags -n and -i work like --name and --ignore-case",
cmd: fmt.Sprintf(`list flows -n LIST-FLOWS-SEARCH-TARGET -i --output json %s`, suite.defaultKosliArguments),
goldenJson: []jsonCheck{{"", "non-empty"}, {"[0].name", "list-flows-search-target"}},
},
{
wantError: true,
name: "providing an argument causes an error",
Expand Down
4 changes: 3 additions & 1 deletion cmd/kosli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ The ^.kosli_ignore^ will be treated as part of the artifact like any other file,
templateArtifactName = "The name of the artifact in the yml template file."
flowNamesFlag = "[defaulted] The comma separated list of Kosli flows. Defaults to all flows of the org."
outputFlag = "[defaulted] The format of the output. Valid formats are: [table, json]."
searchByNameFlag = "[optional] Only list flows whose name contains this substring. The Kosli API supports alphanumeric characters and '-'."
ignoreCaseFlag = "[optional] Perform case-insensitive matching for --name. By default matching is case sensitive."
serviceAccountNameFlag = "The name of the service account whose API keys are managed."
apiKeyDescriptionFlag = "A description for the API key."
apiKeyExpiresAtFlag = "[optional] When the API key expires. Accepts an epoch timestamp or a date like '2026-06-04', '2026-06-04 15:04:05', or an RFC3339 timestamp. Defaults to no expiry."
Expand Down Expand Up @@ -216,7 +218,7 @@ The ^.kosli_ignore^ will be treated as part of the artifact like any other file,
excludePathsFlag = "[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns. Only applicable for --artifact-type dir."
serverExcludePathsFlag = "[optional] The comma separated list of directories and files to exclude from fingerprinting. Can take glob patterns."
shortFlag = "[optional] Print only the Kosli CLI version number."
reverseFlag = "[defaulted] Reverse the order of output list."
reverseFlag = "[optional] Reverse the order of output list."
fingerprintFlag = "[conditional] The SHA256 fingerprint of the artifact. Only required if you don't specify '--artifact-type'."
intervalFlag = "[optional] Expression to define specified snapshots range."
showUnchangedArtifactsFlag = "[defaulted] Show the unchanged artifacts present in both snapshots within the diff output."
Expand Down
Loading