houston-core 0.6.0 → 0.6.1

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +69 -68
  3. data/app/adapters/houston/adapters/deployment/engineyard.rb +1 -1
  4. data/app/adapters/houston/adapters/version_control/git_adapter/github_repo.rb +19 -0
  5. data/app/adapters/houston/adapters/version_control/git_adapter/remote_repo.rb +27 -0
  6. data/app/assets/images/drag-grip.png +0 -0
  7. data/app/assets/javascripts/app/infinite_scroll.coffee +1 -1
  8. data/app/assets/javascripts/app/views/_show_sprint_view.coffee +9 -9
  9. data/app/assets/javascripts/application.js +1 -0
  10. data/app/assets/javascripts/core/app.coffee +5 -0
  11. data/app/assets/javascripts/{app → core}/stacked_area_graph.coffee +0 -0
  12. data/app/assets/javascripts/{app → core}/stacked_bar_graph.coffee +0 -0
  13. data/app/assets/javascripts/dashboard.js +1 -0
  14. data/app/assets/javascripts/vendor.js +0 -1
  15. data/app/assets/stylesheets/application/exceptions.scss +3 -1
  16. data/app/assets/stylesheets/application/navigation.scss +84 -21
  17. data/app/assets/stylesheets/application/releases.scss +32 -2
  18. data/app/assets/stylesheets/application/test.scss +34 -0
  19. data/app/assets/stylesheets/core/colors.scss.erb +33 -3
  20. data/app/assets/stylesheets/dashboard/dashboard.scss +11 -7
  21. data/app/assets/stylesheets/variables.scss +3 -0
  22. data/app/concerns/belongs_to_commit.rb +14 -0
  23. data/app/concerns/project_adapter.rb +24 -6
  24. data/app/controllers/api/v1/projects_controller.rb +18 -0
  25. data/app/controllers/api/v1/sprint_tasks_controller.rb +1 -1
  26. data/app/controllers/deploys_controller.rb +1 -0
  27. data/app/controllers/project_tests_controller.rb +49 -19
  28. data/app/controllers/releases_controller.rb +5 -0
  29. data/app/controllers/test_runs_controller.rb +16 -1
  30. data/app/helpers/test_run_helper.rb +24 -0
  31. data/app/models/deploy.rb +13 -0
  32. data/app/models/github/pull_request.rb +39 -4
  33. data/app/models/release.rb +42 -0
  34. data/app/models/task.rb +3 -2
  35. data/app/models/test_run.rb +4 -0
  36. data/app/presenters/project_presenter.rb +28 -0
  37. data/app/views/deploys/show.html.erb +4 -0
  38. data/app/views/github/pulls/index.html.erb +4 -1
  39. data/app/views/layouts/_mobile_navigation.html.erb +14 -17
  40. data/app/views/layouts/_navigation.html.erb +87 -87
  41. data/app/views/layouts/dashboard.html.erb +2 -2
  42. data/app/views/project_tests/index.html.erb +22 -7
  43. data/app/views/releases/_index.html.erb +65 -0
  44. data/app/views/releases/_results.html.erb +47 -0
  45. data/app/views/releases/index.html.erb +29 -65
  46. data/app/views/sprints/dashboard.html.erb +4 -2
  47. data/config/environments/production.rb +1 -1
  48. data/config/environments/test.rb +4 -1
  49. data/config/initializers/add_navigation_renderers.rb +6 -0
  50. data/config/initializers/requirements.rb +1 -0
  51. data/config/routes.rb +3 -0
  52. data/db/migrate/20151226154901_add_search_vector_to_releases.rb +6 -0
  53. data/db/migrate/20151226155305_generate_index_on_releases.rb +5 -0
  54. data/db/migrate/20151228183704_drop_unused_tables.rb +35 -0
  55. data/db/migrate/20160120145757_add_successful_to_deploys.rb +10 -0
  56. data/db/structure.sql +19 -67
  57. data/houston.gemspec +3 -3
  58. data/lib/configuration.rb +4 -2
  59. data/lib/core_ext/array.rb +37 -0
  60. data/lib/houston/version.rb +1 -1
  61. data/test/integration/ci_integration_test.rb +14 -13
  62. data/test/unit/models/project_test.rb +33 -0
  63. data/test/unit/models/pull_request_test.rb +71 -1
  64. metadata +24 -14
  65. data/app/models/historical_head.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ccdc8ca97e863eac07e91316e4df92a6058c0319
