Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e29de33
format utils
parametalol Feb 21, 2025
03a4e64
Remove default boolean patch
parametalol Feb 21, 2025
cb6d328
format command groups
parametalol Feb 21, 2025
8f08601
rewritten bats tests
parametalol Feb 22, 2025
f559ddf
ignore trailing whitespaces in roxctl output
parametalol Feb 22, 2025
29b741d
fixed some bats tests
parametalol Feb 22, 2025
90e9d90
ignore main command help captialization check
parametalol Feb 22, 2025
98b61a9
comment about kubectl
parametalol Feb 24, 2025
0af78eb
fix bats tests
parametalol Feb 24, 2025
05dfded
new commands tree
parametalol Feb 24, 2025
00adcbc
refactoring
parametalol Feb 24, 2025
fe04dfc
fixes
parametalol Feb 24, 2025
ec47cdf
test formatting of flags from a flagset
parametalol Feb 24, 2025
eca12e6
fix tabs
parametalol Feb 24, 2025
3f6cc05
formatting_writer refactoring
parametalol Feb 24, 2025
1c07ace
reset command_tree_debug.yaml
parametalol Feb 24, 2025
b17ddfa
fix bats tests
parametalol Feb 24, 2025
5c55879
format deprecated commands
parametalol Feb 25, 2025
521c3c1
comments, minor refactorings
parametalol Feb 26, 2025
28ac1ee
CHANGELOG.md
parametalol Feb 27, 2025
5706678
get terminal width
parametalol Feb 27, 2025
ab3dcbd
wordsAndDelimeters bufio.SplitFunc
parametalol Feb 27, 2025
84f41cc
revert bats' helpers.bash
parametalol Feb 27, 2025
3164dcd
make tabWidth formattingWriter property
parametalol Mar 4, 2025
d603513
renamed pop -> popNotLast
parametalol Mar 5, 2025
4e49f50
fix double ln
parametalol Mar 5, 2025
336d0ec
don't pad before ln
parametalol Mar 5, 2025
5364e28
refactoring
parametalol Mar 5, 2025
5558939
test write errors
parametalol Mar 5, 2025
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
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Please avoid adding duplicate information across this changelog and JIRA/doc inp
## [NEXT RELEASE]

### Added Features

- ROX-13493: Support for scale subresource in the admission controller to enable policy detection and enforcement on admission review requests on the scale subresource.

### Removed Features
Expand All @@ -18,9 +19,9 @@ Please avoid adding duplicate information across this changelog and JIRA/doc inp

### Technical Changes

## [4.7.0]

- ROX-28263: New `roxctl` help formatting.

## [4.7.0]

### Added Features

Expand Down
3 changes: 1 addition & 2 deletions roxctl/central/db/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import (
)

const (
warningDeprecatedDbBackup = `WARNING: The backup command has been deprecated. Please use "roxctl central backup"
to create central backup with database, keys and certificates.`
warningDeprecatedDbBackup = `Please use "roxctl central backup" to create central backup with database, keys and certificates.`
)

// Command defines the db backup command. This command is deprecated and can be removed on or after 3.0.57.
Expand Down
2 changes: 1 addition & 1 deletion roxctl/central/db/restore/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@

c.Flags().StringVar(&centralDbRestoreCmd.file, "file", "", "File to restore the DB from (deprecated; use positional argument)")
c.Flags().BoolVar(&centralDbRestoreCmd.interrupt, "interrupt", false, "Interrupt ongoing restore process (if any) to allow resuming")
utils.Must(c.Flags().MarkDeprecated("file", "--file is deprecated; use the positional argument instead"))
utils.Must(c.Flags().MarkDeprecated("file", "use the positional argument instead"))

Check warning on line 72 in roxctl/central/db/restore/v2.go

View check run for this annotation

Codecov / codecov/patch

roxctl/central/db/restore/v2.go#L72

Added line #L72 was not covered by tests
flags.AddForce(c)

return c
Expand Down
14 changes: 2 additions & 12 deletions roxctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"github.com/stackrox/rox/pkg/sync"
"github.com/stackrox/rox/roxctl/common"
"github.com/stackrox/rox/roxctl/maincommand"
"github.com/stackrox/rox/roxctl/utils"

