-
Notifications
You must be signed in to change notification settings - Fork 0
feat(output): improve readability with better formatting #6
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
Changes from all commits
d9b0f4a
1162f38
f406421
2fe2ec5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| # Binaries for programs and plugins | ||
| *.exe | ||
| *.exe~ | ||
| *.dll | ||
| *.so | ||
| *.dylib | ||
|
|
||
| # Test binary, built with `go test -c` | ||
| *.test | ||
|
|
||
| # Output of the go coverage tool, specifically when used with LiteIDE | ||
| *.out | ||
|
|
||
| # Dependency directories (remove the comment below to include it) | ||
| # vendor/ | ||
|
|
||
| # Go workspace file | ||
| go.work | ||
|
|
||
| # Build output | ||
| /bin/ | ||
| /dist/ | ||
| /build/ | ||
|
|
||
| # IDE files | ||
| .vscode/ | ||
| .idea/ | ||
| *.swp | ||
| *.swo | ||
| *~ | ||
|
|
||
| # OS generated files | ||
| .DS_Store | ||
| .DS_Store? | ||
| ._* | ||
| .Spotlight-V100 | ||
| .Trashes | ||
| ehthumbs.db | ||
| Thumbs.db | ||
|
|
||
| # Environment variables | ||
| .env | ||
| .env.local | ||
| .env.*.local | ||
|
|
||
| # Logs | ||
| *.log | ||
| logs/ | ||
|
|
||
| # Temporary files | ||
| *.tmp | ||
| *.temp | ||
| /tmp/ | ||
|
|
||
| # Node.js (if any frontend components) | ||
| node_modules/ | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| package-lock.json | ||
|
|
||
| # Coverage reports | ||
| coverage.txt | ||
| coverage.html | ||
| coverage.out | ||
|
|
||
| # Profiling data | ||
| *.prof | ||
|
|
||
| # Air live reload | ||
| .air.toml | ||
| tmp/ | ||
|
|
||
| # Test cache | ||
| .cache/ | ||
|
|
||
| # Local configuration files | ||
| config.local.* | ||
| *.local.yaml | ||
| *.local.yml | ||
| *.local.json | ||
|
|
||
| # Generated documentation | ||
| docs/build/ | ||
|
|
||
| # Binary name (project specific) | ||
| epgstationctl | ||
|
|
||
| # Development and testing files | ||
| .test/ | ||
| test-results/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package reserves | |
| import ( | ||
| "fmt" | ||
| "strconv" | ||
| "strings" | ||
|
|
||
| "github.com/miscord-dev/epgstationctl/internal/client" | ||
| "github.com/miscord-dev/epgstationctl/internal/commands/root" | ||
|
|
@@ -20,6 +21,9 @@ var ( | |
| // List flags | ||
| reserveType string | ||
| ruleId int | ||
| verbose bool | ||
| full bool | ||
| columns string | ||
|
|
||
| // Create/Update flags | ||
| programId int64 | ||
|
|
@@ -45,7 +49,17 @@ var reservesCmd = &cobra.Command{ | |
| var listCmd = &cobra.Command{ | ||
| Use: "list", | ||
| Short: "List reservations", | ||
| Long: "List all reservations with optional filtering", | ||
| Long: `List all reservations with optional filtering. | ||
|
|
||
| Column Display Options: | ||
| Default: Shows essential columns (Id, Name, StartAt, EndAt, ChannelId, IsConflict, IsSkip, IsOverlap) | ||
| --verbose: Shows additional columns (includes RuleId, ProgramId, Description) | ||
| --full: Shows all available columns | ||
| --columns: Custom column selection (e.g., --columns=Id,Name,StartAt,ChannelId) | ||
|
|
||
| Available columns: Id, Name, StartAt, EndAt, ChannelId, RuleId, ProgramId, IsConflict, | ||
| IsSkip, IsOverlap, Description, AllowEndLack, EncodeMode1, EncodeMode2, EncodeMode3, | ||
| Directory, ParentDirectoryName, Tags, and more.`, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| cfg := root.GetConfig() | ||
| client, err := client.NewEPGStationClient(cfg) | ||
|
|
@@ -84,7 +98,28 @@ var listCmd = &cobra.Command{ | |
| case "json": | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚫 [golangci] reported by reviewdog 🐶 |
||
| formatter = output.NewJSONFormatter(nil) | ||
| default: | ||
| formatter = output.NewTableFormatter(nil, cfg.Output.NoHeader) | ||
| // Define column sets | ||
| defaultColumns := []string{"Id", "Name", "StartAt", "EndAt", "ChannelId", "IsConflict", "IsSkip", "IsOverlap"} | ||
| verboseColumns := []string{"Id", "Name", "StartAt", "EndAt", "ChannelId", "RuleId", "ProgramId", "IsConflict", "IsSkip", "IsOverlap", "Description"} | ||
|
|
||
| var selectedColumns []string | ||
|
|
||
| if columns != "" { | ||
| // Custom columns specified | ||
| selectedColumns = strings.Split(strings.ReplaceAll(columns, " ", ""), ",") | ||
| } else if full { | ||
| // Full output - use default formatter (all columns) | ||
| formatter = output.NewTableFormatter(nil, cfg.Output.NoHeader) | ||
| return formatter.Format(reserves.Reserves) | ||
| } else if verbose { | ||
| // Verbose output | ||
| selectedColumns = verboseColumns | ||
| } else { | ||
| // Default minimal output | ||
| selectedColumns = defaultColumns | ||
| } | ||
|
|
||
| formatter = output.NewTableFormatterWithColumns(nil, cfg.Output.NoHeader, selectedColumns) | ||
| } | ||
|
|
||
| return formatter.Format(reserves.Reserves) | ||
|
|
@@ -373,10 +408,13 @@ var updateSystemCmd = &cobra.Command{ | |
| func init() { | ||
| // List command flags | ||
| listCmd.Flags().IntVar(&offset, "offset", 0, "Offset for pagination") | ||
| listCmd.Flags().IntVarP(&limit, "limit", "l", 24, "Number of reserves to retrieve") | ||
| listCmd.Flags().IntVarP(&limit, "limit", "l", 10, "Number of reserves to retrieve") | ||
| listCmd.Flags().BoolVar(&halfWidth, "half-width", true, "Use half-width characters") | ||
| listCmd.Flags().StringVar(&reserveType, "type", "", "Filter by reserve type (all, normal, conflict, skip, overlap)") | ||
| listCmd.Flags().IntVar(&ruleId, "rule-id", 0, "Filter by rule ID") | ||
| listCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show more columns (includes RuleId, ProgramId, Description)") | ||
| listCmd.Flags().BoolVar(&full, "full", false, "Show all available columns") | ||
| listCmd.Flags().StringVar(&columns, "columns", "", "Comma-separated list of columns to display (e.g., 'Id,Name,StartAt,EndAt')") | ||
|
|
||
| // Show command flags | ||
| showCmd.Flags().BoolVar(&halfWidth, "half-width", true, "Use half-width characters") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package rules | |
| import ( | ||
| "fmt" | ||
| "strconv" | ||
| "strings" | ||
|
|
||
| "github.com/miscord-dev/epgstationctl/internal/client" | ||
| "github.com/miscord-dev/epgstationctl/internal/commands/root" | ||
|
|
@@ -13,6 +14,8 @@ import ( | |
|
|
||
| const ( | ||
| outputFormatJSON = "json" | ||
| channelsAll = "All" | ||
| booleanFalse = "false" | ||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -271,14 +274,14 @@ func formatRulesAsTable(rules client.RulesWithID, formatter output.Formatter) er | |
| Channels string | ||
| } | ||
|
|
||
| var ruleList []RuleInfo | ||
| ruleList := make([]RuleInfo, 0, len(rules.Rules)) | ||
| for _, rule := range rules.Rules { | ||
| status := "Disabled" | ||
| status := "✗" | ||
| if rule.ReserveOption.Enable { | ||
| if rule.IsTimeSpecification { | ||
| status = "Time-based" | ||
| status = "⏰" | ||
| } else { | ||
| status = "Enabled" | ||
| status = "✓" | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -287,23 +290,20 @@ func formatRulesAsTable(rules client.RulesWithID, formatter output.Formatter) er | |
| keyword = *rule.SearchOption.Keyword | ||
| } | ||
|
|
||
| channels := "All" | ||
| var channelParts []string | ||
| if rule.SearchOption.GR != nil && *rule.SearchOption.GR { | ||
| channels = "GR" | ||
| channelParts = append(channelParts, "地上波") | ||
| } | ||
| if rule.SearchOption.BS != nil && *rule.SearchOption.BS { | ||
| if channels != "All" { | ||
| channels += ",BS" | ||
| } else { | ||
| channels = "BS" | ||
| } | ||
| channelParts = append(channelParts, "BS") | ||
| } | ||
| if rule.SearchOption.CS != nil && *rule.SearchOption.CS { | ||
| if channels != "All" { | ||
| channels += ",CS" | ||
| } else { | ||
| channels = "CS" | ||
| } | ||
| channelParts = append(channelParts, "CS") | ||
| } | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚫 [golangci] reported by reviewdog 🐶 |
||
| channels := channelsAll | ||
| if len(channelParts) > 0 { | ||
| channels = strings.Join(channelParts, ",") | ||
| } | ||
|
|
||
| ruleList = append(ruleList, RuleInfo{ | ||
|
|
@@ -358,19 +358,19 @@ func formatRuleDetailsAsTable(rule client.RuleWithID, formatter output.Formatter | |
| details = append(details, RuleDetail{"Channels", fmt.Sprintf("%v", channels)}) | ||
| } | ||
|
|
||
| searchName := "false" | ||
| searchName := booleanFalse | ||
| if rule.SearchOption.Name != nil { | ||
| searchName = fmt.Sprintf("%t", *rule.SearchOption.Name) | ||
| } | ||
| details = append(details, RuleDetail{"SearchName", searchName}) | ||
|
|
||
| searchDescription := "false" | ||
| searchDescription := booleanFalse | ||
| if rule.SearchOption.Description != nil { | ||
| searchDescription = fmt.Sprintf("%t", *rule.SearchOption.Description) | ||
| } | ||
| details = append(details, RuleDetail{"SearchDescription", searchDescription}) | ||
|
|
||
| searchExtended := "false" | ||
| searchExtended := booleanFalse | ||
| if rule.SearchOption.Extended != nil { | ||
| searchExtended = fmt.Sprintf("%t", *rule.SearchOption.Extended) | ||
| } | ||
|
|
||
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.
🚫 [golangci] reported by reviewdog 🐶
string
jsonhas 3 occurrences, make it a constant (goconst)