4
- data.tar.gz: cf508ea2d4af78899f39fb4152dafb5a371bdd14
3
+ metadata.gz: be13a8e98d89a156ac6a8b400cd2dd6740b0c5e4
4
+ data.tar.gz: e74865d4a2f5e58f4f512c7726eb4de9617f1309
5
5
  SHA512:
6
- metadata.gz: efad3f461cf426eae2346593caa7524680b1260cd417603df9ba057deb3ef427d342d40eaa84f2e631b0432976719f1681e83b67c167314ce3cafe486341acfd
7
- data.tar.gz: 3e54190cf91f35922f34f5e21738d3ae4877e976316fa7e346bc6d8231644585c45f6554cdb47a038817e885b7ef6d690d74cddf21eba1f47ae6fc314fd86f68
6
+ metadata.gz: f42b52fbd29e5bbb4126f91793e407759a1eaa0463e94f9e8e527273203dcb0b8a86ff5b6de1ea1c794399874de65202de45f98323aaf33f035b134aa0dcc1c2
7
+ data.tar.gz: a9aa49c934fc7179de43431e9d1308f4f887a2b88b4ca0a28c16abcfa7cfcf3d63edaf1a2a6f6b0aa27a2a0052adcae528c1059dd8f585826bf83bebad90ba20
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- houston-core (0.6.0)
4
+ houston-core (0.6.1)
5
5
  activerecord-import
6
6
  activerecord-pluck_in_batches
7
7
  addressable
@@ -15,7 +15,7 @@ PATH
15
15
  devise (~> 3.5.0)
16
16
  devise_invitable (~> 1.5.3)
17
17
  engineyard (~> 3.2.1)
18
- faraday (~> 0.8.10)
18
+ faraday (~> 0.9.2)
19
19
  faraday-http-cache (~> 1.2.2)
20
20
  faraday-raise-errors (~> 0.2.0)
21
21
  gemoji (~> 2.1.0)
@@ -27,7 +27,7 @@ PATH
27
27
  hpricot (~> 0.8.6)
28
28
  neat-rails
29
29
  nested_editor_for
30
- nokogiri (~> 1.6.6.2)
30
+ nokogiri
31
31
  octokit (~> 4.1.0)
32
32
  oj (~> 2.13)
33
33
  openxml-xlsx (>= 0.2.0)
@@ -36,7 +36,7 @@ PATH
36
36
  premailer (~> 1.8.6)
37
37
  progressbar
38
38
  rack-utf8_sanitizer (~> 1.3.1)
39
- rails (~> 4.2.5)
39
+ rails (~> 4.2.5.1)
40
40
  redcarpet (~> 3.3.2)
41
41
  rufus-scheduler (~> 3.1.7)
42
42
  rugged (~> 0.23.3)
@@ -52,40 +52,40 @@ PATH
52
52
  GEM
53
53
  remote: https://rubygems.org/
54
54
  specs:
55
- actionmailer (4.2.5)
56
- actionpack (= 4.2.5)
57
- actionview (= 4.2.5)
58
- activejob (= 4.2.5)
55
+ actionmailer (4.2.5.1)
56
+ actionpack (= 4.2.5.1)
57
+ actionview (= 4.2.5.1)
58
+ activejob (= 4.2.5.1)
59
59
  mail (~> 2.5, >= 2.5.4)
60
60
  rails-dom-testing (~> 1.0, >= 1.0.5)
61
- actionpack (4.2.5)
62
- actionview (= 4.2.5)
63
- activesupport (= 4.2.5)
61
+ actionpack (4.2.5.1)
62
+ actionview (= 4.2.5.1)
63
+ activesupport (= 4.2.5.1)
64
64
  rack (~> 1.6)
65
65
  rack-test (~> 0.6.2)
66
66
  rails-dom-testing (~> 1.0, >= 1.0.5)
67
67
  rails-html-sanitizer (~> 1.0, >= 1.0.2)
