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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # Pendaxes
2
2
 
3
+ ![sample notification using mail](https://img.skitch.com/20120925-essq4fdifg79axb2ssi2cyb2ne.png)
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
- (writing in cron is recommended)
22
+ See `pendaxes --help` for more.
21
23
 
22
24
  ### Configuration
23
25
 
24
- #### Minimal
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 = Config.new(YAML.load_file(args.first))
14
+ @config = nil
12
15
  end
13
16
 
14
- def run
15
- puts "=> Update repository"
16
- update
17
+ def config
18
+ return @config if @config
19
+ return nil if @args.empty? && !File.exist?(DEFAULT_CONFIG_FILE)
17
20
 
18
- puts "=> Detect pendings"
19
- detect
21
+ @config = Config.new(YAML.load_file(@args.first || DEFAULT_CONFIG_FILE))
22
+ end
20
23
 
21
- puts "=> Writing report"
22
- report
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
- puts "=> Send notifications"
25
- notify
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
- 0
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
- @workspace = Workspace.new(@config.workspace)
32
- @workspace.update
143
+ workspace.update if config.workspace
33
144
  end
34
145
 
35
146
  def detect
36
- @detector = Detector.find(@config.detection.use.to_sym).new(@workspace, {out: $stdout}.merge(@config.detection))
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
- @config.notifications.map{|x| Hashr.new(x) }.each do |notification|
49
- puts " * #{notification.use}"
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
@@ -3,7 +3,7 @@ require 'hashr'
3
3
  module Pendaxes
4
4
  class Config < Hashr
5
5
  define detection: {use: :rspec},
6
- workspace: {},
6
+ workspace: nil,
7
7
  report: {use: :text, to: "report.txt"},
8
8
  notifications: [{use: :terminal}]
9
9
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Pendaxes
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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 || "FETCH_HEAD"
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
@@ -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", "FETCH_HEAD").ordered
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", "FETCH_HEAD").ordered
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.1
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-25 00:00:00.000000000 Z
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: 314574877471589493
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: 314574877471589493
181
+ hash: -3174069537055922012
181
182
  requirements: []
182
183
  rubyforge_project:
183
184
  rubygems_version: 1.8.23