jirastorm 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +67 -0
- data/README.md +128 -0
- data/TODO.md +6 -0
- data/bin/jirastorm +8 -0
- data/jirastorm.gemspec +29 -0
- data/lib/jirastorm.rb +39 -0
- data/lib/jirastorm/cli.rb +118 -0
- data/lib/jirastorm/jira.rb +18 -0
- data/lib/jirastorm/jira/issues.rb +33 -0
- data/lib/jirastorm/stormboard.rb +34 -0
- data/lib/jirastorm/stormboard/idea.rb +28 -0
- data/lib/jirastorm/stormboard/storm.rb +49 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2462117b92b6c2e654a3830c9bc6ece4a2946372
|
4
|
+
data.tar.gz: 031c3cb0c9ccc312123dac2076788536c8539a44
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 91d101e3014137c866ebf1721fffe3ab46545fa8c23436d8786078526cc72694fcef5fdebb2912fecf9254cf80a38a6558cf37dff8263e0f15257403437b5a95
|
7
|
+
data.tar.gz: 51d484a335418dd9332ff3b69d49ba16de546aba2dd4a730050b6810712a5ecb55bd86b8982248b12e17ed9afc37853f957a059f14f7c5fc7e70aa154ee393c4
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
jirastorm (0.1.0)
|
5
|
+
jira-ruby (~> 0.1.16)
|
6
|
+
mixlib-config (~> 2.2)
|
7
|
+
rest-client (~> 1.8)
|
8
|
+
thor (~> 0.19)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activesupport (4.2.4)
|
14
|
+
i18n (~> 0.7)
|
15
|
+
json (~> 1.7, >= 1.7.7)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
18
|
+
tzinfo (~> 1.1)
|
19
|
+
ast (2.1.0)
|
20
|
+
astrolabe (1.3.1)
|
21
|
+
parser (~> 2.2)
|
22
|
+
domain_name (0.5.25)
|
23
|
+
unf (>= 0.0.5, < 1.0.0)
|
24
|
+
http-cookie (1.0.2)
|
25
|
+
domain_name (~> 0.5)
|
26
|
+
i18n (0.7.0)
|
27
|
+
jira-ruby (0.1.16)
|
28
|
+
activesupport
|
29
|
+
oauth (~> 0.4.7)
|
30
|
+
json (1.8.3)
|
31
|
+
mime-types (2.6.2)
|
32
|
+
minitest (5.8.2)
|
33
|
+
mixlib-config (2.2.1)
|
34
|
+
netrc (0.11.0)
|
35
|
+
oauth (0.4.7)
|
36
|
+
parser (2.2.3.0)
|
37
|
+
ast (>= 1.1, < 3.0)
|
38
|
+
powerpack (0.1.1)
|
39
|
+
rainbow (2.0.0)
|
40
|
+
rake (10.4.2)
|
41
|
+
rest-client (1.8.0)
|
42
|
+
http-cookie (>= 1.0.2, < 2.0)
|
43
|
+
mime-types (>= 1.16, < 3.0)
|
44
|
+
netrc (~> 0.7)
|
45
|
+
rubocop (0.34.2)
|
46
|
+
astrolabe (~> 1.3)
|
47
|
+
parser (>= 2.2.2.5, < 3.0)
|
48
|
+
powerpack (~> 0.1)
|
49
|
+
rainbow (>= 1.99.1, < 3.0)
|
50
|
+
ruby-progressbar (~> 1.4)
|
51
|
+
ruby-progressbar (1.7.5)
|
52
|
+
thor (0.19.1)
|
53
|
+
thread_safe (0.3.5)
|
54
|
+
tzinfo (1.2.2)
|
55
|
+
thread_safe (~> 0.1)
|
56
|
+
unf (0.1.4)
|
57
|
+
unf_ext
|
58
|
+
unf_ext (0.0.7.1)
|
59
|
+
|
60
|
+
PLATFORMS
|
61
|
+
ruby
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
bundler (~> 1.6)
|
65
|
+
jirastorm!
|
66
|
+
rake
|
67
|
+
rubocop
|
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# JiraStorm
|
2
|
+
A utility to sync JIRA issues to Stormboard.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
You can install this from RubyGems:
|
6
|
+
|
7
|
+
```
|
8
|
+
gem install jirastorm
|
9
|
+
```
|
10
|
+
|
11
|
+
You can also install from source:
|
12
|
+
|
13
|
+
```
|
14
|
+
git clone https://github.com/danzilio/jirastorm
|
15
|
+
cd jirastorm/
|
16
|
+
bundle install
|
17
|
+
bundle exec gem build jirastorm.gemspec
|
18
|
+
gem install jirastorm-0.1.0.gem
|
19
|
+
```
|
20
|
+
|
21
|
+
## Configuration
|
22
|
+
There are a number of ways to configure JiraStorm. You can pass configuration options to the command line, define them as environment variables, or place them in a configuration file, or any combination thereof.
|
23
|
+
|
24
|
+
### Options
|
25
|
+
| CLI Options | Config File Parameter | Environment Variable |
|
26
|
+
| ------------- | -------------------- | -------------------- |
|
27
|
+
| config-file | | JIRASTORM_CONF |
|
28
|
+
| jira-issue-limit | jira_issue_limit | JIRA_ISSUE_LIMIT |
|
29
|
+
| jira-url | jira_url | JIRA_URL |
|
30
|
+
| jira-username | jira_username | JIRA_USERNAME |
|
31
|
+
| jira-password | jira_password | JIRA_PASSWORD |
|
32
|
+
| stormboard-url | stormboard_url | STORMBOARD_URL |
|
33
|
+
| stormboard-key | stormboard_key | STORMBOARD_KEY |
|
34
|
+
| storm-id | storm_id | STORM_ID |
|
35
|
+
| storm-key | storm_key | STORM_KEY |
|
36
|
+
| storm-name | storm_name | STORM_NAME |
|
37
|
+
| create-storm/no-create-storm | create_storm | |
|
38
|
+
| clean-storm/no-clean-storm | clean_storm | |
|
39
|
+
| log-level | log_level | JIRASTORM_LOG_LEVEL |
|
40
|
+
| log-destination | log_destination | JIRASTORM_LOG_DESTINATION |
|
41
|
+
|
42
|
+
### Command Line Options
|
43
|
+
```
|
44
|
+
Options:
|
45
|
+
[--config-file=CONFIG_FILE] # The path to a configuration file.
|
46
|
+
# Default: ~/.jirastorm.rb
|
47
|
+
[--jira-issue-limit=N] # The maximum number of JIRA issues to sync.
|
48
|
+
[--jira-url=JIRA_URL] # The URL of your JIRA instance.
|
49
|
+
[--jira-username=JIRA_USERNAME] # Your JIRA username.
|
50
|
+
[--jira-password=JIRA_PASSWORD] # Your JIRA password.
|
51
|
+
[--stormboard-url=STORMBOARD_URL] # The URL of the Stormboard API.
|
52
|
+
# Default: https://api.stormboard.com
|
53
|
+
[--stormboard-key=STORMBOARD_KEY] # The API key to use to conncet to Stormboard.
|
54
|
+
[--storm-id=N] # The ID of the Storm to sync to.
|
55
|
+
[--storm-key=STORM_KEY] # The key of a Storm to join.
|
56
|
+
[--storm-name=STORM_NAME] # The name to give the newly created Storm.
|
57
|
+
[--create-storm], [--no-create-storm] # Create a new storm if one is not specified or found.
|
58
|
+
# Default: true
|
59
|
+
[--clean-storm], [--no-clean-storm] # Remove all Storm ideas before syncing.
|
60
|
+
[--log-level=LOG_LEVEL] # The log level to output.
|
61
|
+
# Default: info
|
62
|
+
[--log-destination=LOG_DESTINATION] # A file to log to.
|
63
|
+
```
|
64
|
+
|
65
|
+
### Configuration File Options
|
66
|
+
Most of the CLI options can be defined in a configuration file located at `~/.jirastorm.rb`. The configuration file is just a Ruby script so you can do all kinds of fun things. Here's an example of a configuration file that uses the `highline` gem to prompt the user for a password:
|
67
|
+
|
68
|
+
```
|
69
|
+
require 'highiline/import'
|
70
|
+
|
71
|
+
jira_url 'https://jira.example.com'
|
72
|
+
jira_username 'foo'
|
73
|
+
jira_password ask("Please enter your JIRA password:\n") { |q| q.echo = '*' }
|
74
|
+
stormboard_key 'supersecretstormboardkey'
|
75
|
+
storm_id '90210'
|
76
|
+
```
|
77
|
+
|
78
|
+
## Usage
|
79
|
+
The `jirastorm sync` command accepts a JQL query as an argument. The JIRA issues returned by that JQL query will be synced to Stormboard. This example assumes all configuration is done in the configuration file:
|
80
|
+
|
81
|
+
```
|
82
|
+
jirastorm sync 'project = SYS AND resolution = Unresolved ORDER BY updatedDate DESC'
|
83
|
+
```
|
84
|
+
|
85
|
+
The above example would sync all unresolved tickets in the SYS project in the descending order in which they were last updated. By default JIRA will only return the first 50 issues of a query. You can increase or decrease the maximum number of tickets that get synced to Stormboard by using the `jira-issue-limit` option:
|
86
|
+
|
87
|
+
```
|
88
|
+
jirastorm sync --jira-issue-limit 10 'project = SYS AND resolution = Unresolved ORDER BY updatedDate DESC'
|
89
|
+
```
|
90
|
+
|
91
|
+
Here's the above example with the configuration options defined at the command line:
|
92
|
+
|
93
|
+
```
|
94
|
+
jirastorm sync 'project = SYS AND resolution = Unresolved ORDER BY updatedDate DESC' \
|
95
|
+
--jira-url https://jira.example.com \
|
96
|
+
--jira-username foouser \
|
97
|
+
--jira-password supersecretpassword \
|
98
|
+
--stormboard-key supersecretstormboardkey \
|
99
|
+
--storm-id 90120 \
|
100
|
+
--jira-issue-limit 10 \
|
101
|
+
```
|
102
|
+
|
103
|
+
If you don't specify a Storm ID, JiraStorm will create a new Storm for you. You can specify the name of the Storm using the `storm-name` option:
|
104
|
+
|
105
|
+
```
|
106
|
+
jirastorm sync 'project = SYS AND resolution = Unresolved ORDER BY updatedDate DESC' \
|
107
|
+
--jira-url https://jira.example.com \
|
108
|
+
--jira-username foouser \
|
109
|
+
--jira-password supersecretpassword \
|
110
|
+
--stormboard-key supersecretstormboardkey \
|
111
|
+
--storm-name 'My JIRA Issue Storm!'
|
112
|
+
```
|
113
|
+
|
114
|
+
JiraStorm will output the Storm URL after it finishes syncing.
|
115
|
+
|
116
|
+
## Requirements
|
117
|
+
This gem is compatible with Ruby versions `>= 2.0.0`
|
118
|
+
|
119
|
+
## Contributing
|
120
|
+
1. Fork this repo
|
121
|
+
2. Create a feature branch
|
122
|
+
3. Write a failing test
|
123
|
+
4. Write the code to make that test pass
|
124
|
+
5. Refactor your new code
|
125
|
+
6. Document your changes
|
126
|
+
7. Submit a pull request
|
127
|
+
|
128
|
+
If you need help with any of these steps, please don't hesitate to ask :)
|
data/TODO.md
ADDED
data/bin/jirastorm
ADDED
data/jirastorm.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'jirastorm'
|
6
|
+
spec.version = '0.1.0'
|
7
|
+
spec.authors = ['David Danzilio', 'Jim Cuff']
|
8
|
+
spec.email = ['david@danzilio.net']
|
9
|
+
spec.summary = 'A utility to sync issues between JIRA and Stormboard.'
|
10
|
+
spec.description = 'Syncs issues between JIRA and Stormboard.'
|
11
|
+
spec.homepage = 'http://github.com/danzilio/jirastorm'
|
12
|
+
spec.license = 'Apache 2'
|
13
|
+
|
14
|
+
spec.files = `git ls-files -z`.split("\x0")
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.required_ruby_version = '>= 2.0.0'
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'rubocop'
|
24
|
+
|
25
|
+
spec.add_runtime_dependency 'thor', '~> 0.19'
|
26
|
+
spec.add_runtime_dependency 'mixlib-config', '~> 2.2'
|
27
|
+
spec.add_runtime_dependency 'jira-ruby', '~> 0.1.16'
|
28
|
+
spec.add_runtime_dependency 'rest-client', '~> 1.8'
|
29
|
+
end
|
data/lib/jirastorm.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'mixlib/config'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module JiraStorm
|
5
|
+
extend Mixlib::Config
|
6
|
+
config_strict_mode true
|
7
|
+
|
8
|
+
configurable :config_file
|
9
|
+
configurable :jira_issue_limit
|
10
|
+
configurable :jira_url
|
11
|
+
configurable :jira_username
|
12
|
+
configurable :jira_password
|
13
|
+
configurable :stormboard_url
|
14
|
+
configurable :stormboard_key
|
15
|
+
configurable :storm_id
|
16
|
+
configurable :storm_key
|
17
|
+
configurable :storm_name
|
18
|
+
configurable :create_storm
|
19
|
+
configurable :clean_storm
|
20
|
+
default :log_destination, STDOUT
|
21
|
+
configurable :log_level
|
22
|
+
|
23
|
+
def self.log
|
24
|
+
return @logger if @logger
|
25
|
+
@logger = Logger.new(JiraStorm.log_destination)
|
26
|
+
@logger.level = Logger.const_get log_level.upcase
|
27
|
+
return @logger
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.sync(jira_issues, storm)
|
31
|
+
storm_ideas = storm.ideas.map(&:content)
|
32
|
+
jira_issues.each do |issue|
|
33
|
+
unless storm_ideas.include?(issue.to_s)
|
34
|
+
idea = storm.new_idea(issue.to_s)
|
35
|
+
log.info "JIRA issue #{issue.key} created as Idea ##{idea.id} in Storm ##{JiraStorm[:storm_id]}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'yaml'
|
3
|
+
require 'jirastorm'
|
4
|
+
require 'jirastorm/jira'
|
5
|
+
require 'jirastorm/stormboard'
|
6
|
+
|
7
|
+
module JiraStorm
|
8
|
+
class CLI < Thor
|
9
|
+
class_option :config_file,
|
10
|
+
type: :string,
|
11
|
+
default: ENV['JIRASTORM_CONF'] || File.expand_path('~/.jirastorm.rb'),
|
12
|
+
desc: 'The path to a configuration file.'
|
13
|
+
class_option :jira_issue_limit,
|
14
|
+
type: :numeric,
|
15
|
+
default: ENV['JIRA_ISSUE_LIMIT'],
|
16
|
+
desc: 'The maximum number of JIRA issues to sync.'
|
17
|
+
class_option :jira_url,
|
18
|
+
type: :string,
|
19
|
+
default: ENV['JIRA_URL'],
|
20
|
+
desc: 'The URL of your JIRA instance.'
|
21
|
+
class_option :jira_username,
|
22
|
+
type: :string,
|
23
|
+
default: ENV['JIRA_USERNAME'],
|
24
|
+
desc: 'Your JIRA username.'
|
25
|
+
class_option :jira_password,
|
26
|
+
type: :string,
|
27
|
+
default: ENV['JIRA_PASSWORD'],
|
28
|
+
desc: 'Your JIRA password.'
|
29
|
+
class_option :stormboard_url,
|
30
|
+
type: :string,
|
31
|
+
default: ENV['STORMBOARD_URL'] || 'https://api.stormboard.com',
|
32
|
+
desc: 'The URL of the Stormboard API.'
|
33
|
+
class_option :stormboard_key,
|
34
|
+
type: :string,
|
35
|
+
default: ENV['STORMBOARD_KEY'],
|
36
|
+
desc: 'The API key to use to conncet to Stormboard.'
|
37
|
+
class_option :storm_id,
|
38
|
+
type: :numeric,
|
39
|
+
default: ENV['STORM_ID'],
|
40
|
+
desc: "The Storm ID for the storm you'd like to sync to."
|
41
|
+
class_option :storm_key,
|
42
|
+
type: :string,
|
43
|
+
default: ENV['STORM_KEY'],
|
44
|
+
desc: 'The key of a Storm to join.'
|
45
|
+
class_option :storm_name,
|
46
|
+
type: :string,
|
47
|
+
default: ENV['STORM_NAME'],
|
48
|
+
desc: 'The name to give the newly created Storm.'
|
49
|
+
class_option :create_storm,
|
50
|
+
type: :boolean,
|
51
|
+
default: true,
|
52
|
+
desc: 'Create a new storm if one is not specified or found.'
|
53
|
+
class_option :clean_storm,
|
54
|
+
type: :boolean,
|
55
|
+
default: false,
|
56
|
+
desc: 'Remove all Storm ideas before syncing.'
|
57
|
+
class_option :log_level,
|
58
|
+
type: :string,
|
59
|
+
default: ENV['JIRASTORM_LOG_LEVEL'] || 'info',
|
60
|
+
desc: 'The log level to output.'
|
61
|
+
class_option :log_destination,
|
62
|
+
type: :string,
|
63
|
+
default: ENV['JIRASTORM_LOG_DESTINATION'],
|
64
|
+
desc: 'A file to log to.'
|
65
|
+
|
66
|
+
desc 'sync <jira_query>', 'Syncs the issues returned by <jira_query> to Stormboard.'
|
67
|
+
long_desc <<-LONGDESC
|
68
|
+
Runs the <jira_query> JQL and syncs the issues to Stormboard. Note that
|
69
|
+
the search is already confined to 'issues' in JIRA.
|
70
|
+
|
71
|
+
If no Storm is specified using the --storm_id option a Storm will be
|
72
|
+
created for you. If you'd like to join an existing Storm, you must provide
|
73
|
+
the --storm_id and --storm_key options.
|
74
|
+
|
75
|
+
You must supply the --stormboard_key, --jira_url, --jira_username, and
|
76
|
+
--jira_password parameters, or these must be configured in your
|
77
|
+
configuration file and specified with the --config_file option.
|
78
|
+
Alternatively, you can specify values for these options using environment
|
79
|
+
variables by setting STORMBOARD_KEY, JIRA_URL, JIRA_USERNAME, and
|
80
|
+
JIRA_PASSWORD.
|
81
|
+
|
82
|
+
Command line arguments are given precedence for configuration, followed by
|
83
|
+
environment variables, then configuration file parameters.
|
84
|
+
LONGDESC
|
85
|
+
def sync(jira_query)
|
86
|
+
load_config
|
87
|
+
issues = JiraStorm::Jira::Issues.find(jira_query)
|
88
|
+
storm = JiraStorm::Stormboard::Storm.load
|
89
|
+
JiraStorm.log.info "Found #{storm.ideas.count} ideas in Storm ##{JiraStorm[:storm_id]}"
|
90
|
+
JiraStorm.log.debug "The clean_storm option is set, purging all existing Ideas from Storm ##{JiraStorm[:storm_id]}."
|
91
|
+
storm.purge_ideas if JiraStorm[:clean_storm]
|
92
|
+
JiraStorm.sync(issues, storm)
|
93
|
+
JiraStorm.log.info "Sync complete! Access your storm at https://stormboard.com/storm/#{JiraStorm[:storm_id]}"
|
94
|
+
end
|
95
|
+
|
96
|
+
no_commands do
|
97
|
+
def load_config
|
98
|
+
required = [ :jira_url, :jira_username, :jira_password, :stormboard_url, :stormboard_key ]
|
99
|
+
|
100
|
+
JiraStorm.from_file(options[:config_file]) if options[:config_file] && File.exist?(options[:config_file])
|
101
|
+
|
102
|
+
options.each do |o, v|
|
103
|
+
JiraStorm.send("#{o}=", v)
|
104
|
+
end
|
105
|
+
|
106
|
+
not_supplied = required - JiraStorm.keys
|
107
|
+
|
108
|
+
unless not_supplied.empty?
|
109
|
+
JiraStorm.log.fatal "Missing required configuration options: #{not_supplied.join(', ')}."
|
110
|
+
help
|
111
|
+
exit 1
|
112
|
+
end
|
113
|
+
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'jirastorm/jira/issues'
|
2
|
+
require 'jira'
|
3
|
+
|
4
|
+
module JiraStorm
|
5
|
+
module Jira
|
6
|
+
def self.jira_client
|
7
|
+
return @jira_client if @jira_client
|
8
|
+
options = {}
|
9
|
+
options[:username] = JiraStorm[:jira_username] if JiraStorm[:jira_username]
|
10
|
+
options[:password] = JiraStorm[:jira_password] if JiraStorm[:jira_password]
|
11
|
+
options[:auth_type] = :basic
|
12
|
+
options[:site] = JiraStorm[:jira_url]
|
13
|
+
options[:context_path] = ''
|
14
|
+
|
15
|
+
@jira_client = ::JIRA::Client.new(options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'jirastorm/jira'
|
2
|
+
|
3
|
+
module JiraStorm
|
4
|
+
module Jira
|
5
|
+
class Issues
|
6
|
+
attr_reader :key, :id, :description, :summary
|
7
|
+
|
8
|
+
def self.find(query)
|
9
|
+
issues = []
|
10
|
+
JiraStorm.log.debug "JIRA Issue limit set to #{JiraStorm[:jira_issue_limit]}, limiting query to #{JiraStorm[:jira_issue_limit]} issues." if JiraStorm[:jira_issue_limit]
|
11
|
+
JiraStorm::Jira.jira_client.Issue.jql(query, {max_results: JiraStorm[:jira_issue_limit]}).each do |i|
|
12
|
+
issues << self.new(key: i.key, summary: i.summary, description: i.description)
|
13
|
+
end
|
14
|
+
JiraStorm.log.info "Query returned #{issues.count} issues from JIRA"
|
15
|
+
issues
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(**data)
|
19
|
+
@id = data[:id]
|
20
|
+
@key = data[:key]
|
21
|
+
@description = data[:description]
|
22
|
+
@summary = data[:summary]
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
fields = [key, summary]
|
27
|
+
fields << description if description
|
28
|
+
|
29
|
+
fields.join("\n")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'jirastorm/stormboard/idea'
|
2
|
+
require 'jirastorm/stormboard/storm'
|
3
|
+
require 'rest-client'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module JiraStorm
|
7
|
+
module Stormboard
|
8
|
+
def self.headers(**params)
|
9
|
+
headers = {x_api_key: JiraStorm[:stormboard_key]}
|
10
|
+
headers[:params] = params if params
|
11
|
+
return headers
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.get(endpoint, **params)
|
15
|
+
response = RestClient::Request.execute(method: :get, url: "#{JiraStorm[:stormboard_url]}/#{endpoint}", headers: headers(params))
|
16
|
+
JSON.load(response.body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.post(endpoint, **data)
|
20
|
+
response = RestClient::Request.execute method: :post, url: "#{JiraStorm[:stormboard_url]}/#{endpoint}", payload: data.to_json, headers: headers.merge({content_type: :json, accept: :json})
|
21
|
+
JSON.load(response.body)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.put(endpoint, **params)
|
25
|
+
response = RestClient::Request.execute(method: :put, url: "#{JiraStorm[:stormboard_url]}/#{endpoint}", headers: headers(params))
|
26
|
+
JSON.load(response.body)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.delete(endpoint, **params)
|
30
|
+
response = RestClient::Request.execute(method: :delete, url: "#{JiraStorm[:stormboard_url]}/#{endpoint}", headers: headers(params))
|
31
|
+
JSON.load(response.body)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'jirastorm/stormboard'
|
2
|
+
|
3
|
+
module JiraStorm
|
4
|
+
module Stormboard
|
5
|
+
class Idea
|
6
|
+
attr_accessor :id, :content, :color, :storm
|
7
|
+
|
8
|
+
def self.create(storm, content)
|
9
|
+
response = Stormboard.post 'ideas', stormid: storm, data: content
|
10
|
+
JiraStorm.log.debug "Created Idea ##{response['id']} in Storm ##{storm}"
|
11
|
+
new(storm: storm, id: response['id'], data: content)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(**config)
|
15
|
+
@storm = config[:storm]
|
16
|
+
@id = config[:id]
|
17
|
+
@content = config[:content]
|
18
|
+
@color = config[:color]
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete!
|
22
|
+
JiraStorm.log.debug "Deleting Idea: #{id} from Storm ##{storm}"
|
23
|
+
Stormboard.delete "ideas/#{id}"
|
24
|
+
return
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'jirastorm/stormboard'
|
2
|
+
|
3
|
+
module JiraStorm
|
4
|
+
module Stormboard
|
5
|
+
class Storm
|
6
|
+
attr_reader :title, :id
|
7
|
+
|
8
|
+
def self.load
|
9
|
+
if JiraStorm[:storm_id] && JiraStorm[:storm_key]
|
10
|
+
JiraStorm.log.debug "Joining existing Storm ##{JiraStorm[:storm_id]}"
|
11
|
+
Stormboard.post 'storms/join', stormid: JiraStorm[:storm_id], storm_key: JiraStorm[:storm_key]
|
12
|
+
elsif JiraStorm[:create_storm] && !JiraStorm[:storm_id]
|
13
|
+
title = JiraStorm[:storm_name] || 'JiraStorm'
|
14
|
+
JiraStorm.log.debug "Creating Storm with name #{title}"
|
15
|
+
response = Stormboard.post 'storms', title: title
|
16
|
+
JiraStorm[:storm_id] = response['id']
|
17
|
+
JiraStorm.log.debug "Created Storm with name #{title} and ID ##{JiraStorm[:storm_id]}"
|
18
|
+
JiraStorm.log.info "Newly created Storm available at: https://stormboard.com/storm/#{JiraStorm[:storm_id]}"
|
19
|
+
end
|
20
|
+
|
21
|
+
storm = Stormboard.get "storms/#{JiraStorm[:storm_id]}"
|
22
|
+
storm = storm['storm']
|
23
|
+
new(id: JiraStorm[:storm_id], title: storm['title'])
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(**config)
|
27
|
+
@title = config[:title]
|
28
|
+
@id = config[:id]
|
29
|
+
end
|
30
|
+
|
31
|
+
def purge_ideas
|
32
|
+
ideas.each(&:delete!)
|
33
|
+
@ideas = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def new_idea(content)
|
37
|
+
idea = JiraStorm::Stormboard::Idea.create(self.id, content)
|
38
|
+
@ideas << idea
|
39
|
+
return idea
|
40
|
+
end
|
41
|
+
|
42
|
+
def ideas
|
43
|
+
return @ideas if @ideas
|
44
|
+
ideas = Stormboard.get("storms/#{id}/ideas")['ideas']
|
45
|
+
@ideas = ideas.map { |i| JiraStorm::Stormboard::Idea.new(id: i['id'], content: i['data']['text'], color: i['color'], storm: self.id) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jirastorm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Danzilio
|
8
|
+
- Jim Cuff
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.6'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.6'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rubocop
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: thor
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.19'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.19'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: mixlib-config
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.2'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.2'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: jira-ruby
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.1.16
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 0.1.16
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rest-client
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '1.8'
|
105
|
+
type: :runtime
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '1.8'
|
112
|
+
description: Syncs issues between JIRA and Stormboard.
|
113
|
+
email:
|
114
|
+
- david@danzilio.net
|
115
|
+
executables:
|
116
|
+
- jirastorm
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- Gemfile
|
121
|
+
- Gemfile.lock
|
122
|
+
- README.md
|
123
|
+
- TODO.md
|
124
|
+
- bin/jirastorm
|
125
|
+
- jirastorm.gemspec
|
126
|
+
- lib/jirastorm.rb
|
127
|
+
- lib/jirastorm/cli.rb
|
128
|
+
- lib/jirastorm/jira.rb
|
129
|
+
- lib/jirastorm/jira/issues.rb
|
130
|
+
- lib/jirastorm/stormboard.rb
|
131
|
+
- lib/jirastorm/stormboard/idea.rb
|
132
|
+
- lib/jirastorm/stormboard/storm.rb
|
133
|
+
homepage: http://github.com/danzilio/jirastorm
|
134
|
+
licenses:
|
135
|
+
- Apache 2
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.0.0
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.2.2
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: A utility to sync issues between JIRA and Stormboard.
|
157
|
+
test_files: []
|