tracco 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,15 @@
1
1
  language: ruby
2
+ bundler_args: --without development
2
3
  rvm:
3
4
  - 1.9.3
4
-
5
+ - 2.0.0
6
+ - ruby-head
5
7
  env:
6
8
  global:
7
9
  - developer_public_key: e/zPNGKOwapoxFWZs/CBTAhaoqrDTkqqz+InOmCUvGBcZBpUxH398nPLv8Hi\nNQSvWuspzqanyNbbQrTA/2XhsWF1gIFX+gNexYM7S+MxtRwUD3cpVT8DzVOS\nMuckdMTEAADVsm92vIX/bUs5igxD4+zfXlhzXUNDrzRlZnsUF2M=
8
10
  - access_token_key: GG1Q8oq7GkaXjP0lbMgvQLLEi+LXOZlwmELqjPk39Exfy8114QUs2ki8nr9n\ndGO+tgOSZsCd/bt9IHxS3WWWU0INSYOTgp/prfsDDgosg7/Elk/b6w1OW0At\nX3VAjMeI0yAGloT6XB58LCFyrj6S2b4vCQqyaHR3tlTHai/5bMQ=
9
11
  - tracker_username=trackinguser
10
- - MONGOID_ENV=test
12
+ - TRACCO_ENV=test
11
13
 
12
14
  services:
13
15
  - mongodb
@@ -17,4 +19,3 @@ script: ./script/ci/run_build.sh
17
19
  before_script:
18
20
  - mongo tracco_test --eval 'db.addUser("travis", "test");'
19
21
  - "./script/ci/before_script.sh"
