@@ -26,6 +26,8 @@ type CreateOptions struct {
2626
2727 RepoOverride string
2828 WebMode bool
29+ JSONFill bool
30+ JSONInput string
2931
3032 Title string
3133 Body string
@@ -62,13 +64,22 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
6264 titleProvided := cmd .Flags ().Changed ("title" )
6365 bodyProvided := cmd .Flags ().Changed ("body" )
6466 opts .RepoOverride , _ = cmd .Flags ().GetString ("repo" )
67+ opts .JSONFill = cmd .Flags ().Changed ("json" )
6568
6669 opts .Interactive = ! (titleProvided && bodyProvided )
6770
6871 if opts .Interactive && ! opts .IO .CanPrompt () {
6972 return & cmdutil.FlagError {Err : errors .New ("must provide --title and --body when not running interactively" )}
7073 }
7174
75+ if opts .JSONFill {
76+ opts .Interactive = false
77+
78+ if opts .WebMode {
79+ return errors .New ("--web and --json are mutually exclusive" )
80+ }
81+ }
82+
7283 if runF != nil {
7384 return runF (opts )
7485 }
@@ -83,20 +94,21 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
8394 cmd .Flags ().StringSliceVarP (& opts .Labels , "label" , "l" , nil , "Add labels by `name`" )
8495 cmd .Flags ().StringSliceVarP (& opts .Projects , "project" , "p" , nil , "Add the issue to projects by `name`" )
8596 cmd .Flags ().StringVarP (& opts .Milestone , "milestone" , "m" , "" , "Add the issue to a milestone by `name`" )
97+ cmd .Flags ().StringVarP (& opts .JSONInput , "json" , "j" , "" , "Use JSON to populate and submit issue" )
8698
8799 return cmd
88100}
89101
90- func createRun (opts * CreateOptions ) error {
102+ func createRun (opts * CreateOptions ) ( err error ) {
91103 httpClient , err := opts .HttpClient ()
92104 if err != nil {
93- return err
105+ return
94106 }
95107 apiClient := api .NewClientFromHTTP (httpClient )
96108
97109 baseRepo , err := opts .BaseRepo ()
98110 if err != nil {
99- return err
111+ return
100112 }
101113
102114 templateFiles , legacyTemplate := prShared .FindTemplates (opts .RootDirOverride , "ISSUE_TEMPLATE" )
@@ -123,7 +135,7 @@ func createRun(opts *CreateOptions) error {
123135 if opts .Title != "" || opts .Body != "" {
124136 openURL , err = prShared .WithPrAndIssueQueryParams (openURL , tb )
125137 if err != nil {
126- return err
138+ return
127139 }
128140 } else if len (templateFiles ) > 1 {
129141 openURL += "/choose"
@@ -140,24 +152,28 @@ func createRun(opts *CreateOptions) error {
140152
141153 repo , err := api .GitHubRepo (apiClient , baseRepo )
142154 if err != nil {
143- return err
155+ return
144156 }
145157 if ! repo .HasIssuesEnabled {
146- return fmt .Errorf ("the '%s' repository has disabled issues" , ghrepo .FullName (baseRepo ))
158+ err = fmt .Errorf ("the '%s' repository has disabled issues" , ghrepo .FullName (baseRepo ))
159+ return
147160 }
148161
149162 action := prShared .SubmitAction
150163
151164 if opts .Interactive {
152- editorCommand , err := cmdutil .DetermineEditor (opts .Config )
165+ var editorCommand string
166+ editorCommand , err = cmdutil .DetermineEditor (opts .Config )
153167 if err != nil {
154- return err
168+ return
155169 }
156170
171+ defer prShared .PreserveInput (opts .IO , & tb , & err )()
172+
157173 if tb .Title == "" {
158174 err = prShared .TitleSurvey (& tb )
159175 if err != nil {
160- return err
176+ return
161177 }
162178 }
163179
@@ -166,52 +182,61 @@ func createRun(opts *CreateOptions) error {
166182
167183 templateContent , err = prShared .TemplateSurvey (templateFiles , legacyTemplate , tb )
168184 if err != nil {
169- return err
185+ return
170186 }
171187
172188 err = prShared .BodySurvey (& tb , templateContent , editorCommand )
173189 if err != nil {
174- return err
190+ return
175191 }
176192
177193 if tb .Body == "" {
178194 tb .Body = templateContent
179195 }
180196 }
181197
182- action , err := prShared .ConfirmSubmission (! tb .HasMetadata (), repo .ViewerCanTriage ())
198+ var action prShared.Action
199+ action , err = prShared .ConfirmSubmission (! tb .HasMetadata (), repo .ViewerCanTriage ())
183200 if err != nil {
184- return fmt .Errorf ("unable to confirm: %w" , err )
201+ err = fmt .Errorf ("unable to confirm: %w" , err )
202+ return
185203 }
186204
187205 if action == prShared .MetadataAction {
188206 err = prShared .MetadataSurvey (opts .IO , apiClient , baseRepo , & tb )
189207 if err != nil {
190- return err
208+ return
191209 }
192210
193211 action , err = prShared .ConfirmSubmission (! tb .HasMetadata (), false )
194212 if err != nil {
195- return err
213+ return
196214 }
197215 }
198216
199217 if action == prShared .CancelAction {
200218 fmt .Fprintln (opts .IO .ErrOut , "Discarding." )
201-
202- return nil
219+ return
220+ }
221+ } else if opts .JSONFill {
222+ err = prShared .FillFromJSON (opts .IO , opts .JSONInput , & tb )
223+ if err != nil {
224+ return
203225 }
226+
227+ action = prShared .SubmitAction
204228 } else {
205229 if tb .Title == "" {
206- return fmt .Errorf ("title can't be blank" )
230+ err = fmt .Errorf ("title can't be blank" )
231+ return
207232 }
208233 }
209234
210235 if action == prShared .PreviewAction {
211236 openURL := ghrepo .GenerateRepoURL (baseRepo , "issues/new" )
212237 openURL , err = prShared .WithPrAndIssueQueryParams (openURL , tb )
213238 if err != nil {
214- return err
239+ return
215240 }
216241 if isTerminal {
217242 fmt .Fprintf (opts .IO .ErrOut , "Opening %s in your browser.\n " , utils .DisplayURL (openURL ))
@@ -225,18 +250,19 @@ func createRun(opts *CreateOptions) error {
225250
226251 err = prShared .AddMetadataToIssueParams (apiClient , baseRepo , params , & tb )
227252 if err != nil {
228- return err
253+ return
229254 }
230255
231- newIssue , err := api .IssueCreate (apiClient , repo , params )
256+ var newIssue * api.Issue
257+ newIssue , err = api .IssueCreate (apiClient , repo , params )
232258 if err != nil {
233- return err
259+ return
234260 }
235261
236262 fmt .Fprintln (opts .IO .Out , newIssue .URL )
237263 } else {
238264 panic ("Unreachable state" )
239265 }
240266
241- return nil
267+ return
242268}
0 commit comments