trellohub 0.0.1 → 0.1.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 +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
|