68
- actionview (4.2.5)
69
- activesupport (= 4.2.5)
68
+ actionview (4.2.5.1)
69
+ activesupport (= 4.2.5.1)
70
70
  builder (~> 3.1)
71
71
  erubis (~> 2.7.0)
72
72
  rails-dom-testing (~> 1.0, >= 1.0.5)
73
73
  rails-html-sanitizer (~> 1.0, >= 1.0.2)
74
- activejob (4.2.5)
75
- activesupport (= 4.2.5)
74
+ activejob (4.2.5.1)
75
+ activesupport (= 4.2.5.1)
76
76
  globalid (>= 0.3.0)
77
- activemodel (4.2.5)
78
- activesupport (= 4.2.5)
77
+ activemodel (4.2.5.1)
78
+ activesupport (= 4.2.5.1)
79
79
  builder (~> 3.1)
80
- activerecord (4.2.5)
81
- activemodel (= 4.2.5)
82
- activesupport (= 4.2.5)
80
+ activerecord (4.2.5.1)
81
+ activemodel (= 4.2.5.1)
82
+ activesupport (= 4.2.5.1)
83
83
  arel (~> 6.0)
84
- activerecord-import (0.10.0)
84
+ activerecord-import (0.11.0)
85
85
  activerecord (>= 3.0)
86
- activerecord-pluck_in_batches (0.1.0)
86
+ activerecord-pluck_in_batches (0.1.1)
87
87
  activerecord
88
- activesupport (4.2.5)
88
+ activesupport (4.2.5.1)
89
89
  i18n (~> 0.7)
90
90
  json (~> 1.7, >= 1.7.7)
91
91
  minitest (~> 5.1)
@@ -95,14 +95,15 @@ GEM
95
95
  ansi (1.5.0)
96
96
  arel (6.0.3)
97
97
  bcrypt (3.1.10)
98
- boblail-unfuddle (0.7.0)
98
+ boblail-unfuddle (0.7.1)
99
99
  activesupport
100
100
  builder
101
- faraday (~> 0.8.8)
102
- browser (1.0.1)
101
+ faraday (>= 0.8, < 0.10)
102
+ browser (1.1.0)
103
103
  builder (3.2.2)
104
104
  cancan (1.6.10)
105
- capybara (2.5.0)
105
+ capybara (2.6.0)
106
+ addressable
106
107
  mime-types (>= 1.16)
107
108
  nokogiri (>= 1.3.3)
108
109
  rack (>= 1.0.0)
@@ -112,9 +113,9 @@ GEM
112
113
  codeclimate-test-reporter (0.4.8)
113
114
  simplecov (>= 0.7.1, < 1.0.0)
114
115
  coderay (1.1.0)
115
- coffee-rails (4.1.0)
116
+ coffee-rails (4.1.1)
116
117
  coffee-script (>= 2.2.0)
117
- railties (>= 4.0.0, < 5.0)
118
+ railties (>= 4.0.0, < 5.1.x)
118
119
  coffee-script (2.4.1)
119
120
  coffee-script-source
120
121
  execjs
@@ -125,18 +126,18 @@ GEM
125
126
  addressable
126
127
  default_value_for (3.0.1)
127
128
  activerecord (>= 3.2.0, < 5.0)
128
- devise (3.5.3)
129
+ devise (3.5.5)
129
130
  bcrypt (~> 3.0)
130
131
  orm_adapter (~> 0.1)
131
132
  railties (>= 3.2.6, < 5)
132
133
  responders
133
134
  thread_safe (~> 0.1)
134
135
  warden (~> 1.2.3)
135
- devise_invitable (1.5.3)
136
+ devise_invitable (1.5.5)
136
137
  actionmailer (>= 3.2.6, < 5)
137
138
  devise (>= 3.2.0)
138
139
  docile (1.1.5)
139
- domain_name (0.5.25)
140
+ domain_name (0.5.20160128)
140
141
  unf (>= 0.0.5, < 1.0.0)
141
142
  engineyard (3.2.1)
142
143
  engineyard-cloud-client (~> 2.1)
@@ -159,8 +160,8 @@ GEM
159
160
  factory_girl_rails (4.5.0)
160
161
  factory_girl (~> 4.5.0)
161
162
  railties (>= 3.0.0)
