jirastorm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ To Do Items:
2
+ - Improve human readability of logging
3
+ - Tests, tests, and more tests
4
+ - Break the Stormboard stuff out into a Stormboard API Gem
5
+ - Inline documentation
6
+ - Define the private interfaces
data/bin/jirastorm ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'jirastorm/cli'
7
+
8
+ JiraStorm::CLI.start(ARGV)
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: []