Skip to content

feat: Add --limit and --force flags for shell scripting composability #17

@rianjs

Description

@rianjs

Summary

Add --limit and --force flags to improve shell scripting composability. These were originally planned for PR #14 but deferred due to codebase restructuring in PR #10.

Background

PR #14 added exit codes for shell scripting. The --limit and --force flags were part of the original scope but required modifying 8+ files in the new internal/cmd/ structure. To keep PR #14 focused, these were deferred.

What

--limit/-l Flag

Add a --limit flag to all list commands to cap the number of results returned. This enables efficient shell pipelines without fetching all data.

# Get first 5 apps
newrelic-cli apps list --limit 5

# Get first app ID
newrelic-cli apps list --limit 1 -o plain | cut -f1

--force/-f Flag

Add a --force flag to destructive commands (delete operations) to skip confirmation prompts. This enables non-interactive automation.

# Delete without confirmation (for scripts)
newrelic-cli dashboards delete 12345 --force

# Safe interactive mode (default)
newrelic-cli dashboards delete 12345
# Are you sure? [y/N]

Where

Files needing --limit flag:

  • internal/cmd/apps/list.go
  • internal/cmd/alerts/list.go
  • internal/cmd/users/users.go (list subcommand)
  • internal/cmd/dashboards/dashboards.go (list subcommand)
  • internal/cmd/synthetics/synthetics.go (list subcommand)
  • internal/cmd/logs/logs.go (query subcommand - if applicable)

Files needing --force flag:

  • internal/cmd/dashboards/dashboards.go (delete subcommand)
  • internal/cmd/deployments/deployments.go (delete subcommand)
  • internal/cmd/synthetics/synthetics.go (delete subcommand)

Implementation Pattern

--limit flag

var limit int

func newListCmd(opts *root.Options) *cobra.Command {
    cmd := &cobra.Command{
        Use:   "list",
        Short: "List resources",
        RunE: func(cmd *cobra.Command, args []string) error {
            return runList(opts, limit)
        },
    }
    cmd.Flags().IntVarP(&limit, "limit", "l", 0, "Limit number of results (0 = no limit)")
    return cmd
}

func runList(opts *root.Options, limit int) error {
    // ... fetch items ...
    if limit > 0 && len(items) > limit {
        items = items[:limit]
    }
    // ... render items ...
}

--force flag

var force bool

func newDeleteCmd(opts *root.Options) *cobra.Command {
    cmd := &cobra.Command{
        Use:   "delete <id>",
        Short: "Delete a resource",
        RunE: func(cmd *cobra.Command, args []string) error {
            return runDelete(opts, args[0], force)
        },
    }
    cmd.Flags().BoolVarP(&force, "force", "f", false, "Skip confirmation prompt")
    return cmd
}

func runDelete(opts *root.Options, id string, force bool) error {
    if !force {
        fmt.Fprintf(opts.Stderr, "Delete resource %s? [y/N]: ", id)
        // read confirmation or return error
    }
    // ... perform delete ...
}

Acceptance Criteria

  • --limit flag works on all list commands
  • --force flag works on all delete commands
  • Flags are documented in --help output
  • Unit tests cover limit truncation logic
  • Unit tests cover force flag behavior

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions