pivotal-to-trello 0.1.2 → 0.2.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/.rubocop.yml +102 -0
- data/Dockerfile +24 -0
- data/Gemfile +5 -4
- data/README.markdown +11 -2
- data/Rakefile +10 -10
- data/VERSION +1 -1
- data/lib/pivotal-to-trello.rb +1 -1
- data/lib/pivotal_to_trello/core.rb +91 -83
- data/lib/pivotal_to_trello/pivotal_wrapper.rb +10 -11
- data/lib/pivotal_to_trello/trello_wrapper.rb +44 -25
- data/pivotal-to-trello.gemspec +22 -17
- data/spec/pivotal_to_trello/core_spec.rb +44 -44
- data/spec/pivotal_to_trello/pivotal_wrapper_spec.rb +12 -10
- data/spec/pivotal_to_trello/trello_wrapper_spec.rb +75 -53
- data/spec/spec_helper.rb +35 -34
- metadata +35 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b07f7cf563cfd39dd77fea8ddea116c13442c800
|
4
|
+
data.tar.gz: d1a9f8d00c58de04c1e46bdff752fd32d0c1f482
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe887375672d6a14d4c6ad9d534dd721f5ef1ee7c5d01702212ae05712eba40cbef054d9b3180fb5a2c42e543edc0ca09e9447d21dc3400410e041a1bf80e68e
|
7
|
+
data.tar.gz: 2795928fd620bf9243634b596bfd360d358a554bc15b8f522ba8ea46fc6887e985267b216e19dcdcf549609ef76376efbb25a453b480f8f93be8e44bce00d998
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# See example at https://github.com/bbatsov/rubocop/blob/master/config/default.yml
|
2
|
+
AllCops:
|
3
|
+
TargetRubyVersion: 2.2
|
4
|
+
Exclude:
|
5
|
+
- 'Gemfile'
|
6
|
+
- 'pivotal-to-trello.gemspec'
|
7
|
+
|
8
|
+
# Align the elements of a hash literal if they span more than one line.
|
9
|
+
AlignHash:
|
10
|
+
# Alignment of entries using hash rocket as separator. Valid values are:
|
11
|
+
#
|
12
|
+
# key - left alignment of keys
|
13
|
+
# 'a' => 2
|
14
|
+
# 'bb' => 3
|
15
|
+
# separator - alignment of hash rockets, keys are right aligned
|
16
|
+
# 'a' => 2
|
17
|
+
# 'bb' => 3
|
18
|
+
# table - left alignment of keys, hash rockets, and values
|
19
|
+
# 'a' => 2
|
20
|
+
# 'bb' => 3
|
21
|
+
EnforcedHashRocketStyle: table
|
22
|
+
# Alignment of entries using colon as separator. Valid values are:
|
23
|
+
#
|
24
|
+
# key - left alignment of keys
|
25
|
+
# a: 0
|
26
|
+
# bb: 1
|
27
|
+
# separator - alignment of colons, keys are right aligned
|
28
|
+
# a: 0
|
29
|
+
# bb: 1
|
30
|
+
# table - left alignment of keys and values
|
31
|
+
# a: 0
|
32
|
+
# bb: 1
|
33
|
+
EnforcedColonStyle: table
|
34
|
+
|
35
|
+
Documentation:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
EmptyLines:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Layout/EmptyLinesAroundBlockBody:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
LineLength:
|
45
|
+
Max: 180
|
46
|
+
|
47
|
+
Metrics/AbcSize:
|
48
|
+
Enabled: true
|
49
|
+
Max: 40
|
50
|
+
|
51
|
+
Metrics/ClassLength:
|
52
|
+
Enabled: false
|
53
|
+
CountComments: false
|
54
|
+
|
55
|
+
Metrics/BlockLength:
|
56
|
+
Enabled: false
|
57
|
+
CountComments: false
|
58
|
+
|
59
|
+
Metrics/MethodLength:
|
60
|
+
Enabled: true
|
61
|
+
CountComments: false
|
62
|
+
Max: 25
|
63
|
+
|
64
|
+
ParameterLists:
|
65
|
+
Max: 7
|
66
|
+
CountKeywordArgs: true
|
67
|
+
|
68
|
+
SpaceInsideParens:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
SpaceBeforeFirstArg:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
Style/AndOr:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Style/BlockComments:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Style/BlockDelimiters:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
Style/ClassAndModuleChildren:
|
84
|
+
Enabled: true
|
85
|
+
EnforcedStyle: nested
|
86
|
+
|
87
|
+
Style/FrozenStringLiteralComment:
|
88
|
+
Enabled: false
|
89
|
+
|
90
|
+
Style/RedundantReturn:
|
91
|
+
Enabled: false
|
92
|
+
|
93
|
+
Style/TrailingCommaInArguments:
|
94
|
+
Enabled: true
|
95
|
+
EnforcedStyleForMultiline: comma
|
96
|
+
|
97
|
+
Style/TrailingCommaInLiteral:
|
98
|
+
Enabled: true
|
99
|
+
EnforcedStyleForMultiline: comma
|
100
|
+
|
101
|
+
Style/WordArray:
|
102
|
+
Enabled: false
|
data/Dockerfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
FROM ubuntu:14.04
|
2
|
+
|
3
|
+
MAINTAINER "Dave Perrett" https://github.com/Dockerfile
|
4
|
+
|
5
|
+
# Dependencies
|
6
|
+
RUN apt-get -y update &&\
|
7
|
+
apt-get install -y software-properties-common &&\
|
8
|
+
apt-add-repository ppa:brightbox/ruby-ng &&\
|
9
|
+
apt-get update -q
|
10
|
+
|
11
|
+
RUN apt-get install -y build-essential zlib1g-dev libxml2-dev \
|
12
|
+
ruby2.2 ruby2.2-dev &&\
|
13
|
+
gem install bundler --no-rdoc --no-ri
|
14
|
+
|
15
|
+
# Prepare
|
16
|
+
RUN mkdir /app
|
17
|
+
COPY . /app
|
18
|
+
|
19
|
+
# Install lean
|
20
|
+
RUN cd /app && bundle install --without development
|
21
|
+
|
22
|
+
# And run
|
23
|
+
WORKDIR /app
|
24
|
+
ENTRYPOINT ["bundle", "exec", "/app/bin/pivotal-to-trello"]
|
data/Gemfile
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
-
gem 'highline', '
|
4
|
-
gem 'ruby-trello', '
|
5
|
-
gem 'pivotal-tracker', '
|
3
|
+
gem 'highline', '~> 1.7.8'
|
4
|
+
gem 'ruby-trello', '~> 2.0.0'
|
5
|
+
gem 'pivotal-tracker', '~> 0.5.13'
|
6
6
|
|
7
7
|
group :development do
|
8
8
|
gem 'rspec', '>= 2.14.1'
|
9
9
|
gem 'rdoc', '>= 4.1.1'
|
10
|
-
gem 'jeweler', '>= 2.
|
10
|
+
gem 'jeweler', '>= 2.3.7'
|
11
|
+
gem 'rubocop', '>= 0.49.1'
|
11
12
|
end
|
data/README.markdown
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
pivotal-to-trello [](https://travis-ci.org/recurser/pivotal-to-trello)
|
2
2
|
=================
|
3
3
|
|
4
|
-
This
|
4
|
+
This repo provides a command for exporting a [Pivotal Tracker](https://www.pivotaltracker.com/) project to [Trello](https://trello.com/). The command is available as a gem or a docker container.
|
5
5
|
|
6
6
|
Getting started
|
7
7
|
---------------
|
@@ -10,6 +10,12 @@ Getting started
|
|
10
10
|
|
11
11
|
> gem install pivotal-to-trello
|
12
12
|
|
13
|
+
Or pull the container down using Docker:
|
14
|
+
|
15
|
+
> docker pull recurser/pivotal-to-trello
|
16
|
+
|
17
|
+
When using the docker container, substitute every occurance of `pivotal-to-tracker` with `sudo docker run -a -i recurser/pivotal-to-tracker`
|
18
|
+
|
13
19
|
2. Run the importer:
|
14
20
|
|
15
21
|
> pivotal-to-trello import --trello-key TRELLO_API_KEY --trello-token TRELLO_TOKEN --pivotal-token PIVOTAL_TOKEN
|
@@ -229,6 +235,9 @@ The Pivotal Tracker token can be found at the bottom of your [Pivotal profile pa
|
|
229
235
|
Change history
|
230
236
|
--------------
|
231
237
|
|
238
|
+
* **Version 0.2.0 (2017-08-10)** : Fix label creation, update gem dependencies, add checklist support (thanks @rikthevik!), add docker support (thanks @kennethkalmer!).
|
239
|
+
* **Version 0.1.2 (2014-01-13)** : Update version number in the gemspec.
|
240
|
+
* **Version 0.1.1 (2014-01-13)** : Specify gem dependencies.
|
232
241
|
* **Version 0.1.0 (2014-01-13)** : Initial version.
|
233
242
|
|
234
243
|
Bug Reports
|
@@ -257,4 +266,4 @@ Dave Perrett :: hello@daveperrett.com :: [@daveperrett](http://twitter.com/davep
|
|
257
266
|
Copyright
|
258
267
|
---------
|
259
268
|
|
260
|
-
Copyright (c)
|
269
|
+
Copyright (c) 2017 Dave Perrett. See [License](https://github.com/recurser/jquery-i18n/blob/master/LICENSE) for details.
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ begin
|
|
6
6
|
Bundler.setup(:default, :development)
|
7
7
|
rescue Bundler::BundlerError => e
|
8
8
|
$stderr.puts e.message
|
9
|
-
$stderr.puts
|
9
|
+
$stderr.puts 'Run `bundle install` to install missing gems'
|
10
10
|
exit e.status_code
|
11
11
|
end
|
12
12
|
require 'rake'
|
@@ -14,13 +14,13 @@ require 'rake'
|
|
14
14
|
require 'jeweler'
|
15
15
|
Jeweler::Tasks.new do |gem|
|
16
16
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.name =
|
18
|
-
gem.license =
|
19
|
-
gem.homepage =
|
20
|
-
gem.summary = %
|
21
|
-
gem.description = %
|
22
|
-
gem.email =
|
23
|
-
gem.authors = [
|
17
|
+
gem.name = 'pivotal-to-trello'
|
18
|
+
gem.license = 'MIT'
|
19
|
+
gem.homepage = 'http://github.com/recurser/pivotal-to-trello'
|
20
|
+
gem.summary = %(Pivotal Tracker to Trello exporter)
|
21
|
+
gem.description = %(Pulls stories from Pivotal Tracker and imports them into Trello)
|
22
|
+
gem.email = 'hello@daveperrett.com'
|
23
|
+
gem.authors = ['Dave Perrett', 'Erik Frederiksen', 'Kenneth Kalmer']
|
24
24
|
# dependencies defined in Gemfile
|
25
25
|
end
|
26
26
|
Jeweler::RubygemsDotOrgTasks.new
|
@@ -36,11 +36,11 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
36
36
|
spec.rcov = true
|
37
37
|
end
|
38
38
|
|
39
|
-
task :
|
39
|
+
task default: :spec
|
40
40
|
|
41
41
|
require 'rdoc/task'
|
42
42
|
Rake::RDocTask.new do |rdoc|
|
43
|
-
version = File.exist?('VERSION') ? File.read('VERSION') :
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ''
|
44
44
|
|
45
45
|
rdoc.rdoc_dir = 'rdoc'
|
46
46
|
rdoc.title = "pivotal-to-trello #{version}"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/pivotal-to-trello.rb
CHANGED
@@ -4,113 +4,121 @@ require 'highline/import'
|
|
4
4
|
module PivotalToTrello
|
5
5
|
# The core entry point of the gem, which handles the import process.
|
6
6
|
class Core
|
7
|
-
|
8
7
|
# Constructor
|
9
8
|
def initialize(options = OpenStruct.new)
|
10
9
|
@options = options
|
11
10
|
end
|
12
11
|
|
13
|
-
#
|
14
|
-
# to the given output path.
|
12
|
+
# Imports a Pivotal project into Trello.
|
15
13
|
def import!
|
16
14
|
prompt_for_details
|
17
15
|
|
18
16
|
puts "\nBeginning import..."
|
19
17
|
pivotal.stories(options.pivotal_project_id).each do |story|
|
20
|
-
list_id =
|
21
|
-
|
22
|
-
if story.current_state == 'accepted'
|
23
|
-
list_id = options.accepted_list_id
|
24
|
-
elsif story.current_state == 'rejected'
|
25
|
-
list_id = options.rejected_list_id
|
26
|
-
elsif story.current_state == 'finished'
|
27
|
-
list_id = options.finished_list_id
|
28
|
-
elsif story.current_state == 'delivered'
|
29
|
-
list_id = options.delivered_list_id
|
30
|
-
elsif story.current_state == 'started'
|
31
|
-
list_id = options.current_list_id
|
32
|
-
elsif story.current_state == 'unscheduled'
|
33
|
-
list_id = options.icebox_list_id
|
34
|
-
elsif story.current_state == 'unstarted' && story.story_type == 'feature'
|
35
|
-
list_id = options.feature_list_id
|
36
|
-
elsif story.current_state == 'unstarted' && story.story_type == 'chore'
|
37
|
-
list_id = options.chore_list_id
|
38
|
-
elsif story.current_state == 'unstarted' && story.story_type == 'bug'
|
39
|
-
list_id = options.bug_list_id
|
40
|
-
elsif story.current_state == 'unstarted' && story.story_type == 'release'
|
41
|
-
list_id = options.release_list_id
|
42
|
-
else
|
43
|
-
puts "Ignoring story #{story.id} - type is '#{story.story_type}', state is '#{story.current_state}'"
|
44
|
-
end
|
45
|
-
|
46
|
-
if story.story_type == 'bug' && options.bug_label
|
47
|
-
label = options.bug_label
|
48
|
-
elsif story.story_type == 'feature' && options.feature_label
|
49
|
-
label = options.feature_label
|
50
|
-
elsif story.story_type == 'chore' && options.chore_label
|
51
|
-
label = options.chore_label
|
52
|
-
elsif story.story_type == 'release' && options.release_label
|
53
|
-
label = options.release_label
|
54
|
-
end
|
18
|
+
list_id = get_list_id(story, options)
|
19
|
+
next unless list_id
|
55
20
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
21
|
+
card = trello.create_card(list_id, story)
|
22
|
+
label_color = get_label_color(story, options)
|
23
|
+
trello.add_label(card, story.story_type, label_color) unless label_color.nil?
|
60
24
|
end
|
61
25
|
end
|
62
26
|
|
63
27
|
# Returns the options struct.
|
64
|
-
|
65
|
-
@options
|
66
|
-
end
|
28
|
+
attr_reader :options
|
67
29
|
|
68
30
|
private
|
69
31
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
32
|
+
# Returns the Trello list_id to import the given story into, based on the users input.
|
33
|
+
def get_list_id(story, options)
|
34
|
+
list_id = nil
|
35
|
+
|
36
|
+
if story.current_state == 'accepted'
|
37
|
+
list_id = options.accepted_list_id
|
38
|
+
elsif story.current_state == 'rejected'
|
39
|
+
list_id = options.rejected_list_id
|
40
|
+
elsif story.current_state == 'finished'
|
41
|
+
list_id = options.finished_list_id
|
42
|
+
elsif story.current_state == 'delivered'
|
43
|
+
list_id = options.delivered_list_id
|
44
|
+
elsif story.current_state == 'started'
|
45
|
+
list_id = options.current_list_id
|
46
|
+
elsif story.current_state == 'unscheduled'
|
47
|
+
list_id = options.icebox_list_id
|
48
|
+
elsif story.current_state == 'unstarted' && story.story_type == 'feature'
|
49
|
+
list_id = options.feature_list_id
|
50
|
+
elsif story.current_state == 'unstarted' && story.story_type == 'chore'
|
51
|
+
list_id = options.chore_list_id
|
52
|
+
elsif story.current_state == 'unstarted' && story.story_type == 'bug'
|
53
|
+
list_id = options.bug_list_id
|
54
|
+
elsif story.current_state == 'unstarted' && story.story_type == 'release'
|
55
|
+
list_id = options.release_list_id
|
56
|
+
else
|
57
|
+
puts "Ignoring story #{story.id} - type is '#{story.story_type}', state is '#{story.current_state}'"
|
88
58
|
end
|
89
59
|
|
90
|
-
|
91
|
-
|
92
|
-
say("\n#{question}")
|
93
|
-
choose do |menu|
|
94
|
-
menu.prompt = "Please select an option : "
|
95
|
-
|
96
|
-
choices.each do |key, value|
|
97
|
-
menu.choice value do
|
98
|
-
return key
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
60
|
+
list_id
|
61
|
+
end
|
102
62
|
|
63
|
+
# Returns the Trello label for the given story into, based on the users input.
|
64
|
+
def get_label_color(story, options)
|
65
|
+
label_color = nil
|
66
|
+
|
67
|
+
if story.story_type == 'bug' && options.bug_label
|
68
|
+
label_color = options.bug_label
|
69
|
+
elsif story.story_type == 'feature' && options.feature_label
|
70
|
+
label_color = options.feature_label
|
71
|
+
elsif story.story_type == 'chore' && options.chore_label
|
72
|
+
label_color = options.chore_label
|
73
|
+
elsif story.story_type == 'release' && options.release_label
|
74
|
+
label_color = options.release_label
|
103
75
|
end
|
104
76
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
77
|
+
label_color
|
78
|
+
end
|
79
|
+
|
80
|
+
# Prompts the user for details about the import/export.
|
81
|
+
def prompt_for_details
|
82
|
+
options.pivotal_project_id = prompt_selection('Which Pivotal project would you like to export?', pivotal.project_choices)
|
83
|
+
options.trello_board_id = prompt_selection('Which Trello board would you like to import into?', trello.board_choices)
|
84
|
+
options.icebox_list_id = prompt_selection("Which Trello list would you like to put 'icebox' stories into?", trello.list_choices(options.trello_board_id))
|
85
|
+
options.current_list_id = prompt_selection("Which Trello list would you like to put 'current' stories into?", trello.list_choices(options.trello_board_id))
|
86
|
+
options.finished_list_id = prompt_selection("Which Trello list would you like to put 'finished' stories into?", trello.list_choices(options.trello_board_id))
|
87
|
+
options.delivered_list_id = prompt_selection("Which Trello list would you like to put 'delivered' stories into?", trello.list_choices(options.trello_board_id))
|
88
|
+
options.accepted_list_id = prompt_selection("Which Trello list would you like to put 'accepted' stories into?", trello.list_choices(options.trello_board_id))
|
89
|
+
options.rejected_list_id = prompt_selection("Which Trello list would you like to put 'rejected' stories into?", trello.list_choices(options.trello_board_id))
|
90
|
+
options.bug_list_id = prompt_selection("Which Trello list would you like to put 'backlog' bugs into?", trello.list_choices(options.trello_board_id))
|
91
|
+
options.chore_list_id = prompt_selection("Which Trello list would you like to put 'backlog' chores into?", trello.list_choices(options.trello_board_id))
|
92
|
+
options.feature_list_id = prompt_selection("Which Trello list would you like to put 'backlog' features into?", trello.list_choices(options.trello_board_id))
|
93
|
+
options.release_list_id = prompt_selection("Which Trello list would you like to put 'backlog' releases into?", trello.list_choices(options.trello_board_id))
|
94
|
+
options.bug_label = prompt_selection('What color would you like to label bugs with?', trello.label_choices)
|
95
|
+
options.feature_label = prompt_selection('What color would you like to label features with?', trello.label_choices)
|
96
|
+
options.chore_label = prompt_selection('What color would you like to label chores with?', trello.label_choices)
|
97
|
+
options.release_label = prompt_selection('What color would you like to label releases with?', trello.label_choices)
|
98
|
+
end
|
109
99
|
|
110
|
-
|
111
|
-
|
112
|
-
|
100
|
+
# Prompts the user to select an option from the given list of choices.
|
101
|
+
def prompt_selection(question, choices)
|
102
|
+
say("\n#{question}")
|
103
|
+
choose do |menu|
|
104
|
+
menu.prompt = 'Please select an option : '
|
105
|
+
|
106
|
+
choices.each do |key, value|
|
107
|
+
menu.choice value do
|
108
|
+
return key
|
109
|
+
end
|
110
|
+
end
|
113
111
|
end
|
112
|
+
end
|
114
113
|
|
114
|
+
# Returns an instance of the pivotal wrapper.
|
115
|
+
def pivotal
|
116
|
+
@pivotal ||= PivotalToTrello::PivotalWrapper.new(options.pivotal_token)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Returns an instance of the trello wrapper.
|
120
|
+
def trello
|
121
|
+
@trello ||= PivotalToTrello::TrelloWrapper.new(options.trello_key, options.trello_token)
|
122
|
+
end
|
115
123
|
end
|
116
|
-
end
|
124
|
+
end
|