Skip to content

Commit a780d55

Browse files
author
Ismar Iljazovic
committed
feat: add global non-interactive mode support (from PR ankitpokhrel#905)
Cherry-picked from idleyoungman/feat/global-no-input-mode Original author: Dan Young
1 parent ebf0ce0 commit a780d55

File tree

12 files changed

+102
-7
lines changed

12 files changed

+102
-7
lines changed

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ $ JIRA_CONFIG_FILE=./local_jira_config.yaml jira issue list
145145
$ jira issue list -c ./local_jira_config.yaml
146146
```
147147

148+
#### Non-interactive mode
149+
150+
For programmatic usage and scripting, you can disable all interactive prompts with the `--no-input` flag. This makes the tool suitable for automation and CI/CD pipelines.
151+
152+
Enable non-interactive mode via:
153+
- CLI flag: `jira issue create --no-input -tBug -s"Summary" -b"Description"`
154+
- Config file: Add `no_input: true` to `~/.jira/.config.yml`
155+
- Environment variable: `export JIRA_NO_INPUT=true`
156+
157+
When a required field is missing in non-interactive mode, the command exits with status code 1 and provides an error message.
158+
148159
## Usage
149160
The tool currently comes with an issue, epic, and sprint explorer. The flags are [POSIX-compliant](https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html).
150161
You can combine available flags in any order to create a unique query. For example, the command below will give you high priority issues created this month
@@ -681,7 +692,7 @@ $ jira sprint add SPRINT_ID ISSUE-1 ISSUE-2
681692

682693
### Releases
683694

684-
Interact with releases (project versions).
695+
Interact with releases (project versions).
685696
Ensure the [feature is enabled](https://support.atlassian.com/jira-software-cloud/docs/enable-releases-and-versions/) on your instance.
686697

687698
#### List

internal/cmd/epic/add/add.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ func add(cmd *cobra.Command, args []string) {
4444

4545
qs := getQuestions(params)
4646
if len(qs) > 0 {
47+
if cmdutil.IsNoInputMode() {
48+
cmdutil.Failed("epic key and issue keys are required in non-interactive mode")
49+
}
4750
ans := struct {
4851
EpicKey string
4952
Issues string

internal/cmd/epic/remove/remove.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ func remove(cmd *cobra.Command, args []string) {
4242

4343
qs := getQuestions(params)
4444
if len(qs) > 0 {
45+
if cmdutil.IsNoInputMode() {
46+
cmdutil.Failed("Issue keys are required in non-interactive mode")
47+
}
4548
ans := struct {
4649
EpicKey string
4750
Issues string

internal/cmd/issue/comment/add/add.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func add(cmd *cobra.Command, args []string) {
8989
params.body = ans.Body
9090
}
9191

92-
if !params.noInput {
92+
if cmdutil.ShouldPrompt(params.noInput) {
9393
answer := struct{ Action string }{}
9494
err := survey.Ask([]*survey.Question{getNextAction()}, &answer)
9595
cmdutil.ExitIfError(err)
@@ -200,7 +200,7 @@ func (ac *addCmd) getQuestions() []*survey.Question {
200200
defaultBody = string(b)
201201
}
202202

203-
if ac.params.noInput && ac.params.body == "" {
203+
if !cmdutil.ShouldPrompt(ac.params.noInput) && ac.params.body == "" {
204204
ac.params.body = defaultBody
205205
return qs
206206
}

internal/cmd/issue/delete/delete.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ func (mc *deleteCmd) setIssueKey(project string) error {
101101
return nil
102102
}
103103

104+
if cmdutil.IsNoInputMode() {
105+
return fmt.Errorf("issue key is required in non-interactive mode")
106+
}
107+
104108
var ans string
105109

106110
qs := &survey.Question{

internal/cmd/issue/edit/edit.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,17 @@ func edit(cmd *cobra.Command, args []string) {
9595

9696
cmdutil.ExitIfError(ec.askQuestions(issue, originalBody))
9797

98-
if !params.noInput {
98+
if cmdutil.ShouldPrompt(params.noInput) {
9999
getAnswers(params, issue)
100100
}
101101

102+
// Validate that at least one field was provided in no-input mode
103+
if cmdutil.IsNoInputMode() {
104+
if hasNoChanges(params, originalBody) {
105+
cmdutil.Failed("No editable fields provided. Use flags like -s, -b, -l, -C, -y, etc. to specify changes")
106+
}
107+
}
108+
102109
// Use stdin only if nothing is passed to --body
103110
if params.body == "" && cmdutil.StdinHasData() {
104111
b, err := cmdutil.ReadFile("-")
@@ -246,13 +253,27 @@ func handleUserAssign(project, key, assignee string, client *jira.Client) {
246253
}
247254
}
248255

256+
// hasNoChanges checks if any editable fields were provided in the params.
257+
func hasNoChanges(params *editParams, originalBody string) bool {
258+
return params.summary == "" &&
259+
params.body == "" &&
260+
params.priority == "" &&
261+
len(params.labels) == 0 &&
262+
len(params.components) == 0 &&
263+
len(params.fixVersions) == 0 &&
264+
len(params.affectsVersions) == 0 &&
265+
len(params.customFields) == 0 &&
266+
params.parentIssueKey == "" &&
267+
params.assignee == ""
268+
}
269+
249270
type editCmd struct {
250271
client *jira.Client
251272
params *editParams
252273
}
253274

254275
func (ec *editCmd) askQuestions(issue *jira.Issue, originalBody string) error {
255-
if ec.params.noInput {
276+
if !cmdutil.ShouldPrompt(ec.params.noInput) {
256277
return nil
257278
}
258279

internal/cmd/issue/move/move.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ func (mc *moveCmd) setIssueKey(project string) error {
180180
return nil
181181
}
182182

183+
if cmdutil.IsNoInputMode() {
184+
return fmt.Errorf("issue key is required in non-interactive mode")
185+
}
186+
183187
var ans string
184188

185189
qs := &survey.Question{
@@ -200,6 +204,10 @@ func (mc *moveCmd) setDesiredState(it string) error {
200204
return nil
201205
}
202206

207+
if cmdutil.IsNoInputMode() {
208+
return fmt.Errorf("desired state is required in non-interactive mode")
209+
}
210+
203211
var (
204212
options = make([]string, 0, len(mc.transitions))
205213
ans string

internal/cmd/issue/worklog/add/add.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func add(cmd *cobra.Command, args []string) {
8787
}
8888
}
8989

90-
if !params.noInput {
90+
if cmdutil.ShouldPrompt(params.noInput) {
9191
answer := struct{ Action string }{}
9292
err := survey.Ask([]*survey.Question{getNextAction()}, &answer)
9393
cmdutil.ExitIfError(err)
@@ -205,7 +205,7 @@ func (ac *addCmd) getQuestions() []*survey.Question {
205205
})
206206
}
207207

208-
if !ac.params.noInput && ac.params.comment == "" {
208+
if cmdutil.ShouldPrompt(ac.params.noInput) && ac.params.comment == "" {
209209
qs = append(qs, &survey.Question{
210210
Name: "comment",
211211
Prompt: &surveyext.JiraEditor{

internal/cmd/root/root.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,14 @@ func NewCmdRoot() *cobra.Command {
115115
),
116116
)
117117
cmd.PersistentFlags().BoolVar(&debug, "debug", false, "Turn on debug output")
118+
cmd.PersistentFlags().Bool("no-input", false, "Disable all interactive prompts (fails instead of prompting for input)")
118119

119120
cmd.SetHelpFunc(helpFunc)
120121

121122
_ = viper.BindPFlag("config", cmd.PersistentFlags().Lookup("config"))
122123
_ = viper.BindPFlag("project.key", cmd.PersistentFlags().Lookup("project"))
123124
_ = viper.BindPFlag("debug", cmd.PersistentFlags().Lookup("debug"))
125+
_ = viper.BindPFlag("no_input", cmd.PersistentFlags().Lookup("no-input"))
124126

125127
addChildCommands(&cmd)
126128

internal/cmd/sprint/close/close.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ func closeSprint(cmd *cobra.Command, args []string) {
3737

3838
qs := getQuestions(params)
3939
if len(qs) > 0 {
40+
if cmdutil.IsNoInputMode() {
41+
cmdutil.Failed("Sprint ID is required in non-interactive mode")
42+
}
4043
ans := struct {
4144
SprintID string
4245
}{}

0 commit comments

Comments
 (0)