nine-redmine-client 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -0
- data/README.md +30 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/bin/nine-redmine-client +23 -0
- data/gemfiles/activesupport-4.0.gemfile +5 -0
- data/gemfiles/activesupport-4.1.gemfile +6 -0
- data/gemfiles/activesupport-4.2.gemfile +6 -0
- data/lib/nine-redmine-client.rb +1 -0
- data/lib/redmine_client.rb +9 -0
- data/lib/redmine_client/api.rb +21 -0
- data/lib/redmine_client/base.rb +81 -0
- data/lib/redmine_client/errors.rb +31 -0
- data/lib/redmine_client/issue.rb +12 -0
- data/nine-redmine-client.gemspec +26 -0
- data/spec/redmine_client/base_spec.rb +96 -0
- data/spec/redmine_client/issue_spec.rb +15 -0
- data/spec/spec_helper.rb +31 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fba5a853caa230da439567826e09696d878f377a
|
4
|
+
data.tar.gz: 8e48a5be8c0ecf6d5f13964be9f8530658f5fe9c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0d528a0952735dac141625005248b6ac9253b5e449080fdeb95fa74dafff62a79d7b90af6a94ad0d1996e1d9c634e8860e9cb1ab22ae88abc27ebfb8a6f7f32d
|
7
|
+
data.tar.gz: 47f7b69ea73e8c4a3cc41dd157c5eb67ec65e4335c090c202dc8565852c89b413b872eb9e15c2fa0901c130af848632193caccfc3b3ed39bacbba869024e15c2
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
redmine-client-ruby
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Redmine Ruby Client
|
2
|
+
|
3
|
+
[](https://travis-ci.org/ninech/redmine-client)
|
4
|
+
|
5
|
+
Ruby client library for the Redmine API.
|
6
|
+
|
7
|
+
## Configuration
|
8
|
+
|
9
|
+
In your Rails app create a file `config/initializers/redmine.rb` with the following content:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
RedmineClient::API.configure do |config|
|
13
|
+
config.url = ENV['REDMINE_URL']
|
14
|
+
config.token = ENV['REDMINE_TOKEN']
|
15
|
+
end
|
16
|
+
```
|
17
|
+
|
18
|
+
Here you have to set the config values via environment variables. But you're free to do it differently.
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
The client is very limited. Actually it can only find, create and update issues. That's all for now. But
|
23
|
+
great things start small.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
RedmineClient::Issue.create subject: 'Do this and that', project_id: 1
|
27
|
+
|
28
|
+
issue = RedmineClient::Issue.find(1)
|
29
|
+
issue.update subject: 'New Subject'
|
30
|
+
```
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
APP_ROOT = File.join(File.dirname(Pathname.new(__FILE__).realpath),'..')
|
7
|
+
|
8
|
+
$:.unshift File.join(APP_ROOT, 'lib')
|
9
|
+
$:.unshift File.join(APP_ROOT, 'vendor/bundle')
|
10
|
+
|
11
|
+
Dir.chdir(APP_ROOT)
|
12
|
+
|
13
|
+
require 'bundler/setup'
|
14
|
+
require 'nine-redmine-client'
|
15
|
+
|
16
|
+
fail 'REDMINE_API_KEY environment variable not set!' unless ENV['REDMINE_API_KEY']
|
17
|
+
|
18
|
+
RedmineClient::API.configure do |config|
|
19
|
+
config.url = 'http://redmine.dev/'
|
20
|
+
config.token = ENV['REDMINE_API_KEY']
|
21
|
+
end
|
22
|
+
|
23
|
+
binding.pry
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'redmine_client'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'active_support/configurable'
|
2
|
+
|
3
|
+
module RedmineClient
|
4
|
+
class API
|
5
|
+
def self.config
|
6
|
+
@config ||= Configuration.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.configure
|
10
|
+
yield config
|
11
|
+
Base.setup
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class API::Configuration
|
16
|
+
include ActiveSupport::Configurable
|
17
|
+
|
18
|
+
config_accessor(:url)
|
19
|
+
config_accessor(:token)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module RedmineClient
|
5
|
+
HEADERS = {
|
6
|
+
'User-Agent' => 'Ruby.Redmine.Client',
|
7
|
+
'Accept' => 'application/json',
|
8
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
class Base < OpenStruct
|
12
|
+
include HTTParty
|
13
|
+
|
14
|
+
format :json
|
15
|
+
|
16
|
+
extend Forwardable
|
17
|
+
def_delegators 'self.class', :delete, :get, :post, :put, :resource_path, :resource_name, :bad_response
|
18
|
+
|
19
|
+
def update(attrs = {})
|
20
|
+
resource = put "#{resource_path}/#{id}.json", body: { resource_name => attrs }
|
21
|
+
if resource.success?
|
22
|
+
data = Hash[attrs.map { |key, value| [key.to_sym, value] }]
|
23
|
+
@table.merge!(data)
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def setup
|
31
|
+
base_uri RedmineClient::API.config.url
|
32
|
+
headers HEADERS.merge('X-Redmine-API-Key' => RedmineClient::API.config.token)
|
33
|
+
end
|
34
|
+
|
35
|
+
def resource_path
|
36
|
+
klass = name.split('::').last
|
37
|
+
klass[0] = klass[0].chr.downcase
|
38
|
+
klass.end_with?('y') ? "/#{klass.chop}ies" : "/#{klass}s"
|
39
|
+
end
|
40
|
+
|
41
|
+
def resource_name
|
42
|
+
klass = name.split('::').last
|
43
|
+
klass.downcase
|
44
|
+
end
|
45
|
+
|
46
|
+
def bad_response(response, _params = {})
|
47
|
+
if response.class == HTTParty::Response
|
48
|
+
case response.code
|
49
|
+
when 403
|
50
|
+
fail Errors::AccessDeniedException
|
51
|
+
when 404
|
52
|
+
fail Errors::ResourceNotFoundException
|
53
|
+
when 422
|
54
|
+
fail Errors::UnprocessableEntityException, response
|
55
|
+
when 500
|
56
|
+
fail Errors::InternalErrorException
|
57
|
+
else
|
58
|
+
fail HTTParty::ResponseError, response
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
fail StandardError, 'Unknown error'
|
63
|
+
end
|
64
|
+
|
65
|
+
def find(id)
|
66
|
+
resource = get "#{resource_path}/#{id}.json"
|
67
|
+
resource.ok? ? new(resource[resource_name]) : bad_response(resource, id)
|
68
|
+
end
|
69
|
+
|
70
|
+
def create(attrs = {})
|
71
|
+
resource = post "#{resource_path}.json", body: { resource_name => attrs }
|
72
|
+
if resource.success?
|
73
|
+
data = attrs.merge resource[resource_name]
|
74
|
+
new(data)
|
75
|
+
else
|
76
|
+
bad_response(resource, attrs)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RedmineClient
|
2
|
+
module Errors
|
3
|
+
class AccessDeniedException < StandardError
|
4
|
+
def to_s
|
5
|
+
'Access denied.'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ResourceNotFoundException < StandardError
|
10
|
+
def to_s
|
11
|
+
'Resource not found.'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class UnprocessableEntityException < StandardError
|
16
|
+
def initialize(response)
|
17
|
+
@errors = response.parsed_response['errors']
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
@errors.join(', ')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class InternalErrorException < StandardError
|
26
|
+
def to_s
|
27
|
+
'Internal error'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RedmineClient
|
2
|
+
class Issue < Base
|
3
|
+
def self.search(arguments)
|
4
|
+
issues = get "#{resource_path}.json", query: arguments
|
5
|
+
if issues.ok?
|
6
|
+
issues['issues'].map { |issue| new(issue) }
|
7
|
+
else
|
8
|
+
bad_response(issues, arguments)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
$:.push File.expand_path('../lib', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'nine-redmine-client'
|
7
|
+
s.version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
8
|
+
s.authors = ['nine.ch Development-Team']
|
9
|
+
s.email = ['development@nine.ch']
|
10
|
+
s.homepage = 'http://github.com/ninech/'
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.summary = 'Redmine API ruby client library'
|
13
|
+
s.description = 'To access the Redmine API from ruby scripts.'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
21
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
+
s.add_development_dependency 'pry', '~> 0.10.0'
|
23
|
+
|
24
|
+
s.add_runtime_dependency 'httparty'
|
25
|
+
s.add_runtime_dependency 'activesupport', '>= 4.0.0'
|
26
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RedmineClient::Base do
|
4
|
+
describe '.resource_path' do
|
5
|
+
subject { RedmineClient::Base.resource_path }
|
6
|
+
it { should eq '/bases' }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.resource_name' do
|
10
|
+
subject { RedmineClient::Base.resource_name }
|
11
|
+
it { should eq 'base' }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.bad_response' do
|
15
|
+
subject { described_class.bad_response(response) }
|
16
|
+
|
17
|
+
context 'valid response object' do
|
18
|
+
let(:response) { instance_double('HTTParty::Response', class: HTTParty::Response, code: 500) }
|
19
|
+
|
20
|
+
it 'raises a response error' do
|
21
|
+
expect { subject }.to raise_error RedmineClient::Errors::InternalErrorException
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'unknown error' do
|
26
|
+
let(:response) { double }
|
27
|
+
|
28
|
+
it 'raises a standard error' do
|
29
|
+
expect { subject }.to raise_error StandardError
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'access denied' do
|
34
|
+
let(:response) { instance_double('HTTParty::Response', class: HTTParty::Response, code: 403) }
|
35
|
+
|
36
|
+
it 'raises the correct error' do
|
37
|
+
expect { subject }.to raise_error RedmineClient::Errors::AccessDeniedException
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'resource not found' do
|
42
|
+
let(:response) { instance_double('HTTParty::Response', class: HTTParty::Response, code: 404) }
|
43
|
+
|
44
|
+
it 'raises the correct error' do
|
45
|
+
expect { subject }.to raise_error RedmineClient::Errors::ResourceNotFoundException
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'Unprocessable entity error' do
|
50
|
+
let(:response) { instance_double('HTTParty::Response', class: HTTParty::Response, code: 422) }
|
51
|
+
|
52
|
+
before do
|
53
|
+
allow(response).to receive(:parsed_response).
|
54
|
+
and_return('errors' => ['a is bad', 'b is bad'])
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises the correct error' do
|
58
|
+
expect { subject }.to raise_error RedmineClient::Errors::UnprocessableEntityException
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'displays a human-readable error message' do
|
62
|
+
expect { subject }.to raise_error(
|
63
|
+
RedmineClient::Errors::UnprocessableEntityException,
|
64
|
+
'a is bad, b is bad'
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '.find' do
|
71
|
+
subject { RedmineClient::Base.find(1) }
|
72
|
+
|
73
|
+
it 'starts a get request with the correct path' do
|
74
|
+
allow(RedmineClient::Base).to receive(:new)
|
75
|
+
|
76
|
+
expect(RedmineClient::Base).to receive(:get).with('/bases/1.json').and_return double(ok?: true, :[] => '')
|
77
|
+
|
78
|
+
RedmineClient::Base.find(1)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'creates a new instance when the response is ok' do
|
82
|
+
response = double(ok?: true, :[] => {})
|
83
|
+
allow(RedmineClient::Base).to receive(:get).and_return(response)
|
84
|
+
|
85
|
+
expect(RedmineClient::Base).to receive(:new).with({})
|
86
|
+
RedmineClient::Base.find(1)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'fails when the response smells' do
|
90
|
+
response = double(ok?: false)
|
91
|
+
allow(RedmineClient::Base).to receive(:get).and_return(response)
|
92
|
+
expect(RedmineClient::Base).to receive(:bad_response).with(response, 1)
|
93
|
+
RedmineClient::Base.find(1)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RedmineClient::Issue do
|
4
|
+
describe '.search' do
|
5
|
+
subject { RedmineClient::Issue.search(subject: 'nice subject', status_id: '*') }
|
6
|
+
|
7
|
+
it 'starts a get request with the correct path' do
|
8
|
+
allow(RedmineClient::Issue).to receive(:new)
|
9
|
+
expect(RedmineClient::Issue).
|
10
|
+
to receive(:get).with('/issues.json', query: { subject: 'nice subject', status_id: '*'}).
|
11
|
+
and_return double(ok?: true, :[] => [])
|
12
|
+
subject
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'redmine_client'
|
2
|
+
|
3
|
+
RedmineClient::API.configure do |config|
|
4
|
+
config.url = 'http://redmine.test'
|
5
|
+
config.token = 'abcd'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'pry'
|
9
|
+
|
10
|
+
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.filter_run :focus
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
|
16
|
+
if config.files_to_run.one?
|
17
|
+
config.default_formatter = 'doc'
|
18
|
+
end
|
19
|
+
|
20
|
+
config.order = :random
|
21
|
+
Kernel.srand config.seed
|
22
|
+
|
23
|
+
config.expect_with :rspec do |expectations|
|
24
|
+
expectations.syntax = :expect
|
25
|
+
end
|
26
|
+
|
27
|
+
config.mock_with :rspec do |mocks|
|
28
|
+
mocks.syntax = :expect
|
29
|
+
mocks.verify_partial_doubles = true
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nine-redmine-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nine.ch Development-Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.10.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.10.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: httparty
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activesupport
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 4.0.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 4.0.0
|
83
|
+
description: To access the Redmine API from ruby scripts.
|
84
|
+
email:
|
85
|
+
- development@nine.ch
|
86
|
+
executables:
|
87
|
+
- nine-redmine-client
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".ruby-gemset"
|
94
|
+
- ".ruby-version"
|
95
|
+
- ".travis.yml"
|
96
|
+
- CHANGELOG.md
|
97
|
+
- Gemfile
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- VERSION
|
101
|
+
- bin/nine-redmine-client
|
102
|
+
- gemfiles/activesupport-4.0.gemfile
|
103
|
+
- gemfiles/activesupport-4.1.gemfile
|
104
|
+
- gemfiles/activesupport-4.2.gemfile
|
105
|
+
- lib/nine-redmine-client.rb
|
106
|
+
- lib/redmine_client.rb
|
107
|
+
- lib/redmine_client/api.rb
|
108
|
+
- lib/redmine_client/base.rb
|
109
|
+
- lib/redmine_client/errors.rb
|
110
|
+
- lib/redmine_client/issue.rb
|
111
|
+
- nine-redmine-client.gemspec
|
112
|
+
- spec/redmine_client/base_spec.rb
|
113
|
+
- spec/redmine_client/issue_spec.rb
|
114
|
+
- spec/spec_helper.rb
|
115
|
+
homepage: http://github.com/ninech/
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.5.1
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Redmine API ruby client library
|
139
|
+
test_files: []
|