20
-
data/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ 0.0.16 / 2013-03-12
2
+ ==================
3
+ slowly migrating from rake tasks to bin commands
4
+ improving readme
5
+ dropping ruby 1.9.2 support due to Mongoid issues (http://mongoid.org/en/mongoid/docs/tips.html#ruby)
6
+ updating depending gems
7
+ improving Tracco load env, avoiding double env loading when running the specs, renaming MONGOID_ENV to a more generic TRACCO_ENV
8
+ adding a logo for Tracco!
9
+ adding Ruby 2.0.0 compatibility
10
+ adding awesome_print gem to the console task
11
+ adding an helper task to copy the configuration template files
1
12
 
2
13
  0.0.15 / 2013-03-01
3
14
  ==================
data/Gemfile CHANGED
@@ -5,5 +5,11 @@ gemspec
5
5
  # gem 'ruby-trello', :require => 'trello', :path => '../ruby-trello' # to hack on the ruby-trello gem itself
6
6
 
7
7
  group :test do
8
+ gem 'rspec'
9
+ gem 'rspec-mocks'
10
+ gem 'mongoid-rspec'
11
+ gem 'database_cleaner'
12
+ gem 'factory_girl'
8
13
  gem 'simplecov', :require => false, :platforms => [:mri, :mri_19]
14
+ gem 'rake' # see http://about.travis-ci.org/docs/user/languages/ruby/#Default-Test-Script
9
15
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tracco (0.0.15)
4
+ tracco (0.0.16)
5
5
  bson_ext
6
6
  chronic
7
7
  google_drive
@@ -9,6 +9,7 @@ PATH
9
9
  mongoid
10
10
  rainbow
11
11
  ruby-trello
12
+ thor
12
13
 
13
14
  GEM
14
15
  remote: https://rubygems.org/
@@ -20,14 +21,15 @@ GEM
20
21
  i18n (~> 0.6)
21
22
  multi_json (~> 1.0)
22
23
  addressable (2.3.3)
23
- bson (1.8.2)
24
- bson_ext (1.8.2)
25
- bson (~> 1.8.2)
24
+ awesome_print (1.1.0)
25
+ bson (1.8.3)
26
+ bson_ext (1.8.3)
27
+ bson (~> 1.8.3)
26
28
  builder (3.0.4)
27
29
  chronic (0.9.1)
28
30
  columnize (0.3.6)
29
31
  database_cleaner (0.9.1)
30
- debugger (1.3.3)
32
+ debugger (1.4.0)
31
33
  columnize (>= 0.3.1)
32
34
  debugger-linecache (~> 1.1.1)
33
35
  debugger-ruby_core_source (~> 1.2.0)
@@ -39,27 +41,27 @@ GEM
39
41
  activesupport (>= 3.0.0)
40
42
  faraday (0.8.6)
41
43
  multipart-post (~> 1.1)
42
- google_drive (0.3.3)
44
+ google_drive (0.3.4)
43
45
  nokogiri (>= 1.4.4, != 1.5.2, != 1.5.1)
44
46
  oauth (>= 0.3.6)
45
47
  oauth2 (>= 0.5.0)
46
48
  highline (1.6.15)
47
49
  httpauth (0.2.0)
48
- i18n (0.6.2)
50
+ i18n (0.6.4)
49
51
  json (1.7.7)
50
- jwt (0.1.5)
51
- multi_json (>= 1.0)
52
+ jwt (0.1.7)
53
+ multi_json (>= 1.5)
52
54
  mime-types (1.21)
53
55
  mongoid (3.1.2)
54
56
  activemodel (~> 3.2)
55
57
  moped (~> 1.4.2)
56
58
  origin (~> 1.0)
57
59
  tzinfo (~> 0.3.22)
58
- mongoid-rspec (1.6.0)
60
+ mongoid-rspec (1.7.0)
59
61
  mongoid (>= 3.0.1)
60
62
  rake
61
63
  rspec (>= 2.9)
62
- moped (1.4.2)
64
+ moped (1.4.3)
63
65
  multi_json (1.6.1)
64
66
  multi_xml (0.5.3)
65
67
  multipart-post (1.2.0)
@@ -86,7 +88,7 @@ GEM
86
88
  rspec-expectations (2.13.0)
87
89
  diff-lcs (>= 1.1.3, < 2.0)
88
90
  rspec-mocks (2.13.0)
89
- ruby-trello (0.5.1)
91
+ ruby-trello (0.6.0)
90
92
  activemodel
91
93
  addressable (~> 2.3)
92
94
  json
@@ -96,12 +98,14 @@ GEM
96
98
  multi_json (~> 1.0)
97
99
  simplecov-html (~> 0.7.1)
98
100
  simplecov-html (0.7.1)
99
- tzinfo (0.3.35)
101
+ thor (0.17.0)
102
+ tzinfo (0.3.36)
100
103
 
101
104
  PLATFORMS
102
105
  ruby
103
106
 
104
107
  DEPENDENCIES
108
+ awesome_print
105
109
  database_cleaner
106
110
  debugger
107
111
  factory_girl
data/README.md CHANGED
@@ -1,30 +1,35 @@
1
- [![Build Status](https://secure.travis-ci.org/xpepper/tracco.png)](http://travis-ci.org/xpepper/tracco)
2
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/xpepper/tracco)
1
+ ![Tracco Logo](https://raw.github.com/xpepper/tracco/master/images/tracco.logo.png)
3
2
 
4
- # Tracco
3
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/tracco.png)](http://badge.fury.io/rb/tracco)
4
+ [![Build Status](https://secure.travis-ci.org/xpepper/tracco.png?branch=master)](http://travis-ci.org/xpepper/tracco)
5
+ [![Code Climate](https://codeclimate.com/github/xpepper/tracco.png)](https://codeclimate.com/github/xpepper/tracco)
5
6
 
6
7
  ## What is Tracco?
7
8
  Tracco is an effort tracker for Trello: the purpose of Tracco is to extract and track estimates and actual efforts out of the cards on your Trello boards.
8
- All you have to do is notify all of your estimates and efforts tracked on your Trello cards using a simple conventional format.
9
+ All you have to do is add estimates and efforts as comments added on your Trello cards, using a simple conventional format.
9
10
  Tracco will extract and store these estimates and actual efforts to let you mine useful key metrics (e.g. estimate errors, remaining efforts, pair programming frequencies, and so on).
10
11
 
11
12
  ## Why Tracco?
12
- Trello is a very good surrogate for a physical team board: it's simple and effective, and it can really help when you have a distributed team.
13
- That said, Trello does not (still) offer a way to track time estimated and actually spent on cards, though many people [ask for that feature](https://trello.com/card/time-tracking/4d5ea62fd76aa1136000000c/1054) on Trello's development board.
13
+ [Trello](https://trello.com) is a very good surrogate for a physical team board: it's simple and effective, and it can really help when you have a distributed team.
14
+ That said, Trello (still) doesn't offer a way to track time estimated and actually spent on cards, though many people are [asking for that feature](https://trello.com/card/time-tracking/4d5ea62fd76aa1136000000c/1054) on Trello's development board.
15
+
16
+ Having that precise need, we defined a simple convention to track estimates and efforts on cards: we use a predefined board member (let's call him 'tracking user') which we sent comments to (we call them 'tracking notifications'), using the comment form available on the card panel.
17
+
18
+ ![A tracking example](https://raw.github.com/xpepper/tracco/master/images/tracking_example.png)
14
19
 
15
- Having that precise need, we defined a simple convention to track estimates and efforts on cards: we use a predefined board member (let's call him 'tracking user') which we sent special notifications to (we call them 'tracking notifications').
16
20
  This 'tracking user' will then receives estimates and efforts notifications, and Tracco will collect and store them.
17
- Moreover, a web app will be soon available to properly present card estimates and efforts (we're working on it).
21
+ Moreover, a web app is available to properly present card estimates and efforts: [Trello Effort App](https://github.com/xpepper/trello_effort_app).
18
22
 
19
23
  ## More details
20
- All you need to have to start using Tracco is a Trello account, a Trello board and a board member to use as 'tracking user'.
24
+ To start using Tracco you should have a Trello account, a Trello board and a board member to use as 'tracking user'.
21
25
  You'll also need to know your Trello developer key and generate a proper auth token to have access to the trackinguser's notifications.
22
26
  To see how to have these two keys, see [the following section](#api_key).
23
27
 
24
28
  The Trello API is used behind the scenes to read data from the team board. Tracco uses the awesome [Trello API Ruby wrapper](https://github.com/jeremytregunna/ruby-trello) for this purpose.
25
29
 
26
30
  ## Usage
27
- This tool can be used as a standalone gem or cloning this git repo.
31
+ Tracco is not provided with a built-in viewer for the collected data, so the recommended way to use Tracco is by using [Trello Effort App](https://github.com/xpepper/trello_effort_app) or including the gem in your own viewer app.
32
+ By the way, this tool can be used as a standalone gem or cloning this git repo.
28
33
 
29
34
  ### Installation as a ruby gem
30
35
 
@@ -38,16 +43,21 @@ gem install tracco
38
43
  git clone git://github.com/xpepper/tracco.git
39
44
  ```
40
45
 
41
- Then cd in the cloned repo and copy the config template
46
+ Then cd in the cloned repo and install all the dependencies with Bundler
42
47
 
43
48
  ```shell
44
49
  cd tracco
50
+ bundle install
51
+ ```
52
+
53
+ Then copy the config template
54
+ ```shell
45
55
  cp config/config.template.yaml config/config.yml
46
56
  ```
47
57
 
48
- and then fill the correct values in the placeholders in config.yml (see _"Where do I get an API key and API secret?"_ section).
58
+ and fill the correct values in the placeholders (see _"Where do I get an API key and API secret?"_ section).
49
59
 
50
- Then copy the mongoid config template
60
+ And finally copy the mongoid config template
51
61
 
52
62
  ```shell
53
63
  cp config/mongoid.template.yaml config/mongoid.yml
@@ -55,33 +65,27 @@ cp config/mongoid.template.yaml config/mongoid.yml
55
65
 
56
66
  and fill the correct values for the mongodb environments ([see here](http://mongoid.org/en/mongoid/docs/installation.html#configuration) to have more details).
57
67
 
58
- Then run bundle to get all the required gems:
59
-
60
- ```shell
61
- bundle install
62
- ```
63
-
64
68
 
65
69
  Full Disclosure: this library is still work-in-progress, so if you find anything missing or not functioning as you expect it to, please [open an issue on github](https://github.com/xpepper/tracco/issues).
66
70
 
67
71
  ## Requirements
72
+ * MRI version 1.9.3+
68
73
  * [mongoDB](http://www.mongodb.org/) - macosx users with homebrew will just run 'brew install mongodb' to have mongoDB installed on their machine.
69
74
  * (optional) [rvm](https://rvm.io/rvm/install/) is useful (but optional) for development
70
75
 
71
76
 
72
-
73
77
  ### <a id="api_key"></a>Where do I get an API key?
74
78
  Log in to Trello with your account and visit [https://trello.com/1/appKey/generate](https://trello.com/1/appKey/generate) to get your developer\_public\_key.
75
79
 
76
80
  ### Where do I get an API Access Token Key?
77
81
  To generate a proper access token key, log in to Trello with the 'tracking user' account. Then go to this URL:
78
82
 
79
- https://trello.com/1/connect?key=<YOUR_DEVELOPER_PUBLIC_KEY>&name=Trello+Effort+Tracker&response_type=token&scope=read,write&expiration=never
83
+ https://trello.com/1/connect?key=<YOUR_DEVELOPER_PUBLIC_KEY>&name=Tracco&response_type=token&scope=read&expiration=never
80
84
 
81
- At the end of this process, you'll receive a valid access\_token\_key, which is needed by Tracco to fetch all the tracking notifications sent to the 'tracking user'.
85
+ At the end of this process, you'll receive a valid access\_token\_key, which is needed by Tracco to have the proper rights to fetch all the tracking notifications sent as comments to the 'tracking user'.
82
86
 
83
- ## Usage
84
- The best way is to use one of the rake task defined, e.g.
87
+ ## Collecting data from Trello
88
+ To collect and store tracking data from your Trello board, you can use one of the provided rake tasks, e.g.
85
89
 
86
90
  ```ruby
87
91
  rake 'run:today[test]' # will extract today's tracked data and store on the test db
@@ -106,7 +110,7 @@ Tracking data collected from Trello are stored in a MongoDB database.
106
110
 
107
111
  There are two env variables you can set to configure mongodb
108
112
 
109
- - `MONGOID_ENV` defines which mongodb env is actually used (development, test, production). Development is the default mongo environment.
113
+ - `TRACCO_ENV` defines which mongodb environment is actually used ("development", "test", "production"). Development is the default environment.
110
114
  - `MONGOID_CONFIG_PATH` defines the path to the mongoid configuration file (default is `config/mongoid.yml`)
111
115
 
112
116
  A standard mongoid.yml is the following:
@@ -171,7 +175,7 @@ The default env is development. To load a console in the (e.g.) production db en
171
175
  rake "console[production]"
172
176
  ```
173
177
 
174
- ### Estimate format convention
178
+ ## Estimate format convention
175
179
  To set an estimate on a card, a Trello user should send a notification from that card to the tracker username, e.g.
176
180
 
177
181
  @trackinguser [15p]
@@ -184,7 +188,7 @@ estimates can be given in hours (h), days (d/g) or pomodori (p).
184
188
 
185
189
  will add the estimate (4 hours) in date 22.11.2012.
186
190
 
187
- ### Effort format convention
191
+ ## Effort format convention
188
192
  To set an effort in the current day on a card, a Trello user should send a notification from that card to the tracker username, e.g.
189
193
 
190
194
  @trackinguser +6p
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
3
+
4
+ require 'trello'
5
+ require 'rainbow'
6
+ require 'set'
7
+ require 'yaml'
8
+ require 'chronic'
9
+ require 'mongoid'
10
+ require 'forwardable'
11
+
12
+ require 'tracco/cli'
13
+ require 'tracco/version'
14
+ require 'tracco/mongoid_helper'
15
+ require 'tracco/trello_configuration'
16
+ require 'tracco/trello_authorize'
17
+ require 'tracco/models/tracked_card'
18
+ require 'tracco/models/member'
19
+ require 'tracco/models/estimate'
20
+ require 'tracco/models/effort'
21
+ require 'tracco/tracking/base'
22
+ require 'tracco/tracking/estimate_tracking'
23
+ require 'tracco/tracking/effort_tracking'
24
+ require 'tracco/tracking/card_done_tracking'
25
+ require 'tracco/tracking/invalid_tracking'
26
+ require 'tracco/tracking/factory'
27
+ require 'tracco/trello_tracker'
28
+ require 'tracco/configuration'
29
+ require 'tracco/exporters/google_docs'
30
+
31
+ require 'patches/trello/member'
32
+ require 'patches/trello/card'
33
+
34
+ Tracco::CLI.start(ARGV)
Binary file
@@ -8,7 +8,7 @@ module Trello
8
8
  begin
9
9
  list_name = list.name.strip
10
10
  rescue Trello::Error => e
11
- Trello::Logger.error("Cannot find column for card #{name}")
11
+ Trello.logger.error("Cannot find column for card #{name}")
12
12
  end
13
13
 
14
14
  !!(list_name =~ /^DONE/i)
@@ -1,39 +1,56 @@
1
+ #TODO: deprecated (use 'tracco console')
1
2
  desc "Open an irb session preloaded with this library, e.g. rake 'console[production]' will open a irb session with the production db env"
2
- task :console, [:db_env] do |t, args|
3
- args.with_defaults(db_env: "development")
4
- sh "export MONGOID_ENV=#{args.db_env}; irb -rubygems -I lib -r tracco.rb -r startup_trello.rb"
3
+ task :console, [:tracco_env] do |t, args|
4
+ args.with_defaults(tracco_env: "development")
5
+ sh "export TRACCO_ENV=#{args.tracco_env}; irb -rubygems -I lib -r tracco -r startup_trello.rb -r awesome_print"
5
6
  end
6
7
 
7
- task :c, [:db_env] do |t, args|
8
- Rake::Task[:console].invoke(args.db_env)
8
+ #TODO: deprecated (use 'tracco console')
9
+ task :c, [:tracco_env] do |t, args|
10
+ Rake::Task[:console].invoke(args.tracco_env)
9
11
  end
10
12
 
13
+ desc "Copy template config files"
14
+ task :prepare do
15
+ Dir.glob("config/*.template.yml").each do |file|
16
+ template_file = File.basename(file)
17
+ target_file = template_file.sub('.template', '')
18
+ if File.exists?(File.join('config', target_file))
19
+ puts "skipping #{target_file.color(:yellow)}, already exists."
20
+ else
21
+ cp File.join('config', template_file), File.join('config', target_file)
22
+ puts "please edit the #{target_file} to have all the proper configurations"
23
+ end
24
+ end
25
+ end
26
+
27
+ #TODO: deprecated (use 'tracco collect')
11
28
  namespace :run do
12
29
  include TrelloConfiguration
13
30
 
14
31
  desc "Run on the cards tracked starting from a given day, e.g. rake 'run:from_day[2012-11-1]'"
15
- task :from_day, [:starting_date, :db_env] => [:ensure_environment] do |t, args|
16
- args.with_defaults(starting_date: Date.today.to_s, db_env: "development")
17
- TrelloConfiguration::Database.load_env(args.db_env)
32
+ task :from_day, [:starting_date, :tracco_env] => [:ensure_environment] do |t, args|
33
+ args.with_defaults(starting_date: Date.today.to_s, tracco_env: "development")
34
+ Tracco::Database.load_env(args.tracco_env)
18
35
 
19
36
  tracker = Tracco::TrelloTracker.new
20
37
  tracker.track(Date.parse(args.starting_date))
21
38
  end
22
39
 
23
40
  desc "Run on the cards tracked today, #{Date.today}"
24
- task :today, [:db_env] => [:ensure_environment] do |t, args|
25
- args.with_defaults(db_env: "development")
26
- Rake.application.invoke_task("run:from_day[#{Date.today.to_s}, #{args.db_env}]")
41
+ task :today, [:tracco_env] => [:ensure_environment] do |t, args|
42
+ args.with_defaults(tracco_env: "development")
43
+ Rake.application.invoke_task("run:from_day[#{Date.today.to_s}, #{args.tracco_env}]")
27
44
  end
28
45
  end
29
46
 
30
47
  namespace :export do
31
48
  desc "Export all cards to a google docs spreadsheet, e.g. rake \"export:google_docs[my_sheet,tracking,production]\""
32
- task :google_docs, [:spreadsheet, :worksheet, :db_env] => [:ensure_environment] do |t, args|
33
- args.with_defaults(db_env: "development")
34
- TrelloConfiguration::Database.load_env(args.db_env)
49
+ task :google_docs, [:spreadsheet, :worksheet, :tracco_env] => [:ensure_environment] do |t, args|
50
+ args.with_defaults(tracco_env: "development")
51
+ Tracco::Database.load_env(args.tracco_env)
35
52
 
36
- exporter = Tracco::GoogleDocsExporter.new(args.spreadsheet, args.worksheet)
53
+ exporter = Tracco::Exporters::GoogleDocs.new(args.spreadsheet, args.worksheet)
37
54
  spreadsheet_url = exporter.export
38
55
 
39
56
  puts "[DONE]".color(:green)
@@ -6,6 +6,8 @@ require 'chronic'
6
6
  require 'mongoid'
7
7
  require 'forwardable'
8
8
 
9
+ require 'tracco/cli'
10
+ require 'tracco/version'
9
11
  require 'tracco/mongoid_helper'
10
12
  require 'tracco/trello_configuration'
11
13
  require 'tracco/trello_authorize'
@@ -20,11 +22,11 @@ require 'tracco/tracking/card_done_tracking'
20
22
  require 'tracco/tracking/invalid_tracking'
21
23
  require 'tracco/tracking/factory'
22
24
  require 'tracco/trello_tracker'
23
- require 'tracco/google_docs_exporter'
25
+ require 'tracco/configuration'
26
+ require 'tracco/exporters/google_docs'
24
27
 
25
28
  require 'patches/trello/member'
26
29
  require 'patches/trello/card'
27
30
 
28
- TrelloConfiguration::Database.load_env(ENV['MONGOID_ENV'] || "development", ENV['MONGOID_CONFIG_PATH'])
29
-
30
31
  Trello.logger.level = Logger::DEBUG
32
+ Tracco.load_env!
@@ -0,0 +1,66 @@
1
+ require 'thor'
2
+ require 'thor/actions'
3
+
4
+ module Tracco
5
+ class CLI < Thor
6
+ include Thor::Actions
7
+
8
+ desc "console ENVIRONMENT", "Open an irb session preloaded with this library"
9
+ long_desc <<-LONGDESC
10
+ Open an irb session preloaded with this library.
11
+ e.g. 'tracco console production' will open a irb session with the production environment
12
+ LONGDESC
13
+ def console(environment="development")
14
+ error("invalid environment specified: #{environment}") unless is_valid_env?(environment)
15
+
16
+ run "export TRACCO_ENV=#{environment}; irb -rubygems -I lib -r tracco -r startup_trello.rb -r awesome_print"
17
+ end
18
+ map %w(c) => :console
19
+
20
+
21
+ desc "collect STARTING_FROM", "Run tracking data fetching on the cards tracked starting from a given date"
22
+ method_option :environment, :aliases => "-e", :desc => "the env to use", :default => "development"
23
+ method_option :mongoid_config_path, :aliases => "-m", :desc => "the mongoid config file to use"
24
+ def collect(starting_date=Date.today.to_s)
25
+ environment = options[:environment]
26
+ error("invalid environment specified: #{environment}") unless is_valid_env?(environment)
27
+
28
+ starting_date = Date.today.to_s if starting_date == "today"
29
+ error("invalid date: #{starting_date}") unless is_valid_date?(starting_date)
30
+
31
+ Tracco::Database.load_env(environment, options[:mongoid_config_path])
32
+
33
+ puts "collecting tracking data starting from #{starting_date} in the #{environment} env."
34
+ tracker = Tracco::TrelloTracker.new
35
+ tracker.track(Date.parse(starting_date))
36
+ end
37
+
38
+
39
+ desc "version", "Prints Tracco's version information"
40
+ def version
41
+ say "Tracco version #{Tracco::VERSION}"
42
+ end
43
+ map %w(-v --version) => :version
44
+
45
+
46
+ private
47
+
48
+ def is_valid_env?(environment)
49
+ %w{production development test}.include? environment
50
+ end
51
+
52
+ def is_valid_date?(date)
53
+ begin
54
+ Date.parse(date)
55
+ true
56
+ rescue ArgumentError
57
+ false
58
+ end
59
+ end
60
+
61
+ def error(message)
62
+ say "ERROR: #{message}"
63
+ exit 1
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,27 @@
1
+ module Tracco
2
+ def self.environment
3
+ ENV['TRACCO_ENV']
4
+ end
5
+
6
+ def self.environment=(env_name)
7
+ ENV['TRACCO_ENV'] = env_name.to_s
8
+ end
9
+
10
+ def self.load_env!
11
+ begin
12
+ Database.load_env(environment || "development", ENV['MONGOID_CONFIG_PATH'])
13
+ rescue Errno::ENOENT => e
14
+ puts e.message
15
+ puts "try running 'rake prepare'"
16
+ end
17
+ end
18
+
19
+ class Database
20
+ def self.load_env(tracco_env, mongoid_configuration_path=nil)
21
+ Tracco.environment = tracco_env
22
+ Mongoid.load!(mongoid_configuration_path || "config/mongoid.yml", tracco_env)
23
+ Trello.logger.info "Mongo db env: #{tracco_env.color(:green)}."
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,71 @@
1
+ require "google_drive"
2
+ require 'highline/import'
3
+
4
+ module Tracco
5
+ module Exporters
6
+ class GoogleDocs
7
+ include TrelloConfiguration
8
+
9
+ def initialize(spreadsheet_name, worksheet_name)
10
+ @spreadsheet_name = spreadsheet_name || "trello effort tracking"
11
+ @worksheet_name = worksheet_name || "tracking"
12
+ end
13
+
14
+ def export
15
+ Trello.logger.info "Running exporter from db env '#{Environment.name}' to google docs '#{@spreadsheet_name.color(:green)}##{@worksheet_name.color(:green)}'..."
16
+
17
+ spreadsheet = google_docs_session.spreadsheet_by_title(@spreadsheet_name) || google_docs_session.create_spreadsheet(@spreadsheet_name)
18
+ worksheet = spreadsheet.worksheet_by_title(@worksheet_name) || spreadsheet.add_worksheet(@worksheet_name)
19
+
20
+ create_header(worksheet)
21
+ index = 2 # skip the header
22
+
23
+ cards = TrackedCard.all_tracked_cards(:method => :first_activity_date, :order => :desc)
24
+ cards.each do |card|
25
+ print ".".color(:green)
26
+ worksheet[index, columns[:user_story_id]] = card.short_id
27
+ worksheet[index, columns[:user_story_name]] = card.name
28
+ worksheet[index, columns[:start_date]] = card.working_start_date
29
+ worksheet[index, columns[:total_effort]] = card.total_effort
30
+ worksheet[index, columns[:last_estimate_error]] = card.last_estimate_error
31
+ card.estimates.each_with_index do |estimate, i|
32
+ worksheet[index, columns[:estimate]+i] = estimate.amount
33
+ end
34
+ index += 1
35
+ end
36
+
37
+ saved = worksheet.save
38
+ spreadsheet.human_url if saved
39
+ end
40
+
41
+ private
42
+
43
+ def google_docs_session(email=configuration["google_docs_username"])
44
+ @session ||= login(email)
45
+ end
46
+
47
+ def login(email)
48
+ username = ask("Enter your google docs username: ") { |q| q.default = email }
49
+ password = ask("Enter your google docs password: ") { |q| q.echo = false }
50
+
51
+ GoogleDrive.login(username, password)
52
+ end
53
+
54
+ def columns
55
+ @columns ||= {
56
+ user_story_id: 1,
57
+ user_story_name: 2,
58
+ start_date: 3,
59
+ total_effort: 4,
60
+ last_estimate_error: 5,
61
+ estimate: 6,
62
+ }
63
+ end
64
+
65
+ def create_header(worksheet)
66
+ worksheet.update_cells(1,1, [["ID", "Story Name", "Start Date", "Total Effort (hours)", "Last estimate error (%)", "First Estimate", "2nd estimate", "3rd estimate"]])
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -2,7 +2,6 @@ module Tracco
2
2
  module Tracking
3
3
  module Base
4
4
  extend Forwardable
5
- include TrelloConfiguration
6
5
 
7
6
  TIME_CONVERTERS = {
8
7
  'h' => lambda { |estimate| estimate },
@@ -26,7 +25,7 @@ module Tracco
26
25
  end
27
26
 
28
27
  def to_s
29
- "[#{date}] From #{notifier.username.color(:green)}\t on card '#{trello_card.name.color(:yellow)}': #{raw_text}"
28
+ "[#{date}] From #{notifier.username.color(:green)}\t on card '#{trello_card.name.color(:yellow)}': #{tracking_message}"
30
29
  end
31
30
 
32
31
  private
@@ -44,10 +43,14 @@ module Tracco
44
43
  end
45
44
 
46
45
  def raw_tracking
47
- raw_text.gsub("@#{tracker_username}", "")
46
+ @raw_tracking ||= remove_tracker_from(tracking_message)
48
47
  end
49
48
 
50
- def raw_text
49
+ def remove_tracker_from(tracking_message)
50
+ tracking_message.sub(/^\s*@\w+\s/, "")
51
+ end
52
+
53
+ def tracking_message
51
54
  tracking_notification.data['text']
52
55
  end
53
56
 
@@ -5,7 +5,7 @@ module Tracco
5
5
 
6
6
  def add_to(card)
7
7
  # do nothing
8
- Trello.logger.warn "Ignoring tracking notification: '#{raw_text}'"
8
+ Trello.logger.warn "Ignoring tracking notification: '#{tracking_message}'"
9
9
  end
10
10
 
11
11
  def estimate
@@ -14,20 +14,8 @@ module TrelloConfiguration
14
14
 
15
15
  end
16
16
 
17
- class Database
18
- def self.load_env(db_env, mongoid_configuration_path=nil)
19
- ENV['MONGOID_ENV'] = db_env
20
- Mongoid.load!(mongoid_configuration_path || "config/mongoid.yml", db_env)
21
- Trello.logger.info "Mongo db env: #{db_env.color(:green)}."
22
- end
23
- end
24
-
25
17
  private
26
18
 
27
- def db_environment
28
- ENV['MONGOID_ENV']
29
- end
30
-
31
19
  def configuration
32
20
  @configuration ||= load_configuration
33
21
  end
@@ -22,7 +22,7 @@ module Tracco
22
22
  begin
23
23
  tracked_card = TrackedCard.update_or_create_with(tracking_notification.card)
24
24
  tracked_card.add!(tracking)
25
- Trello.logger.info tracking
25
+ Trello.logger.info tracking.to_s
26
26
 
27
27
  rescue StandardError => e
28
28
  Trello.logger.warn "skipping tracking: #{e.message}".color(:magenta)
@@ -1,3 +1,3 @@
1
1
  module Tracco
2
- VERSION = '0.0.15'
2
+ VERSION = '0.0.16'
3
3
  end
@@ -1,2 +1,3 @@
1
1
  #!/usr/bin/env sh
2
- bundle exec rake spec:fast
2
+ bundle exec rake spec
3
+ # bundle exec rake spec:fast
@@ -4,9 +4,14 @@ require 'trello'
4
4
  describe "TrelloAuthorization" do
5
5
  include TrelloAuthorize
6
6
 
7
+ let(:config) {
8
+ # auth params for trackinguser_for_test/testinguser!
9
+ trello_testing_board_auth_params
10
+ }
11
+
7
12
  it "authorizes connection to Trello", :needs_valid_configuration => true do
8
- authorize_on_trello
9
-
10
- Trello::Member.find("me").should_not be_nil
13
+ authorize_on_trello(developer_public_key: config.dev_key, access_token_key: config.token)
14
+
15
+ Trello::Member.find("me").username.should == "trackinguser_for_test"
11
16
  end
12
17
  end
@@ -14,9 +14,7 @@ module Tracco
14
14
 
15
15
  let(:config) {
16
16
  # auth params for trackinguser_for_test/testinguser!
17
- OpenStruct.new(tracker: "trackinguser_for_test",
18
- dev_key: "ef7c400e711057d7ba5e00be20139a33",
19
- token: "9047d8fdbfdc960d41910673e300516cc8630dd4967e9b418fc27e410516362e")
17
+ trello_testing_board_auth_params
20
18
  }
21
19
 
22
20
  it "tracks some estimates and efforts", :needs_valid_configuration => true do
@@ -51,18 +49,5 @@ module Tracco
51
49
  another_done_card.should be_done
52
50
  end
53
51
 
54
-
55
- private
56
-
57
- def without_logging(&block)
58
- original_error_level = Trello.logger.level
59
-
60
- begin
61
- Trello.logger.level = Logger::WARN
62
- block.call unless block.nil?
63
- ensure
64
- Trello.logger.level = original_error_level
65
- end
66
- end
67
52
  end
68
53
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Trello::Card do
4
4
 
5
5
  describe "#in_done_column?" do
6
-
6
+
7
7
  let(:trello_card) { Trello::Card.new("name" => "a name", "desc" => "any description") }
8
8
 
9
9
  let(:todo_column) { Trello::List.new("name" => "ToDo") }
@@ -21,5 +21,10 @@ describe Trello::Card do
21
21
  trello_card.in_done_column?.should be_false
22
22
  end
23
23
 
24
+ it "is false when the card cannot be found on Trello" do
25
+ trello_card.stub(:list).and_raise(Trello::Error)
26
+ trello_card.in_done_column?.should be_false
27
+ end
28
+
24
29
  end
25
30
  end
@@ -14,6 +14,7 @@ rescue Bundler::GemNotFound => e
14
14
  exit!
15
15
  end
16
16
 
17
+ ENV['TRACCO_ENV'] = "test"
17
18
  require 'tracco'
18
19
 
19
20
  require 'factory_girl'
@@ -27,6 +28,3 @@ RSpec.configure do |configuration|
27
28
  configuration.include Mongoid::Matchers
28
29
  configuration.include FactoryGirl::Syntax::Methods # Repeating "FactoryGirl" is too verbose for me...
29
30
  end
30
-
31
- # force test env for the mongodb configuration
32
- TrelloConfiguration::Database.load_env("test")
@@ -5,8 +5,15 @@ TIME_MEASUREMENTS = {
5
5
  pomodori: 'p'
6
6
  }
7
7
 
8
+ def trello_testing_board_auth_params
9
+ # auth params for trackinguser_for_test/testinguser!
10
+ OpenStruct.new(tracker: "trackinguser_for_test",
11
+ dev_key: "ef7c400e711057d7ba5e00be20139a33",
12
+ token: "9047d8fdbfdc960d41910673e300516cc8630dd4967e9b418fc27e410516362e")
13
+ end
14
+
8
15
  def unrecognized_notification
9
- create_notification(data: { 'text' => '@trackinguser hi there!' })
16
+ create_notification(data: { 'text' => '@any_tracker hi there!' })
10
17
  end
11
18
 
12
19
  def notification_with_message(message)
@@ -14,11 +21,11 @@ def notification_with_message(message)
14
21
  end
15
22
 
16
23
  def create_estimate(time_measurement)
17
- create_notification(data: { 'text' => "@trackinguser [1.5#{TIME_MEASUREMENTS[time_measurement]}]" })
24
+ create_notification(data: { 'text' => "@any_tracker [1.5#{TIME_MEASUREMENTS[time_measurement]}]" })
18
25
  end
19
26
 
20
27
  def create_effort(time_measurement)
21
- create_notification(data: { 'text' => "@trackinguser +4.5#{TIME_MEASUREMENTS[time_measurement]}]" })
28
+ create_notification(data: { 'text' => "@any_tracker +4.5#{TIME_MEASUREMENTS[time_measurement]}]" })
22
29
  end
23
30
 
24
31
  def with(notification)
@@ -31,8 +38,19 @@ def with_message(notification_message, &block)
31
38
  end
32
39
 
33
40
  def create_notification(custom_params)
34
- params = { data: { 'text' => "@trackinguser +2h" }, date: "2012-10-28T21:06:14.801Z", member_creator: stub(username: "pietrodibello") }
41
+ params = { data: { 'text' => "@any_tracker +2h" }, date: "2012-10-28T21:06:14.801Z", member_creator: stub(username: "pietrodibello") }
35
42
  params.merge!(custom_params)
36
43
 
37
44
  stub(data: params[:data], date: params[:date], member_creator: params[:member_creator]).as_null_object
38
45
  end
46
+
47
+ def without_logging(&block)
48
+ original_error_level = Trello.logger.level
49
+
50
+ begin
51
+ Trello.logger.level = Logger::WARN
52
+ block.call unless block.nil?
53
+ ensure
54
+ Trello.logger.level = original_error_level
55
+ end
56
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tracco do
4
+
5
+ before(:each) do
6
+ @original = ENV["TRACCO_ENV"]
7
+ end
8
+
9
+ after(:each) do
10
+ ENV["TRACCO_ENV"] = @original
11
+ end
12
+
13
+ describe ".environment" do
14
+
15
+ it "tells the current environment name" do
16
+ ENV['TRACCO_ENV'] = "any_env"
17
+
18
+ Tracco.environment.should == "any_env"
19
+ end
20
+
21
+ it "sets an environment variable" do
22
+ Tracco.environment = "an_env"
23
+
24
+ Tracco.environment.should == "an_env"
25
+ ENV['TRACCO_ENV'].should == "an_env"
26
+ end
27
+ end
28
+
29
+ describe ".environment=" do
30
+
31
+ it "tells the current environment name" do
32
+ ENV['TRACCO_ENV'] = "any_env"
33
+
34
+ Tracco.environment.should == "any_env"
35
+ end
36
+
37
+ it "sets an environment variable" do
38
+ Tracco.environment = "an_env"
39
+
40
+ Tracco.environment.should == "an_env"
41
+ ENV['TRACCO_ENV'].should == "an_env"
42
+ end
43
+ end
44
+
45
+ end
@@ -11,7 +11,7 @@ module Tracco
11
11
  end
12
12
 
13
13
  before(:each) do
14
- Trello::Member.stub(:find).and_return(Member.new(username: "any"))
14
+ Trello::Member.stub(:find).and_return(Member.new(username: "any_member"))
15
15
  end
16
16
 
17
17
  it "is nil when the notification does not contain an estimate" do
@@ -19,42 +19,47 @@ module Tracco
19
19
  end
20
20
 
21
21
  it "does not parse effort in minutes (e.g. +30m)" do
22
- with_message("@trackinguser +30m") { |tracking| tracking.effort.should be_nil }
22
+ with_message("@test_tracker +30m") { |tracking| tracking.effort.should be_nil }
23
+ end
24
+
25
+ it "does not count the tracker as a member of the effort" do
26
+ with_message("@test_tracker +3p") { |tracking| tracking.effort.members.map(&:username).should == ["any_member"] }
23
27
  end
24
28
 
25
29
  it "is the hour-based effort when the notification contains an effort in hours" do
26
30
  Trello::Member.should_receive(:find).with("michelepangrazzi").and_return(michelepangrazzi)
27
31
 
28
- raw_data = create_notification(data: { 'text' => "@trackinguser +2h" },
32
+ raw_data = create_notification(data: { 'text' => "@test_tracker +2h" },
29
33
  date: "2012-10-28T21:06:14.801Z",
30
34
  member_creator: stub(username: "michelepangrazzi"))
31
35
 
32
- Tracking::Factory.build_from(raw_data).effort.should == Effort.new(amount: 2.0, date: Date.parse('2012-10-28'), members: [michelepangrazzi])
36
+ expected_effort = Effort.new(amount: 2.0, date: Date.parse('2012-10-28'), members: [michelepangrazzi])
37
+ Tracking::Factory.build_from(raw_data).effort.should == expected_effort
33
38
  end
34
39
 
35
40
  it "converts the effort in hours when the notification contains an effort in days" do
36
- with_message("@trackinguser +1.5d") { |t| t.effort.amount.should == 8+4 }
37
- with_message("@trackinguser +1.5g") { |t| t.effort.amount.should == 8+4 }
41
+ with_message("@test_tracker +1.5d") { |t| t.effort.amount.should == 8+4 }
42
+ with_message("@test_tracker +1.5g") { |t| t.effort.amount.should == 8+4 }
38
43
  end
39
44
 
40
45
  it "converts the effort in hours when the notification contains an effort in pomodori" do
41
- with_message("@trackinguser +10p") { |t| t.effort.amount.should == 5}
46
+ with_message("@test_tracker +10p") { |t| t.effort.amount.should == 5}
42
47
  end
43
48
 
44
49
  it "fetch the effort from a complex effort message" do
45
- with_message "@trackinguser ho speso +2h e spero che stavolta possiamo rilasciarla" do |tracking|
50
+ with_message "@test_tracker ho speso +2h e spero che stavolta possiamo rilasciarla" do |tracking|
46
51
  tracking.effort.amount.should == 2.0
47
52
  end
48
53
  end
49
54
 
50
55
  it "fetch the effort even when beween square brackets" do
51
- with_message "@trackinguser [+0.5h]" do |tracking|
56
+ with_message "@test_tracker [+0.5h]" do |tracking|
52
57
  tracking.effort.amount.should == 0.5
53
58
  end
54
59
  end
55
60
 
56
61
  it "computes the effort considering all the mentioned team mates in the message" do
57
- with_message "@trackinguser +2h assieme a @michelepangrazzi e @alessandrodescovi" do |tracking|
62
+ with_message "@test_tracker +2h assieme a @michelepangrazzi e @alessandrodescovi" do |tracking|
58
63
  tracking.effort.amount.should == 2.0 * 3
59
64
  end
60
65
  end
@@ -64,7 +69,7 @@ module Tracco
64
69
  Trello::Member.should_receive(:find).with(username).and_return(self.send(username))
65
70
  end
66
71
 
67
- notification = create_notification(data: { 'text' => "@trackinguser +2h assieme a @michelepangrazzi e @alessandrodescovi" },
72
+ notification = create_notification(data: { 'text' => "@test_tracker +2h assieme a @michelepangrazzi e @alessandrodescovi" },
68
73
  member_creator: stub(username: "pietrodibello"))
69
74
  with notification do |tracking|
70
75
  tracking.effort.members.should == [michelepangrazzi, alessandrodescovi, pietrodibello]
@@ -76,7 +81,7 @@ module Tracco
76
81
  Trello::Member.should_receive(:find).with(username).and_return(self.send(username))
77
82
  end
78
83
 
79
- notification = create_notification(data: { 'text' => "@trackinguser +3p (@alessandrodescovi @michelevincenzi)" },
84
+ notification = create_notification(data: { 'text' => "@test_tracker +3p (@alessandrodescovi @michelevincenzi)" },
80
85
  member_creator: stub(username: "pietrodibello"))
81
86
 
82
87
  with notification do |tracking|
@@ -86,7 +91,7 @@ module Tracco
86
91
  end
87
92
 
88
93
  it "tracks the effort with the date given in the notification text, not the actual notification date" do
89
- raw_data = create_notification(data: { 'text' => "@trackinguser 22.11.2012 +6p" }, date: "2012-09-19T12:46:13.713Z")
94
+ raw_data = create_notification(data: { 'text' => "@test_tracker 22.11.2012 +6p" }, date: "2012-09-19T12:46:13.713Z")
90
95
 
91
96
  tracking = Tracking::Factory.build_from(raw_data)
92
97
 
@@ -94,7 +99,7 @@ module Tracco
94
99
  end
95
100
 
96
101
  it "tracks the effort to yesterday when the keyword 'yesterday' is present before the effort amount" do
97
- raw_data = create_notification(data: { 'text' => "@trackinguser yesterday +6p" }, date: "2012-09-19T12:46:13.713Z")
102
+ raw_data = create_notification(data: { 'text' => "@test_tracker yesterday +6p" }, date: "2012-09-19T12:46:13.713Z")
98
103
 
99
104
  tracking = Tracking::Factory.build_from(raw_data)
100
105
 
@@ -102,7 +107,7 @@ module Tracco
102
107
  end
103
108
 
104
109
  it "tracks the effort to yesterday when the keyword 'yesterday' is present before the effort amount" do
105
- raw_data = create_notification(data: { 'text' => "@trackinguser +6p yesterday" }, date: "2012-09-19T12:46:13.713Z")
110
+ raw_data = create_notification(data: { 'text' => "@test_tracker +6p yesterday" }, date: "2012-09-19T12:46:13.713Z")
106
111
 
107
112
  tracking = Tracking::Factory.build_from(raw_data)
108
113
 
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module Tracco
4
+ module Tracking
5
+ describe InvalidTracking do
6
+
7
+ describe "#add_to" do
8
+ it "just logs a warning message and does nothing" do
9
+ Trello.logger.should_receive(:warn).with(/^Ignoring tracking notification:/)
10
+
11
+ invalid_tracking = Tracking::Factory.build_from(unrecognized_notification)
12
+ invalid_tracking.add_to(TrackedCard.new)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -12,6 +12,15 @@ describe TrelloConfiguration do
12
12
  authorization_params_from_config_file["developer_public_key"].should == "any_dpk"
13
13
  authorization_params_from_config_file["access_token_key"].should == "any_atk"
14
14
  end
15
+
16
+ it "returns an empty hash when the configuration file is invalid" do
17
+ YAML.should_receive(:load_file).with("config/config.yml").and_raise(NoMethodError)
18
+
19
+ without_logging do
20
+ authorization_params_from_config_file.should == {}
21
+ end
22
+ end
23
+
15
24
  end
16
25
 
17
26
  describe "#tracker_username" do
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.require_paths = ["lib"]
21
21
  gem.files = `git ls-files`.split("\n")
22
+ gem.executables = %w(tracco)
22
23
  gem.test_files = `git ls-files -- {spec}/*`.split("\n")
23
24
  gem.extra_rdoc_files = ["README.md"]
24
25
 
@@ -31,12 +32,8 @@ Gem::Specification.new do |gem|
31
32
  gem.add_runtime_dependency 'rainbow'
32
33
  gem.add_runtime_dependency 'chronic'
33
34
  gem.add_runtime_dependency 'highline'
35
+ gem.add_runtime_dependency 'thor'
34
36
 
35
- gem.add_development_dependency 'rake'
36
- gem.add_development_dependency 'rspec'
37
- gem.add_development_dependency 'rspec-mocks'
38
- gem.add_development_dependency 'mongoid-rspec'
39
- gem.add_development_dependency 'database_cleaner'
40
- gem.add_development_dependency 'factory_girl'
37
+ gem.add_development_dependency 'awesome_print'
41
38
  gem.add_development_dependency 'debugger'
42
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracco
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.16
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-01 00:00:00.000000000 Z
12
+ date: 2013-03-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-trello
@@ -124,78 +124,14 @@ dependencies:
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
- name: rake
127
+ name: thor
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
131
  - - ! '>='
132
132
  - !ruby/object:Gem::Version
133
133
  version: '0'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ! '>='
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
- - !ruby/object:Gem::Dependency
143
- name: rspec
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ! '>='
148
- - !ruby/object:Gem::Version
149
- version: '0'
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
- requirements:
155
- - - ! '>='
156
- - !ruby/object:Gem::Version
157
- version: '0'
158
- - !ruby/object:Gem::Dependency
159
- name: rspec-mocks
160
- requirement: !ruby/object:Gem::Requirement
161
- none: false
162
- requirements:
163
- - - ! '>='
164
- - !ruby/object:Gem::Version
165
- version: '0'
166
- type: :development
167
- prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
- requirements:
171
- - - ! '>='
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- - !ruby/object:Gem::Dependency
175
- name: mongoid-rspec
176
- requirement: !ruby/object:Gem::Requirement
177
- none: false
178
- requirements:
179
- - - ! '>='
180
- - !ruby/object:Gem::Version
181
- version: '0'
182
- type: :development
183
- prerelease: false
184
- version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
- requirements:
187
- - - ! '>='
188
- - !ruby/object:Gem::Version
189
- version: '0'
190
- - !ruby/object:Gem::Dependency
191
- name: database_cleaner
192
- requirement: !ruby/object:Gem::Requirement
193
- none: false
194
- requirements:
195
- - - ! '>='
196
- - !ruby/object:Gem::Version
197
- version: '0'
198
- type: :development
134
+ type: :runtime
199
135
  prerelease: false
200
136
  version_requirements: !ruby/object:Gem::Requirement
201
137
  none: false
@@ -204,7 +140,7 @@ dependencies:
204
140
  - !ruby/object:Gem::Version
205
141
  version: '0'
206
142
  - !ruby/object:Gem::Dependency
207
- name: factory_girl
143
+ name: awesome_print
208
144
  requirement: !ruby/object:Gem::Requirement
209
145
  none: false
210
146
  requirements:
@@ -238,7 +174,8 @@ dependencies:
238
174
  description: ! 'Tracco is a Trello effort tracker: the purpose of Tracco is to extract
239
175
  and track estimates and actual efforts out of the cards on your Trello boards.'
240
176
  email: pierodibello@gmail.com
241
- executables: []
177
+ executables:
178
+ - tracco
242
179
  extensions: []
243
180
  extra_rdoc_files:
244
181
  - README.md
@@ -253,16 +190,21 @@ files:
253
190
  - LICENSE.txt
254
191
  - README.md
255
192
  - Rakefile
193
+ - bin/tracco
256
194
  - config/config.template.yml
257
195
  - config/config.yml.trackinguser_for_test
258
196
  - config/mongoid.template.yml
197
+ - images/tracco.logo.png
198
+ - images/tracking_example.png
259
199
  - lib/patches/trello/card.rb
260
200
  - lib/patches/trello/member.rb
261
201
  - lib/startup_trello.rb
262
202
  - lib/tasks/rspec.rake
263
203
  - lib/tasks/tasks.rake
264
204
  - lib/tracco.rb
265
- - lib/tracco/google_docs_exporter.rb
205
+ - lib/tracco/cli.rb
206
+ - lib/tracco/configuration.rb
207
+ - lib/tracco/exporters/google_docs.rb
266
208
  - lib/tracco/models/effort.rb
267
209
  - lib/tracco/models/estimate.rb
268
210
  - lib/tracco/models/member.rb
@@ -295,10 +237,12 @@ files:
295
237
  - spec/spec_helper.rb
296
238
  - spec/support/database_cleaner.rb
297
239
  - spec/support/spec_helper_methods.rb
240
+ - spec/tracco_spec.rb
298
241
  - spec/tracking/card_done_tracking_spec.rb
299
242
  - spec/tracking/effort_tracking_spec.rb
300
243
  - spec/tracking/estimate_tracking_spec.rb
301
244
  - spec/tracking/factory_spec.rb
245
+ - spec/tracking/invalid_tracking_spec.rb
302
246
  - spec/trello_authorize_spec.rb
303
247
  - spec/trello_configuration_spec.rb
304
248
  - spec/trello_tracker_spec.rb
@@ -318,7 +262,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
318
262
  version: '0'
319
263
  segments:
320
264
  - 0
321
- hash: -2610639466740555589
265
+ hash: -2206961055360224389
322
266
  required_rubygems_version: !ruby/object:Gem::Requirement
323
267
  none: false
324
268
  requirements:
@@ -1,70 +0,0 @@
1
- require "google_drive"
2
- require 'highline/import'
3
-
4
- module Tracco
5
- class GoogleDocsExporter
6
- include TrelloConfiguration
7
-
8
- def initialize(spreadsheet_name, worksheet_name)
9
- @spreadsheet_name = spreadsheet_name || "trello effort tracking"
10
- @worksheet_name = worksheet_name || "tracking"
11
- end
12
-
13
- def export
14
- Trello.logger.info "Running exporter from db env '#{db_environment}' to google docs '#{@spreadsheet_name.color(:green)}##{@worksheet_name.color(:green)}'..."
15
-
16
- spreadsheet = google_docs_session.spreadsheet_by_title(@spreadsheet_name) || google_docs_session.create_spreadsheet(@spreadsheet_name)
17
- worksheet = spreadsheet.worksheet_by_title(@worksheet_name) || spreadsheet.add_worksheet(@worksheet_name)
18
-
19
- create_header(worksheet)
20
- index = 2 # skip the header
21
-
22
- cards = TrackedCard.all_tracked_cards(:method => :first_activity_date, :order => :desc)
23
- cards.each do |card|
24
- print ".".color(:green)
25
- worksheet[index, columns[:user_story_id]] = card.short_id
26
- worksheet[index, columns[:user_story_name]] = card.name
27
- worksheet[index, columns[:start_date]] = card.working_start_date
28
- worksheet[index, columns[:total_effort]] = card.total_effort
29
- worksheet[index, columns[:last_estimate_error]] = card.last_estimate_error
30
- card.estimates.each_with_index do |estimate, i|
31
- worksheet[index, columns[:estimate]+i] = estimate.amount
32
- end
33
- index += 1
34
- end
35
-
36
- saved = worksheet.save
37
- spreadsheet.human_url if saved
38
- end
39
-
40
- private
41
-
42
- def google_docs_session(email=configuration["google_docs_username"])
43
- @session ||= login(email)
44
- end
45
-
46
- def login(email)
47
- username = ask("Enter your google docs username: ") { |q| q.default = email }
48
- password = ask("Enter your google docs password: ") { |q| q.echo = false }
49
-
50
- GoogleDrive.login(username, password)
51
- end
52
-
53
- def columns
54
- @columns ||= {
55
- user_story_id: 1,
56
- user_story_name: 2,
57
- start_date: 3,
58
- total_effort: 4,
59
- last_estimate_error: 5,
60
- estimate: 6,
61
- }
62
- end
63
-
64
- def create_header(worksheet)
65
- worksheet.update_cells(1,1, [["ID", "Story Name", "Start Date", "Total Effort (hours)", "Last estimate error (%)", "First Estimate", "2nd estimate", "3rd estimate"]])
66
- end
67
-
68
- end
69
-
70
- end