Skip to content

Commit af88f5a

Browse files
committed
feat: Support JSON Output Format
- Adds --json parameter to view and list commands - Output contains formatted camelCase custom field names - Limitation: without filtering, you may see customfield name conflict errors Co-authored by Claude AI
1 parent 4928d3b commit af88f5a

File tree

4 files changed

+920
-1
lines changed

4 files changed

+920
-1
lines changed

internal/cmd/issue/list/list.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/spf13/viper"
1010

1111
"github.com/ankitpokhrel/jira-cli/api"
12+
"github.com/ankitpokhrel/jira-cli/internal/cmdcommon"
1213
"github.com/ankitpokhrel/jira-cli/internal/cmdutil"
1314
"github.com/ankitpokhrel/jira-cli/internal/query"
1415
"github.com/ankitpokhrel/jira-cli/internal/view"
@@ -56,6 +57,9 @@ $ jira issue list --plain --delimeter "|"
5657
# List issues as raw JSON data
5758
$ jira issue list --raw
5859
60+
# List issues in JSON with human-readable custom field names
61+
$ jira issue list --json
62+
5963
# List issues of type "Epic" in status "Done"
6064
$ jira issue list -tEpic -sDone
6165
@@ -133,9 +137,17 @@ func loadList(cmd *cobra.Command, args []string) {
133137
return
134138
}
135139

140+
jsonOutput, err := cmd.Flags().GetBool("json")
141+
cmdutil.ExitIfError(err)
142+
136143
raw, err := cmd.Flags().GetBool("raw")
137144
cmdutil.ExitIfError(err)
138145

146+
if jsonOutput {
147+
outputJSON(issues)
148+
return
149+
}
150+
139151
if raw {
140152
outputRawJSON(issues)
141153
return
@@ -208,6 +220,31 @@ func outputRawJSON(issues []*jira.Issue) {
208220
fmt.Println(string(data))
209221
}
210222

223+
func outputJSON(issues []*jira.Issue) {
224+
// Marshal issues to JSON first
225+
rawJSON, err := json.Marshal(issues)
226+
if err != nil {
227+
cmdutil.Failed("Failed to marshal issues: %s", err)
228+
return
229+
}
230+
231+
// Get field mappings
232+
fieldMappings, err := cmdcommon.GetConfiguredCustomFields()
233+
if err != nil {
234+
cmdutil.Warn("Unable to load custom field mappings: %s", err)
235+
fieldMappings = []jira.IssueTypeField{}
236+
}
237+
238+
// Convert custom field IDs to readable names
239+
jsonOutput, err := jira.TransformIssueFields(rawJSON, fieldMappings)
240+
if err != nil {
241+
cmdutil.Failed("Failed to format JSON output: %s", err)
242+
return
243+
}
244+
245+
fmt.Println(string(jsonOutput))
246+
}
247+
211248
// SetFlags sets flags supported by a list command.
212249
func SetFlags(cmd *cobra.Command) {
213250
cmd.Flags().SortFlags = false
@@ -245,6 +282,7 @@ func SetFlags(cmd *cobra.Command) {
245282
cmd.Flags().String("delimiter", "\t", "Custom delimeter for columns in plain mode. Works only with --plain")
246283
cmd.Flags().Uint("comments", 1, "Show N comments when viewing the issue")
247284
cmd.Flags().Bool("raw", false, "Print raw JSON output")
285+
cmd.Flags().Bool("json", false, "Print JSON output with human-readable custom field names")
248286
cmd.Flags().Bool("csv", false, "Print output in CSV format")
249287

250288
if cmd.HasParent() && cmd.Parent().Name() != "sprint" {

internal/cmd/issue/view/view.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/spf13/viper"
88

99
"github.com/ankitpokhrel/jira-cli/api"
10+
"github.com/ankitpokhrel/jira-cli/internal/cmdcommon"
1011
"github.com/ankitpokhrel/jira-cli/internal/cmdutil"
1112
tuiView "github.com/ankitpokhrel/jira-cli/internal/view"
1213
"github.com/ankitpokhrel/jira-cli/pkg/jira"
@@ -21,9 +22,13 @@ const (
2122
$ jira issue view ISSUE-1 --comments 5
2223
2324
# Get the raw JSON data
24-
$ jira issue view ISSUE-1 --raw`
25+
$ jira issue view ISSUE-1 --raw
26+
27+
# Get JSON output with human-readable custom field names
28+
$ jira issue view ISSUE-1 --json`
2529

2630
flagRaw = "raw"
31+
flagJSON = "json"
2732
flagDebug = "debug"
2833
flagComments = "comments"
2934
flagPlain = "plain"
@@ -52,14 +57,22 @@ func NewCmdView() *cobra.Command {
5257
cmd.Flags().Uint(flagComments, 1, "Show N comments")
5358
cmd.Flags().Bool(flagPlain, false, "Display output in plain mode")
5459
cmd.Flags().Bool(flagRaw, false, "Print raw Jira API response")
60+
cmd.Flags().Bool(flagJSON, false, "Print JSON output with human-readable custom field names")
5561

5662
return &cmd
5763
}
5864

5965
func view(cmd *cobra.Command, args []string) {
66+
jsonOutput, err := cmd.Flags().GetBool(flagJSON)
67+
cmdutil.ExitIfError(err)
68+
6069
raw, err := cmd.Flags().GetBool(flagRaw)
6170
cmdutil.ExitIfError(err)
6271

72+
if jsonOutput {
73+
viewJSON(cmd, args)
74+
return
75+
}
6376
if raw {
6477
viewRaw(cmd, args)
6578
return
@@ -85,6 +98,39 @@ func viewRaw(cmd *cobra.Command, args []string) {
8598
fmt.Println(apiResp)
8699
}
87100

101+
func viewJSON(cmd *cobra.Command, args []string) {
102+
debug, err := cmd.Flags().GetBool(flagDebug)
103+
cmdutil.ExitIfError(err)
104+
105+
key := cmdutil.GetJiraIssueKey(viper.GetString(configProject), args[0])
106+
107+
// Get raw JSON
108+
apiResp, err := func() (string, error) {
109+
s := cmdutil.Info(messageFetchingData)
110+
defer s.Stop()
111+
112+
client := api.DefaultClient(debug)
113+
return api.ProxyGetIssueRaw(client, key)
114+
}()
115+
cmdutil.ExitIfError(err)
116+
117+
// Get custom field mappings from config
118+
fieldMappings, err := cmdcommon.GetConfiguredCustomFields()
119+
if err != nil {
120+
cmdutil.Warn("Unable to load custom field mappings: %s", err)
121+
fieldMappings = []jira.IssueTypeField{}
122+
}
123+
124+
// Convert custom field IDs to readable names
125+
jsonOutput, err := jira.TransformIssueFields([]byte(apiResp), fieldMappings)
126+
if err != nil {
127+
cmdutil.Failed("Failed to format JSON output: %s", err)
128+
return
129+
}
130+
131+
fmt.Println(string(jsonOutput))
132+
}
133+
88134
func viewPretty(cmd *cobra.Command, args []string) {
89135
debug, err := cmd.Flags().GetBool(flagDebug)
90136
cmdutil.ExitIfError(err)

pkg/jira/transform.go

Lines changed: 105 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)