embulk-input-jira 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +8 -0
- data/LICENSE +13 -0
- data/README.md +45 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/embulk-input-jira.gemspec +22 -0
- data/lib/embulk/input/jira-input-plugin-utils.rb +36 -0
- data/lib/embulk/input/jira.rb +113 -0
- data/lib/jira/api.rb +25 -0
- data/lib/jira/issue.rb +63 -0
- data/spec/embulk/input/jira-input-plugin-utils_spec.rb +88 -0
- data/spec/embulk/input/jira_spec.rb +247 -0
- data/spec/embulk_spec.rb +30 -0
- data/spec/jira/issue_spec.rb +181 -0
- data/spec/jira_api_spec.rb +92 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/prepare_embulk.rb +12 -0
- data/spec/support/stdout_and_err_capture.rb +32 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c300bb312a6bbf2bfa30a0ed5531e7c3a70a7c4f
|
4
|
+
data.tar.gz: 1cd0319e3794bbde87d9fb82b1d4c9833bb05678
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73cb22cdbf30f9a43b4d3c3a42d3487064581cb56a6af3fc7c4b3dbd4cd700c5c89979126cbc712da38b1ea588bb6ff0d5ad61675c840e62f8694bb67c73d37f
|
7
|
+
data.tar.gz: 5ad6cf1fbcef9d78c22a1b21f03df1818d856f0a3803cf339aaea0ccf4fbb9bb640c8b30100b5993b3c963eea68ab99d5d2af3ba7e6e8a19f31972ddd6aa2dc3
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- jruby-19mode
|
4
|
+
env:
|
5
|
+
global:
|
6
|
+
secure: "NCkU3f60cn5Gmzq+NwDmKdQSq+ApF/rPqSHPirk1+ZPW9n+H9912meUuJr9qyn03MPdc6wAQinsl3skdPNh1Qz02TI/WZGMiCQTLh3nKIMzaaxx6I+OZ1TV7A4MoJMQ7oYQdXdbvRYXpOVRnfVDxpUC+BDk2T8xmjfm9cht+PGTzM6RxpmSL842hiudkcyxHxgEf66EGpi6h2G2PqYNfQrksqiVMWlLiTO5a2ee+iw9qTMhgKrhEKLCb+dFB56gtKIOpd3MxieLwf3PDcsjM+TSaWo6Bp+mjdA3zGJNz5wbWRVSdrIvKvxmf3eRqAGssBhBDO/LUN3LnI+/T/7J9XZZd7WXNudo/t6HQXhJkUIvOucCxSg8/uRsxrMAmF2zkJOnYGSvN3HNqdzyz86TK4/Xckl+gX51b0uYncHfZYSojn4py1RWPYpX/L2RHbzMn1MJ7B3/VZ21vY97aHhDgNyyAMxPnTAuR1IZicEgA8y8AmZkkK9tWq5wvAOKI91V+W8iBEaO2dZIib+KdJSUUj/Q3TM3i4wX9O/AU7tknsnCApvxQeveELJ4SxfFd/Z2imqmQWM0wIgp1u7Vjguf8kSaxcuQHonZNdwvvYOkbYxHvUqltzlmE1qFC/kQe6o9fS3NuiugHCYVeFs+LXVVW+nl0pWztFYMicUmQq7T781w="
|
7
|
+
notifications:
|
8
|
+
slack:
|
9
|
+
secure: QouVFiuH4dTRpjUExfu4NqOYCmt53rmchedTbXqsDXOuLoUbGCMHJgoaYnxJn4Gltqydp8dHXJTE+1hBHZTCGqvO4gng5Z66N7r2DaUk15+mCJPcRl15aMX6J5bXvMp5M7xZYd4AhmB4b3RsdsF4qyH1rf2k9IhakQX09xj1C1OjO3SvMDT/PSQ3cV4mVs4zltYBmNeln9J5rZNexHBg/Mbwz1IqPnR0In5vEUhwBwRc3eo7JoxjBR5/3ffVJcLG1uf9askuW3YacR4XVMYXzFlUErS9QHyugSNTac03YpJmfg8YtY2H1o5ScicwMda3T0nKixHff/Ftkwh7DNsji0edW1WVk+Zt+0P/8ULj/k5gS4uhCERaXNFqRovwqI7is2I1rQFs3TQAQynmXyT0y/jHF0YspTStvuUjSFvuX4P0yaeX39Flih8ZM/js+TkKWjunFsBueqLzcDIjaJ2DFRPi1xDkmwayBhZEpECUE5R19170QsOyIbiG4NFXWWbDIUIapFZKoiohIp46J+NqWYu0Hp/TN6wcqPW7bXVamMma28koM1BLVajW/Ikknqg3Yzf7pzKkRxmoda/fkdfMkr4pqH056YIVKeHKRbrHnfEBArG++HW/T+L8GBW8wH+9fJVeu0G1VsSFH57YARIyO3WF0eqpHB6HHySn2p+DM3Y=
|
10
|
+
jdk:
|
11
|
+
- oraclejdk8
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
source 'https://rubygems.org/'
|
2
|
+
|
3
|
+
# NOTE: Bundler.require(:runtime, :development) in spec_helper that require all dependencies
|
4
|
+
# but require 'embulk' will be failed. so separate it from gemspec ecosystem
|
5
|
+
gem 'embulk', ">= 0.6", "< 1.0"
|
6
|
+
gem "codeclimate-test-reporter", require: nil
|
7
|
+
|
8
|
+
gemspec
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2015 Everyleaf Corporation
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/treasure-data/embulk-input-jira.svg)](https://travis-ci.org/treasure-data/embulk-input-jira)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/treasure-data/embulk-input-jira/badges/gpa.svg)](https://codeclimate.com/github/treasure-data/embulk-input-jira)
|
3
|
+
[![Test Coverage](https://codeclimate.com/github/treasure-data/embulk-input-jira/badges/coverage.svg)](https://codeclimate.com/github/treasure-data/embulk-input-jira/coverage)
|
4
|
+
|
5
|
+
# Jira input plugin for Embulk
|
6
|
+
|
7
|
+
embulk-input-jira is the Embulk input plugin for [JIRA](https://www.atlassian.com/software/jira).
|
8
|
+
|
9
|
+
## Overview
|
10
|
+
|
11
|
+
* **Plugin type**: input
|
12
|
+
* **Resume supported**: no
|
13
|
+
* **Cleanup supported**: no
|
14
|
+
* **Guess supported**: yes
|
15
|
+
|
16
|
+
## Configuration
|
17
|
+
|
18
|
+
- **username** JIRA username (string, required)
|
19
|
+
- **password** JIRA password (string, required)
|
20
|
+
- **uri** JIRA API endpoint (string, required)
|
21
|
+
- **jql** [JQL](https://confluence.atlassian.com/display/JIRA/Advanced+Searching) for extract target issues (string, required)
|
22
|
+
- **columns** target issue attributes. You can generate this configuration by `guess` command (array, required)
|
23
|
+
|
24
|
+
## Example
|
25
|
+
|
26
|
+
```yaml
|
27
|
+
in:
|
28
|
+
type: jira
|
29
|
+
username: USERNAME
|
30
|
+
password: PASSWORD
|
31
|
+
uri: http://localhost:8090
|
32
|
+
jql: project = PRO AND summary~Fix
|
33
|
+
columns:
|
34
|
+
- {name: id, type: long}
|
35
|
+
- {name: key, type: string}
|
36
|
+
- {name: project.name, type: string}
|
37
|
+
- {name: summary, type: string}
|
38
|
+
- {name: assignee.name, type: string}
|
39
|
+
```
|
40
|
+
|
41
|
+
## Build
|
42
|
+
|
43
|
+
```
|
44
|
+
$ bundle exec rake build
|
45
|
+
```
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = "embulk-input-jira"
|
4
|
+
spec.version = File.read(File.expand_path("../VERSION", __FILE__)).strip
|
5
|
+
spec.authors = ["uu59", "yoshihara"]
|
6
|
+
spec.summary = "Jira input plugin for Embulk"
|
7
|
+
spec.description = "Loads records from Jira."
|
8
|
+
spec.email = ["k@uu59.org", "h.yoshihara@everyleaf.com"]
|
9
|
+
spec.licenses = ["Apache2"]
|
10
|
+
spec.homepage = "https://github.com/treasure-data/embulk-input-jira"
|
11
|
+
|
12
|
+
spec.files = `git ls-files`.split("\n") + Dir["classpath/*.jar"]
|
13
|
+
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
14
|
+
spec.require_paths = ["lib"]
|
15
|
+
|
16
|
+
spec.add_dependency 'jiralicious', ['~> 0.5.0']
|
17
|
+
spec.add_development_dependency 'bundler', ['~> 1.0']
|
18
|
+
spec.add_development_dependency 'rake', ['>= 10.0']
|
19
|
+
spec.add_development_dependency 'rspec', "~> 3.2.0"
|
20
|
+
spec.add_development_dependency 'simplecov'
|
21
|
+
spec.add_development_dependency 'pry'
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# This module contains methods for Plugin.
|
2
|
+
|
3
|
+
module Embulk
|
4
|
+
module Input
|
5
|
+
module JiraInputPluginUtils
|
6
|
+
# Guess::SchemaGuess.from_hash_records returns Columns
|
7
|
+
# containing 'index' key, but it is needless.
|
8
|
+
def self.guess_columns(records)
|
9
|
+
schema = Guess::SchemaGuess.from_hash_records(records)
|
10
|
+
|
11
|
+
schema.map do |c|
|
12
|
+
column = {name: c.name, type: c.type}
|
13
|
+
column[:format] = c.format if c.format
|
14
|
+
column
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.cast(value, type)
|
19
|
+
return value if value.nil?
|
20
|
+
|
21
|
+
case type.to_sym
|
22
|
+
when :long
|
23
|
+
Integer(value)
|
24
|
+
when :double
|
25
|
+
Float(value)
|
26
|
+
when :timestamp
|
27
|
+
Time.parse(value)
|
28
|
+
when :boolean
|
29
|
+
!!value
|
30
|
+
else
|
31
|
+
value.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "embulk/input/jira-input-plugin-utils"
|
2
|
+
require "jira/api"
|
3
|
+
|
4
|
+
module Embulk
|
5
|
+
module Input
|
6
|
+
class JiraInputPlugin < InputPlugin
|
7
|
+
PER_PAGE = 50
|
8
|
+
|
9
|
+
Plugin.register_input("jira", self)
|
10
|
+
|
11
|
+
def self.version
|
12
|
+
File.read(File.expand_path("../../../../VERSION", __FILE__)).strip
|
13
|
+
end
|
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)[0..10].map do |issue|
|
64
|
+
issue.to_record
|
65
|
+
end
|
66
|
+
|
67
|
+
columns = JiraInputPluginUtils.guess_columns(records)
|
68
|
+
|
69
|
+
guessed_config = {
|
70
|
+
"username" => username,
|
71
|
+
"password" => password,
|
72
|
+
"uri" => uri,
|
73
|
+
"api_version" => api_version,
|
74
|
+
"auth_type" => auth_type,
|
75
|
+
"columns" => columns,
|
76
|
+
}
|
77
|
+
|
78
|
+
return guessed_config
|
79
|
+
end
|
80
|
+
|
81
|
+
def init
|
82
|
+
@attributes = task["attributes"]
|
83
|
+
@jira = Jira::Api.setup do |config|
|
84
|
+
config.username = task["username"]
|
85
|
+
config.password = task["password"]
|
86
|
+
config.uri = task["uri"]
|
87
|
+
config.api_version = "latest"
|
88
|
+
config.auth_type = :basic
|
89
|
+
end
|
90
|
+
@jql = task["jql"]
|
91
|
+
end
|
92
|
+
|
93
|
+
def run
|
94
|
+
total_count = @jira.total_count(@jql)
|
95
|
+
|
96
|
+
0.step(total_count, PER_PAGE) do |start_at|
|
97
|
+
@jira.search_issues(@jql, start_at: start_at).each do |issue|
|
98
|
+
values = @attributes.map do |(attribute_name, type)|
|
99
|
+
JiraInputPluginUtils.cast(issue[attribute_name], type)
|
100
|
+
end
|
101
|
+
|
102
|
+
page_builder.add(values)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
page_builder.finish
|
107
|
+
|
108
|
+
commit_report = {}
|
109
|
+
return commit_report
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/jira/api.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require "jiralicious"
|
2
|
+
require "jira/issue"
|
3
|
+
|
4
|
+
module Jira
|
5
|
+
class Api
|
6
|
+
def self.setup(&block)
|
7
|
+
Jiralicious.configure(&block)
|
8
|
+
new
|
9
|
+
end
|
10
|
+
|
11
|
+
def search_issues(jql, options={})
|
12
|
+
search(jql, options).issues.map do |issue|
|
13
|
+
::Jira::Issue.new(issue)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def search(jql, options={})
|
18
|
+
Jiralicious.search(jql, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def total_count(jql)
|
22
|
+
search(jql, max_results: 1).num_results
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/jira/issue.rb
ADDED
@@ -0,0 +1,63 @@
|
|
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
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "embulk/input/jira-input-plugin-utils"
|
3
|
+
|
4
|
+
describe Embulk::Input::JiraInputPluginUtils do
|
5
|
+
describe ".guess_columns" do
|
6
|
+
subject do
|
7
|
+
Embulk::Input::JiraInputPluginUtils.guess_columns(records)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:records) do
|
11
|
+
[
|
12
|
+
{"project_key" => "FOO", "comment.total" => 3, "created" => "2015-03-01T00:12:00"}
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:expected) do
|
17
|
+
[
|
18
|
+
{name: "project_key", type: :string},
|
19
|
+
{name: "comment.total", type: :long},
|
20
|
+
{name: "created", type: :timestamp, format: "%Y-%m-%dT%H:%M:%S"}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns Array containing columns without 'index' key from each record" do
|
25
|
+
expect(subject).to eq expected
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".cast" do
|
30
|
+
subject do
|
31
|
+
Embulk::Input::JiraInputPluginUtils.cast(value, type)
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when value is nil" do
|
35
|
+
let(:value) { nil }
|
36
|
+
let(:type) { :string }
|
37
|
+
|
38
|
+
it "returns nil" do
|
39
|
+
expect(subject).to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when value is not nil" do
|
44
|
+
let(:value) { 123 }
|
45
|
+
|
46
|
+
context "and type is :string" do
|
47
|
+
let(:type) { :string }
|
48
|
+
|
49
|
+
it "returns '123'" do
|
50
|
+
expect(subject).to eq "123"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "and type is :long" do
|
55
|
+
let(:type) { :long }
|
56
|
+
|
57
|
+
it "returns 123" do
|
58
|
+
expect(subject).to eq 123
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "and type is :double" do
|
63
|
+
let(:type) { :double }
|
64
|
+
|
65
|
+
it "returns 123.0" do
|
66
|
+
expect(subject).to eq 123.0
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "and type is :timestamp" do
|
71
|
+
let(:value) { "2015-03-01T00:12:00" }
|
72
|
+
let(:type) { :timestamp }
|
73
|
+
|
74
|
+
it "returns Time object" do
|
75
|
+
expect(subject).to eq Time.new(2015, 3, 1, 0, 12, 0)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "and type is :boolean" do
|
80
|
+
let(:type) { :boolean }
|
81
|
+
|
82
|
+
it "returns true" do
|
83
|
+
expect(subject).to be true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "embulk/input/jira"
|
3
|
+
|
4
|
+
describe Embulk::Input::JiraInputPlugin do
|
5
|
+
let(:username) { "jira-user" }
|
6
|
+
let(:password) { "password" }
|
7
|
+
let(:uri) { "http://jira.example/" }
|
8
|
+
let(:jql) { "PROJECT=#{project_name}" }
|
9
|
+
let(:project_name) { "FOO" }
|
10
|
+
|
11
|
+
describe ".transaction" do
|
12
|
+
subject { Embulk::Input::JiraInputPlugin.transaction(config, &control) }
|
13
|
+
|
14
|
+
let(:config) { Object.new } # add mock later
|
15
|
+
let(:control) { Proc.new{|task, columns, count| } } # do nothing
|
16
|
+
|
17
|
+
let(:task) do
|
18
|
+
{
|
19
|
+
"username" => username,
|
20
|
+
"password" => password,
|
21
|
+
"uri" => uri,
|
22
|
+
"jql" => jql,
|
23
|
+
"attributes" => {
|
24
|
+
"project.key" => :string,
|
25
|
+
"comment.total" => :long
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:columns) do
|
31
|
+
[
|
32
|
+
{"name" => "project.key", "type" => "string"},
|
33
|
+
{"name" => "comment.total", "type" => "long"}
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:column_structs) do
|
38
|
+
[
|
39
|
+
Embulk::Column.new(nil, "project.key", :string),
|
40
|
+
Embulk::Column.new(nil, "comment.total", :long)
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
allow(config).to receive(:param).with("username", :string).and_return(username)
|
46
|
+
allow(config).to receive(:param).with("password", :string).and_return(password)
|
47
|
+
allow(config).to receive(:param).with("uri", :string).and_return(uri)
|
48
|
+
allow(config).to receive(:param).with("jql", :string).and_return(jql)
|
49
|
+
allow(config).to receive(:param).with("columns", :array).and_return(columns)
|
50
|
+
end
|
51
|
+
|
52
|
+
# NOTE: I should check other factor, but i don't know it...
|
53
|
+
it "calls .resume method with proper parameters" do
|
54
|
+
expect(Embulk::Input::JiraInputPlugin).to receive(:resume).with(task, column_structs, 1, &control)
|
55
|
+
subject
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe ".resume" do
|
60
|
+
subject { Embulk::Input::JiraInputPlugin.resume(task, columns, count, &control) }
|
61
|
+
|
62
|
+
let(:task) do
|
63
|
+
{
|
64
|
+
"username" => username,
|
65
|
+
"password" => password,
|
66
|
+
"uri" => uri,
|
67
|
+
"jql" => jql,
|
68
|
+
"attributes" => {
|
69
|
+
"project.key" => :string,
|
70
|
+
"comment.total" => :long
|
71
|
+
}
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:columns) do
|
76
|
+
[
|
77
|
+
Embulk::Column.new(nil, "project.key", :string),
|
78
|
+
Embulk::Column.new(nil, "comment.total", :long)
|
79
|
+
]
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:count) { 1 }
|
83
|
+
let(:control) { Proc.new{|task, columns, count| } } # do nothing
|
84
|
+
|
85
|
+
let(:next_config_diff) { {} }
|
86
|
+
|
87
|
+
it "returns next_config_diff" do
|
88
|
+
expect(subject).to eq next_config_diff
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe ".guess" do
|
93
|
+
subject { Embulk::Input::JiraInputPlugin.guess(config) }
|
94
|
+
|
95
|
+
let(:config) { Object.new } # add mock later
|
96
|
+
|
97
|
+
let(:jira_api) { Jira::Api.new }
|
98
|
+
let(:jira_issues) { [Jira::Issue.new(attributes)] }
|
99
|
+
let(:attributes) do
|
100
|
+
{
|
101
|
+
"id" => "100",
|
102
|
+
"jira_key" => "FOO-100",
|
103
|
+
"fields" =>
|
104
|
+
{
|
105
|
+
"project" => {
|
106
|
+
"name" => project_name,
|
107
|
+
"key" => project_name,
|
108
|
+
},
|
109
|
+
"comment" => {
|
110
|
+
"total" => 0,
|
111
|
+
"comments" => []
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
let(:guessed_config) do
|
118
|
+
{
|
119
|
+
"username" => username,
|
120
|
+
"password" => password,
|
121
|
+
"uri" => uri,
|
122
|
+
"api_version" => "latest",
|
123
|
+
"auth_type" => "basic",
|
124
|
+
"columns" => [
|
125
|
+
{name: "id", type: :long},
|
126
|
+
{name: "key", type: :string},
|
127
|
+
{name: "project.name", type: :string},
|
128
|
+
{name: "comment", type: :string}
|
129
|
+
]
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
before do
|
134
|
+
allow(jira_api).to receive(:search_issues).and_return(jira_issues)
|
135
|
+
|
136
|
+
allow(config).to receive(:param).with("username", :string).and_return(username)
|
137
|
+
allow(config).to receive(:param).with("password", :string).and_return(password)
|
138
|
+
allow(config).to receive(:param).with("uri", :string).and_return(uri)
|
139
|
+
allow(config).to receive(:param).with("jql", :string).and_return(jql)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "setup Jira::Api" do
|
143
|
+
expect(Jira::Api).to receive(:setup).and_return(jira_api)
|
144
|
+
subject
|
145
|
+
end
|
146
|
+
|
147
|
+
it "returns guessed config" do
|
148
|
+
allow(Jira::Api).to receive(:setup).and_return(jira_api)
|
149
|
+
|
150
|
+
expect(subject).to eq guessed_config
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#init (.new)" do
|
155
|
+
# NOTE: InputPlugin.initialize calls #init method.
|
156
|
+
|
157
|
+
subject { Embulk::Input::JiraInputPlugin.new({}, nil, nil, nil) }
|
158
|
+
|
159
|
+
it "setup Jira::Api" do
|
160
|
+
expect(Jira::Api).to receive(:setup)
|
161
|
+
subject
|
162
|
+
end
|
163
|
+
|
164
|
+
it "is a Embulk::InputPlugin" do
|
165
|
+
allow(Jira::Api).to receive(:setup)
|
166
|
+
expect(subject).to be_a(Embulk::InputPlugin)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "#run" do
|
171
|
+
subject do
|
172
|
+
Embulk::Input::JiraInputPlugin.new(task, nil, nil, page_builder).run
|
173
|
+
end
|
174
|
+
|
175
|
+
let(:jira_api) { Jira::Api.new }
|
176
|
+
let(:jira_issues) do
|
177
|
+
(1..total_count).map do |i|
|
178
|
+
attributes = fields.merge("id" => i.to_s, "jira_key" => "FOO-#{i}")
|
179
|
+
|
180
|
+
Jira::Issue.new(attributes)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
let(:total_count) { max_result + 10 }
|
185
|
+
let(:max_result) { Embulk::Input::JiraInputPlugin::PER_PAGE }
|
186
|
+
|
187
|
+
|
188
|
+
let(:page_builder) { Object.new } # add mock later
|
189
|
+
let(:task) do
|
190
|
+
{
|
191
|
+
"jql" => jql,
|
192
|
+
"attributes" => {"project.key" => "string"}
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
let(:fields) do
|
197
|
+
{
|
198
|
+
"fields" =>
|
199
|
+
{
|
200
|
+
"project" => {
|
201
|
+
"key" => project_name,
|
202
|
+
},
|
203
|
+
}
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
207
|
+
let(:commit_report) { {} }
|
208
|
+
|
209
|
+
before do
|
210
|
+
# TODO: create stubs without each `it` expected
|
211
|
+
allow(Jira::Api).to receive(:setup).and_return(jira_api)
|
212
|
+
|
213
|
+
0.step(total_count, max_result) do |start_at|
|
214
|
+
issues = jira_issues[start_at..(start_at + max_result - 1)]
|
215
|
+
allow(jira_api).to receive(:search_issues).with(jql, start_at: start_at).and_return(issues)
|
216
|
+
end
|
217
|
+
allow(jira_api).to receive(:total_count).and_return(total_count)
|
218
|
+
|
219
|
+
allow(page_builder).to receive(:add).with([project_name])
|
220
|
+
allow(page_builder).to receive(:finish)
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'search JIRA issues' do
|
224
|
+
expect(jira_api).to receive(:search_issues)
|
225
|
+
subject
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'page build and finish' do
|
229
|
+
expect(page_builder).to receive(:add).with([project_name]).exactly(total_count).times
|
230
|
+
expect(page_builder).to receive(:finish)
|
231
|
+
subject
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'returns commit report' do
|
235
|
+
expect(subject).to eq commit_report
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe ".version" do
|
240
|
+
let(:version_file_path) { File.expand_path("../../../../VERSION", __FILE__) }
|
241
|
+
subject { Embulk::Input::JiraInputPlugin.version }
|
242
|
+
|
243
|
+
it "returns VERSION file content without line-break" do
|
244
|
+
expect(subject).to eq File.read(version_file_path).strip
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
data/spec/embulk_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Embulk do
|
4
|
+
describe "registerd jira as input plugin" do
|
5
|
+
let(:config) { <<-YAML }
|
6
|
+
in:
|
7
|
+
type: jira
|
8
|
+
YAML
|
9
|
+
let(:config_file) { Tempfile.new("embulk-conf") }
|
10
|
+
|
11
|
+
before do
|
12
|
+
config_file.puts config
|
13
|
+
config_file.close
|
14
|
+
end
|
15
|
+
|
16
|
+
subject {
|
17
|
+
capture_output(:out) do
|
18
|
+
Embulk.run ["preview", config_file.path]
|
19
|
+
end
|
20
|
+
}
|
21
|
+
|
22
|
+
it do
|
23
|
+
# NOTE: can't stub `exit` so stubbing `raise`
|
24
|
+
# https://github.com/embulk/embulk/blob/v0.6.9/lib/embulk/command/embulk_run.rb#L335
|
25
|
+
allow(Embulk).to receive(:raise)
|
26
|
+
|
27
|
+
is_expected.to_not include("InputPlugin 'jira' is not found.")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "jira/issue"
|
3
|
+
|
4
|
+
describe Jira::Issue do
|
5
|
+
describe ".initialize" do
|
6
|
+
context "when argument has 'fields' key" do
|
7
|
+
let(:issue_attributes) do
|
8
|
+
{
|
9
|
+
"id" => 1,
|
10
|
+
"jira_key" => "PRO-1",
|
11
|
+
"fields" =>
|
12
|
+
{
|
13
|
+
"summary" => "jira issue",
|
14
|
+
"project" =>
|
15
|
+
{
|
16
|
+
"key" => "FOO",
|
17
|
+
},
|
18
|
+
}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
it "has @id with argument['id']" do
|
23
|
+
expect(Jira::Issue.new(issue_attributes).id).to eq issue_attributes["id"]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "has @key with argument['jira_key']" do
|
27
|
+
expect(Jira::Issue.new(issue_attributes).key).to eq issue_attributes["jira_key"]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "has @fields with argument['fields']" do
|
31
|
+
expect(Jira::Issue.new(issue_attributes).fields).to eq issue_attributes["fields"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when argument doesn't have 'fields' key" do
|
36
|
+
let(:issue_attributes) do
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises error" do
|
41
|
+
expect { Jira::Issue.new(issue_attributes) }.to raise_error
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#[]" do
|
47
|
+
subject { Jira::Issue.new(issue_attributes)[attribute_name] }
|
48
|
+
|
49
|
+
let(:issue_attributes) do
|
50
|
+
{
|
51
|
+
"id" => "1",
|
52
|
+
"jira_key" => "FOO-1",
|
53
|
+
"fields" => {
|
54
|
+
"summary" => "jira issue",
|
55
|
+
"project" => project_attribute,
|
56
|
+
"labels" =>
|
57
|
+
[
|
58
|
+
"Feature",
|
59
|
+
"WantTo"
|
60
|
+
],
|
61
|
+
"priority" => {
|
62
|
+
"iconUrl" => "https://jira-api/images/icon.png",
|
63
|
+
"name" => "Must",
|
64
|
+
"id" => "1"
|
65
|
+
},
|
66
|
+
"customfield_1" => nil,
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:project_attribute) do
|
72
|
+
{
|
73
|
+
"key" => "FOO",
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'id' do
|
78
|
+
let(:attribute_name) { 'id' }
|
79
|
+
|
80
|
+
it "returns issue id" do
|
81
|
+
expect(subject).to eq "1"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'key' do
|
86
|
+
let(:attribute_name) { 'key' }
|
87
|
+
|
88
|
+
it "returns issue key" do
|
89
|
+
expect(subject).to eq "FOO-1"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'summary' do
|
94
|
+
let(:attribute_name) { 'summary' }
|
95
|
+
|
96
|
+
it "returns issue summary" do
|
97
|
+
expect(subject).to eq 'jira issue'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'project.key' do
|
102
|
+
let(:attribute_name) { 'project.key' }
|
103
|
+
|
104
|
+
context "when project is not nil" do
|
105
|
+
it "returns issue's project key" do
|
106
|
+
expect(subject).to eq 'FOO'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when project is nil" do
|
111
|
+
let(:project_attribute) { nil }
|
112
|
+
|
113
|
+
it "returns nil" do
|
114
|
+
expect(subject).to be_nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'labels' do
|
120
|
+
let(:attribute_name) { 'labels' }
|
121
|
+
|
122
|
+
it "returns issue's labels JSON string" do
|
123
|
+
expect(subject).to eq '["Feature","WantTo"]'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'priority' do
|
128
|
+
let(:attribute_name) { 'priority' }
|
129
|
+
|
130
|
+
it "returns issue's priority JSON string" do
|
131
|
+
expect(subject).to eq '{"iconUrl":"https://jira-api/images/icon.png","name":"Must","id":"1"}'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#to_record" do
|
137
|
+
subject do
|
138
|
+
Jira::Issue.new(issue_attributes).to_record
|
139
|
+
end
|
140
|
+
|
141
|
+
let(:issue_attributes) do
|
142
|
+
{
|
143
|
+
"id" => 1,
|
144
|
+
"jira_key" => "FOO-1",
|
145
|
+
"fields" => {
|
146
|
+
"summary" => "jira issue",
|
147
|
+
"project" => {
|
148
|
+
"id" => "FOO",
|
149
|
+
},
|
150
|
+
"labels" =>
|
151
|
+
[
|
152
|
+
"Feature",
|
153
|
+
"WantTo"
|
154
|
+
],
|
155
|
+
"priority" => {
|
156
|
+
"iconUrl" => "https://jira-api/images/icon.png",
|
157
|
+
"name" => "Must",
|
158
|
+
"id" => "1"
|
159
|
+
},
|
160
|
+
"customfield_1" => nil,
|
161
|
+
}
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
let(:expected) do
|
166
|
+
{
|
167
|
+
"id" => 1,
|
168
|
+
"key" => "FOO-1",
|
169
|
+
"summary" => "jira issue",
|
170
|
+
"project.id" => "FOO",
|
171
|
+
"labels" => "[\"Feature\",\"WantTo\"]",
|
172
|
+
"priority.name" => "Must",
|
173
|
+
"customfield_1" => "null"
|
174
|
+
}
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'return guessed record' do
|
178
|
+
expect(subject).to eq expected
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# TODO: move to spec/jira/api_spec.rb
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "jira/api"
|
5
|
+
|
6
|
+
describe Jira::Api do
|
7
|
+
describe ".setup" do
|
8
|
+
subject { Jira::Api.setup {} }
|
9
|
+
|
10
|
+
it "returns Jira::Api instance" do
|
11
|
+
expect(subject.is_a?(Jira::Api)).to be_truthy
|
12
|
+
end
|
13
|
+
|
14
|
+
it "calls Jiralicious.configure" do
|
15
|
+
allow(Jiralicious).to receive(:configure)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#search" do
|
20
|
+
let(:jql) { "project=FOO" }
|
21
|
+
|
22
|
+
subject { Jira::Api.new.search(jql) }
|
23
|
+
|
24
|
+
it do
|
25
|
+
allow(Jiralicious).to receive(:search).with(jql)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#search_issues" do
|
30
|
+
let(:jql) { "project=FOO" }
|
31
|
+
let(:results) do
|
32
|
+
[
|
33
|
+
{
|
34
|
+
"id" => 1,
|
35
|
+
"jira_key" => "FOO-1",
|
36
|
+
"fields" =>
|
37
|
+
{
|
38
|
+
"summary" => "issue summary",
|
39
|
+
"project" =>
|
40
|
+
{
|
41
|
+
"key" => "FOO"
|
42
|
+
}
|
43
|
+
}
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"id" => 2,
|
47
|
+
"jira_key" => "FOO-2",
|
48
|
+
"fields" =>
|
49
|
+
{
|
50
|
+
"summary" => "jira issue",
|
51
|
+
"project" =>
|
52
|
+
{
|
53
|
+
"key" => "FOO"
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
subject { Jira::Api.new.search_issues(jql) }
|
61
|
+
|
62
|
+
it do
|
63
|
+
allow(Jiralicious).to receive_message_chain(:search, :issues).and_return(results)
|
64
|
+
|
65
|
+
expect(subject).to be_kind_of Array
|
66
|
+
expect(subject.map(&:class)).to match_array [Jira::Issue, Jira::Issue]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#total_count" do
|
71
|
+
subject { jira_api.total_count(jql) }
|
72
|
+
|
73
|
+
let(:jira_api) { Jira::Api.new }
|
74
|
+
let(:jql) { "project=FOO" }
|
75
|
+
let(:results) { Object.new } # add mock later
|
76
|
+
let(:results_count) { 5 }
|
77
|
+
|
78
|
+
before do
|
79
|
+
allow(results).to receive(:num_results).and_return(results_count)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "calls Jira::Api#search with proper arguments" do
|
83
|
+
expect(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
|
84
|
+
subject
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns issues count" do
|
88
|
+
allow(jira_api).to receive(:search).with(jql, max_results: 1).and_return(results)
|
89
|
+
expect(subject).to eq results_count
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
Bundler.require(:runtime, :development)
|
4
|
+
require "codeclimate-test-reporter"
|
5
|
+
CodeClimate::TestReporter.start
|
6
|
+
|
7
|
+
require "embulk/command/embulk_run"
|
8
|
+
|
9
|
+
Dir["./spec/support/**/*.rb"].each{|file| require file }
|
10
|
+
|
11
|
+
if ENV["COVERAGE"]
|
12
|
+
require "simplecov"
|
13
|
+
SimpleCov.start
|
14
|
+
end
|
15
|
+
|
16
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.include StdoutAndErrCapture
|
20
|
+
config.include PrepareEmbulk
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module PrepareEmbulk
|
2
|
+
require "embulk/command/embulk_run"
|
3
|
+
|
4
|
+
classpath_dir = Embulk.home("classpath")
|
5
|
+
jars = Dir.entries(classpath_dir).select{|f| f =~ /\.jar$/ }.sort
|
6
|
+
jars.each do |jar|
|
7
|
+
require File.join(classpath_dir, jar)
|
8
|
+
end
|
9
|
+
require "embulk/java/bootstrap"
|
10
|
+
|
11
|
+
require "embulk"
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module StdoutAndErrCapture
|
2
|
+
def capture_output(output = :out, &block)
|
3
|
+
java_import 'java.io.PrintStream'
|
4
|
+
java_import 'java.io.ByteArrayOutputStream'
|
5
|
+
java_import 'java.lang.System'
|
6
|
+
|
7
|
+
ruby_original_stream = output == :out ? $stdout.dup : $stderr.dup
|
8
|
+
java_original_stream = System.send(output) # :out or :err
|
9
|
+
ruby_buf = StringIO.new
|
10
|
+
java_buf = ByteArrayOutputStream.new
|
11
|
+
|
12
|
+
case output
|
13
|
+
when :out
|
14
|
+
$stdout = ruby_buf
|
15
|
+
when :err
|
16
|
+
$stderr = ruby_buf
|
17
|
+
end
|
18
|
+
System.setOut(PrintStream.new(java_buf))
|
19
|
+
|
20
|
+
block.call
|
21
|
+
|
22
|
+
ruby_buf.string + java_buf.toString
|
23
|
+
ensure
|
24
|
+
System.setOut(java_original_stream)
|
25
|
+
case output
|
26
|
+
when :out
|
27
|
+
$stdout = ruby_original_stream
|
28
|
+
when :err
|
29
|
+
$stderr = ruby_original_stream
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: embulk-input-jira
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- uu59
|
8
|
+
- yoshihara
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-05-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.5.0
|
20
|
+
name: jiralicious
|
21
|
+
prerelease: false
|
22
|
+
type: :runtime
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.5.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
name: bundler
|
35
|
+
prerelease: false
|
36
|
+
type: :development
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
name: rake
|
49
|
+
prerelease: false
|
50
|
+
type: :development
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '10.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.2.0
|
62
|
+
name: rspec
|
63
|
+
prerelease: false
|
64
|
+
type: :development
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 3.2.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
name: simplecov
|
77
|
+
prerelease: false
|
78
|
+
type: :development
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
name: pry
|
91
|
+
prerelease: false
|
92
|
+
type: :development
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
description: Loads records from Jira.
|
99
|
+
email:
|
100
|
+
- k@uu59.org
|
101
|
+
- h.yoshihara@everyleaf.com
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- .gitignore
|
107
|
+
- .travis.yml
|
108
|
+
- CHANGELOG.md
|
109
|
+
- Gemfile
|
110
|
+
- LICENSE
|
111
|
+
- README.md
|
112
|
+
- Rakefile
|
113
|
+
- VERSION
|
114
|
+
- embulk-input-jira.gemspec
|
115
|
+
- lib/embulk/input/jira-input-plugin-utils.rb
|
116
|
+
- lib/embulk/input/jira.rb
|
117
|
+
- lib/jira/api.rb
|
118
|
+
- lib/jira/issue.rb
|
119
|
+
- spec/embulk/input/jira-input-plugin-utils_spec.rb
|
120
|
+
- spec/embulk/input/jira_spec.rb
|
121
|
+
- spec/embulk_spec.rb
|
122
|
+
- spec/jira/issue_spec.rb
|
123
|
+
- spec/jira_api_spec.rb
|
124
|
+
- spec/spec_helper.rb
|
125
|
+
- spec/support/prepare_embulk.rb
|
126
|
+
- spec/support/stdout_and_err_capture.rb
|
127
|
+
homepage: https://github.com/treasure-data/embulk-input-jira
|
128
|
+
licenses:
|
129
|
+
- Apache2
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.4.6
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: Jira input plugin for Embulk
|
151
|
+
test_files:
|
152
|
+
- spec/embulk/input/jira-input-plugin-utils_spec.rb
|
153
|
+
- spec/embulk/input/jira_spec.rb
|
154
|
+
- spec/embulk_spec.rb
|
155
|
+
- spec/jira/issue_spec.rb
|
156
|
+
- spec/jira_api_spec.rb
|
157
|
+
- spec/spec_helper.rb
|
158
|
+
- spec/support/prepare_embulk.rb
|
159
|
+
- spec/support/stdout_and_err_capture.rb
|