pendaxes 0.0.1 → 0.0.2
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.
- data/README.md +14 -57
- data/lib/pendaxes/command_line.rb +158 -23
- data/lib/pendaxes/config.rb +1 -1
- data/lib/pendaxes/detectors/rspec.rb +7 -0
- data/lib/pendaxes/notificators/file.rb +16 -0
- data/lib/pendaxes/version.rb +1 -1
- data/lib/pendaxes/workspace.rb +4 -1
- data/spec/workspace_spec.rb +2 -2
- metadata +5 -4
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Pendaxes
|
2
2
|
|
3
|
+

|
4
|
+
|
3
5
|
Throw axes to pending makers!
|
4
6
|
|
5
7
|
Leaving a pending long time is really bad, shouldn't be happened. They'll make a trouble.
|
@@ -17,11 +19,16 @@ Avoid the trouble due to pending examples :D
|
|
17
19
|
|
18
20
|
$ pendaxes <config_file>
|
19
21
|
|
20
|
-
|
22
|
+
See `pendaxes --help` for more.
|
21
23
|
|
22
24
|
### Configuration
|
23
25
|
|
24
|
-
|
26
|
+
$ pendaxes --init # will write to .pendaxes.yml
|
27
|
+
$ pendaxes --init config.yml # will write to config.yml
|
28
|
+
|
29
|
+
see https://github.com/cookpad/pendaxes/wiki/Configuration for detail.
|
30
|
+
|
31
|
+
#### Example
|
25
32
|
|
26
33
|
Clone `https://github.com/foo/bar.git` to `/path/to/be/cloned/repository`, then detect pendings using rspec detector (default).
|
27
34
|
|
@@ -30,67 +37,17 @@ Finally send notification to committers via email (from `no-reply@example.com`).
|
|
30
37
|
workspace:
|
31
38
|
path: /path/to/be/cloned/repository # where to clone?
|
32
39
|
repository: https://github.com/foo/bar.git # where clone from?
|
33
|
-
report:
|
34
|
-
use: haml
|
35
|
-
to: "report.html"
|
36
40
|
notifications:
|
41
|
+
- use: file
|
42
|
+
to: "report.html"
|
43
|
+
reporter:
|
44
|
+
use: haml
|
37
45
|
- use: mail
|
38
46
|
from: no-reply@example.com
|
47
|
+
delivery_method: sendmail
|
39
48
|
reporter:
|
40
49
|
use: haml
|
41
50
|
|
42
|
-
|
43
|
-
#### Full
|
44
|
-
|
45
|
-
detection:
|
46
|
-
use: rspec # use rspec detector for pending detection. (default)
|
47
|
-
# pattern: '*_spec.rb' # this will be passed after `git grep ... --`. Default is "*_spec.rb".
|
48
|
-
# allowed_for: 604800 # (second) = 1 week. Pendings will be marked "not allowed" if it elapsed more than this value
|
49
|
-
|
50
|
-
workspace:
|
51
|
-
path: /path/to/be/cloned/repository # where to clone?
|
52
|
-
repository: "https://github.com/user/repo.git" # where clone from?
|
53
|
-
|
54
|
-
report: # report configuration to save
|
55
|
-
use: haml # what reporter to use (haml and text is bundled in the gem)
|
56
|
-
to: "report.html" # where to save?
|
57
|
-
include_allowed: true # include "allowed" pendings in report. (default: true)
|
58
|
-
# VVV haml reporter specific configuration VVV
|
59
|
-
commit_url: "https://github.com/user/repo/commit/%commit%" # Used for link to commit. %commit% will be replaced to sha1. If not specified, will not be a link.
|
60
|
-
file_url: "https://github.com/user/repo/blob/HEAD/%file%#L%line%" # Used for link to file. %file% and %line% will be replaced to filepath and line no. If not specified, will not be a link.
|
61
|
-
|
62
|
-
notifications: # notifications. multiple values are accepted.
|
63
|
-
- use: terminal # use terminal notificator.
|
64
|
-
- use: mail # use mail notificator.
|
65
|
-
reporter: # reporter setting for this (mail) notification
|
66
|
-
use: haml
|
67
|
-
commit_url: "https://github.com/user/repo/commit/%commit%"
|
68
|
-
file_url: "https://github.com/user/repo/blob/HEAD/%file%#L%line%"
|
69
|
-
|
70
|
-
# VVV mail notificator specific configuration VVV
|
71
|
-
from: no-reply@example.com
|
72
|
-
to: foo@example.com # (optional) mail will be sent once to this mail address.
|
73
|
-
# without this, mail will be sent separated for each committer.
|
74
|
-
# (mails will include pendings added by its recipient only.)
|
75
|
-
|
76
|
-
delivery_method: sendmail # specify delivery_method. https://github.com/mikel/mail for more detail.
|
77
|
-
delivery_options: # (optional) used as option for delivery_method.
|
78
|
-
:location: /usr/sbin/sendmail
|
79
|
-
|
80
|
-
whitelist: # (optional) if whitelist set, mail won't be sent if not matched.
|
81
|
-
- foo@bar # complete match.
|
82
|
-
- /example\.com$/ # used as regexp.
|
83
|
-
blacklist: # (optional) mail won't be sent if matched. preferred than whitelist.
|
84
|
-
- black@example.com
|
85
|
-
- /^black/
|
86
|
-
|
87
|
-
alias: # (optional) Aliasing emails. if mail will be sent to <value> if git commit author is <key>.
|
88
|
-
"foo@gmail.com": "foo@company.com"
|
89
|
-
|
90
|
-
|
91
|
-
* Reporter: generates text or html by given pendings
|
92
|
-
* Notificator: get text or html by reporter, and notify it (via mail, to terminal, etc...)
|
93
|
-
|
94
51
|
## Axes?
|
95
52
|
|
96
53
|
斧... Axe in Japanese. Recently, Japanese engineer says a review comment as axe (斧).
|
@@ -3,54 +3,189 @@ require_relative "./workspace"
|
|
3
3
|
require_relative "./detector"
|
4
4
|
require_relative "./reporter"
|
5
5
|
require_relative "./notificator"
|
6
|
+
require 'yaml'
|
6
7
|
|
7
8
|
module Pendaxes
|
8
9
|
class CommandLine
|
10
|
+
DEFAULT_CONFIG_FILE = ".pendaxes.yml"
|
11
|
+
|
9
12
|
def initialize(*args)
|
10
13
|
@args = args
|
11
|
-
@config =
|
14
|
+
@config = nil
|
12
15
|
end
|
13
16
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
+
def config
|
18
|
+
return @config if @config
|
19
|
+
return nil if @args.empty? && !File.exist?(DEFAULT_CONFIG_FILE)
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
@config = Config.new(YAML.load_file(@args.first || DEFAULT_CONFIG_FILE))
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
|
24
|
+
def write_default_config(options={})
|
25
|
+
options[:to] ||= DEFAULT_CONFIG_FILE
|
26
|
+
workspace = (options[:path] || options[:repository])
|
27
|
+
open(options[:to], 'w') do |io|
|
28
|
+
io.puts <<-EOC
|
29
|
+
# Pendaxes default configuration file.
|
30
|
+
# See https://github.com/cookpad/pendaxes/wiki/Configuration for detail.
|
23
31
|
|
24
|
-
|
25
|
-
|
32
|
+
##
|
33
|
+
# for automatic git-pulling. recommend to set if you run periodically.
|
34
|
+
#
|
35
|
+
# path: path to working copy to use.
|
36
|
+
# if not exist, pendaxes will clone automatically from `repository`.
|
37
|
+
# PENDAXES WILL DO "git reset --hard".
|
38
|
+
# MAKE SURE path TO BE NOT SAME WITH working copy you use.
|
39
|
+
#
|
40
|
+
# repository: remote url of repository.
|
41
|
+
# if `path` doesn't exist, will automatically cloned from specified url.
|
42
|
+
##
|
26
43
|
|
27
|
-
|
44
|
+
#{workspace ? '' : '# '}workspace:
|
45
|
+
#{options[:path] ? '' : '# '} path: #{options[:path] || '/tmp/repository'}
|
46
|
+
#{options[:repository] ? '' : '# '} repository: #{options[:repository] || "git@github.com:cookpad/pendaxes.git"}
|
47
|
+
|
48
|
+
##
|
49
|
+
# Settings of notification.
|
50
|
+
# See https://github.com/cookpad/pendaxes/wiki/Configuration for detail.
|
51
|
+
##
|
52
|
+
|
53
|
+
notifications:
|
54
|
+
- use: file # write report to file.
|
55
|
+
to: report.html # path to write.
|
56
|
+
reporter:
|
57
|
+
use: haml
|
58
|
+
# - use: mail # send mails to each committer of pending.
|
59
|
+
# reporter:
|
60
|
+
# use: haml
|
61
|
+
# from: no-reply@example.com
|
62
|
+
# delivery_method: sendmail
|
63
|
+
# - use: terminal # show pendings on STDOUT.
|
64
|
+
|
65
|
+
##
|
66
|
+
# Settings for pending detection
|
67
|
+
##
|
68
|
+
|
69
|
+
detector:
|
70
|
+
use: rspec # Use rspec detector. Currently only rspec is available.
|
71
|
+
pattern: # pattern of rspec file. this will be passed right after of "git grep --".
|
72
|
+
- '*_spec.rb'
|
73
|
+
# - 'spec/**/*.rb'
|
74
|
+
EOC
|
75
|
+
end
|
76
|
+
|
77
|
+
puts "Just written default config file to #{options[:to]} !"
|
78
|
+
if workspace
|
79
|
+
puts "\nWith automatic git-pulling enabled:"
|
80
|
+
|
81
|
+
if options[:repository] && options[:path]
|
82
|
+
puts " * using #{options[:repository]}"
|
83
|
+
puts " * will cloned at #{options[:path]}"
|
84
|
+
|
85
|
+
if File.exist?(options[:path])
|
86
|
+
puts "WARNING: #{options[:path]} already exists! Pendaxes does `git reset --hard`, be careful!"
|
87
|
+
end
|
88
|
+
elsif options[:path]
|
89
|
+
puts " * using working copy on #{options[:path]}"
|
90
|
+
puts "WARNING: #{options[:path]} doesn't exist, you have to clone." unless File.exist?(options[:path])
|
91
|
+
elsif options[:repository]
|
92
|
+
end
|
93
|
+
else
|
94
|
+
puts <<-EOM
|
95
|
+
|
96
|
+
In default configuration, this will do:
|
97
|
+
|
98
|
+
1. Detect pendings
|
99
|
+
2. Write report file to "./report.html"
|
100
|
+
|
101
|
+
For more about configuration, see https://github.com/cookpad/pendaxes/wiki/Configuration !
|
102
|
+
EOM
|
103
|
+
|
104
|
+
if File.exist?(".git")
|
105
|
+
puts "\nWARNING: this directory doesn't seem git working copy."
|
106
|
+
puts "(Pendaxes works with git working copy.)"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def init
|
112
|
+
write_default_config(to: @args[1], path: @args[2], repository: @args[3])
|
113
|
+
end
|
114
|
+
|
115
|
+
def usage
|
116
|
+
puts <<-USAGE
|
117
|
+
Usage:
|
118
|
+
pendaxes [config]
|
119
|
+
config: (default = ./.pendaxes.yml)
|
120
|
+
Path to config file to use.
|
121
|
+
|
122
|
+
pendaxes --init [config] [path] [remote]
|
123
|
+
|
124
|
+
config: (default = ./.pendaxes.yml)
|
125
|
+
Where to write config file.
|
126
|
+
path: (optional)
|
127
|
+
Path to working copy.
|
128
|
+
remote: (optional)
|
129
|
+
remote git url. if `path` doesn't exist,
|
130
|
+
will be cloned from this onto `path`.
|
131
|
+
|
132
|
+
pendaxes --help
|
133
|
+
|
134
|
+
Show this help.
|
135
|
+
USAGE
|
136
|
+
end
|
137
|
+
|
138
|
+
def workspace
|
139
|
+
@workspace ||= Workspace.new(config.workspace || {path: Dir.pwd})
|
28
140
|
end
|
29
141
|
|
30
142
|
def update
|
31
|
-
|
32
|
-
@workspace.update
|
143
|
+
workspace.update if config.workspace
|
33
144
|
end
|
34
145
|
|
35
146
|
def detect
|
36
|
-
@detector = Detector.find(
|
147
|
+
@detector = Detector.find(config.detection.use.to_sym).new(@workspace, {out: $stdout}.merge(config.detection))
|
37
148
|
@pendings = @detector.detect
|
38
149
|
end
|
39
150
|
|
40
|
-
def report
|
41
|
-
@reporter = Reporter.find(@config.report.use.to_sym).new(@config.report)
|
42
|
-
@reporter.add @pendings
|
43
|
-
report = @reporter.report
|
44
|
-
open(@config.report.to, 'w') {|io| io.puts report }
|
45
|
-
end
|
46
|
-
|
47
151
|
def notify
|
48
|
-
|
49
|
-
puts "
|
152
|
+
config.notifications.map{|x| Hashr.new(x) }.each do |notification|
|
153
|
+
puts " * #{notification.use}"
|
50
154
|
notificator = Notificator.find(notification.use.to_sym).new({out: $stdout}.merge(notification))
|
51
155
|
notificator.add @pendings
|
52
156
|
notificator.notify
|
53
157
|
end
|
54
158
|
end
|
159
|
+
|
160
|
+
def run
|
161
|
+
case @args.first
|
162
|
+
when "--help"
|
163
|
+
usage
|
164
|
+
when "--init"
|
165
|
+
init
|
166
|
+
else
|
167
|
+
unless config
|
168
|
+
warn "./.pendaxes.yml not exists. showing usage..."
|
169
|
+
usage
|
170
|
+
return 1
|
171
|
+
end
|
172
|
+
|
173
|
+
if config.workspace
|
174
|
+
puts "=> Update repository"
|
175
|
+
update
|
176
|
+
else
|
177
|
+
warn "=> Using this working copy. To use automatic fetching, please fill 'workspace' in your config file."
|
178
|
+
workspace # to initialize @workspace
|
179
|
+
end
|
180
|
+
|
181
|
+
puts "=> Detect pendings"
|
182
|
+
detect
|
183
|
+
|
184
|
+
puts "=> Send notifications"
|
185
|
+
notify
|
186
|
+
end
|
187
|
+
|
188
|
+
0
|
189
|
+
end
|
55
190
|
end
|
56
191
|
end
|
data/lib/pendaxes/config.rb
CHANGED
@@ -51,6 +51,7 @@ module Pendaxes
|
|
51
51
|
}
|
52
52
|
|
53
53
|
pending[:commit] = blame(file, line)
|
54
|
+
next unless pending[:commit]
|
54
55
|
pending[:allowed] = (Time.now - pending[:commit][:at]) <= @config.allowed_for
|
55
56
|
|
56
57
|
pendings << pending
|
@@ -70,6 +71,12 @@ module Pendaxes
|
|
70
71
|
sha: blame[0].first, name: blame[1][1..-1].join(' '),
|
71
72
|
email: blame[2][1..-1].join(' ').gsub(/^</,'').gsub(/>$/,'')
|
72
73
|
}
|
74
|
+
|
75
|
+
if commit[:sha] == "0000000000000000000000000000000000000000" && commit[:name] == "Not Committed Yet"
|
76
|
+
@config.out.puts " NOT COMMITTED YET, skipping." if @config.out
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
|
73
80
|
commit[:at] = Time.parse(@workspace.git(*%w(log --pretty=%aD -n1), commit[:sha]).chomp)
|
74
81
|
commit
|
75
82
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../notificator'
|
2
|
+
|
3
|
+
module Pendaxes
|
4
|
+
class Notificator
|
5
|
+
class File < Notificator
|
6
|
+
defaults to: "report.txt", reporter: {use: :text}
|
7
|
+
|
8
|
+
def notify
|
9
|
+
@config.out.puts " * writing report to #{@config.to}" if @config.out
|
10
|
+
open(@config.to, 'w') do |io|
|
11
|
+
io.puts report_for(pendings)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/pendaxes/version.rb
CHANGED
data/lib/pendaxes/workspace.rb
CHANGED
@@ -10,6 +10,7 @@ module Pendaxes
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def clone
|
13
|
+
raise RemoteUrlMissing, "Set git remote url to workspace.repository, or clone to path yourself." unless @config.repository
|
13
14
|
FileUtils.remove_entry_secure(path) if File.exist?(path)
|
14
15
|
git "clone", @config.repository, path
|
15
16
|
end
|
@@ -19,7 +20,7 @@ module Pendaxes
|
|
19
20
|
|
20
21
|
dive do
|
21
22
|
git "fetch", "origin"
|
22
|
-
git "reset", "--hard", @config.branch || "
|
23
|
+
git "reset", "--hard", @config.branch || "origin/HEAD"
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -35,5 +36,7 @@ module Pendaxes
|
|
35
36
|
str = IO.popen([@config.git || "git", *args], 'r', &:read)
|
36
37
|
$?.success? ? str : nil
|
37
38
|
end
|
39
|
+
|
40
|
+
class RemoteUrlMissing < Exception; end
|
38
41
|
end
|
39
42
|
end
|
data/spec/workspace_spec.rb
CHANGED
@@ -37,7 +37,7 @@ describe Pendaxes::Workspace do
|
|
37
37
|
it "fetch and reset" do
|
38
38
|
subject.should_receive(:dive).and_yield.ordered
|
39
39
|
subject.should_receive(:git).with("fetch", "origin").ordered
|
40
|
-
subject.should_receive(:git).with("reset", "--hard", "
|
40
|
+
subject.should_receive(:git).with("reset", "--hard", "origin/HEAD").ordered
|
41
41
|
|
42
42
|
subject.update
|
43
43
|
end
|
@@ -51,7 +51,7 @@ describe Pendaxes::Workspace do
|
|
51
51
|
subject.should_receive(:clone).ordered
|
52
52
|
subject.should_receive(:dive).and_yield.ordered
|
53
53
|
subject.should_receive(:git).with("fetch", "origin").ordered
|
54
|
-
subject.should_receive(:git).with("reset", "--hard", "
|
54
|
+
subject.should_receive(:git).with("reset", "--hard", "origin/HEAD").ordered
|
55
55
|
|
56
56
|
subject.update
|
57
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pendaxes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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: 2012-09-
|
12
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashr
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- lib/pendaxes/detectors/rspec.rb
|
132
132
|
- lib/pendaxes/finder.rb
|
133
133
|
- lib/pendaxes/notificator.rb
|
134
|
+
- lib/pendaxes/notificators/file.rb
|
134
135
|
- lib/pendaxes/notificators/mail.rb
|
135
136
|
- lib/pendaxes/notificators/terminal.rb
|
136
137
|
- lib/pendaxes/pending_manager.rb
|
@@ -168,7 +169,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
168
169
|
version: '0'
|
169
170
|
segments:
|
170
171
|
- 0
|
171
|
-
hash:
|
172
|
+
hash: -3174069537055922012
|
172
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
174
|
none: false
|
174
175
|
requirements:
|
@@ -177,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
178
|
version: '0'
|
178
179
|
segments:
|
179
180
|
- 0
|
180
|
-
hash:
|
181
|
+
hash: -3174069537055922012
|
181
182
|
requirements: []
|
182
183
|
rubyforge_project:
|
183
184
|
rubygems_version: 1.8.23
|