speedflow-plugin-jira 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e86db3144dfa9255cb647663724cb8e12ec86e76
4
+ data.tar.gz: 9ea700d99decf1955e7d1df581514fc8bc14ffb2
5
+ SHA512:
6
+ metadata.gz: 04539b08a4ba7828d1a910d44b800187f71b0e1b8efa7d255f1f5fa647fd90567c258b30afb6fc4e2cde46b198d754dc628310d361ee581f2295eb8a386fc3b6
7
+ data.tar.gz: d115c35351527e4d2554c2f7581b9daff00c14d0c17d82cd98337f5ed53b38366637e9d4dbda072757f26525e32adfb2bf13da48e83bf6dd034bad229a304f7f
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Speedflow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Speedflow Plugin Jira
2
+
3
+ [![Build Status](https://travis-ci.org/speedflow/speedflow-plugin-jira.svg?branch=master)](https://travis-ci.org/speedflow/speedflow-plugin-jira)
4
+ [![Gem Version](https://badge.fury.io/rb/speedflow-plugin-jira.svg)](https://badge.fury.io/rb/speedflow-plugin-jira)
5
+ [![Code Climate](https://codeclimate.com/github/speedflow/speedflow-plugin-jira/badges/gpa.svg)](https://codeclimate.com/github/speedflow/speedflow-plugin-jira)
6
+ [![Test Coverage](https://codeclimate.com/github/speedflow/speedflow-plugin-jira/badges/coverage.svg)](https://codeclimate.com/github/speedflow/speedflow-plugin-jira/coverage)
7
+ [![Inline docs](http://inch-ci.org/github/speedflow/speedflow-plugin-jira.svg?branch=master)](http://inch-ci.org/github/speedflow/speedflow-plugin-jira)
8
+
9
+ :package: A Speedflow plugin to work with Jira.
10
+
11
+ ## How to install?
12
+
13
+ `gem install speedflow-plugin-jira`
14
+
15
+ ## How to configure?
16
+
17
+ `.speedflow.yml` :
18
+ ```yml
19
+ ---
20
+ plugins:
21
+ - jira
22
+
23
+ # ...
24
+
25
+ jira:
26
+ site: "{JIRA_SITE}"
27
+ username: "{JIRA_USERNAME}"
28
+ password: "{JIRA_PASSWORD}"
29
+ ```
30
+
31
+ `~/.zshrc` or `~/.bashrc` :
32
+ ```sh
33
+ # Jira
34
+ export JIRA_SITE="https://xxx.atlassian.net/"
35
+ export JIRA_USERNAME="..."
36
+ export JIRA_PASSWORD="..."
37
+ ```
38
+
39
+ ### How to use in my flow?
40
+
41
+ #### Search an issue
42
+
43
+ `.speedflow.yml` :
44
+ ```yml
45
+ #...
46
+
47
+ flow:
48
+ test:
49
+ - plugin: jira
50
+ action: search_issue
51
+ ```
52
+
53
+ #### Create an issue (beta)
54
+
55
+ `.speedflow.yml` :
56
+ ```yml
57
+ #...
58
+
59
+ flow:
60
+ test:
61
+ - plugin: jira
62
+ action: create_issue
63
+ arguments:
64
+ title: ~
65
+ project:
66
+ default: TEST
67
+ ```
68
+
69
+ #### Change issue assignee
70
+
71
+ `.speedflow.yml` :
72
+ ```yml
73
+ #...
74
+
75
+ flow:
76
+ test:
77
+ - plugin: jira
78
+ action: change_issue_assignee
79
+ arguments:
80
+ assignee:
81
+ default: "{JIRA_USERNAME}"
82
+ issue: ~
83
+ ```
84
+
85
+ #### Change issue transition
86
+
87
+ `.speedflow.yml` :
88
+ ```yml
89
+ #...
90
+
91
+ flow:
92
+ test:
93
+ - plugin: jira
94
+ action: change_issue_transition
95
+ arguments:
96
+ transition: ~
97
+ issue: ~
98
+ ```
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'speedflow/plugin/jira'
5
+
6
+ require 'pry'
7
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1 @@
1
+ require 'speedflow/plugin/jira'
@@ -0,0 +1,47 @@
1
+ require 'speedflow/plugin/jira/version'
2
+ require 'speedflow/plugin/jira/formatter/issue_formatter'
3
+ require 'speedflow/plugin/jira/plugin_core'
4
+ require 'speedflow/plugin/jira/prompt'
5
+ require 'speedflow/plugin/jira/configuration'
6
+ require 'speedflow/plugin/jira/client'
7
+
8
+ # Speedflow GEM, help you to boost your flow and keep your time.
9
+ module Speedflow
10
+ module Plugin
11
+ # Jira Speedflow plugin.
12
+ module Jira
13
+ # TODO: Move this system in the core Utils
14
+ class << self
15
+ ACTIONS = [
16
+ :action_create_issue,
17
+ :action_search_issue,
18
+ :action_change_issue_assignee,
19
+ :action_change_issue_transition
20
+ ].freeze
21
+
22
+ # @return [Speedflow::Plugin::Jira.PluginCore] Plugin.
23
+ attr_writer :plugin
24
+
25
+ # Public: Magic method to route to action
26
+ #
27
+ # args - Some arguments :)
28
+ #
29
+ # Returns nothing.
30
+ def method_missing(*args)
31
+ action = args.first
32
+
33
+ raise NoMethodError, action unless ACTIONS.include? action
34
+
35
+ plugin.new(args.last).send(action)
36
+ end
37
+
38
+ # Public: Plugin.
39
+ #
40
+ # Returns Speedflow::Plugin::Jira.PluginCore instance.
41
+ def plugin
42
+ @plugin ||= PluginCore
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,154 @@
1
+ require 'jira'
2
+ require 'json'
3
+
4
+ module Speedflow
5
+ module Plugin
6
+ module Jira
7
+ # Jira Client
8
+ class Client
9
+ include ::Speedflow::Plugin::Jira::Formatter
10
+
11
+ # @return [Prompt] Prompt.
12
+ attr_writer :prompt
13
+
14
+ # @return [JIRA::Client] JIRA Client.
15
+ attr_writer :jira_client
16
+
17
+ # Initialize.
18
+ #
19
+ # config - Speedflow::Plugin::Jira::Configuration instance.
20
+ # prompt - Speedflow::Plugin::Jira::Prompt instance.
21
+ #
22
+ # Examples
23
+ #
24
+ # Client.new({}, Speedflow::Plugin::Jira::Prompt.new)
25
+ # # => <Speedflow::Plugin::Jira::Client>
26
+ #
27
+ # Returns nothing.
28
+ def initialize(config, prompt)
29
+ @config = config
30
+ @prompt = prompt
31
+ end
32
+
33
+ # Public: Search issue.
34
+ #
35
+ # project - Project name.
36
+ # title - Issue title.
37
+ #
38
+ # Returns Hash of issue.
39
+ def search_issue(project, title)
40
+ safe do
41
+ jira_client
42
+ .Issue.jql("PROJECT = \"#{project}\" AND text ~ \"#{title}\"")
43
+ end
44
+ end
45
+
46
+ # Public: Create issue.
47
+ #
48
+ # project_key - Project key.
49
+ # title - Title (summary).
50
+ # issue_type_id - Issue type (Fixnum).
51
+ #
52
+ # Returns Hash of issue.
53
+ def create_issue(project_key, title, issue_type_id)
54
+ safe do
55
+ issue = jira_client.Issue.build
56
+ data = IssueFormatter.to_create(project_key, title, issue_type_id)
57
+ issue.save!(data)
58
+ issue.fetch
59
+ end
60
+ end
61
+
62
+ # Public: Update issue.
63
+ #
64
+ # issue_key - Key of issue.
65
+ # assignee_name - Assignee name.
66
+ #
67
+ # Returns Hash of issue.
68
+ def update_issue_assignee(issue_key, assignee_name)
69
+ safe do
70
+ issue = jira_client.Issue.find(issue_key)
71
+ data = IssueFormatter.to_assignee(assignee_name)
72
+ issue.save!(data)
73
+ end
74
+ end
75
+
76
+ # Public: Update issue transition.
77
+ #
78
+ # issue_key - Key of issue.
79
+ # transition_id - Transition ID.
80
+ #
81
+ # Returns Hash of issue.
82
+ def update_issue_transition(issue_key, transition_id)
83
+ safe do
84
+ issue = jira_client.Issue.find(issue_key)
85
+ issue.transitions.build.save!(transition: transition_id)
86
+ end
87
+ end
88
+
89
+ # Public: Jira project.
90
+ #
91
+ # project_key - Project key.
92
+ #
93
+ # Returns JIRA::Resource.Project.
94
+ def project(project_key)
95
+ safe { jira_client.Project.find(project_key) }
96
+ end
97
+
98
+ # Public: Jira projects.
99
+ #
100
+ # Returns Hash of projects.
101
+ def projects
102
+ safe { jira_client.Project.all }
103
+ end
104
+
105
+ # Public: Jira issue transitions.
106
+ #
107
+ # issue_key - Issue key.
108
+ #
109
+ # Returns Hash of transitions.
110
+ def issue_trans(issue_key)
111
+ safe do
112
+ issue = jira_client.Issue.find(issue_key, expand: 'transitions')
113
+ issue.transitions
114
+ end
115
+ end
116
+
117
+ # Public: Jira issue types.
118
+ #
119
+ # Returns Hash of issue types.
120
+ def issue_types
121
+ safe { jira_client.Issuetype.all }
122
+ end
123
+
124
+ # Public: Safe process JIRA action.
125
+ #
126
+ # Returns nothing.
127
+ def safe
128
+ yield
129
+ rescue ::JIRA::HTTPError => exception
130
+ prompt.error 'Jira errors'
131
+ prompt.errors exception
132
+ abort
133
+ rescue ::URI::InvalidURIError
134
+ prompt.error 'Invalid URL'
135
+ abort
136
+ end
137
+
138
+ # Public: Jira client.
139
+ #
140
+ # Returns JIRA::Client instance.
141
+ def jira_client
142
+ @jira_client ||= ::JIRA::Client.new(@config.auth)
143
+ end
144
+
145
+ # Public: Prompt.
146
+ #
147
+ # Returns ::Speedflow::Plugin::Jira::Prompt instance.
148
+ def prompt
149
+ @prompt ||= ::Speedflow::Plugin::Jira::Prompt.new
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,84 @@
1
+ module Speedflow
2
+ module Plugin
3
+ module Jira
4
+ # Jira Configuration
5
+ class Configuration
6
+ CONFIG_KEY = '_config'.freeze
7
+ PLUGIN_KEY = 'jira'.freeze
8
+
9
+ # Initialize.
10
+ #
11
+ # arguments - Hash of arguments.
12
+ #
13
+ # Examples
14
+ #
15
+ # Configuration.new({})
16
+ # # => <Speedflow::Plugin::Jira::Configuration>
17
+ #
18
+ # Returns nothing.
19
+ def initialize(arguments)
20
+ @arguments = arguments
21
+ end
22
+
23
+ # Public: Auth configuration.
24
+ #
25
+ # Returns Hash of auth configuration.
26
+ def auth
27
+ {
28
+ username: by_config('username'),
29
+ password: by_config('password'),
30
+ site: by_config('site'),
31
+ context_path: by_config('context_path', '/'),
32
+ auth_type: by_config('auth_type', :basic),
33
+ read_timeout: by_config('read_timeout', 120)
34
+ }
35
+ end
36
+
37
+ # Public: Get a specific config.
38
+ #
39
+ # key - Key of config.
40
+ # default_value - Default value.
41
+ #
42
+ # Returns value of config key.
43
+ def by_config(key, default_value = '')
44
+ if @arguments.key?(CONFIG_KEY) &&
45
+ @arguments[CONFIG_KEY].key?(PLUGIN_KEY)
46
+ config = @arguments[CONFIG_KEY][PLUGIN_KEY]
47
+ end
48
+ config.key?(key) ? config[key] : default_value
49
+ end
50
+
51
+ # Public: Get an input config by key.
52
+ #
53
+ # key - Key of config.
54
+ # default_value - Default value.
55
+ #
56
+ # Returns value of input config key.
57
+ def by_input(key, default_value = '')
58
+ if @arguments.key?(key)
59
+ @arguments[key]['value'].to_s
60
+ else
61
+ default_value
62
+ end
63
+ end
64
+
65
+ # Public: Get an input config by key but required.
66
+ #
67
+ # key - Key of config.
68
+ # default_value - Default value.
69
+ #
70
+ # Returns value of input config key or Exception.
71
+ def by_required_input(key, default_value = '')
72
+ value = by_input(key, default_value)
73
+
74
+ # TODO: Improve communication with core for errors
75
+ if by_input(key).empty?
76
+ raise Exception, "Required value for '#{key}'."
77
+ end
78
+
79
+ value
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,43 @@
1
+ module Speedflow
2
+ module Plugin
3
+ module Jira
4
+ # Formatter
5
+ module Formatter
6
+ # Issue formatter
7
+ module IssueFormatter
8
+ # Public: To create issue.
9
+ #
10
+ # project_key - Project Key.
11
+ # title - Issue title.
12
+ # issue_type_id - Issue type ID.
13
+ #
14
+ # Returns Hash of fields.
15
+ def self.to_create(project_key, title, issue_type_id)
16
+ {
17
+ 'fields' => {
18
+ 'project' => { 'key' => project_key.to_s },
19
+ 'summary' => title.to_s,
20
+ 'issuetype' => { 'id' => issue_type_id.to_s }
21
+ }
22
+ }
23
+ end
24
+
25
+ # Public: To assignee.
26
+ #
27
+ # assignee_name - Assignee name.
28
+ #
29
+ # Returns Hash of fields.
30
+ def self.to_assignee(assignee_name)
31
+ {
32
+ 'fields' => {
33
+ 'assignee' => {
34
+ 'name' => assignee_name.to_s
35
+ }
36
+ }
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end