embulk-input-jira 0.0.1 → 0.0.2

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: c300bb312a6bbf2bfa30a0ed5531e7c3a70a7c4f
4
- data.tar.gz: 1cd0319e3794bbde87d9fb82b1d4c9833bb05678
3
+ metadata.gz: c37d6bfba4c1f808f3911a222698a62e87b1a6ec
4
+ data.tar.gz: 4348bce6dd5c2c293e090396f8375c4a520830cd
5
5
  SHA512:
6
- metadata.gz: 73cb22cdbf30f9a43b4d3c3a42d3487064581cb56a6af3fc7c4b3dbd4cd700c5c89979126cbc712da38b1ea588bb6ff0d5ad61675c840e62f8694bb67c73d37f
7
- data.tar.gz: 5ad6cf1fbcef9d78c22a1b21f03df1818d856f0a3803cf339aaea0ccf4fbb9bb640c8b30100b5993b3c963eea68ab99d5d2af3ba7e6e8a19f31972ddd6aa2dc3
6
+ metadata.gz: e383256cdde3bb1623a7777ff4eb811842a8fb1a37a26ea8319a6c9e8f3d7ab5f9ec572b2ee55e7e648c4d923ede50655ea36b14ab3c411488b29bd6b5951923
7
+ data.tar.gz: 91d53c2b6ebf59b2ee8dd0888da96360c592b2b56be0349caae291dc8874fac2ed61bfab7778e1a666a410b250a4f99c4db9191bf907161eb912fcae495d3d70
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
- ## 0.0.1 (2015-05-28)
1
+ ## 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)
4
+ * [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)
6
+
7
+ ## 0.0.1 - 2015-05-28
2
8
 
3
9
  The first release!!
data/Rakefile CHANGED
@@ -1,5 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
2
  require 'rspec/core/rake_task'
3
+ require "json"
4
+ require "pathname"
5
+ require "open-uri"
6
+
3
7
 
4
8
  task default: :spec
5
9
 
@@ -7,3 +11,51 @@ desc "Run all examples"
7
11
  RSpec::Core::RakeTask.new(:spec) do |t|
8
12
  t.rspec_opts = %w[--color]
9
13
  end
