Skip to content

Commit 8daf9f8

Browse files
committed
Add 'Until' column to contributors index
1 parent bc321ae commit 8daf9f8

15 files changed

+126
-25
lines changed

app/assets/stylesheets/screen.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ TABLES GENERALS
330330
font-size: 1.1em;
331331
}
332332

333-
#table-wrap table td.contributor-since {
333+
#table-wrap table td.contributor-timestamp {
334334
white-space: nowrap;
335335
text-align: left;
336336
}

app/models/contributor.rb

+19-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def self._all_with_ncommits(joins, where=nil)
3939
order('ncommits DESC, contributors.url_id ASC')
4040
end
4141

42-
def self.set_first_contribution_timestamps(only_new)
43-
scope = only_new ? 'first_contribution_at IS NULL' : '1 = 1'
42+
def self.set_first_contribution_timestamps(only_missing)
43+
scope = only_missing ? 'first_contribution_at IS NULL' : '1 = 1'
4444

4545
connection.execute(<<-SQL)
4646
UPDATE contributors
@@ -56,6 +56,23 @@ def self.set_first_contribution_timestamps(only_new)
5656
SQL
5757
end
5858

59+
def self.set_last_contribution_timestamps(only_missing)
60+
scope = only_missing ? 'last_contribution_at IS NULL' : '1 = 1'
61+
62+
connection.execute(<<-SQL)
63+
UPDATE contributors
64+
SET last_contribution_at = last_contributions.committer_date
65+
FROM (
66+
SELECT contributor_id, MAX(commits.committer_date) AS committer_date
67+
FROM contributions
68+
INNER JOIN commits ON commits.id = commit_id
69+
GROUP BY contributor_id
70+
) AS last_contributions
71+
WHERE id = last_contributions.contributor_id
72+
AND #{scope}
73+
SQL
74+
end
75+
5976
# The contributors table may change if new name equivalences are added and IDs
6077
# in particular are expected to move. So, we just put the parameterized name
6178
# in URLs, which is unique anyway.

app/models/repo.rb

+3-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def sync
8585
if ncommits > 0 || nreleases > 0 || rebuild_all
8686
sync_names
8787
sync_ranks
88-
sync_first_contribution_timestamps
88+
sync_contribution_timestamps
8989
end
9090

9191
RepoUpdate.create!(
@@ -188,8 +188,9 @@ def sync_ranks
188188
end
189189
end
190190

191-
def sync_first_contribution_timestamps
191+
def sync_contribution_timestamps
192192
Contributor.set_first_contribution_timestamps(!rebuild_all)
193+
Contributor.set_last_contribution_timestamps(!rebuild_all)
193194
end
194195

195196
# Determines whether the names mapping has been updated. This is useful because

app/views/contributors/_contributor.html.erb

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
<tr class="<%= cycle 'even', 'odd' %>">
1+
<tr id="<%= contributor.name.downcase.tr(' ', '-') %>" class="<%= cycle 'even', 'odd' %>">
22
<td class="contributor-rank">#<%= contributor.rank %></td>
33
<td class="contributor-name"><%= link_to_contributor contributor %></td>
4-
<td class="contributor-since"><%= date contributor.first_contribution_at %></td>
4+
<td class="contributor-timestamp"><%= date contributor.first_contribution_at %></td>
5+
<td class="contributor-timestamp"><%= date contributor.last_contribution_at %></td>
56
<td class="no-commits">
67
<% path = if @time_window
78
contributor_commits_in_time_window_path(contributor, @time_window)

app/views/contributors/index.html.erb

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<th></th>
1515
<th>Name</th>
1616
<th>Since</th>
17+
<th>Until</th>
1718
<th>Commits</th>
1819
</tr>
1920
<%= render @contributors %>

db/migrate/20150326181907_add_first_contribution_at_to_contributors.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class AddFirstContributionAtToContributors < ActiveRecord::Migration[4.2]
22
def up
33
add_column :contributors, :first_contribution_at, :datetime
4-
Contributor.try(:fill_missing_first_contribution_timestamps)
4+
Contributor.set_first_contribution_timestamps
55
end
66

77
def down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class AddLastContributionAtToContributors < ActiveRecord::Migration[7.1]
2+
def up
3+
add_column :contributors, :last_contribution_at, :datetime
4+
Contributor.set_last_contribution_timestamps
5+
end
6+
7+
def down
8+
remove_column :contributors, :last_contribution_at
9+
end
10+
end

db/schema.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.0].define(version: 2016_05_12_095609) do
13+
ActiveRecord::Schema[7.1].define(version: 2024_08_24_030051) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "plpgsql"
1616

