trellohub 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/Gemfile +9 -0
- data/README.md +33 -7
- data/bin/trellohub +7 -0
- data/lib/trellohub.rb +10 -3
- data/lib/trellohub/card.rb +8 -79
- data/lib/trellohub/configurable.rb +75 -36
- data/lib/trellohub/core_ext/array.rb +10 -0
- data/lib/trellohub/core_ext/hash.rb +9 -1
- data/lib/trellohub/core_ext/string.rb +22 -0
- data/lib/trellohub/form.rb +142 -0
- data/lib/trellohub/form/card.rb +163 -0
- data/lib/trellohub/form/issue.rb +191 -0
- data/lib/trellohub/list.rb +18 -2
- data/lib/trellohub/member.rb +14 -2
- data/lib/trellohub/mocking.rb +87 -0
- data/lib/trellohub/repository.rb +47 -0
- data/lib/trellohub/synchronal.rb +22 -41
- data/lib/trellohub/version.rb +1 -1
- data/spec/helper.rb +59 -0
- data/spec/trellohub_spec.rb +51 -0
- metadata +20 -7
- data/lib/trellohub/cards.rb +0 -58
- data/lib/trellohub/lists.rb +0 -17
data/lib/trellohub/list.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
require 'trellohub/board'
|
3
|
-
require 'trellohub/lists'
|
4
3
|
|
5
4
|
module Trellohub
|
6
5
|
class List < OpenStruct
|
@@ -28,7 +27,24 @@ module Trellohub
|
|
28
27
|
end
|
29
28
|
|
30
29
|
class << self
|
31
|
-
|
30
|
+
def all
|
31
|
+
@all || self.all!
|
32
|
+
end
|
33
|
+
|
34
|
+
def all!
|
35
|
+
@all = Trell.lists(Trellohub::Board.id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_by(id: nil, name: nil)
|
39
|
+
case
|
40
|
+
when !id.nil?
|
41
|
+
self.all.find { |list| list.id == id }
|
42
|
+
when !name.nil?
|
43
|
+
self.all.find { |list| list.name == name }
|
44
|
+
else
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
33
49
|
end
|
34
50
|
end
|
data/lib/trellohub/member.rb
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
module Trellohub
|
2
2
|
module Member
|
3
3
|
class << self
|
4
|
-
def
|
4
|
+
def find_by(id: nil, username: nil)
|
5
5
|
@members = {} if @members.nil?
|
6
|
-
|
6
|
+
|
7
|
+
case
|
8
|
+
when !id.nil?
|
9
|
+
if member = @members.find { |key, value| value.id == id }
|
10
|
+
member.last
|
11
|
+
else
|
12
|
+
member = Trell.member(id)
|
13
|
+
@members[:"#{member.username}"] = member
|
14
|
+
end
|
15
|
+
when !username.nil?
|
16
|
+
@members[:"#{username}"] ||= Trell.member(username)
|
17
|
+
end
|
18
|
+
|
7
19
|
rescue Trell::NotFound
|
8
20
|
nil
|
9
21
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'awesome_print'
|
2
|
+
|
3
|
+
module Trellohub
|
4
|
+
module Mocking
|
5
|
+
class << self
|
6
|
+
attr_reader :called_requests
|
7
|
+
|
8
|
+
def start
|
9
|
+
::Octokit::Client.__send__ :include, NoRequest
|
10
|
+
::Trell::Client.__send__ :include, NoRequest
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop
|
14
|
+
::Octokit::Client.__send__ :include, Request
|
15
|
+
::Trell::Client.__send__ :include, Request
|
16
|
+
end
|
17
|
+
|
18
|
+
def request_methods
|
19
|
+
%i(post put patch delete)
|
20
|
+
end
|
21
|
+
|
22
|
+
def push_called_request(klass, method, path)
|
23
|
+
@called_requests = {} if @called_requests.nil?
|
24
|
+
@called_requests[klass] = {} if @called_requests[klass].nil?
|
25
|
+
@called_requests[klass][method] = [] if @called_requests[klass][method].nil?
|
26
|
+
|
27
|
+
@called_requests[klass][method] << path
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_request_summary
|
31
|
+
puts "## Request Summary"
|
32
|
+
|
33
|
+
if @called_requests
|
34
|
+
@called_requests.keys.each do |klass|
|
35
|
+
@called_requests[klass].keys.each do |method|
|
36
|
+
puts "- #{klass} #{method.upcase}: #{@called_requests[klass][method].count}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
else
|
40
|
+
puts 'No requests'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def overriding_method(http_method)
|
45
|
+
<<-METHOD
|
46
|
+
def #{http_method}_without_http(url, options = {})
|
47
|
+
Trellohub::Mocking.print_request(self.class.name, "#{http_method}", url, options)
|
48
|
+
end
|
49
|
+
METHOD
|
50
|
+
end
|
51
|
+
|
52
|
+
def print_request(klass, method, path, *body)
|
53
|
+
push_called_request(klass, method, path)
|
54
|
+
host = klass.split('::').first.constantize.web_endpoint
|
55
|
+
puts "[#{method.upcase}] #{host}#{path}"
|
56
|
+
ap body
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module Request
|
61
|
+
def self.included(base)
|
62
|
+
Trellohub::Mocking.request_methods.each do |m|
|
63
|
+
base.class_eval do
|
64
|
+
alias_method m.to_sym, :"#{m}_with_http" if method_defined? :"#{m}_with_http"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
module NoRequest
|
71
|
+
Trellohub::Mocking.request_methods.each do |http_method|
|
72
|
+
class_eval Trellohub::Mocking.overriding_method(http_method),
|
73
|
+
__FILE__,
|
74
|
+
__LINE__ + 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.included(base)
|
78
|
+
Trellohub::Mocking.request_methods.each do |m|
|
79
|
+
base.class_eval do
|
80
|
+
alias_method :"#{m}_with_http", m.to_sym unless method_defined? :"#{m}_with_http"
|
81
|
+
alias_method m.to_sym, :"#{m}_without_http"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Trellohub
|
4
|
+
class Repository < OpenStruct
|
5
|
+
def issues
|
6
|
+
@issues ||= case
|
7
|
+
when milestone.is_a?(String)
|
8
|
+
[]
|
9
|
+
when milestone.nil?
|
10
|
+
Octokit.issues(full_name, state: 'all')
|
11
|
+
else
|
12
|
+
Octokit.issues(full_name, milestone: milestone.number, state: 'all')
|
13
|
+
end
|
14
|
+
rescue Octokit::NotFound
|
15
|
+
[]
|
16
|
+
# The "state: all" option was not supported by GitHub Enterprise API
|
17
|
+
rescue Octokit::UnprocessableEntity
|
18
|
+
@issues ||= case
|
19
|
+
when milestone.nil?
|
20
|
+
Octokit.issues(full_name, state: 'open') +
|
21
|
+
Octokit.issues(full_name, state: 'closed')
|
22
|
+
else
|
23
|
+
Octokit.issues(full_name, milestone: milestone.number, state: 'open') +
|
24
|
+
Octokit.issues(full_name, milestone: milestone.number, state: 'closed')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def milestone
|
29
|
+
@milestone ||= super
|
30
|
+
if @milestone.is_a?(String)
|
31
|
+
m = find_milestone
|
32
|
+
@milestone = m if m
|
33
|
+
end
|
34
|
+
@milestone
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_milestone
|
38
|
+
return nil if all_milestones.empty?
|
39
|
+
milestone = @all_milestones.find { |m| m.title == @milestone }
|
40
|
+
milestone if milestone
|
41
|
+
end
|
42
|
+
|
43
|
+
def all_milestones
|
44
|
+
@all_milestones ||= Octokit.milestones(full_name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/trellohub/synchronal.rb
CHANGED
@@ -1,56 +1,37 @@
|
|
1
1
|
module Trellohub
|
2
2
|
module Synchronal
|
3
|
-
SYNCHRONAL_KEYS = %i(
|
4
|
-
temporary_cards_by_issues
|
5
|
-
temporary_cards
|
6
|
-
)
|
7
|
-
|
8
|
-
attr_reader(*SYNCHRONAL_KEYS)
|
9
|
-
|
10
3
|
def synchronize
|
4
|
+
synchronize_to_cards_from_issues
|
5
|
+
synchronize_to_issues_from_cards
|
6
|
+
Trellohub::Mocking.print_request_summary if Trellohub.dry_run
|
7
|
+
true
|
11
8
|
end
|
12
9
|
alias_method :sync, :synchronize
|
13
10
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
milestones = Octokit.milestones(repo)
|
18
|
-
return [] if milestones.empty?
|
11
|
+
def synchronize_to_cards_from_issues
|
12
|
+
Form.with_issues.each do |issue_form|
|
13
|
+
card_form = Form.with_cards.find_by_key(issue_form.key)
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
case
|
16
|
+
when card_form.nil?
|
17
|
+
issue_form.save_as_card
|
18
|
+
when Form.compare(issue_form, card_form)
|
19
|
+
card_form.save_as_issue
|
20
|
+
end
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
24
|
+
def synchronize_to_issues_from_cards
|
25
|
+
Form.with_cards.each do |card_form|
|
26
|
+
issue_form = Form.with_issues.find_by_key(card_form.key)
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
case
|
29
|
+
when issue_form.nil?
|
30
|
+
card_form.save_as_issue
|
31
|
+
when Form.compare(card_form, issue_form)
|
32
|
+
issue_form.save_as_card
|
33
|
+
end
|
37
34
|
end
|
38
35
|
end
|
39
|
-
|
40
|
-
def trello_cards
|
41
|
-
@trello_cards ||= Trellohub::Card.all.
|
42
|
-
each.with_object([]) do |card, cards|
|
43
|
-
temp_card = Trellohub::Card.new
|
44
|
-
temp_card.import card
|
45
|
-
cards << temp_card
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# def import_from_github_issues
|
50
|
-
# issued_cards(repo, 'open').each do |card|
|
51
|
-
# Trell.create_card card.slice(*valid_card_attributes)
|
52
|
-
# end
|
53
|
-
# end
|
54
|
-
# alias_method :import, :import_from_github_issues
|
55
36
|
end
|
56
37
|
end
|
data/lib/trellohub/version.rb
CHANGED
data/spec/helper.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
require 'coveralls'
|
5
|
+
require 'trellohub'
|
6
|
+
require 'rspec'
|
7
|
+
require 'ap'
|
8
|
+
require 'vcr'
|
9
|
+
require 'webmock/rspec'
|
10
|
+
|
11
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
12
|
+
SimpleCov::Formatter::HTMLFormatter,
|
13
|
+
Coveralls::SimpleCov::Formatter
|
14
|
+
]
|
15
|
+
SimpleCov.start
|
16
|
+
|
17
|
+
WebMock.disable_net_connect!(allow: 'coveralls.io')
|
18
|
+
RSpec.configure { |c| c.include WebMock::API }
|
19
|
+
|
20
|
+
VCR.configure do |c|
|
21
|
+
c.configure_rspec_metadata!
|
22
|
+
c.cassette_library_dir = 'spec/cassettes'
|
23
|
+
c.hook_into :webmock
|
24
|
+
c.default_cassette_options = {
|
25
|
+
serialize_with: :json,
|
26
|
+
preserve_exact_body_bytes: true,
|
27
|
+
decode_compressed_response: true,
|
28
|
+
record: :once
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def fixture_path
|
33
|
+
File.expand_path('../fixtures', __FILE__)
|
34
|
+
end
|
35
|
+
|
36
|
+
def fixture(file)
|
37
|
+
File.read(fixture_path + '/' + file)
|
38
|
+
end
|
39
|
+
|
40
|
+
def decode(file)
|
41
|
+
JSON.parse(fixture file)
|
42
|
+
end
|
43
|
+
|
44
|
+
def json_response(file)
|
45
|
+
{
|
46
|
+
body: fixture(file),
|
47
|
+
headers: { content_type: 'application/json; charset=utf-8' }
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def method_missing(method, *args, &block)
|
52
|
+
if method =~ /^a_(get|post|put|delete)$/
|
53
|
+
a_request(Regexp.last_match[1].to_sym, *args, &block)
|
54
|
+
elsif method =~ /^stub_(get|post|put|delete|head|patch)$/
|
55
|
+
stub_request(Regexp.last_match[1].to_sym, *args, &block)
|
56
|
+
else
|
57
|
+
super
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Trellohub do
|
4
|
+
describe '.configure' do
|
5
|
+
Trellohub::Configurable.keys.each do |key|
|
6
|
+
it "sets the #{key.to_s.gsub('_', ' ')}" do
|
7
|
+
Trellohub.configure { |config| config.send("#{key}=", key) }
|
8
|
+
expect(Trellohub.instance_variable_get(:"@#{key}")).to eq(key)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.default!' do
|
14
|
+
it 'sets defaults' do
|
15
|
+
Trellohub.default!
|
16
|
+
expect(Trellohub.config_file).to be_nil
|
17
|
+
expect(Trellohub.repositories).to eq []
|
18
|
+
expect(Trellohub.lists).to eq []
|
19
|
+
expect(Trellohub.options).to eq(default_assignee: true, default_member: true)
|
20
|
+
expect(Trellohub.github_api_endpoint).to eq Octokit.api_endpoint
|
21
|
+
expect(Trellohub.github_web_endpoint).to eq Octokit.web_endpoint
|
22
|
+
expect(Trellohub.dry_run).to eq false
|
23
|
+
expect(Trellohub.debug).to eq true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.load!' do
|
28
|
+
it 'loads config file' do
|
29
|
+
path = './boards/example.yml'
|
30
|
+
expect(YAML).to receive(:load_file).with(path).and_call_original
|
31
|
+
expect(Trellohub::Configurable).to receive(:keys).and_call_original
|
32
|
+
expect(Trellohub::Repository).to receive(:new).with(any_args()).
|
33
|
+
at_least(:once).and_call_original
|
34
|
+
expect(Trellohub::List).to receive(:new).with(any_args()).
|
35
|
+
at_least(:once).and_call_original
|
36
|
+
|
37
|
+
Trellohub.load!(path)
|
38
|
+
|
39
|
+
expect(Trellohub.config_file).to be_nil
|
40
|
+
expect(Trellohub.repositories).to be_a Array
|
41
|
+
expect(Trellohub.repositories.last).to be_a Trellohub::Repository
|
42
|
+
expect(Trellohub.lists).to be_a Array
|
43
|
+
expect(Trellohub.lists.last).to be_a Trellohub::List
|
44
|
+
expect(Trellohub.options).to eq(default_assignee: true, default_member: true)
|
45
|
+
expect(Trellohub.github_api_endpoint).to eq Octokit.api_endpoint
|
46
|
+
expect(Trellohub.github_web_endpoint).to eq Octokit.web_endpoint
|
47
|
+
expect(Trellohub.dry_run).to eq false
|
48
|
+
expect(Trellohub.debug).to eq true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trellohub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- linyows
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|
@@ -70,27 +70,38 @@ description: Trellohub is uniform task management by synchronizing the github is
|
|
70
70
|
and trello cards.
|
71
71
|
email:
|
72
72
|
- linyows@gmail.com
|
73
|
-
executables:
|
73
|
+
executables:
|
74
|
+
- trellohub
|
74
75
|
extensions: []
|
75
76
|
extra_rdoc_files: []
|
76
77
|
files:
|
77
78
|
- ".gitignore"
|
79
|
+
- ".rspec"
|
80
|
+
- ".travis.yml"
|
78
81
|
- Gemfile
|
79
82
|
- LICENSE.txt
|
80
83
|
- README.md
|
81
84
|
- Rakefile
|
85
|
+
- bin/trellohub
|
82
86
|
- boards/example.yml
|
83
87
|
- lib/trellohub.rb
|
84
88
|
- lib/trellohub/board.rb
|
85
89
|
- lib/trellohub/card.rb
|
86
|
-
- lib/trellohub/cards.rb
|
87
90
|
- lib/trellohub/configurable.rb
|
91
|
+
- lib/trellohub/core_ext/array.rb
|
88
92
|
- lib/trellohub/core_ext/hash.rb
|
93
|
+
- lib/trellohub/core_ext/string.rb
|
94
|
+
- lib/trellohub/form.rb
|
95
|
+
- lib/trellohub/form/card.rb
|
96
|
+
- lib/trellohub/form/issue.rb
|
89
97
|
- lib/trellohub/list.rb
|
90
|
-
- lib/trellohub/lists.rb
|
91
98
|
- lib/trellohub/member.rb
|
99
|
+
- lib/trellohub/mocking.rb
|
100
|
+
- lib/trellohub/repository.rb
|
92
101
|
- lib/trellohub/synchronal.rb
|
93
102
|
- lib/trellohub/version.rb
|
103
|
+
- spec/helper.rb
|
104
|
+
- spec/trellohub_spec.rb
|
94
105
|
- trellohub.gemspec
|
95
106
|
homepage: https://github.com/linyows/trellohub
|
96
107
|
licenses:
|
@@ -112,9 +123,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
123
|
version: '0'
|
113
124
|
requirements: []
|
114
125
|
rubyforge_project:
|
115
|
-
rubygems_version: 2.2.
|
126
|
+
rubygems_version: 2.2.2
|
116
127
|
signing_key:
|
117
128
|
specification_version: 4
|
118
129
|
summary: Trellohub is uniform task management by synchronizing the github issues and
|
119
130
|
trello cards.
|
120
|
-
test_files:
|
131
|
+
test_files:
|
132
|
+
- spec/helper.rb
|
133
|
+
- spec/trellohub_spec.rb
|