embulk-input-jira 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c37d6bfba4c1f808f3911a222698a62e87b1a6ec
4
- data.tar.gz: 4348bce6dd5c2c293e090396f8375c4a520830cd
3
+ metadata.gz: 5e99c37b9c22a10ca74920b940eb2acf874d0676
4
+ data.tar.gz: b85987d31a8870a6136d14dd75f6b65605160211
5
5
  SHA512:
6
- metadata.gz: e383256cdde3bb1623a7777ff4eb811842a8fb1a37a26ea8319a6c9e8f3d7ab5f9ec572b2ee55e7e648c4d923ede50655ea36b14ab3c411488b29bd6b5951923
7
- data.tar.gz: 91d53c2b6ebf59b2ee8dd0888da96360c592b2b56be0349caae291dc8874fac2ed61bfab7778e1a666a410b250a4f99c4db9191bf907161eb912fcae495d3d70
6
+ metadata.gz: 010bff47e3e9c3a48c24d1da78ef835450f350d7b102969e5ab89c4847425e368719009bc70511f54d2f46347f70e9235883e3e383e3c54651fbfb5a86d193be
7
+ data.tar.gz: 6a99ada3fcfc2fc9d0b51484a40e85d6d51797a75964251714d9ebcc8d4f3b24f6f3e6f7af56097e329fd8647f9f7d9397587d827dfc10e1a273e658c9b32005
data/CHANGELOG.md CHANGED
@@ -1,8 +1,13 @@
1
+ ## 0.0.3 - 2015-06-12
2
+ * [enhancement] Limit records for guess and preview [#25](https://github.com/treasure-data/embulk-input-jira/pull/25)
3
+ * [maintenance] Define version number as constant [#24](https://github.com/treasure-data/embulk-input-jira/pull/24)
4
+ * [maintenance] Restructure file and class [#23](https://github.com/treasure-data/embulk-input-jira/pull/23)
5
+
1
6
  ## 0.0.2 - 2015-06-04
2
- * [maintenance] Add release:prepare task for development [#21](https://github.com/treasure-data/embulk-input-jira/pull/21)
3
- * [enhancement] Add timeout and retry for JIRA API search [#20](https://github.com/treasure-data/embulk-input-jira/pull/20)
7
+ * [maintenance] Add release:prepare task for development [#21](https://github.com/treasure-data/embulk-input-jira/pull/21)
8
+ * [enhancement] Add timeout and retry for JIRA API search [#20](https://github.com/treasure-data/embulk-input-jira/pull/20)
4
9
  * [enhancement] Display progress [#19](https://github.com/treasure-data/embulk-input-jira/pull/19)
5
- * [maintenance] Remove needless guessed config [#18](https://github.com/treasure-data/embulk-input-jira/pull/18)
10
+ * [maintenance] Remove needless guessed config [#18](https://github.com/treasure-data/embulk-input-jira/pull/18)
6
11
 
7
12
  ## 0.0.1 - 2015-05-28
8
13
 
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require 'rspec/core/rake_task'
3
3
  require "json"
4
4
  require "pathname"
5
5
  require "open-uri"
6
+ require File.expand_path("../lib/embulk/input/jira/version.rb", __FILE__)
6
7
 
7
8
 
8
9
  task default: :spec
@@ -16,13 +17,12 @@ namespace :release do
16
17
  desc "Add header of now version release to ChangeLog and bump up version"
17
18
  task :prepare do
18
19
  root_dir = Pathname.new(File.expand_path("../", __FILE__))
19
- version_file = root_dir.join("VERSION")
20
20
  changelog_file = root_dir.join("CHANGELOG.md")
21
21
 
22
22
  system("git fetch origin")
23
23
 
24
24
  # detect merged PR
25
- old_version = version_file.read.strip
25
+ old_version = Embulk::Input::Jira::VERSION
26
26
  pr_numbers = `git log v#{old_version}..origin/master --oneline`.scan(/#[0-9]+/)
27
27
 
28
28
  if !$?.success? || pr_numbers.empty?
@@ -38,7 +38,7 @@ namespace :release do
38
38
  pr_descriptions = pr_numbers.map do |number|
39
39
  body = open("https://api.github.com/repos/treasure-data/embulk-input-jira/issues/#{number.gsub("#", "")}").read
40
40
  payload = JSON.parse(body)
41
- "* [] #{payload["title"]} [#{number}](https://github.com/treasure-data/embulk-input-jira/pull/#{number.gsub('#', '')}) "
41
+ "* [] #{payload["title"]} [#{number}](https://github.com/treasure-data/embulk-input-jira/pull/#{number.gsub('#', '')})"
42
42
  end.join("\n")
43
43
 
44
44
  new_changelog = <<-HEADER
@@ -51,7 +51,11 @@ HEADER
51
51
  File.open(changelog_file, "w") {|f| f.write(new_changelog) }
52
52
 
53
53
  # Update version.rb
54
- File.open(version_file, "w") {|f| f.write new_version }
54
+ version_file = root_dir.join("./lib/embulk/input/jira/version.rb")
55
+ old_content = version_file.read
56
+ File.open(version_file, "w") do |f|
57
+ f.write old_content.gsub(old_version, new_version)
58
+ end
55
59
 
56
60
  # Update Gemfile.lock
57
61
  system("bundle install")
@@ -1,7 +1,8 @@
1
+ require File.expand_path("../lib/embulk/input/jira/version.rb", __FILE__)
1
2
 
2
3
  Gem::Specification.new do |spec|
3
4
  spec.name = "embulk-input-jira"
4
- spec.version = File.read(File.expand_path("../VERSION", __FILE__)).strip
5
+ spec.version = Embulk::Input::Jira::VERSION
5
6
  spec.authors = ["uu59", "yoshihara"]
6
7
  spec.summary = "Jira input plugin for Embulk"
7
8
  spec.description = "Loads records from Jira."
@@ -0,0 +1,54 @@
1
+ require "jiralicious"
2
+ require "embulk/input/jira/issue"
3
+ require "timeout"
4
+
5
+ module Embulk
6
+ module Input
7
+ module Jira
8
+ class Api
9
+ SEARCH_TIMEOUT_SECONDS = 5
10
+ SEARCH_ISSUES_TIMEOUT_SECONDS = 60
11
+ DEFAULT_SEARCH_RETRY_TIMES = 10
12
+
13
+ def self.setup(&block)
14
+ Jiralicious.configure(&block)
15
+ new
16
+ end
17
+
18
+ def search_issues(jql, options={})
19
+ timeout_and_retry(SEARCH_ISSUES_TIMEOUT_SECONDS) do
20
+ search(jql, options).issues.map do |issue|
21
+ Jira::Issue.new(issue)
22
+ end
23
+ end
24
+ end
25
+
26
+ def search(jql, options={})
27
+ timeout_and_retry(SEARCH_TIMEOUT_SECONDS) do
28
+ Jiralicious.search(jql, options)
29
+ end
30
+ end
31
+
32
+ def total_count(jql)
33
+ search(jql, max_results: 1).num_results
34
+ end
35
+
36
+ private
37
+
38
+ def timeout_and_retry(wait, retry_times = DEFAULT_SEARCH_RETRY_TIMES, &block)
39
+ count = 1
40
+ begin
41
+ Timeout.timeout(wait) do
42
+ yield
43
+ end
44
+ rescue Timeout::Error => e
45
+ count += 1
46
+ sleep count # retry after some seconds for JIRA API perhaps under the overload
47
+ raise e if count > retry_times
48
+ retry
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,67 @@
1
+ module Embulk
2
+ module Input
3
+ module Jira
4
+ class Issue
5
+ attr_reader :id, :key, :fields
6
+
7
+ def initialize(attributes)
8
+ @id = attributes.fetch("id")
9
+
10
+ # https://github.com/dorack/jiralicious/blob/404b7b6d5b7020f42064cf8d7a745ab02057e728/lib/jiralicious/issue.rb#L11-L12
11
+ @key = attributes.fetch("jira_key")
12
+ @fields = attributes.fetch("fields")
13
+ end
14
+
15
+ def [](attribute)
16
+ case attribute
17
+ when "id"
18
+ return id
19
+ when "key"
20
+ return key
21
+ end
22
+
23
+ chunk = fields
24
+ attribute.split('.').each do |key|
25
+ chunk = chunk[key]
26
+ return chunk if chunk.nil?
27
+ end
28
+
29
+ if chunk.is_a?(Array) || chunk.is_a?(Hash)
30
+ chunk.to_json.to_s
31
+ else
32
+ chunk
33
+ end
34
+ end
35
+
36
+ def to_record
37
+ record = {}
38
+
39
+ record["id"] = id
40
+ record["key"] = key
41
+
42
+ fields.each_pair do |key, value|
43
+ record_key = key
44
+ record_value = value.to_json.to_s
45
+
46
+ case value
47
+ when String
48
+ record_value = value
49
+ when Hash
50
+ if value.keys.include?("name")
51
+ record_key += ".name"
52
+ record_value = value["name"]
53
+ elsif value.keys.include?("id")
54
+ record_key += ".id"
55
+ record_value = value["id"]
56
+ end
57
+ end
58
+
59
+ record[record_key] = record_value
60
+ end
61
+
62
+ record
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,7 @@
1
+ module Embulk
2
+ module Input
3
+ module Jira
4
+ VERSION = "0.0.3".freeze
5
+ end
6
+ end
7
+ end
@@ -1,127 +1,9 @@
1
- require "embulk/input/jira-input-plugin-utils"
2
- require "jira/api"
3
- require "logger"
4
- require "time"
1
+ require "embulk/input/jira_input_plugin"
2
+ require "embulk/input/jira/version"
5
3
 
6
4
  module Embulk
7
5
  module Input
8
- class JiraInputPlugin < InputPlugin
9
- PER_PAGE = 50
10
-
11
- Plugin.register_input("jira", self)
12
-
13
- def self.version
14
- File.read(File.expand_path("../../../../VERSION", __FILE__)).strip
15
- end
16
-
17
- def self.transaction(config, &control)
18
- task = {
19
- "username" => config.param("username", :string),
20
- "password" => config.param("password", :string),
21
- "uri" => config.param("uri", :string),
22
- "jql" => config.param("jql", :string),
23
- }
24
-
25
- attributes = {}
26
- columns = config.param("columns", :array).map do |column|
27
- name = column["name"]
28
- type = column["type"].to_sym
29
- attributes[name] = type
30
- Column.new(nil, name, type, column["format"])
31
- end
32
-
33
- task["attributes"] = attributes
34
-
35
- resume(task, columns, 1, &control)
36
- end
37
-
38
- def self.resume(task, columns, count, &control)
39
- commit_reports = yield(task, columns, count)
40
-
41
- next_config_diff = {}
42
- return next_config_diff
43
- end
44
-
45
- def self.guess(config)
46
- # TODO: api_version should be 2 (the latest version)
47
- # auth_type should be specified from config. (The future task)
48
-
49
- username = config.param("username", :string)
50
- password = config.param("password", :string)
51
- uri = config.param("uri", :string)
52
- api_version = "latest"
53
- auth_type = "basic"
54
- jql = config.param("jql", :string)
55
-
56
- jira = Jira::Api.setup do |jira_config|
57
- jira_config.username = username
58
- jira_config.password = password
59
- jira_config.uri = uri
60
- jira_config.api_version = api_version
61
- jira_config.auth_type = auth_type
62
- end
63
-
64
- # TODO: we use 0..10 issues to guess config?
65
- records = jira.search_issues(jql)[0..10].map do |issue|
66
- issue.to_record
67
- end
68
-
69
- columns = JiraInputPluginUtils.guess_columns(records)
70
-
71
- guessed_config = {
72
- "columns" => columns,
73
- }
74
-
75
- return guessed_config
76
- end
77
-
78
- def init
79
- @attributes = task["attributes"]
80
- @jira = Jira::Api.setup do |config|
81
- config.username = task["username"]
82
- config.password = task["password"]
83
- config.uri = task["uri"]
84
- config.api_version = "latest"
85
- config.auth_type = :basic
86
- end
87
- @jql = task["jql"]
88
- end
89
-
90
- def run
91
- total_count = @jira.total_count(@jql)
92
- last_page = (total_count.to_f / PER_PAGE).ceil
93
-
94
- 0.step(total_count, PER_PAGE).with_index(1) do |start_at, page|
95
- logger.debug "Fetching #{page} / #{last_page} page"
96
- @jira.search_issues(@jql, start_at: start_at).each do |issue|
97
- values = @attributes.map do |(attribute_name, type)|
98
- JiraInputPluginUtils.cast(issue[attribute_name], type)
99
- end
100
-
101
- page_builder.add(values)
102
- end
103
- end
104
-
105
- page_builder.finish
106
-
107
- commit_report = {}
108
- return commit_report
109
- end
110
-
111
- def self.logger
112
- @logger ||=
113
- begin
114
- logger = Logger.new($stdout)
115
- logger.formatter = proc do |severity, datetime, progname, msg|
116
- "#{datetime.strftime("%Y-%m-%d %H:%M:%S.%L %z")} [#{severity}] #{msg}\n"
117
- end
118
- logger
119
- end
120
- end
121
-
122
- def logger
123
- self.class.logger
124
- end
6
+ module Jira
125
7
  end
126
8
  end
127
9
  end
@@ -0,0 +1,135 @@
1
+ require "embulk/input/jira_input_plugin_utils"
2
+ require "embulk/input/jira/api"
3
+ require "logger"
4
+ require "time"
5
+
6
+ module Embulk
7
+ module Input
8
+ class JiraInputPlugin < InputPlugin
9
+ PER_PAGE = 50
10
+ GUESS_RECORDS_COUNT = 10
11
+ PREVIEW_RECORDS_COUNT = 15
12
+
13
+ Plugin.register_input("jira", self)
14
+
15
+ def self.transaction(config, &control)
16
+ task = {
17
+ "username" => config.param("username", :string),
18
+ "password" => config.param("password", :string),
19
+ "uri" => config.param("uri", :string),
20
+ "jql" => config.param("jql", :string),
21
+ }
22
+
23
+ attributes = {}
24
+ columns = config.param("columns", :array).map do |column|
25
+ name = column["name"]
26
+ type = column["type"].to_sym
27
+ attributes[name] = type
28
+ Column.new(nil, name, type, column["format"])
29
+ end
30
+
31
+ task["attributes"] = attributes
32
+
33
+ resume(task, columns, 1, &control)
34
+ end
35
+
36
+ def self.resume(task, columns, count, &control)
37
+ commit_reports = yield(task, columns, count)
38
+
39
+ next_config_diff = {}
40
+ return next_config_diff
41
+ end
42
+
43
+ def self.guess(config)
44
+ # TODO: api_version should be 2 (the latest version)
45
+ # auth_type should be specified from config. (The future task)
46
+
47
+ username = config.param("username", :string)
48
+ password = config.param("password", :string)
49
+ uri = config.param("uri", :string)
50
+ api_version = "latest"
51
+ auth_type = "basic"
52
+ jql = config.param("jql", :string)
53
+
54
+ jira = Jira::Api.setup do |jira_config|
55
+ jira_config.username = username
56
+ jira_config.password = password
57
+ jira_config.uri = uri
58
+ jira_config.api_version = api_version
59
+ jira_config.auth_type = auth_type
60
+ end
61
+
62
+ # TODO: we use 0..10 issues to guess config?
63
+ records = jira.search_issues(jql, max_results: GUESS_RECORDS_COUNT).map do |issue|
64
+ issue.to_record
65
+ end
66
+
67
+ columns = JiraInputPluginUtils.guess_columns(records)
68
+
69
+ guessed_config = {
70
+ "columns" => columns,
71
+ }
72
+
73
+ return guessed_config
74
+ end
75
+
76
+ def init
77
+ @attributes = task["attributes"]
78
+ @jira = Jira::Api.setup do |config|
79
+ config.username = task["username"]
80
+ config.password = task["password"]
81
+ config.uri = task["uri"]
82
+ config.api_version = "latest"
83
+ config.auth_type = :basic
84
+ end
85
+ @jql = task["jql"]
86
+ end
87
+
88
+ def run
89
+ # NOTE: This is workaround for "org.embulk.spi.Exec.isPreview"
90
+ # TODO: Extract process for preview command to method
91
+ if org.embulk.spi.Exec.session().isPreview()
92
+ options = {max_results: PREVIEW_RECORDS_COUNT}
93
+ total_count = PREVIEW_RECORDS_COUNT
94
+ last_page = 1
95
+ logger.debug "For preview mode, JIRA input plugin fetches records at most #{PREVIEW_RECORDS_COUNT}"
96
+ else
97
+ options = {}
98
+ total_count = @jira.total_count(@jql)
99
+ last_page = (total_count.to_f / PER_PAGE).ceil
100
+ end
101
+
102
+ 0.step(total_count, PER_PAGE).with_index(1) do |start_at, page|
103
+ logger.debug "Fetching #{page} / #{last_page} page"
104
+ @jira.search_issues(@jql, options.merge(start_at: start_at)).each do |issue|
105
+ values = @attributes.map do |(attribute_name, type)|
106
+ JiraInputPluginUtils.cast(issue[attribute_name], type)
107
+ end
108
+
109
+ page_builder.add(values)
110
+ end
111
+ end
112
+
113
+ page_builder.finish
114
+
115
+ commit_report = {}
116
+ return commit_report
117
+ end
118
+
119
+ def self.logger
120
+ @logger ||=
121
+ begin
122
+ logger = Logger.new($stdout)
123
+ logger.formatter = proc do |severity, datetime, progname, msg|
124
+ "#{datetime.strftime("%Y-%m-%d %H:%M:%S.%L %z")} [#{severity}] #{msg}\n"
125
+ end
126
+ logger
127
+ end
128
+ end
129
+
130
+ def logger
131
+ self.class.logger
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,14 +1,11 @@
1
- # TODO: move to spec/jira/api_spec.rb
2
-
3
1
  require "spec_helper"
4
- require "jira/api"
5
2
 
6
- describe Jira::Api do
3
+ describe Embulk::Input::Jira::Api do
7
4
  describe ".setup" do
8
- subject { Jira::Api.setup {} }
5
+ subject { Embulk::Input::Jira::Api.setup {} }
9
6
 
10
- it "returns Jira::Api instance" do
11
- expect(subject.is_a?(Jira::Api)).to be_truthy
7
+ it "returns Embulk::Input::Jira::Api instance" do
8
+ expect(subject.is_a?(Embulk::Input::Jira::Api)).to be_truthy
12
9
  end
13
10
 
14
11
  it "calls Jiralicious.configure" do
@@ -18,7 +15,7 @@ describe Jira::Api do
18
15
 
19
16
  describe "#search" do
20
17
  let(:jql) { "project=FOO" }
21
- let(:api) { Jira::Api.new }
18
+ let(:api) { Embulk::Input::Jira::Api.new }
22
19
 
23
20
  subject { api.search(jql) }
24
21
 
@@ -33,7 +30,7 @@ describe Jira::Api do
33
30
  end
34
31
 
35
32
  it "retry DEFAULT_SEARCH_RETRY_TIMES times then raise error" do
36
- expect(Timeout).to receive(:timeout).exactly(Jira::Api::DEFAULT_SEARCH_RETRY_TIMES)
33
+ expect(Timeout).to receive(:timeout).exactly(Embulk::Input::Jira::Api::DEFAULT_SEARCH_RETRY_TIMES)
37
34
  expect { subject }.to raise_error
38
35
  end
39
36
  end
@@ -70,20 +67,20 @@ describe Jira::Api do
70
67
  ]
71
68
  end
72
69
 
73
- subject { Jira::Api.new.search_issues(jql) }
70
+ subject { Embulk::Input::Jira::Api.new.search_issues(jql) }
74
71
 
75
72
  it do
76
73
  allow(Jiralicious).to receive_message_chain(:search, :issues).and_return(results)
77
74
 
78
75
  expect(subject).to be_kind_of Array
79
- expect(subject.map(&:class)).to match_array [Jira::Issue, Jira::Issue]
76
+ expect(subject.map(&:class)).to match_array [Embulk::Input::Jira::Issue, Embulk::Input::Jira::Issue]
80
77
  end
81
78
  end
82
79
 
83
80
  describe "#total_count" do
84
81
  subject { jira_api.total_count(jql) }
85
82
 
86
- let(:jira_api) { Jira::Api.new }
83
+ let(:jira_api) { Embulk::Input::Jira::Api.new }
87
84
  let(:jql) { "project=FOO" }
88
85
  let(:results) { Object.new } # add mock later
89
86
  let(:results_count) { 5 }
@@ -92,7 +89,7 @@ describe Jira::Api do
92
89
  allow(results).to receive(:num_results).and_return(results_count)
93
90
  end
94
91
 
95
- it "calls Jira::Api#search with proper arguments" do
92
+ it "calls Embulk::Input::Jira::Api#search with proper arguments" do
96
93
  expect(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
97
94
  subject
98
95
  end
@@ -106,7 +103,7 @@ describe Jira::Api do
106
103
  describe "#timeout_and_retry" do
107
104
  let(:wait) { 1 }
108
105
  let(:retry_times) { 3 }
109
- let(:jira_api) { Jira::Api.new }
106
+ let(:jira_api) { Embulk::Input::Jira::Api.new }
110
107
  let(:block) { proc{ "it works" } }
111
108
 
112
109
  subject { jira_api.send(:timeout_and_retry, wait, retry_times, &block) }
@@ -1,7 +1,6 @@
1
1
  require "spec_helper"
2
- require "jira/issue"
3
2
 
4
- describe Jira::Issue do
3
+ describe Embulk::Input::Jira::Issue do
5
4
  describe ".initialize" do
6
5
  context "when argument has 'fields' key" do
7
6
  let(:issue_attributes) do
@@ -20,15 +19,15 @@ describe Jira::Issue do
20
19
  end
21
20
 
22
21
  it "has @id with argument['id']" do
23
- expect(Jira::Issue.new(issue_attributes).id).to eq issue_attributes["id"]
22
+ expect(Embulk::Input::Jira::Issue.new(issue_attributes).id).to eq issue_attributes["id"]
24
23
  end
25
24
 
26
25
  it "has @key with argument['jira_key']" do
27
- expect(Jira::Issue.new(issue_attributes).key).to eq issue_attributes["jira_key"]
26
+ expect(Embulk::Input::Jira::Issue.new(issue_attributes).key).to eq issue_attributes["jira_key"]
28
27
  end
29
28
 
30
29
  it "has @fields with argument['fields']" do
31
- expect(Jira::Issue.new(issue_attributes).fields).to eq issue_attributes["fields"]
30
+ expect(Embulk::Input::Jira::Issue.new(issue_attributes).fields).to eq issue_attributes["fields"]
32
31
  end
33
32
  end
34
33
 
@@ -38,13 +37,13 @@ describe Jira::Issue do
38
37
  end
39
38
 
40
39
  it "raises error" do
41
- expect { Jira::Issue.new(issue_attributes) }.to raise_error
40
+ expect { Embulk::Input::Jira::Issue.new(issue_attributes) }.to raise_error
42
41
  end
43
42
  end
44
43
  end
45
44
 
46
45
  describe "#[]" do
47
- subject { Jira::Issue.new(issue_attributes)[attribute_name] }
46
+ subject { Embulk::Input::Jira::Issue.new(issue_attributes)[attribute_name] }
48
47
 
49
48
  let(:issue_attributes) do
50
49
  {
@@ -135,7 +134,7 @@ describe Jira::Issue do
135
134
 
136
135
  describe "#to_record" do
137
136
  subject do
138
- Jira::Issue.new(issue_attributes).to_record
137
+ Embulk::Input::Jira::Issue.new(issue_attributes).to_record
139
138
  end
140
139
 
141
140
  let(:issue_attributes) do
@@ -1,5 +1,4 @@
1
1
  require "spec_helper"
2
- require "embulk/input/jira-input-plugin-utils"
3
2
 
4
3
  describe Embulk::Input::JiraInputPluginUtils do
5
4
  describe ".guess_columns" do
@@ -1,5 +1,4 @@
1
1
  require "spec_helper"
2
- require "embulk/input/jira"
3
2
 
4
3
  describe Embulk::Input::JiraInputPlugin do
5
4
  let(:username) { "jira-user" }
@@ -94,8 +93,8 @@ describe Embulk::Input::JiraInputPlugin do
94
93
 
95
94
  let(:config) { Object.new } # add mock later
96
95
 
97
- let(:jira_api) { Jira::Api.new }
98
- let(:jira_issues) { [Jira::Issue.new(attributes)] }
96
+ let(:jira_api) { Embulk::Input::Jira::Api.new }
97
+ let(:jira_issues) { [Embulk::Input::Jira::Issue.new(attributes)] }
99
98
  let(:attributes) do
100
99
  {
101
100
  "id" => "100",
@@ -126,7 +125,7 @@ describe Embulk::Input::JiraInputPlugin do
126
125
  end
127
126
 
128
127
  before do
129
- allow(jira_api).to receive(:search_issues).and_return(jira_issues)
128
+ allow(jira_api).to receive(:search_issues).with(jql, max_results: Embulk::Input::JiraInputPlugin::GUESS_RECORDS_COUNT).and_return(jira_issues)
130
129
 
131
130
  allow(config).to receive(:param).with("username", :string).and_return(username)
132
131
  allow(config).to receive(:param).with("password", :string).and_return(password)
@@ -134,13 +133,13 @@ describe Embulk::Input::JiraInputPlugin do
134
133
  allow(config).to receive(:param).with("jql", :string).and_return(jql)
135
134
  end
136
135
 
137
- it "setup Jira::Api" do
138
- expect(Jira::Api).to receive(:setup).and_return(jira_api)
136
+ it "setup Embulk::Input::Jira::Api" do
137
+ expect(Embulk::Input::Jira::Api).to receive(:setup).and_return(jira_api)
139
138
  subject
140
139
  end
141
140
 
142
141
  it "returns guessed config" do
143
- allow(Jira::Api).to receive(:setup).and_return(jira_api)
142
+ allow(Embulk::Input::Jira::Api).to receive(:setup).and_return(jira_api)
144
143
 
145
144
  expect(subject).to eq guessed_config
146
145
  end
@@ -151,13 +150,13 @@ describe Embulk::Input::JiraInputPlugin do
151
150
 
152
151
  subject { Embulk::Input::JiraInputPlugin.new({}, nil, nil, nil) }
153
152
 
154
- it "setup Jira::Api" do
155
- expect(Jira::Api).to receive(:setup)
153
+ it "setup Embulk::Input::Jira::Api" do
154
+ expect(Embulk::Input::Jira::Api).to receive(:setup)
156
155
  subject
157
156
  end
158
157
 
159
158
  it "is a Embulk::InputPlugin" do
160
- allow(Jira::Api).to receive(:setup)
159
+ allow(Embulk::Input::Jira::Api).to receive(:setup)
161
160
  expect(subject).to be_a(Embulk::InputPlugin)
162
161
  end
163
162
  end
@@ -171,12 +170,12 @@ describe Embulk::Input::JiraInputPlugin do
171
170
  result
172
171
  end
173
172
 
174
- let(:jira_api) { Jira::Api.new }
173
+ let(:jira_api) { Embulk::Input::Jira::Api.new }
175
174
  let(:jira_issues) do
176
175
  (1..total_count).map do |i|
177
176
  attributes = fields.merge("id" => i.to_s, "jira_key" => "FOO-#{i}")
178
177
 
179
- Jira::Issue.new(attributes)
178
+ Embulk::Input::Jira::Issue.new(attributes)
180
179
  end
181
180
  end
182
181
 
@@ -206,8 +205,10 @@ describe Embulk::Input::JiraInputPlugin do
206
205
  let(:commit_report) { {} }
207
206
 
208
207
  before do
208
+ allow(org.embulk.spi.Exec).to receive_message_chain(:session, :isPreview).and_return(false)
209
+
209
210
  # TODO: create stubs without each `it` expected
210
- allow(Jira::Api).to receive(:setup).and_return(jira_api)
211
+ allow(Embulk::Input::Jira::Api).to receive(:setup).and_return(jira_api)
211
212
 
212
213
  0.step(total_count, max_result) do |start_at|
213
214
  issues = jira_issues[start_at..(start_at + max_result - 1)]
@@ -235,15 +236,6 @@ describe Embulk::Input::JiraInputPlugin do
235
236
  end
236
237
  end
237
238
 
238
- describe ".version" do
239
- let(:version_file_path) { File.expand_path("../../../../VERSION", __FILE__) }
240
- subject { Embulk::Input::JiraInputPlugin.version }
241
-
242
- it "returns VERSION file content without line-break" do
243
- expect(subject).to eq File.read(version_file_path).strip
244
- end
245
- end
246
-
247
239
  describe ".logger" do
248
240
  let(:logger) { Embulk::Input::JiraInputPlugin.logger }
249
241
 
data/spec/embulk_spec.rb CHANGED
@@ -11,6 +11,7 @@ in:
11
11
  before do
12
12
  config_file.puts config
13
13
  config_file.close
14
+ allow(org.embulk.spi.Exec).to receive_message_chain(:session, :isPreview).and_return(true)
14
15
  end
15
16
 
16
17
  subject {
data/spec/spec_helper.rb CHANGED
@@ -14,6 +14,7 @@ if ENV["COVERAGE"]
14
14
  end
15
15
 
16
16
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
17
+ require "embulk/input/jira"
17
18
 
18
19
  RSpec.configure do |config|
19
20
  config.include StdoutAndErrCapture
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-jira
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - uu59
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-04 00:00:00.000000000 Z
12
+ date: 2015-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement
@@ -110,17 +110,18 @@ files:
110
110
  - LICENSE
111
111
  - README.md
112
112
  - Rakefile
113
- - VERSION
114
113
  - embulk-input-jira.gemspec
115
- - lib/embulk/input/jira-input-plugin-utils.rb
116
114
  - lib/embulk/input/jira.rb
117
- - lib/jira/api.rb
118
- - lib/jira/issue.rb
115
+ - lib/embulk/input/jira/api.rb
116
+ - lib/embulk/input/jira/issue.rb
117
+ - lib/embulk/input/jira/version.rb
118
+ - lib/embulk/input/jira_input_plugin.rb
119
+ - lib/embulk/input/jira_input_plugin_utils.rb
119
120
  - spec/embulk/input/jira-input-plugin-utils_spec.rb
120
- - spec/embulk/input/jira_spec.rb
121
+ - spec/embulk/input/jira/api_spec.rb
122
+ - spec/embulk/input/jira/issue_spec.rb
123
+ - spec/embulk/input/jira_input_plugin_spec.rb
121
124
  - spec/embulk_spec.rb
122
- - spec/jira/issue_spec.rb
123
- - spec/jira_api_spec.rb
124
125
  - spec/spec_helper.rb
125
126
  - spec/support/prepare_embulk.rb
126
127
  - spec/support/stdout_and_err_capture.rb
@@ -150,10 +151,10 @@ specification_version: 4
150
151
  summary: Jira input plugin for Embulk
151
152
  test_files:
152
153
  - spec/embulk/input/jira-input-plugin-utils_spec.rb
153
- - spec/embulk/input/jira_spec.rb
154
+ - spec/embulk/input/jira/api_spec.rb
155
+ - spec/embulk/input/jira/issue_spec.rb
156
+ - spec/embulk/input/jira_input_plugin_spec.rb
154
157
  - spec/embulk_spec.rb
155
- - spec/jira/issue_spec.rb
156
- - spec/jira_api_spec.rb
157
158
  - spec/spec_helper.rb
158
159
  - spec/support/prepare_embulk.rb
159
160
  - spec/support/stdout_and_err_capture.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.2
data/lib/jira/api.rb DELETED
@@ -1,50 +0,0 @@
1
- require "jiralicious"
2
- require "jira/issue"
3
- require "timeout"
4
-
5
- module Jira
6
- class Api
7
- SEARCH_TIMEOUT_SECONDS = 5
8
- SEARCH_ISSUES_TIMEOUT_SECONDS = 60
9
- DEFAULT_SEARCH_RETRY_TIMES = 10
10
-
11
- def self.setup(&block)
12
- Jiralicious.configure(&block)
13
- new
14
- end
15
-
16
- def search_issues(jql, options={})
17
- timeout_and_retry(SEARCH_ISSUES_TIMEOUT_SECONDS) do
18
- search(jql, options).issues.map do |issue|
19
- ::Jira::Issue.new(issue)
20
- end
21
- end
22
- end
23
-
24
- def search(jql, options={})
25
- timeout_and_retry(SEARCH_TIMEOUT_SECONDS) do
26
- Jiralicious.search(jql, options)
27
- end
28
- end
29
-
30
- def total_count(jql)
31
- search(jql, max_results: 1).num_results
32
- end
33
-
34
- private
35
-
36
- def timeout_and_retry(wait, retry_times = DEFAULT_SEARCH_RETRY_TIMES, &block)
37
- count = 1
38
- begin
39
- Timeout.timeout(wait) do
40
- yield
41
- end
42
- rescue Timeout::Error => e
43
- count += 1
44
- sleep count # retry after some seconds for JIRA API perhaps under the overload
45
- raise e if count > retry_times
46
- retry
47
- end
48
- end
49
- end
50
- end
data/lib/jira/issue.rb DELETED
@@ -1,63 +0,0 @@
1
- module Jira
2
- class Issue
3
- attr_reader :id, :key, :fields
4
-
5
- def initialize(attributes)
6
- @id = attributes.fetch("id")
7
-
8
- # https://github.com/dorack/jiralicious/blob/404b7b6d5b7020f42064cf8d7a745ab02057e728/lib/jiralicious/issue.rb#L11-L12
9
- @key = attributes.fetch("jira_key")
10
- @fields = attributes.fetch("fields")
11
- end
12
-
13
- def [](attribute)
14
- case attribute
15
- when "id"
16
- return id
17
- when "key"
18
- return key
19
- end
20
-
21
- chunk = fields
22
- attribute.split('.').each do |key|
23
- chunk = chunk[key]
24
- return chunk if chunk.nil?
25
- end
26
-
27
- if chunk.is_a?(Array) || chunk.is_a?(Hash)
28
- chunk.to_json.to_s
29
- else
30
- chunk
31
- end
32
- end
33
-
34
- def to_record
35
- record = {}
36
-
37
- record["id"] = id
38
- record["key"] = key
39
-
40
- fields.each_pair do |key, value|
41
- record_key = key
42
- record_value = value.to_json.to_s
43
-
44
- case value
45
- when String
46
- record_value = value
47
- when Hash
48
- if value.keys.include?("name")
49
- record_key += ".name"
50
- record_value = value["name"]
51
- elsif value.keys.include?("id")
52
- record_key += ".id"
53
- record_value = value["id"]
54
- end
55
- end
56
-
57
- record[record_key] = record_value
58
- end
59
-
60
- record
61
- end
62
- end
63
- end