gradesfirst 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/gradesfirst.gemspec +1 -1
- data/lib/gradesfirst/cli.rb +8 -2
- data/lib/gradesfirst/pair_command.rb +107 -0
- data/test/cli_test.rb +14 -2
- data/test/fixtures/pair.txt +3 -0
- data/test/pair_command_test.rb +29 -0
- metadata +16 -5
- checksums.yaml +0 -15
data/gradesfirst.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.platform = Gem::Platform::RUBY
|
3
3
|
s.name = "gradesfirst"
|
4
|
-
s.version = "0.
|
4
|
+
s.version = "0.5.0"
|
5
5
|
s.summary = "GradesFirst command line utility for developers."
|
6
6
|
s.description = "This utility will help manage the various tasks developers need to do on their workstation such as database updates."
|
7
7
|
s.license = "MIT"
|
data/lib/gradesfirst/cli.rb
CHANGED
@@ -4,6 +4,7 @@ require 'gradesfirst/cli_helper'
|
|
4
4
|
require 'gradesfirst/command'
|
5
5
|
require 'gradesfirst/branch_command'
|
6
6
|
require 'gradesfirst/commit_message_command'
|
7
|
+
require 'gradesfirst/pair_command'
|
7
8
|
require 'gradesfirst/task_cli'
|
8
9
|
|
9
10
|
require 'pivotal_tracker'
|
@@ -15,13 +16,18 @@ module GradesFirst
|
|
15
16
|
desc 'branch', GradesFirst::BranchCommand.description
|
16
17
|
def branch
|
17
18
|
set_pivotal_tracker_api_token
|
18
|
-
execute
|
19
|
+
execute GradesFirst::BranchCommand
|
19
20
|
end
|
20
21
|
|
21
22
|
desc 'commit-message', GradesFirst::CommitMessageCommand.description
|
22
23
|
def commit_message
|
23
24
|
set_pivotal_tracker_api_token
|
24
|
-
execute
|
25
|
+
execute GradesFirst::CommitMessageCommand
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'pair', GradesFirst::PairCommand.description
|
29
|
+
def pair
|
30
|
+
execute GradesFirst::PairCommand
|
25
31
|
end
|
26
32
|
|
27
33
|
desc 'task COMMAND', 'Manage tasks related to a PivotalTracker story.'
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'gradesfirst/command'
|
3
|
+
|
4
|
+
module GradesFirst
|
5
|
+
# Implementation of a Thor command for determining who your next pair is for
|
6
|
+
# pair programming or code review.
|
7
|
+
class PairCommand < GradesFirst::Command
|
8
|
+
# Description of the "gf pair" Thor command that will be used in the
|
9
|
+
# commandline help.
|
10
|
+
def self.description
|
11
|
+
'Show the current developer pairings.'
|
12
|
+
end
|
13
|
+
|
14
|
+
# Performs the gf pair Thor command which determines the current
|
15
|
+
# developer pairings.
|
16
|
+
def execute
|
17
|
+
@pairing = pairings[pairing_index]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Generates the command line output response. The output of the pair
|
21
|
+
# command will be a list of developer pairings for code review, pair
|
22
|
+
# programming, etc.
|
23
|
+
def response
|
24
|
+
@pairing.map{|pair| pair.compact.join(' and ')}.join("\n") + "\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Currently returns a hard coded list but could be moved to a configuration
|
30
|
+
# file in the future.
|
31
|
+
def developers
|
32
|
+
return @developers unless @developers.nil?
|
33
|
+
|
34
|
+
@developers = [
|
35
|
+
"Anthony Crumley",
|
36
|
+
"Tom Miller",
|
37
|
+
"Andrew Sellers",
|
38
|
+
"Matt Turney",
|
39
|
+
"Zac Williams",
|
40
|
+
"Ben Holley"
|
41
|
+
].sort
|
42
|
+
@developers << nil if @developers.length.odd?
|
43
|
+
|
44
|
+
@developers
|
45
|
+
end
|
46
|
+
|
47
|
+
# This algorythm was written by Tom Miller based on the wikipedia article on
|
48
|
+
# round robin tournaments.
|
49
|
+
#
|
50
|
+
# https://en.wikipedia.org/wiki/Round-robin_tournament
|
51
|
+
def pairings
|
52
|
+
top, bottom = developers.each_slice(developers.length/2).to_a
|
53
|
+
pivot, *top = top
|
54
|
+
|
55
|
+
result = []
|
56
|
+
(developers.length-1).times do
|
57
|
+
top.unshift(bottom.shift)
|
58
|
+
bottom.push(top.pop)
|
59
|
+
result << [pivot, *top].zip(bottom)
|
60
|
+
end
|
61
|
+
|
62
|
+
result
|
63
|
+
end
|
64
|
+
|
65
|
+
def pairing_index
|
66
|
+
sprint % max_pairing_index
|
67
|
+
end
|
68
|
+
|
69
|
+
def max_pairing_index
|
70
|
+
developers.length - 1
|
71
|
+
end
|
72
|
+
|
73
|
+
def sprint
|
74
|
+
week / sprint_length_in_weeks
|
75
|
+
end
|
76
|
+
|
77
|
+
# Currently this is hard coded but could be moved to a configuration file
|
78
|
+
# in the future.
|
79
|
+
def sprint_length_in_weeks
|
80
|
+
2
|
81
|
+
end
|
82
|
+
|
83
|
+
def week
|
84
|
+
(now.to_i - day_zero.to_i) / seconds_in_a_week
|
85
|
+
end
|
86
|
+
|
87
|
+
def seconds_in_a_week
|
88
|
+
days_in_a_week = 7
|
89
|
+
hours_in_a_day = 24
|
90
|
+
minutes_in_an_hour = 60
|
91
|
+
seconds_in_a_minute = 60
|
92
|
+
|
93
|
+
days_in_a_week * hours_in_a_day * minutes_in_an_hour * seconds_in_a_minute
|
94
|
+
end
|
95
|
+
|
96
|
+
def now
|
97
|
+
Time.now
|
98
|
+
end
|
99
|
+
|
100
|
+
# Currently hard coded to return the beginning of a GradesFirst sprint but
|
101
|
+
# could be put in a configuration file in the future.
|
102
|
+
def day_zero
|
103
|
+
Time.parse("2014-3-11 00:00:00")
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/test/cli_test.rb
CHANGED
@@ -4,8 +4,16 @@ require 'gradesfirst/cli'
|
|
4
4
|
describe GradesFirst::CLI do
|
5
5
|
|
6
6
|
def assert_command_hooked_up(shell_command, klass)
|
7
|
-
assert_includes
|
8
|
-
|
7
|
+
assert_includes(
|
8
|
+
klass.instance_methods,
|
9
|
+
:execute,
|
10
|
+
"#{klass.name} does not implement the #execute method"
|
11
|
+
)
|
12
|
+
assert_includes(
|
13
|
+
klass.instance_methods,
|
14
|
+
:response,
|
15
|
+
"#{klass.name} does not implement the #response method"
|
16
|
+
)
|
9
17
|
|
10
18
|
execute_arity = klass.instance_method(:execute).arity
|
11
19
|
if execute_arity < 0
|
@@ -38,6 +46,10 @@ describe GradesFirst::CLI do
|
|
38
46
|
assert_command_hooked_up 'commit-message', GradesFirst::CommitMessageCommand
|
39
47
|
end
|
40
48
|
|
49
|
+
specify 'pair command is hooked up' do
|
50
|
+
assert_command_hooked_up 'pair', GradesFirst::PairCommand
|
51
|
+
end
|
52
|
+
|
41
53
|
# Waiting on fix for subcommands with default command.
|
42
54
|
# https://github.com/erikhuda/thor/pull/374
|
43
55
|
#specify 'task command is hooked up to default list subcommand' do
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'gradesfirst/pair_command'
|
3
|
+
|
4
|
+
describe GradesFirst::PairCommand do
|
5
|
+
before do
|
6
|
+
@command = GradesFirst::PairCommand.new
|
7
|
+
@developers = [
|
8
|
+
'Mickey Mouse',
|
9
|
+
'Cat Woman',
|
10
|
+
'Wonder Woman',
|
11
|
+
'Superman',
|
12
|
+
'Minnie Mouse',
|
13
|
+
'Ironman'
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
specify '#execute pairs developers correctly' do
|
18
|
+
@command.stub :developers, @developers do
|
19
|
+
@command.stub :now, Time.parse("2014-3-25 00:00:00") do
|
20
|
+
@command.execute
|
21
|
+
end
|
22
|
+
end
|
23
|
+
assert_equal(
|
24
|
+
fixture_file('pair.txt'),
|
25
|
+
@command.response,
|
26
|
+
'Programmer pairing is not correct.'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gradesfirst
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- GradesFirst
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
12
|
+
date: 2014-03-31 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: thor
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: http_magic
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: minitest
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -74,6 +81,7 @@ files:
|
|
74
81
|
- lib/gradesfirst/cli_helper.rb
|
75
82
|
- lib/gradesfirst/command.rb
|
76
83
|
- lib/gradesfirst/commit_message_command.rb
|
84
|
+
- lib/gradesfirst/pair_command.rb
|
77
85
|
- lib/gradesfirst/task_add_command.rb
|
78
86
|
- lib/gradesfirst/task_cli.rb
|
79
87
|
- lib/gradesfirst/task_command.rb
|
@@ -89,6 +97,7 @@ files:
|
|
89
97
|
- test/fixtures/commit_message.txt
|
90
98
|
- test/fixtures/gf_branch.txt
|
91
99
|
- test/fixtures/git_branch.txt
|
100
|
+
- test/fixtures/pair.txt
|
92
101
|
- test/fixtures/projects.json
|
93
102
|
- test/fixtures/story_bar.json
|
94
103
|
- test/fixtures/story_foo.json
|
@@ -99,6 +108,7 @@ files:
|
|
99
108
|
- test/fixtures/task_toggled.txt
|
100
109
|
- test/fixtures/tasks.json
|
101
110
|
- test/fixtures/tasks.txt
|
111
|
+
- test/pair_command_test.rb
|
102
112
|
- test/support/pivotal_test_helper.rb
|
103
113
|
- test/support/request_expectation.rb
|
104
114
|
- test/task_add_command_test.rb
|
@@ -110,25 +120,26 @@ files:
|
|
110
120
|
homepage: http://www.gradesfirst.com
|
111
121
|
licenses:
|
112
122
|
- MIT
|
113
|
-
metadata: {}
|
114
123
|
post_install_message:
|
115
124
|
rdoc_options: []
|
116
125
|
require_paths:
|
117
126
|
- lib
|
118
127
|
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
119
129
|
requirements:
|
120
130
|
- - ! '>='
|
121
131
|
- !ruby/object:Gem::Version
|
122
132
|
version: 1.8.7
|
123
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
124
135
|
requirements:
|
125
136
|
- - ! '>='
|
126
137
|
- !ruby/object:Gem::Version
|
127
138
|
version: 1.3.6
|
128
139
|
requirements: []
|
129
140
|
rubyforge_project:
|
130
|
-
rubygems_version:
|
141
|
+
rubygems_version: 1.8.25
|
131
142
|
signing_key:
|
132
|
-
specification_version:
|
143
|
+
specification_version: 3
|
133
144
|
summary: GradesFirst command line utility for developers.
|
134
145
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
YTQ2ODU5MGIxYWQwM2QwZjc1YWVkMmRlNDE5OTY5MDk2NmI2ZmI5ZQ==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NjYxNmE1MmJlM2I5MmM1ZGQ3OWMyNWY3MGY1NjQ1MDRjMjZiYzdjMg==
|
7
|
-
SHA512:
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MDJmYmQxNzM1NzAzMTUzM2I5Yzc3MjdhMTRhYjRlNTUyMTg3YjIyN2VmOTkz
|
10
|
-
MzExODcxMWRjOGQwMWUxN2E4NjE5MWVhY2I3YzkxODBjOGU3ZTNlZTdlOWY2
|
11
|
-
MjUyZWU3YzZjY2E4N2ViOTExY2VlY2JhYWFkODY0NTdlYTdhZjQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZGEyMjY5NjM3ZmQwMzY1Nzg3NDgwMzJjZjQ5ZGJiMDdiZmM4ODY1MThlMGQw
|
14
|
-
MjU4ODhmMTVkNDIwODE5NDhiNTg3NTQ2NTk2NzZkNjgzZjM4ZmU3ZjcwNDdj
|
15
|
-
NmQ5ZTZiYjRhOGEyNjQyZDBlZTJhOTVlYzQzZTQwYTZmNmE2YWI=
|