162
- faraday (0.8.11)
163
- multipart-post (~> 1.2.0)
163
+ faraday (0.9.2)
164
+ multipart-post (>= 1.2, < 3)
164
165
  faraday-http-cache (1.2.2)
165
166
  faraday (~> 0.8)
166
167
  faraday-raise-errors (0.2.0)
@@ -194,7 +195,7 @@ GEM
194
195
  domain_name (~> 0.5)
195
196
  i18n (0.7.0)
196
197
  json (1.8.3)
197
- jwt (1.5.2)
198
+ jwt (1.5.1)
198
199
  launchy (2.4.3)
199
200
  addressable (~> 2.3)
200
201
  libv8 (3.16.14.13)
@@ -204,8 +205,8 @@ GEM
204
205
  mime-types (>= 1.16, < 3)
205
206
  method_source (0.8.2)
206
207
  mime-types (2.99)
207
- mini_portile (0.6.2)
208
- minitest (5.8.3)
208
+ mini_portile2 (2.0.0)
209
+ minitest (5.8.4)
209
210
  minitest-reporters (1.1.7)
210
211
  ansi
211
212
  builder
@@ -215,24 +216,24 @@ GEM
215
216
  minitest-reporters
216
217
  multi_json (1.11.2)
217
218
  multi_xml (0.5.5)
218
- multipart-post (1.2.0)
219
+ multipart-post (2.0.0)
219
220
  neat-rails (0.1.0)
220
221
  nested_editor_for (0.1.0)
221
222
  net-ldap (0.12.1)
222
- net-ssh (2.9.2)
223
+ net-ssh (2.9.4)
223
224
  netrc (0.11.0)
224
- nokogiri (1.6.6.4)
225
- mini_portile (~> 0.6.0)
225
+ nokogiri (1.6.7.2)
226
+ mini_portile2 (~> 2.0.0.rc2)
226
227
  oauth (0.4.7)
227
- oauth2 (1.0.0)
228
+ oauth2 (1.1.0)
228
229
  faraday (>= 0.8, < 0.10)
229
- jwt (~> 1.0)
230
+ jwt (~> 1.0, < 1.5.2)
230
231
  multi_json (~> 1.3)
231
232
  multi_xml (~> 0.5)
232
- rack (~> 1.2)
233
+ rack (>= 1.2, < 3)
233
234
  octokit (4.1.1)
234
235
  sawyer (~> 0.6.0, >= 0.5.3)
235
- oj (2.14.0)
236
+ oj (2.14.3)
236
237
  openxml-package (0.2.2)
237
238
  nokogiri
238
239
  ox
@@ -241,7 +242,7 @@ GEM
241
242
  nokogiri
242
243
  openxml-package (>= 0.2.0)
243
244
  orm_adapter (0.5.0)
244
- ox (2.2.2)
245
+ ox (2.2.3)
245
246
  pg (0.18.4)
246
247
  pg_search (1.0.5)
247
248
  activerecord (>= 3.1)
@@ -258,18 +259,18 @@ GEM
258
259
  rack (1.6.4)
259
260
  rack-test (0.6.3)
260
261
  rack (>= 1.0)
261
- rack-utf8_sanitizer (1.3.1)
262
- rack (~> 1.0)
263
- rails (4.2.5)
264
- actionmailer (= 4.2.5)
265
- actionpack (= 4.2.5)
266
- actionview (= 4.2.5)
267
- activejob (= 4.2.5)
268
- activemodel (= 4.2.5)
269
- activerecord (= 4.2.5)
270
- activesupport (= 4.2.5)
262
+ rack-utf8_sanitizer (1.3.2)
263
+ rack (>= 1.0, < 3.0)
264
+ rails (4.2.5.1)
265
+ actionmailer (= 4.2.5.1)
266
+ actionpack (= 4.2.5.1)
267
+ actionview (= 4.2.5.1)
268
+ activejob (= 4.2.5.1)
269
+ activemodel (= 4.2.5.1)
270
+ activerecord (= 4.2.5.1)
271
+ activesupport (= 4.2.5.1)
271
272
  bundler (>= 1.3.0, < 2.0)
272
- railties (= 4.2.5)
273
+ railties (= 4.2.5.1)
273
274
  sprockets-rails