14
+
15
+ namespace :release do
16
+ desc "Add header of now version release to ChangeLog and bump up version"
17
+ task :prepare do
18
+ root_dir = Pathname.new(File.expand_path("../", __FILE__))
19
+ version_file = root_dir.join("VERSION")
20
+ changelog_file = root_dir.join("CHANGELOG.md")
21
+
22
+ system("git fetch origin")
23
+
24
+ # detect merged PR
25
+ old_version = version_file.read.strip
26
+ pr_numbers = `git log v#{old_version}..origin/master --oneline`.scan(/#[0-9]+/)
27
+
28
+ if !$?.success? || pr_numbers.empty?
29
+ puts "Detecting PR failed. Please confirm if any PR were merged after the latest release."
30
+ exit(false)
31
+ end
32
+
33
+ # Generate new version
34
+ major, minor, patch = old_version.split(".").map(&:to_i)
35
+ new_version = "#{major}.#{minor}.#{patch + 1}"
36
+
37
+ # Update ChangeLog
38
+ pr_descriptions = pr_numbers.map do |number|
39
+ body = open("https://api.github.com/repos/treasure-data/embulk-input-jira/issues/#{number.gsub("#", "")}").read
40
+ payload = JSON.parse(body)
41
+ "* [] #{payload["title"]} [#{number}](https://github.com/treasure-data/embulk-input-jira/pull/#{number.gsub('#', '')}) "
42
+ end.join("\n")
43
+
44
+ new_changelog = <<-HEADER
45
+ ## #{new_version} - #{Time.now.strftime("%Y-%m-%d")}
46
+ #{pr_descriptions}
47
+
48
+ #{changelog_file.read.chomp}
49
+ HEADER
50
+
51
+ File.open(changelog_file, "w") {|f| f.write(new_changelog) }
52
+
53
+ # Update version.rb
54
+ File.open(version_file, "w") {|f| f.write new_version }
55
+
56
+ # Update Gemfile.lock
57
+ system("bundle install")
58
+
59
+ puts "ChangeLog, version and Gemfile.lock were updated. New version is #{new_version}."
60
+ end
61
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -1,5 +1,7 @@
1
1
  require "embulk/input/jira-input-plugin-utils"
2
2
  require "jira/api"
3
+ require "logger"
4
+ require "time"
3
5
 
4
6
  module Embulk
5
7
  module Input
@@ -67,11 +69,6 @@ module Embulk
67
69
  columns = JiraInputPluginUtils.guess_columns(records)
68
70
 
69
71
  guessed_config = {
70
- "username" => username,
71
- "password" => password,
72
- "uri" => uri,
73
- "api_version" => api_version,
74
- "auth_type" => auth_type,
75
72
  "columns" => columns,
76
73
  }
77
74
 
@@ -92,8 +89,10 @@ module Embulk
92
89
 
93
90
  def run
94
91
  total_count = @jira.total_count(@jql)
92
+ last_page = (total_count.to_f / PER_PAGE).ceil
95
93
 
96
- 0.step(total_count, PER_PAGE) do |start_at|
94
+ 0.step(total_count, PER_PAGE).with_index(1) do |start_at, page|
95
+ logger.debug "Fetching #{page} / #{last_page} page"
97
96
  @jira.search_issues(@jql, start_at: start_at).each do |issue|
98
97
  values = @attributes.map do |(attribute_name, type)|
99
98
  JiraInputPluginUtils.cast(issue[attribute_name], type)
@@ -108,6 +107,21 @@ module Embulk
108
107
  commit_report = {}
109
108
  return commit_report
110
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
111
125
  end
112
126
  end
113
127
  end
data/lib/jira/api.rb CHANGED
@@ -1,25 +1,50 @@
1
1
  require "jiralicious"
2
2
  require "jira/issue"
3
+ require "timeout"
3
4
 
4
5
  module Jira
5
6
  class Api
7
+ SEARCH_TIMEOUT_SECONDS = 5
8
+ SEARCH_ISSUES_TIMEOUT_SECONDS = 60
9
+ DEFAULT_SEARCH_RETRY_TIMES = 10
10
+
6
11
  def self.setup(&block)
7
12
  Jiralicious.configure(&block)
8
13
  new
9
14
  end
10
15
 
11
16
  def search_issues(jql, options={})
12
- search(jql, options).issues.map do |issue|
13
- ::Jira::Issue.new(issue)
17
+ timeout_and_retry(SEARCH_ISSUES_TIMEOUT_SECONDS) do
18
+ search(jql, options).issues.map do |issue|
19
+ ::Jira::Issue.new(issue)
20
+ end
14
21
  end
15
22
  end
16
23
 
17
24
  def search(jql, options={})
18
- Jiralicious.search(jql, options)
25
+ timeout_and_retry(SEARCH_TIMEOUT_SECONDS) do
26
+ Jiralicious.search(jql, options)
27
+ end
19
28
  end
20
29
 
21
30
  def total_count(jql)
22
31
  search(jql, max_results: 1).num_results
23
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
24
49
  end
25
50
  end
@@ -116,11 +116,6 @@ describe Embulk::Input::JiraInputPlugin do
116
116
 
117
117
  let(:guessed_config) do
118
118
  {
119
- "username" => username,
120
- "password" => password,
121
- "uri" => uri,
122
- "api_version" => "latest",
123
- "auth_type" => "basic",
124
119
  "columns" => [
125
120
  {name: "id", type: :long},
126
121
  {name: "key", type: :string},
@@ -169,7 +164,11 @@ describe Embulk::Input::JiraInputPlugin do
169
164
 
170
165
  describe "#run" do
171
166
  subject do
172
- Embulk::Input::JiraInputPlugin.new(task, nil, nil, page_builder).run
167
+ result = nil
168
+ capture_output(:out) do
169
+ result = Embulk::Input::JiraInputPlugin.new(task, nil, nil, page_builder).run
170
+ end
171
+ result
173
172
  end
174
173
 
175
174
  let(:jira_api) { Jira::Api.new }
@@ -244,4 +243,21 @@ describe Embulk::Input::JiraInputPlugin do
244
243
  expect(subject).to eq File.read(version_file_path).strip
245
244
  end
246
245
  end
246
+
247
+ describe ".logger" do
248
+ let(:logger) { Embulk::Input::JiraInputPlugin.logger }
249
+
250
+ subject { logger }
251
+
252
+ it { is_expected.to be_a(Logger) }
253
+ end
254
+
255
+ describe "#logger" do
256
+ let(:instance) { Embulk::Input::JiraInputPlugin.new({}, nil, nil, nil) }
257
+ let(:logger) { instance.logger }
258
+
259
+ subject { logger }
260
+
261
+ it { is_expected.to be_a(Logger) }
262
+ end
247
263
  end
@@ -18,12 +18,25 @@ describe Jira::Api do
18
18
 
19
19
  describe "#search" do
20
20
  let(:jql) { "project=FOO" }
21
+ let(:api) { Jira::Api.new }
21
22
 
22
- subject { Jira::Api.new.search(jql) }
23
+ subject { api.search(jql) }
23
24
 
24
25
  it do
25
26
  allow(Jiralicious).to receive(:search).with(jql)
26
27
  end
28
+
29
+ describe "retry and timeout" do
30
+ before do
31
+ allow(Timeout).to receive(:timeout) { raise Timeout::Error }
32
+ allow(api).to receive(:sleep)
33
+ end
34
+
35
+ it "retry DEFAULT_SEARCH_RETRY_TIMES times then raise error" do
36
+ expect(Timeout).to receive(:timeout).exactly(Jira::Api::DEFAULT_SEARCH_RETRY_TIMES)
37
+ expect { subject }.to raise_error
38
+ end
39
+ end
27
40
  end
28
41
 
29
42
  describe "#search_issues" do
@@ -89,4 +102,28 @@ describe Jira::Api do
89
102
  expect(subject).to eq results_count
90
103
  end
91
104
  end
105
+
106
+ describe "#timeout_and_retry" do
107
+ let(:wait) { 1 }
108
+ let(:retry_times) { 3 }
109
+ let(:jira_api) { Jira::Api.new }
110
+ let(:block) { proc{ "it works" } }
111
+
112
+ subject { jira_api.send(:timeout_and_retry, wait, retry_times, &block) }
113
+
114
+ before do
115
+ allow(jira_api).to receive(:sleep)
116
+ end
117
+
118
+ it "return given block result if timeout is not occured" do
119
+ expect(subject).to eq block.call
120
+ end
121
+
122
+ it "Always timeout, raise error after N times retry" do
123
+ allow(Timeout).to receive(:timeout) { raise Timeout::Error }
124
+
125
+ expect(Timeout).to receive(:timeout).with(wait).exactly(retry_times).times
126
+ expect { subject }.to raise_error(Timeout::Error)
127
+ end
128
+ end
92
129
  end
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.1
4
+ version: 0.0.2
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-05-28 00:00:00.000000000 Z
12
+ date: 2015-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement