-
Notifications
You must be signed in to change notification settings - Fork 225
OCM-1520 | feat: Add --hide-empty-columns flag to rosa list commands #2983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: olucasfreitas The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2983 +/- ##
==========================================
- Coverage 27.37% 27.18% -0.19%
==========================================
Files 306 308 +2
Lines 34350 34710 +360
==========================================
+ Hits 9403 9437 +34
- Misses 24301 24615 +314
- Partials 646 658 +12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks much better than the original write, left some comments- will wait for you to make changes before doing review on the pkg/output
files introduced since they may change
dd91dc0
to
cbf08f0
Compare
@hunterkepley addressed all the comments in the new commit |
ef825a0
to
eb6702d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more comments, looking good 🙂 Noticed a couple of improvements which could be made to lessen the LoC committed for this effort, as well as a couple Go things that would be useful
cmd/list/accessrequests/cmd.go
Outdated
if err := writer.Flush(); err != nil { | ||
return err | ||
} | ||
|
||
_, hasPending, pendingId := getAccessRequestsOutput(clusterId, accessRequests) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why wouldn't we use the output like the original file did here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're no longer using the output string from getAccessRequestsOutput because we've refactored the code to use the dynamic headers approach with output.BuildTable()
eb6702d
to
2f270f0
Compare
2f270f0
to
bdf62a6
Compare
@hunterkepley new comments addressed on the new commit |
@olucasfreitas: all tests passed! Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some suggestions on the implementation of BuildTable
as well as the edge case
@@ -126,7 +125,6 @@ var _ = Describe("rosa attach policy", func() { | |||
Expect(err).NotTo(HaveOccurred()) | |||
|
|||
stdOut, _ := t.StdOutReader.Read() | |||
fmt.Println(stdOut) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unnecessary change
func checkForPendingRequests(clusterId string, accessRequests []*v1.AccessRequest) (bool, string) { | ||
hasPending := false | ||
id := "<ID>" | ||
for _, accessRequest := range accessRequests { | ||
if accessRequest.Status().State() == v1.AccessRequestStatePending { | ||
if accessRequest.Status().State() == v1.AccessRequestStatePending || | ||
accessRequest.Status().State() == v1.AccessRequestStateApproved { | ||
hasPending = true | ||
if clusterId != "" { | ||
id = accessRequest.ID() | ||
} | ||
// Once we find the first pending/approved request for the cluster, we can break | ||
// since we only need one ID for the suggestion message | ||
if clusterId != "" && hasPending { | ||
break | ||
} | ||
} | ||
output += fmt.Sprintf("%s\t%s\t%s\t%s\n", | ||
accessRequest.Status().State(), | ||
accessRequest.ID(), | ||
accessRequest.ClusterId(), | ||
accessRequest.UpdatedAt().Format(time.UnixDate)) | ||
} | ||
|
||
return output, hasPending, id | ||
return hasPending, id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This command has been altered pretty heavily in terms of how it gathers data and im worried it will have different a different table for certain clusters after these changes. Could you provide some output from it to show that it works the same?
writer, | ||
"%s\t%s\t%s\t%s\t%s\n", | ||
row := []string{ | ||
accountRole.RoleName, | ||
accountRole.RoleType, | ||
accountRole.RoleARN, | ||
accountRole.Version, | ||
awsManaged, | ||
) | ||
} | ||
tableData = append(tableData, row) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be simplified:
tableData = append(tableData, []string{
accountRole.RoleName,
...
...
})
if err := writer.Flush(); err != nil { | ||
_ = r.Reporter.Errorf("Failed to flush output: %v", err) | ||
os.Exit(1) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file looks great
// removeEmptyColumnsExceptSpecial removes empty columns except those marked as special | ||
// (i.e., columns that are controlled by explicit flags and should be shown even if empty) | ||
func removeEmptyColumnsExceptSpecial(headers []string, tableData [][]string, specialColumns map[int]bool) ([]string, [][]string) { | ||
var newHeaders []string | ||
var columnsToKeep []int | ||
|
||
for i, header := range headers { | ||
// Keep special columns regardless of whether they're empty | ||
if specialColumns[i] { | ||
newHeaders = append(newHeaders, header) | ||
columnsToKeep = append(columnsToKeep, i) | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to come up with a solution which can take in special cases, rather than this.
Also the name of this function is not clear
func BuildTable(writer *tabwriter.Writer, separator string, tableData [][]string) { | ||
for _, row := range tableData { | ||
if len(row) == 0 { | ||
continue | ||
} | ||
|
||
// Build format string dynamically based on number of columns | ||
formatString := buildFormatString(len(row), separator) | ||
|
||
// Convert []string to []interface{} for fmt.Fprintf | ||
args := make([]any, len(row)) | ||
for i, v := range row { | ||
args[i] = v | ||
} | ||
|
||
fmt.Fprintf(writer, formatString, args...) | ||
} | ||
} | ||
|
||
// buildFormatString creates a format string with the appropriate number of %s placeholders | ||
func buildFormatString(columnCount int, separator string) string { | ||
if columnCount == 0 { | ||
return "\n" | ||
} | ||
|
||
format := "" | ||
for i := range columnCount { | ||
format += "%s" | ||
if i < columnCount-1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could simplify this somewhat.
finalString := ""
for i, row := range c {
finalString += strings.Join(row, "\t")
if i < len(c) {
finalString+="\n"
}
}
This accomplishes joining rows using a separator \t
Now, if we want to use a custom separator (such as col1\t\tcol2\t\tcol3\tcol4\tcol5\n
which has \t\t
and \t
) to avoid making an edge case function like you have, we can modify this slightly
separators := ["\t\t", "\t\t", "\t", "\t"] // Pass in rather than `separator` string
// To make it simple, you can edit this slice in `RemoveEmptyColumns` like you do with the tableData
// Combine rows with separator simply, using only a single nested for loop
for i, row := range c {
for j, col := range row {
finalStr += col + separators[j]
}
if i < len(c) {
finalStr += "\n"
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to make sure the separators list is the same length as each row. Probably could also add an if statement in the loop to break if it is >= the length of the separator list
for _, row := range tableData { | ||
var newRow []string | ||
for _, colIdx := range columnsToKeep { | ||
if colIdx < len(row) { | ||
newRow = append(newRow, row[colIdx]) | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
colIdx
-> col
(lets keep naming consistent..)
if colIdx < len(row) { | ||
newRow = append(newRow, row[colIdx]) | ||
} else { | ||
newRow = append(newRow, "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't do anything
Here's a Go Playground showing the solution I came up with for a list of separators: https://go.dev/play/p/2qUevkuSUUz |
Details
This PR improves the UX when listing resources by introducing a new
--hide-empty-columns
flag that automatically hides columns containing no data across all rows, making the output cleaner and more readable.The flag has been added to the following
rosa list
commands:Note: The following commands do NOT have this flag:
list machinepools
- Already has built-in auto-hide empty columns logiclist version
,list userroles
,list user
,list rhRegion
,list tuningconfigs
,list oidcprovider
,list kubeletconfig
,list externalauthprovider
- These maintain their original behaviorDefault Behavior (All Columns Shown)
Run any supported list command without the flag:
You should see all columns displayed, including empty ones:
Using --hide-empty-columns Flag
Run the same command with the flag:
Empty columns (like TOPOLOGY in this example) should be automatically hidden:
New behavior of the '--all'
The
--all
flag shows the 3 additional columns (AZ TYPE, WIN-LI ENABLED, DEDICATED HOST) but still hides empty columns:Example output:
Ticket
Closes [OCM-1520]