274
275
  rails-deprecated_sanitizer (1.0.3)
275
276
  activesupport (>= 4.2.0.alpha)
@@ -277,18 +278,18 @@ GEM
277
278
  activesupport (>= 4.2.0.beta, < 5.0)
278
279
  nokogiri (~> 1.6.0)
279
280
  rails-deprecated_sanitizer (>= 1.0.1)
280
- rails-html-sanitizer (1.0.2)
281
+ rails-html-sanitizer (1.0.3)
281
282
  loofah (~> 2.0)
282
- railties (4.2.5)
283
- actionpack (= 4.2.5)
284
- activesupport (= 4.2.5)
283
+ railties (4.2.5.1)
284
+ actionpack (= 4.2.5.1)
285
+ activesupport (= 4.2.5.1)
285
286
  rake (>= 0.8.7)
286
287
  thor (>= 0.18.1, < 2.0)
287
- rake (10.4.2)
288
- redcarpet (3.3.3)
288
+ rake (10.5.0)
289
+ redcarpet (3.3.4)
289
290
  ref (2.0.0)
290
- responders (2.1.0)
291
- railties (>= 4.2.0, < 5)
291
+ responders (2.1.1)
292
+ railties (>= 4.2.0, < 5.1)
292
293
  rest-client (1.8.0)
293
294
  http-cookie (>= 1.0.2, < 2.0)
294
295
  mime-types (>= 1.16, < 3.0)
@@ -299,7 +300,7 @@ GEM
299
300
  rufus-scheduler (3.1.10)
300
301
  rugged (0.23.3)
301
302
  safe_yaml (1.0.4)
302
- sass (3.4.20)
303
+ sass (3.4.21)
303
304
  sass-rails (5.0.4)
304
305
  railties (>= 4.0.0, < 5.0)
305
306
  sass (~> 3.1)
@@ -347,9 +348,9 @@ GEM
347
348
  unf (0.1.4)
348
349
  unf_ext
349
350
  unf_ext (0.0.7.1)
350
- warden (1.2.4)
351
+ warden (1.2.6)
351
352
  rack (>= 1.0)
352
- webmock (1.22.3)
353
+ webmock (1.22.6)
353
354
  addressable (>= 2.3.6)
354
355
  crack (>= 0.3.2)
355
356
  hashdiff
@@ -74,7 +74,7 @@ module Houston
74
74
  deployment.successful = runner.call(out, err)
75
75
 
76
76
  Houston.try({max_tries: 5, ignore: true}, exceptions_wrapping(PG::ConnectionBad)) do
77
- deploy.update_attributes!(completed_at: Time.now)
77
+ deploy.update_attributes!(successful: deployment.successful, completed_at: Time.now)
78
78
  end
79
79
 
80
80
  rescue StandardError => e
@@ -12,6 +12,10 @@ module Houston
12
12
  .gsub(/\.git$/, "")
13
13
  end
14
14
 
15
+ def pulls_url
16
+ "#{project_url}/pulls"
17
+ end
18
+
15
19
  def commit_url(sha)
16
20
  "#{project_url}/commit/#{sha}"
17
21
  end