@@ -42,6 +42,7 @@
4242
t.string "url_id", null: false
4343
t.integer "rank"
4444
t.datetime "first_contribution_at", precision: nil
45+
t.datetime "last_contribution_at"
4546
t.index ["name"], name: "index_contributors_on_name", unique: true
4647
t.index ["url_id"], name: "index_contributors_on_url_id", unique: true
4748
end

test/controllers/contributors_controller_test.rb

+18-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class ContributorsControllerTest < ActionController::TestCase
44
def test_index_main_listing
55
# Order by ncommits DESC, url_id ASC.
6-
expected = [[:jeremy, 3], [:david, 2], [:jose, 1], [:vijay, 1], [:xavier, 1]]
6+
expected = [[:jeremy, 3], [:david, 2], [:jose, 2], [:vijay, 1], [:xavier, 1]]
77

88
get :index
99

@@ -13,13 +13,27 @@ def test_index_main_listing
1313
assert_equal expected.size, actual.size
1414

1515
expected.zip(actual).each do |e, a|
16-
assert_equal contributors(e.first).name, a.name
16+
contributor = contributors(e.first)
17+
18+
assert_equal contributor.name, a.name
1719
assert_equal e.second, a.ncommits
20+
21+
assert_select "tr##{contributor.name.downcase.tr(' ', '-') }" do |elements|
22+
assert_select 'td.contributor-rank', "##{contributor.rank.to_s}"
23+
assert_select 'td.contributor-name', /#{contributor.name}/
24+
assert_select 'td.contributor-timestamp' do |elements|
25+
assert_equal 2, elements.size
26+
assert_equal contributor.first_contribution_at.strftime("%d %b %Y"), elements[0].text.strip
27+
assert_equal contributor.last_contribution_at.strftime("%d %b %Y"), elements[1].text.strip
28+
end
29+
assert_select "td.no-commits", e.second.to_s
30+
end
1831
end
1932
end
2033

2134
def test_index_by_release
2235
releases = {
36+
'v4.0.0' => [[:jose, 1]],
2337
'v3.2.0' => [[:jeremy, 1], [:jose, 1], [:vijay, 1]],
2438
'v0.14.4' => [[:david, 1]]
2539
}
@@ -48,11 +62,11 @@ def test_in_time_window
4862
date_range = '20121201-20121231'
4963

5064
time_windows = {
51-
'all-time' => [[:jeremy, 3], [:david, 2], [:jose, 1], [:vijay, 1], [:xavier, 1]],
65+
'all-time' => [[:jeremy, 3], [:david, 2], [:jose, 2], [:vijay, 1], [:xavier, 1]],
5266
'today' => [[:jeremy, 1]],
5367
'this-week' => [[:jeremy, 1], [:xavier, 1]],
5468
'this-month' => [[:david, 1], [:jeremy, 1], [:xavier, 1]],
55-
'this-year' => [[:jeremy, 3], [:david, 1], [:jose, 1], [:vijay, 1], [:xavier, 1]],
69+
'this-year' => [[:jeremy, 3], [:jose, 2], [:david, 1], [:vijay, 1], [:xavier, 1]],
5670
since => [[:jeremy, 1], [:xavier, 1]],
5771
date_range => [[:david, 1], [:jeremy, 1], [:xavier, 1]],
5872
}

