totrello 0.3.04 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +3 -83
- data/.hound.yml +1 -0
- data/.totrello.yml +3 -0
- data/.travis.yml +3 -7
- data/Gemfile +0 -1
- data/Guardfile +37 -0
- data/README.md +3 -1
- data/bin/ToTrello +31 -39
- data/lib/totrello.rb +3 -59
- data/lib/totrello/todos.rb +65 -0
- data/lib/totrello/trello_builder.rb +59 -0
- data/lib/totrello/trello_config.rb +31 -0
- data/lib/totrello/trelloize.rb +32 -0
- data/lib/totrello/version.rb +1 -1
- data/spec/fixtures/.totrello.yml +11 -0
- data/spec/fixtures/fixture.rb +19 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/todos_spec.rb +183 -0
- data/spec/totrello_spec.rb +7 -0
- data/spec/trello_builder_spec.rb +166 -0
- data/spec/trello_config_spec.rb +105 -0
- data/spec/trelloize_spec.rb +49 -0
- data/totrello.gemspec +10 -0
- metadata +165 -18
- data/lib/to_do_find.rb +0 -101
- data/lib/totrello_config.rb +0 -52
- data/lib/trello_creator.rb +0 -63
- data/test/spec_helper.rb +0 -8
- data/test/test_data/testing.rb +0 -19
- data/test/to_do_find_spec.rb +0 -67
- data/test/totrello_config_spec.rb +0 -23
- data/test/totrello_spec.rb +0 -67
- data/test/trello_creator_spec.rb +0 -60
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjdkYzk3ZjhjZTQyZmEzZWRhMTYxMmZjMzMzYWEwMjJjN2NhZGRjYQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjlhMjQ3M2ZiNWVlNjE1YjE1MDhlYjllYWRkMmI4OGZlYWU2Y2QyNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YWI2NmYxNDYzNzdjNjNlOWU3NmUwNjY1YmJiNmViMmEwMzdmZThhZmUxYTdm
|
10
|
+
ODM2MzUwYjJiMGU1ZDFlMWI0MmExOTI2Yjk2N2E4NjJkNzhkZTM4MzgwM2Ni
|
11
|
+
ZmQ0NTQyYzE0MjU2MDFmYzQ0NmUzMzAyOTgxMjI5YjFlZDkxMzA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzA1YjVkYWZjZGEzODE1NzA1ZmQ3YzRhYjJmYzQ4NGQ2OWFlMmQ5YWRlYWUx
|
14
|
+
MDZhMWEyNmVhYmQ4ZTc5ZjE2NjA4ZDMxNWQ3NjAwZWRkZDc2ZjU3ODgyMjNm
|
15
|
+
N2NjMTE3Mjg4MjAxMDk1MGRjOGU1ZTg2Y2U3N2M3ZjhhYzUyNGI=
|
data/.gitignore
CHANGED
@@ -5,87 +5,7 @@
|
|
5
5
|
/coverage/
|
6
6
|
/doc/
|
7
7
|
/pkg/
|
8
|
-
/spec/
|
8
|
+
/spec/cassettes/
|
9
9
|
/tmp/
|
10
|
-
*.
|
11
|
-
|
12
|
-
*.o
|
13
|
-
*.a
|
14
|
-
mkmf.log
|
15
|
-
|
16
|
-
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
17
|
-
|
18
|
-
/*.iml
|
19
|
-
|
20
|
-
## Directory-based project format:
|
21
|
-
.idea/
|
22
|
-
# if you remove the above rule, at least ignore the follwing:
|
23
|
-
|
24
|
-
# User-specific stuff:
|
25
|
-
# .idea/workspace.xml
|
26
|
-
# .idea/tasks.xml
|
27
|
-
# .idea/dictionaries
|
28
|
-
|
29
|
-
# Sensitive or high-churn files:
|
30
|
-
# .idea/dataSources.ids
|
31
|
-
# .idea/dataSources.xml
|
32
|
-
# .idea/sqlDataSources.xml
|
33
|
-
# .idea/dynamic.xml
|
34
|
-
# .idea/uiDesigner.xml
|
35
|
-
|
36
|
-
# Gradle:
|
37
|
-
# .idea/gradle.xml
|
38
|
-
# .idea/libraries
|
39
|
-
|
40
|
-
# Mongo Explorer plugin:
|
41
|
-
# .idea/mongoSettings.xml
|
42
|
-
|
43
|
-
## File-based project format:
|
44
|
-
*.ipr
|
45
|
-
*.iws
|
46
|
-
|
47
|
-
## Plugin-specific files:
|
48
|
-
|
49
|
-
# IntelliJ
|
50
|
-
out/
|
51
|
-
|
52
|
-
# mpeltonen/sbt-idea plugin
|
53
|
-
.idea_modules/
|
54
|
-
|
55
|
-
# JIRA plugin
|
56
|
-
atlassian-ide-plugin.xml
|
57
|
-
|
58
|
-
# Crashlytics plugin (for Android Studio and IntelliJ)
|
59
|
-
com_crashlytics_export_strings.xml
|
60
|
-
|
61
|
-
*.rbc
|
62
|
-
capybara-*.html
|
63
|
-
.rspec
|
64
|
-
/log
|
65
|
-
/tmp
|
66
|
-
/db/*.sqlite3
|
67
|
-
/public/system
|
68
|
-
/coverage/
|
69
|
-
/spec/tmp
|
70
|
-
**.orig
|
71
|
-
rerun.txt
|
72
|
-
pickle-email-*.html
|
73
|
-
|
74
|
-
# TODO Comment out these rules if you are OK with secrets being uploaded to the repo
|
75
|
-
config/initializers/secret_token.rb
|
76
|
-
config/secrets.yml
|
77
|
-
|
78
|
-
## Environment normalisation:
|
79
|
-
/.bundle
|
80
|
-
/vendor/bundle
|
81
|
-
|
82
|
-
# these should all be checked in to normalise the environment:
|
83
|
-
# Gemfile.lock, .ruby-version, .ruby-gemset
|
84
|
-
|
85
|
-
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
86
|
-
.rvmrc
|
87
|
-
|
88
|
-
# if using bower-rails ignore default bower_components path bower.json files
|
89
|
-
/vendor/assets/bower_components
|
90
|
-
*.bowerrc
|
91
|
-
bower.json
|
10
|
+
*.gem
|
11
|
+
.env
|
data/.hound.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
fail_on_violations: true
|
data/.totrello.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.
|
5
|
-
|
6
|
-
- 2.1.1
|
7
|
-
- 2.0.0-p247
|
8
|
-
- 1.9.3-p194
|
9
|
-
script: gem install bundler && bundle exec rspec test/*
|
3
|
+
- 2.3.0
|
4
|
+
- 2.2.4
|
5
|
+
script: gem install bundler && bundle exec rspec
|
10
6
|
deploy:
|
11
7
|
provider: rubygems
|
12
8
|
api_key:
|
data/Gemfile
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec feature)
|
6
|
+
|
7
|
+
## Uncomment to clear the screen before every task
|
8
|
+
# clearing :on
|
9
|
+
|
10
|
+
## Guard internally checks for changes in the Guardfile and exits.
|
11
|
+
## If you want Guard to automatically start up again, run guard in a
|
12
|
+
## shell loop, e.g.:
|
13
|
+
##
|
14
|
+
## $ while bundle exec guard; do echo "Restarting Guard..."; done
|
15
|
+
##
|
16
|
+
## Note: if you are using the `directories` clause above and you are not
|
17
|
+
## watching the project directory ('.'), the you will want to move the Guardfile
|
18
|
+
## to a watched dir and symlink it back, e.g.
|
19
|
+
#
|
20
|
+
# $ mkdir config
|
21
|
+
# $ mv Guardfile config/
|
22
|
+
# $ ln -s config/Guardfile .
|
23
|
+
#
|
24
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
25
|
+
|
26
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
27
|
+
# rspec may be run, below are examples of the most common uses.
|
28
|
+
# * bundler: 'bundle exec rspec'
|
29
|
+
# * bundler binstubs: 'bin/rspec'
|
30
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
31
|
+
# installed the spring binstubs per the docs)
|
32
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
33
|
+
# * 'just' rspec: 'rspec'
|
34
|
+
guard :rspec, cmd: 'rspec' do
|
35
|
+
watch(%r{^spec/.+_spec\.rb$})
|
36
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
37
|
+
end
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Test Coverage](https://codeclimate.com/github/whatisinternet/ToTrello/badges/coverage.svg)](https://codeclimate.com/github/whatisinternet/ToTrello)
|
5
5
|
# Totrello
|
6
6
|
|
7
|
-
|
7
|
+
Turns Todo items into Trello cards
|
8
8
|
|
9
9
|
## Notes
|
10
10
|
|
@@ -65,6 +65,8 @@ The ToTrello yml file allows you to customize the way ToTrello functions:
|
|
65
65
|
|
66
66
|
## Contributing
|
67
67
|
|
68
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
69
|
+
|
68
70
|
1. Fork it ( https://github.com/whatisinternet/totrello/fork )
|
69
71
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
70
72
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
data/bin/ToTrello
CHANGED
@@ -1,52 +1,44 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'totrello'
|
3
|
+
require 'totrello/trelloize'
|
4
|
+
|
4
5
|
TRELLO_DEVELOPER_PUBLIC_KEY = ENV['TRELLO_DEVELOPER_PUBLIC_KEY']
|
5
6
|
TRELLO_MEMBER_TOKEN = ENV['TRELLO_MEMBER_TOKEN']
|
6
7
|
|
7
8
|
def main
|
9
|
+
return trello unless TRELLO_DEVELOPER_PUBLIC_KEY.nil? || TRELLO_MEMBER_TOKEN.nil?
|
10
|
+
error_message
|
11
|
+
exit(-1)
|
12
|
+
end
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
exit(-1)
|
26
|
-
else
|
27
|
-
|
28
|
-
dir = ARGV[0].to_s
|
29
|
-
if dir == ''
|
30
|
-
dir = Dir.pwd
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
puts "You've specified to work in: #{dir}"
|
35
|
-
trel = Totrello::Trelloize.new(dir)
|
36
|
-
puts 'Generating your board'
|
37
|
-
board = trel.create_or_gen_board
|
38
|
-
return -1 if board.nil?
|
39
|
-
puts "Created or found a board with the ID: #{board.name}"
|
40
|
-
puts 'Finding your todo items... '
|
41
|
-
todos = trel.get_todos
|
42
|
-
puts "Woot! We've got'em"
|
43
|
-
trel.create_cards(board, todos)
|
44
|
-
puts "And you're ready to go!"
|
45
|
-
|
14
|
+
def error_message
|
15
|
+
puts "ERROR:\n"
|
16
|
+
puts "Your Trello developer PK is: #{TRELLO_DEVELOPER_PUBLIC_KEY}\n"
|
17
|
+
puts "Your Trello member token is: #{TRELLO_MEMBER_TOKEN}\n\n"
|
18
|
+
puts "It looks like you haven't set either a TRELLO_DEVELOPER_PUBLIC_KEY or TRELLO_MEMBER_TOKEN.\n\n"
|
19
|
+
puts "You can generate a TRELLO_DEVELOPER_PUBLIC_KEY at:\n"
|
20
|
+
puts "https://trello.com/1/appKey/generate\n"
|
21
|
+
puts "You can generate a TRELLO_MEMBER_TOKEN at:\n"
|
22
|
+
puts " https://trello.com/1/authorize?key=[TRELLO_DEVELOPER_PUBLIC_KEY]&name=ToTrelloGem&expiration=never&response_type=token&scope=read,write\n\n"
|
23
|
+
puts "Then run:\n"
|
24
|
+
puts " $ export TRELLO_DEVELOPER_PUBLIC_KEY='[Your key here]'\n"
|
25
|
+
puts " $ export TRELLO_MEMBER_TOKEN='[Your key here]'\n"
|
26
|
+
puts "\nAnd try ToTrello again.\n"
|
27
|
+
end
|
46
28
|
|
29
|
+
def trello
|
30
|
+
dir = ARGV[0].to_s
|
31
|
+
if dir == ''
|
32
|
+
dir = Dir.pwd
|
47
33
|
end
|
48
34
|
|
35
|
+
trel = Trelloize.new(dir)
|
36
|
+
todo_finder = Todos.new
|
37
|
+
|
38
|
+
board = trel.trello.find_or_create_board(trel.config)
|
39
|
+
todos = todo_finder.all_todos(trel.directory, trel.config)
|
40
|
+
trel.find_and_create_cards_from_todos(todos, board)
|
49
41
|
end
|
50
42
|
|
51
43
|
|
52
|
-
main
|
44
|
+
main
|
data/lib/totrello.rb
CHANGED
@@ -1,61 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require 'trello_creator'
|
3
|
-
require 'to_do_find'
|
4
|
-
require 'totrello_config'
|
1
|
+
require 'totrello/version'
|
5
2
|
|
6
|
-
|
7
|
-
module
|
8
|
-
|
9
|
-
class Trelloize
|
10
|
-
@trello
|
11
|
-
@directory
|
12
|
-
@config
|
13
|
-
|
14
|
-
def initialize(directory)
|
15
|
-
@trello = TrelloCreator.new
|
16
|
-
@directory = directory
|
17
|
-
totrello_config = TotrelloConfig.new(directory)
|
18
|
-
@config = totrello_config.build_hash
|
19
|
-
end
|
20
|
-
|
21
|
-
def create_or_gen_board
|
22
|
-
board = @trello.find_board(@config[:board_name].to_s)
|
23
|
-
board ||= @trello.create_board(@config[:board_name].to_s, 'Auto Generated by ToTrello Gem')
|
24
|
-
end
|
25
|
-
|
26
|
-
def create_trello_card(board, list, todo, filename)
|
27
|
-
description = gen_description(filename,todo, @config[:project_name].to_s)
|
28
|
-
card = @trello.create_card(board, todo[:todo], description ,list)
|
29
|
-
end
|
30
|
-
|
31
|
-
def gen_description(file, todo, project_name)
|
32
|
-
out = "TODO item found by the [ToTrello](https://rubygems.org/gems/totrello) gem\n"
|
33
|
-
out += "**Project name:** #{project_name}\n"
|
34
|
-
out += "**Filename**: #{file}\n"
|
35
|
-
out += "**Action item**: #{todo[:todo]}\n"
|
36
|
-
out += "**Location (at or near) line**: #{todo[:location]}\n"
|
37
|
-
end
|
38
|
-
|
39
|
-
def create_cards(board, todos)
|
40
|
-
todos[:todo_list].each do |tdl|
|
41
|
-
tdl[:todos].each do |td|
|
42
|
-
unless td == ''
|
43
|
-
create_trello_card(board, @config[:default_list], td, tdl[:file])
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_todos
|
50
|
-
todo = ToDoFind.new
|
51
|
-
todos = todo.search(@directory,
|
52
|
-
Array( @config[:excludes]),
|
53
|
-
Array( @config[:todo_types]),
|
54
|
-
Array( @config[:file_types]),
|
55
|
-
Array( @config[:comment_style]))
|
56
|
-
todos
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
3
|
+
# ToTrello
|
4
|
+
module ToTrello
|
61
5
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Todos
|
2
|
+
class Todos
|
3
|
+
def all_todos(root_directory = "#{Dir.pwd}", config)
|
4
|
+
files = load_files(root_directory, config)
|
5
|
+
files.map {|f| todos_for_file(f, config) }.flatten
|
6
|
+
end
|
7
|
+
|
8
|
+
def load_files(root_directory = "#{Dir.pwd}", config)
|
9
|
+
Dir.glob("#{root_directory}/**/*").select do |f|
|
10
|
+
next if File.directory?(f) || config.excludes.include?(f)
|
11
|
+
split_file_name = f.split('.')
|
12
|
+
File.file?(f) &&
|
13
|
+
config.file_types.include?(".#{split_file_name.last}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def todos_for_file(file, config)
|
18
|
+
lines_with_indexes = lines_with_index_for_file(file)
|
19
|
+
lines_with_indexes.reduce([]) do |todos, line|
|
20
|
+
if todo?(line[:line], config)
|
21
|
+
cleaned_todo = clean_todo(line[:line], config)
|
22
|
+
unless cleaned_todo.nil?
|
23
|
+
todos.push({
|
24
|
+
todo: cleaned_todo,
|
25
|
+
line_number: line[:index],
|
26
|
+
file: file.to_s
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
todos
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def lines_with_index_for_file(file)
|
35
|
+
lines = File.readlines file.to_s
|
36
|
+
lines.map.with_index do |line, idx|
|
37
|
+
{ line: line, index: idx }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def todo?(line, config)
|
42
|
+
return false if line.empty?
|
43
|
+
todo_types = config.todo_types
|
44
|
+
todo_types.any? do |todo_type|
|
45
|
+
return false if line.index(todo_type).nil?
|
46
|
+
return false unless config.comment_style.any? do |cs|
|
47
|
+
line.strip.start_with?(cs)
|
48
|
+
end
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def clean_todo(todo, config)
|
54
|
+
config.todo_types.each do |style|
|
55
|
+
todo.delete!(style)
|
56
|
+
end
|
57
|
+
config.comment_style.each do |style|
|
58
|
+
todo.delete!(style)
|
59
|
+
end
|
60
|
+
todo.delete!('#')
|
61
|
+
todo.delete!(':')
|
62
|
+
todo.chomp!
|
63
|
+
todo.lstrip!
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'trello'
|
2
|
+
|
3
|
+
# TrelloBuilder
|
4
|
+
class TrelloBuilder
|
5
|
+
def initialize
|
6
|
+
Trello.configure do |config|
|
7
|
+
config.developer_public_key = TRELLO_DEVELOPER_PUBLIC_KEY
|
8
|
+
config.member_token = TRELLO_MEMBER_TOKEN
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def cards(board, list)
|
13
|
+
Trello::List.new('idBoard' => board, 'id' => list).cards
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_board(config)
|
17
|
+
Trello::Board.create(name: config.board_name, description: 'A Trello board')
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_card(board, card_name, description, list_name)
|
21
|
+
list_names = ['To Do', 'Doing', 'Done']
|
22
|
+
return if card_exists?(board, list_names, card_name)
|
23
|
+
list = find_list(board, list_name)
|
24
|
+
card = Trello::Card.create(name: card_name,
|
25
|
+
list_id: list,
|
26
|
+
desc: description)
|
27
|
+
card.save
|
28
|
+
end
|
29
|
+
|
30
|
+
def card_exists?(board, list_names, card_name)
|
31
|
+
list_names.any? do |list_name|
|
32
|
+
list = find_list(board, list_name)
|
33
|
+
all_cards = cards(board, list)
|
34
|
+
all_cards.any? do |card|
|
35
|
+
card.name.include? card_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_board(config)
|
41
|
+
board_name = config.board_name
|
42
|
+
trello_board = Trello::Board.all.find do |board|
|
43
|
+
board.name.casecmp(board_name.upcase) && !board.closed
|
44
|
+
end
|
45
|
+
return nil if trello_board.nil?
|
46
|
+
Trello::Board.find(trello_board.id)
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_list(board, list_name)
|
50
|
+
return unless board
|
51
|
+
board.lists.find { |list| list.name == list_name }.id
|
52
|
+
end
|
53
|
+
|
54
|
+
def find_or_create_board(config)
|
55
|
+
board = find_board(config)
|
56
|
+
board = create_board(config) if board.nil?
|
57
|
+
board
|
58
|
+
end
|
59
|
+
end
|