// Make sure devbuild setting is registered.
_ "github.com/stackrox/rox/pkg/devbuild"
Expand All @@ -17,18 +18,7 @@
func main() {
c := maincommand.Command()

// This is a workaround. Cobra/pflag takes care of presenting flag usage information
// to the user including the respective flag default values.
//
// But, as an exception, showing the default value for a flag is skipped in pflag if
// that value is the zero value for a certain standard type.
//
// In our case this caused the unintended behaviour of not showing the default values
// for our boolean flags which default to `false`.
//
// Until we have a better solution (e.g. way to control this behaviour in upstream pflag)
// we simply add the usage information "(default false)" to our affected boolean flags.
AddMissingDefaultsToFlagUsage(c)
c.SetHelpFunc(utils.FormatHelp)

Check warning on line 21 in roxctl/main.go

View check run for this annotation

Codecov / codecov/patch

roxctl/main.go#L21

Added line #L21 was not covered by tests

once := sync.Once{}
// Peak only the deepest command path. The hooks are added to all commands.
Expand Down
1 change: 0 additions & 1 deletion roxctl/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ func mockRunE(_ *cobra.Command, _ []string) error { return nil }

func TestCommandReconstruction(t *testing.T) {
root := maincommand.Command()
AddMissingDefaultsToFlagUsage(root)

type testCase struct {
args []string
Expand Down
2 changes: 2 additions & 0 deletions roxctl/maincommand/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func versionCommand(cliEnvironment environment.Environment) *cobra.Command {
// Command constructs and returns the roxctl command tree
func Command() *cobra.Command {
c := &cobra.Command{
Long: "roxctl is a command-line interface (CLI) for running commands" +
" on Red Hat Advanced Cluster Security for Kubernetes (RHACS)",
SilenceUsage: true,
Use: os.Args[0],
}
Expand Down
2 changes: 1 addition & 1 deletion roxctl/maincommand/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func checkUsageFirstCharacter(t *testing.T, command *cobra.Command) {
if !isCapitalized(command.Short) {
t.Errorf("%q, short usage: %q", getCommandPath(command), command.Short)
}
if !isCapitalized(command.Long) {
if !isCapitalized(command.Long) && !strings.HasPrefix(command.Long, "roxctl ") {
t.Errorf("%q, long usage: %q", getCommandPath(command), command.Long)
}
for _, subcommand := range command.Commands() {
Expand Down
30 changes: 0 additions & 30 deletions roxctl/patch_flag_usage.go

This file was deleted.

116 changes: 116 additions & 0 deletions roxctl/utils/formatting_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package utils

import (
"bufio"
"io"
"strings"
)

const defaultTabWidth = 8

// formattingWriter implements StringWriter interface.
// It writes strings to the underlying writer indenting and wrapping the text.
type formattingWriter struct {
raw io.StringWriter
width int
indent indents
tabWidth int

currentLine int
written int
indentReset bool
}

var _ io.StringWriter = (*formattingWriter)(nil)

func makeFormattingWriter(w io.StringWriter, width int, tabWidth int, indent ...int) *formattingWriter {
return &formattingWriter{raw: w, width: width, indent: indent, tabWidth: tabWidth}
}

// write is an internal method that writes the string to the underlying writer.
func (w *formattingWriter) write(s string) error {
n, err := w.raw.WriteString(s)
w.currentLine += n
w.written += n
return err //nolint:wrapcheck
}

// writePadding is an internal method, that takes the next indent value and the
// writes the according number of spaces. If the indent value is negative, it is
// calculated as tabulation offset, i.e. the spaces are added to reach the
// required offset. Returns true if a new line has been written.
func (w *formattingWriter) writePadding() (bool, error) {
w.indentReset = false
padding := w.indent.popNotLast()
if padding < 0 {
// Indent to tabulation.
padding = -padding
if padding > w.currentLine {
padding -= w.currentLine
} else {
return true, nil
}
} else if w.currentLine+padding > w.width {
return true, nil
}
return false, w.write(strings.Repeat(" ", padding))
}

// ln is an internal method that writes a new line to the underlying writer.
func (w *formattingWriter) ln() error {
_, err := w.raw.WriteString("\n")
w.currentLine = 0
return err //nolint:wrapcheck
}

// SetIndent updates the indentation for the following writings.
func (w *formattingWriter) SetIndent(indent ...int) {
w.indentReset = true
w.indent = indent
}

// WriteString writes the string to the underlying writer, with the configured
// indentation and wrapping.
// Implements the StringWriter interface.
func (w *formattingWriter) WriteString(s string) (int, error) {
w.written = 0
tokenScanner := bufio.NewScanner(strings.NewReader(s))
tokenScanner.Split(wordsAndDelimeters)
var err error
for err == nil && tokenScanner.Scan() {
token := tokenScanner.Text()
length := len(token)
switch token {
case "\t":
length = defaultTabWidth
case "\n":
if w.currentLine == 0 {
w.indent.popNotLast()
w.indentReset = false
}
err = w.ln()
continue
}
ln := false
if w.currentLine == 0 || w.indentReset {
if ln, err = w.writePadding(); err != nil {
break
}
}
// Write a new line and a padding in case of line overflow:
if ln || w.currentLine+length > w.width {
if err = w.ln(); err != nil {
break
}
if token == " " {
// Do not write space token that caused line break.
continue
}
if _, err = w.writePadding(); err != nil {
break
}
}
err = w.write(token)
}
return w.written, err
}
Loading
Loading