test/controllers/releases_controller_test.rb

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ def test_index
55
get :index
66
assert_response :success
77

8-
assert_select 'span.listing-total', 'Showing 5 releases'
9-
108
expected = %w(
9+
v4_0_0
1110
v3_2_0
1211
v2_3_2_1
1312
v2_3_2
@@ -24,7 +23,7 @@ def test_index
2423
assert_equal e.contributors.count, a.ncontributors
2524
end
2625

27-
assert_select 'span.listing-total', 'Showing 5 releases'
26+
assert_select 'span.listing-total', 'Showing #{expected.size} releases'
2827
assert_select 'li.current', 'Releases'
2928
end
3029
end

test/fixtures/commits.yml

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# WARNING: contributors.yml has first contribution timestamps that depend on
1+
# WARNING: contributors.yml has contribution timestamps that depend on
22
# these fixtures. Keep them in sync as needed.
33
#
44
# In the following comments we assumed today is 26 December 2012.
@@ -40,7 +40,7 @@ commit_26c024e:
4040
one, because it is issued at parse-time. It seemed to in
4141
some places because the constant was the only expression in
4242
the block and therefore it was its return value, that could
43-
potentially be used by silence_warnings are return value of
43+
potentially be used by silence_warnings as a return value of
4444
the yield call.
4545
4646
To bypass the warning we assign to a variable. The chosen
@@ -90,6 +90,20 @@ commit_5b90635:
9090
release: 'v3_2_0'
9191
merge: false
9292

93+
# This commit belongs to this year, release 4.0.0
94+
commit_e243a8a:
95+
sha1: 'e243a8a32eb4c8777f07ca4b974bd7e38d9477d3'
96+
author_email: '[email protected]'
97+
author_name: 'José Valim'
98+
author_date: '2012-07-18 07:21:57'
99+
committer_email: '[email protected]'
100+
committer_name: 'José Valim'
101+
committer_date: '2012-07-18 07:47:52'
102+
message: |
103+
Update changelog for migration generator change
104+
release: v4_0_0
105+
merge: false
106+
93107
# This commit is seven years old, release v0.14.4.
94108
commit_e0ef631:
95109
sha1: 'e0ef63105538f8d97faa095234f069913dd5229c'
@@ -106,7 +120,7 @@ commit_e0ef631:
106120
release: 'v0_14_4'
107121
merge: false
108122

109-
# This commit has a committer_date that is more recent the author_date and
123+
# This commit has a committer_date that is more recent than the author_date and
110124
# should appear in the contributions list before 5b90635.
111125
commit_7cdfd91:
112126
sha1: '7cdfd910b7cdd398f8b54542c5a6a17966a5c8f3'

test/fixtures/contributions.yml

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ contribution_<%= n += 1 %>:
2020
commit: commit_5b90635
2121
contributor: jose
2222

23+
contribution_<%= n += 1 %>:
24+
commit: commit_e243a8a
25+
contributor: jose
26+
2327
contribution_<%= n += 1 %>:
2428
commit: commit_5b90635
2529
contributor: jeremy

test/fixtures/contributors.yml

+5
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,28 @@ david:
22
name: 'David Heinemeier Hansson'
33
url_id: 'david-heinemeier-hansson'
44
first_contribution_at: '2005-11-11 10:07:24'
5+
last_contribution_at: '2012-12-07 20:38:53'
56

67
jeremy:
78
name: 'Jeremy Daer'
89
url_id: 'jeremy-kemper'
910
first_contribution_at: '2012-01-19 19:49:13'
11+
last_contribution_at: '2012-12-26 21:16:05'
1012

1113
jose:
1214
name: 'José Valim'
1315
url_id: 'jose-valim'
1416
first_contribution_at: '2012-01-19 19:49:13'
17+
last_contribution_at: '2012-07-18 07:47:52'
1518

1619
xavier:
1720
name: 'Xavier Noria'
1821
url_id: 'xavier-noria'
1922
first_contribution_at: '2012-12-24 21:16:16'
23+
last_contribution_at: '2012-12-24 21:16:16'
2024

2125
vijay:
2226
name: 'Vijay Dev'
2327
url_id: 'vijay-dev'
2428
first_contribution_at: '2012-01-20 00:47:14'
29+
last_contribution_at: '2012-01-20 00:47:14'

test/fixtures/releases.yml

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
v4_0_0:
2+
tag: 'v4.0.0'
3+
major: 4
4+
minor: 0
5+
tiny: 0
6+
patch: 0
7+
date: '2013-06-25 14:27:04'
8+
19
v3_2_0:
210
tag: 'v3.2.0'
311
major: 3

test/models/repo_test.rb

+32-6
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,48 @@ class RepoTest < ActiveSupport::TestCase
99
end
1010
end
1111

12-
test '#sync_first_contributed_timestamps' do
13-
Contributor.update_all(first_contribution_at: nil)
14-
Repo.new.send(:sync_first_contribution_timestamps)
12+
test '#sync_contribution_timestamps' do
13+
Contributor.update_all(first_contribution_at: nil, last_contribution_at: nil)
14+
Repo.new.send(:sync_contribution_timestamps)
1515

1616
assert_first_contribution :commit_e0ef631, :david
17+
assert_last_contribution :commit_339e4e8, :david
18+
1719
assert_first_contribution :commit_5b90635, :jeremy
20+
assert_last_contribution :commit_b821094, :jeremy
21+
1822
assert_first_contribution :commit_5b90635, :jose
23+
assert_last_contribution :commit_e243a8a, :jose
24+
1925
assert_first_contribution :commit_26c024e, :xavier
26+
assert_last_contribution :commit_26c024e, :xavier
27+
2028
assert_first_contribution :commit_6c65676, :vijay
29+
assert_last_contribution :commit_6c65676, :vijay
2130
end
2231

23-
test '#sync_first_contributed_timestamps rebuilding all' do
32+
test '#sync_contribution_timestamps rebuilding all' do
2433
Contributor.update_all(
25-
first_contribution_at: Commit.minimum(:committer_date) - 1.year
34+
first_contribution_at: Commit.minimum(:committer_date) - 1.year,
35+
last_contribution_at: Commit.maximum(:committer_date) + 1.year
2636
)
2737

28-
Repo.new(rebuild_all: true).send(:sync_first_contribution_timestamps)
38+
Repo.new(rebuild_all: true).send(:sync_contribution_timestamps)
2939

3040
assert_first_contribution :commit_e0ef631, :david
41+
assert_last_contribution :commit_339e4e8, :david
42+
3143
assert_first_contribution :commit_5b90635, :jeremy
44+
assert_last_contribution :commit_b821094, :jeremy
45+
3246
assert_first_contribution :commit_5b90635, :jose
47+
assert_last_contribution :commit_e243a8a, :jose
48+
3349
assert_first_contribution :commit_26c024e, :xavier
50+
assert_last_contribution :commit_26c024e, :xavier
51+
3452
assert_first_contribution :commit_6c65676, :vijay
53+
assert_last_contribution :commit_6c65676, :vijay
3554
end
3655

3756
def assert_first_contribution(commit, contributor)
@@ -40,4 +59,11 @@ def assert_first_contribution(commit, contributor)
4059

4160
assert_equal expected, actual
4261
end
62+
63+
def assert_last_contribution(commit, contributor)
64+
expected = commits(commit).committer_date
65+
actual = contributors(contributor).last_contribution_at
66+
67+
assert_equal expected, actual
68+
end
4369
end

0 commit comments

Comments
 (0)