@@ -31,6 +35,21 @@ module Houston
31
35
  Addressable::URI.parse(location).path[0...-4].gsub(/^\//, "")
32
36
  end
33
37
 
38
+ def create_commit_status(sha, status={})
39
+ status = OpenStruct.new(status) if status.is_a?(Hash)
40
+ unless %w{pending success failure error}.member?(status.state)
41
+ raise ArgumentError, ":state must be either 'pending', 'success', 'failure', or 'error'"
42
+ end
43
+
44
+ target_url = status.url if status.respond_to?(:url)
45
+ target_url = status.target_url if status.respond_to?(:target_url)
46
+
47
+ Houston.github.create_status(repo_name, sha, status.state, {
48
+ context: status.context,
49
+ target_url: target_url,
50
+ description: status.description })
51
+ end
52
+
34
53
 
35
54
 
36
55
  # GitHub API
@@ -27,6 +27,11 @@ module Houston
27
27
 
28
28
 
29
29
 
30
+ def before_update(project)
31
+ return true unless project.slug_changed?
32
+ rename *project.changes[:slug]
33
+ end
34
+
30
35
  def git_path
31
36
  @git_path
32
37
  end
@@ -132,6 +137,28 @@ module Houston
132
137
  close
133
138
  end
134
139
 
140
+ def rename(from, to)
141
+ old_git_path = Houston.root.join("tmp", "#{from}.git").to_s
142
+ new_git_path = Houston.root.join("tmp", "#{to}.git").to_s
143
+
144
+ unless File.exists?(old_git_path)
145
+ Rails.logger.info "\e[34m[remote_repo.rename] #{old_git_path} does not exist\e[0m"
146
+ @git_path = new_git_path
147
+ remove_instance_variable :@connection if defined?(@connection)
148
+ return true
149
+ end
150
+
151
+ if system "mv #{old_git_path} #{new_git_path}"
152
+ Rails.logger.info "\e[32m[remote_repo.rename] Renamed #{old_git_path} to #{File.basename(new_git_path)}\e[0m"
153
+ @git_path = new_git_path
154
+ remove_instance_variable :@connection if defined?(@connection)
155
+ return true
156
+ end
157
+
158
+ Rails.logger.warn "\e[31m[remote_repo.rename] Failed to rename #{old_git_path} to #{File.basename(new_git_path)}\e[0m"
159
+ false
160
+ end
161
+
135
162
  end
136
163
  end
137
164
  end
@@ -25,7 +25,7 @@ class @InfiniteScroll
25
25
  @$el.addClass('loading')
26
26
  xhr.done (html, status, e)=>
27
27
  @$el.removeClass('loading')
28
- if e.status is 204
28
+ if html is "" or e?.status is 204
29
29
  @$el.addClass('done')
30
30
  else
31
31
  @$el.append(html)
@@ -3,6 +3,7 @@ class @ShowSprintView extends Backbone.View
3
3
  initialize: ->
4
4
  @sprintId = @options.sprintId
5
5
  @sprintStart = @options.sprintStart
6
+ @height = @options.height ? 260
6
7
  @template = HandlebarsTemplates['sprints/show']
7
8
  @tasks = _.sortBy @options.sprintTasks, (task)-> task.projectTitle
8
9
  super
@@ -32,7 +33,7 @@ class @ShowSprintView extends Backbone.View
32
33
  # Find the total amount of effort to accomplish
33
34
  committedByDay = {}
34
35
  completedByDay = {}
35
- totalEffort = 0
36
+ @totalEffort = 0
36
37
  for task in tasks
37
38
  effort = +task.effort
38
39
  if task.completed
@@ -47,7 +48,7 @@ class @ShowSprintView extends Backbone.View
47
48
  effort = 0 if day < monday # this task was released before this sprint started!
48
49
 
49
50
  committedByDay[day] = (committedByDay[day] || 0) + effort
50
- totalEffort += effort
51
+ @totalEffort += effort
51
52
 
52
53
  # for debugging
53
54
  window.completedByDay = completedByDay
@@ -55,8 +56,8 @@ class @ShowSprintView extends Backbone.View
55
56
  # Transform into remaining effort by day:
56
57
  # Iterate by day in case there are some days
57
58
  # where no progress was made
58
- toChartData = (progressByDay)->
59
- remainingEffort = totalEffort
59
+ toChartData = (progressByDay)=>
60
+ remainingEffort = @totalEffort
60
61
  data = [
61
62
  day: saturday
62
63
  effort: Math.ceil(remainingEffort)
@@ -71,14 +72,13 @@ class @ShowSprintView extends Backbone.View
71
72
 
72
73
  committed = toChartData(committedByDay)
73
74
  completed = toChartData(completedByDay)
74
- toCommit = committed.last().effort
75
- toComplete = completed.last().effort
75
+ @toCommit = committed.last().effort
76
+ @toComplete = completed.last().effort
76
77
 
77
78
  new Houston.BurndownChart()
79
+ .height(@height)
78
80
  .days(days)
79
- .totalEffort(totalEffort)
81
+ .totalEffort(@totalEffort)
80
82
  .addLine('committed', committed)
81
83
  .addLine('completed', completed)
82
84
  .render()
83
-
84
- $('body').toggleClass('green', totalEffort > 0 and (toCommit == 0 or toComplete == 0))