issue-beaver 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +72 -0
- data/README.md +38 -0
- data/Rakefile +16 -0
- data/bin/issuebeaver +5 -0
- data/issue-beaver.gemspec +18 -0
- data/lib/enumerable/merge.rb +24 -0
- data/lib/issue_beaver/grammars/ruby_comments.rb +9 -0
- data/lib/issue_beaver/grammars/ruby_comments.treetop +110 -0
- data/lib/issue_beaver/grammars.rb +4 -0
- data/lib/issue_beaver/models/git.rb +63 -0
- data/lib/issue_beaver/models/github_issue.rb +106 -0
- data/lib/issue_beaver/models/github_issue_repository.rb +96 -0
- data/lib/issue_beaver/models/merger.rb +146 -0
- data/lib/issue_beaver/models/todo_comments.rb +57 -0
- data/lib/issue_beaver/models.rb +5 -0
- data/lib/issue_beaver/runner.rb +176 -0
- data/lib/issue_beaver/shared/attributes_model.rb +51 -0
- data/lib/issue_beaver/shared/hash.rb +16 -0
- data/lib/issue_beaver/shared/model_collection.rb +27 -0
- data/lib/issue_beaver/shared.rb +3 -0
- data/lib/issue_beaver.rb +7 -0
- data/lib/password/password.rb +132 -0
- data/spec/fixtures/ruby.rb +6 -0
- data/spec/fixtures/ruby2.rb +16 -0
- data/spec/grammars/ruby_comments_spec.rb +60 -0
- data/spec/spec_helper.rb +2 -0
- metadata +78 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_model'
|
3
|
+
|
4
|
+
module IssueBeaver
|
5
|
+
module Shared
|
6
|
+
module AttributesModel
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
|
11
|
+
included do
|
12
|
+
|
13
|
+
attr_accessor :attributes
|
14
|
+
|
15
|
+
include ActiveModel::AttributeMethods
|
16
|
+
|
17
|
+
include ActiveModel::Dirty
|
18
|
+
|
19
|
+
attribute_method_suffix '='
|
20
|
+
|
21
|
+
|
22
|
+
def attribute(key)
|
23
|
+
attributes[key]
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def attribute=(key, value)
|
28
|
+
attribute_will_change!(key) unless value == attributes[key]
|
29
|
+
attributes[key] = value
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def update_attributes(attrs)
|
34
|
+
attrs.each do |key, value|
|
35
|
+
send(:attribute=, key, value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def modifier
|
41
|
+
if new?
|
42
|
+
"added"
|
43
|
+
elsif changed?
|
44
|
+
"modified"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def except(*blacklist)
|
4
|
+
{}.tap do |h|
|
5
|
+
(keys - blacklist - blacklist.map(&:to_s)).each { |k| h[k] = self[k] }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def only(*whitelist)
|
11
|
+
{}.tap do |h|
|
12
|
+
(keys & (whitelist | whitelist.map(&:to_s))).each { |k| h[k] = self[k] }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module IssueBeaver
|
2
|
+
module Shared
|
3
|
+
class ModelCollection
|
4
|
+
|
5
|
+
def initialize(model, array)
|
6
|
+
@model = model
|
7
|
+
@array = array
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def dup
|
12
|
+
self.class.new(@model, @array.dup)
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def method_missing(name, *args, &block)
|
17
|
+
if @model.respond_to?(name)
|
18
|
+
target = @model
|
19
|
+
else
|
20
|
+
target = @array
|
21
|
+
end
|
22
|
+
target.send(name, *args, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/issue_beaver.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# https://gist.github.com/2040373
|
2
|
+
# Ask for a password from CLI,
|
3
|
+
# if it exists.
|
4
|
+
module Password
|
5
|
+
|
6
|
+
# --- Platform inspectors
|
7
|
+
|
8
|
+
def windows? ; RUBY_PLATFORM =~ /win(32|dows|ce)|djgpp|(ms|cyg|bcc)win|mingw32/i end
|
9
|
+
def jruby? ; RUBY_PLATFORM =~ /java/i end
|
10
|
+
def os2? ; RUBY_PLATFORM =~ /os2/i end
|
11
|
+
def beos? ; RUBY_PLATFORM =~ /beos/i end
|
12
|
+
def unix? ; !jruby? && !windows? && !os2? && !beos? end
|
13
|
+
# NOTE: 99.999% of mac detection code has a subtle flaw.
|
14
|
+
# i.e.: RUBY_PLATFORM =~ /darwin|apple|mac/i
|
15
|
+
|
16
|
+
def mac? ; RUBY_PLATFORM =~ /.*(sal|86).*-darwin1/i end # e.g.. 'x86_64-darwin11.3.0' MRI 1.9.3 Lion
|
17
|
+
# 'x86_64-apple-darwin11.3.0' Rubinius Lion
|
18
|
+
# 'i686-darwin11.3.0' RubyEnterprise Lion
|
19
|
+
# 'universal-darwin10.0' MacRuby Lion
|
20
|
+
|
21
|
+
def ios? ; RUBY_PLATFORM =~ /arm-darwin/i end # e.g., 'arm-darwin9'
|
22
|
+
|
23
|
+
# Can you spot the implication?
|
24
|
+
|
25
|
+
def linux? ; RUBY_PLATFORM =~ /linux/i end
|
26
|
+
# patches welcome: rh, oel, sl, slc, cent, fed, ubt, deb, mint, sles, suse, arch, parabola, nixos, ad ⧝
|
27
|
+
def bsd? ; freebsd? || netbsd? || openbsd? end
|
28
|
+
def freebsd? ; RUBY_PLATFORM =~ /freebsd/i end
|
29
|
+
def netbsd? ; RUBY_PLATFORM =~ /netbsd/i end
|
30
|
+
def openbsd? ; RUBY_PLATFORM =~ /openbsd/i end
|
31
|
+
def solaris? ; RUBY_PLATFORM =~ /solaris/i end
|
32
|
+
|
33
|
+
# TODO: cleanly chain signal handlers to prevent leaving -(echo|icanon)
|
34
|
+
|
35
|
+
# --- Lé code
|
36
|
+
|
37
|
+
def ask_for_password_on_unix(prompt = "Enter password: ")
|
38
|
+
raise 'Could not ask for password because there is no interactive terminal (tty)' unless $stdin.tty?
|
39
|
+
unless prompt.nil?
|
40
|
+
$stderr.print prompt
|
41
|
+
$stderr.flush
|
42
|
+
end
|
43
|
+
raise 'Could not disable echo to ask for password security' unless system 'stty -echo -icanon'
|
44
|
+
password = $stdin.gets
|
45
|
+
password.chomp! if password
|
46
|
+
password
|
47
|
+
ensure
|
48
|
+
raise 'Could not re-enable echo while securely asking for password' unless system 'stty echo icanon'
|
49
|
+
end
|
50
|
+
|
51
|
+
def ask_for_password_on_windows(prompt = "Enter password: ")
|
52
|
+
raise 'Could not ask for password because there is no interactive terminal (tty)' unless $stdin.tty?
|
53
|
+
|
54
|
+
require 'Win32API'
|
55
|
+
|
56
|
+
char = nil
|
57
|
+
password = ''
|
58
|
+
|
59
|
+
unless prompt.nil?
|
60
|
+
$stderr.print prompt
|
61
|
+
$stderr.flush
|
62
|
+
end
|
63
|
+
|
64
|
+
while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
|
65
|
+
break if char == 10 || char == 13 # return or newline
|
66
|
+
if char == 127 || char == 8 # backspace and delete
|
67
|
+
password[-1] = ' '
|
68
|
+
password.slice!(-1, 1)
|
69
|
+
else
|
70
|
+
password << char.chr
|
71
|
+
end
|
72
|
+
end
|
73
|
+
char = ' '
|
74
|
+
|
75
|
+
$stderr.puts
|
76
|
+
password
|
77
|
+
end
|
78
|
+
|
79
|
+
def ask_for_password_on_jruby(prompt = "Enter password: ")
|
80
|
+
raise 'Could not ask for password because there is no interactive terminal (tty)' unless $stdin.tty?
|
81
|
+
|
82
|
+
password=''
|
83
|
+
|
84
|
+
require 'java'
|
85
|
+
include_class 'java.lang.System'
|
86
|
+
include_class 'java.io.Console'
|
87
|
+
|
88
|
+
unless prompt.nil?
|
89
|
+
$stderr.print prompt
|
90
|
+
$stderr.flush
|
91
|
+
end
|
92
|
+
|
93
|
+
console = System.console()
|
94
|
+
return unless console != java.null
|
95
|
+
loop do
|
96
|
+
break unless (read_passwd = console.readPassword()) != java.null
|
97
|
+
passwd_chr = java.lang.String.new(read_passwd).to_string
|
98
|
+
case passwd_chr
|
99
|
+
when "\e" # ESC
|
100
|
+
password.length.times do |i|
|
101
|
+
password[i] = ' '
|
102
|
+
end
|
103
|
+
return nil
|
104
|
+
when "", "\r", "\n" # Enter (for certain), ..., ...
|
105
|
+
break
|
106
|
+
when "\177", "\b" # Ctrl-H, Bkspace
|
107
|
+
if password.length > 0
|
108
|
+
password[-1] = ' '
|
109
|
+
password.slice!(-1, 1)
|
110
|
+
end
|
111
|
+
when "\004" # Ctrl-D
|
112
|
+
password.length.times do |i|
|
113
|
+
password[i] = ' '
|
114
|
+
end
|
115
|
+
password = ''
|
116
|
+
else
|
117
|
+
password << passwd_chr
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
$stderr.puts
|
122
|
+
passwd
|
123
|
+
end
|
124
|
+
|
125
|
+
def ask(prompt = "Enter password: ")
|
126
|
+
%w|windows unix jruby|.each do |platform|
|
127
|
+
eval "return ask_for_password_on_#{platform}(prompt) if #{platform}?"
|
128
|
+
end
|
129
|
+
raise "Could not read password on unknown Ruby platform: #{RUBY_DESCRIPTION}"
|
130
|
+
end
|
131
|
+
extend self
|
132
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Foo
|
2
|
+
# TODO: This line should be found in the tests
|
3
|
+
# And this should be found
|
4
|
+
# as the body
|
5
|
+
def foo(a,b,c)
|
6
|
+
puts "Hello World!"
|
7
|
+
end
|
8
|
+
# TODO: Second comment
|
9
|
+
|
10
|
+
# Not the body
|
11
|
+
|
12
|
+
# TODO: Change to 42 @foobar
|
13
|
+
def bar
|
14
|
+
23
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe IssueBeaver::Grammars::RubyCommentsParser do
|
4
|
+
|
5
|
+
context "ruby.rb" do
|
6
|
+
let(:ruby_code) { File.read('./spec/fixtures/ruby.rb') }
|
7
|
+
subject { IssueBeaver::Grammars::RubyCommentsParser.new.parse(ruby_code) }
|
8
|
+
let(:comment) {subject.comments[0]}
|
9
|
+
|
10
|
+
it "should find the one comment" do
|
11
|
+
subject.comments.length.should == 1
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have correct properties" do
|
15
|
+
comment['begin_line'].should == 2
|
16
|
+
comment['title'].should == "This line should be found in the tests"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should find the comment body" do
|
20
|
+
comment['body'].should == nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "ruby2.rb" do
|
25
|
+
let(:ruby_code) { File.read('./spec/fixtures/ruby2.rb') }
|
26
|
+
subject { IssueBeaver::Grammars::RubyCommentsParser.new.parse(ruby_code) }
|
27
|
+
let(:comments) {subject.comments}
|
28
|
+
|
29
|
+
it "should find the number of comment" do
|
30
|
+
comments.length.should == 3
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have correct properties" do
|
34
|
+
comments[0]['begin_line'].should == 2
|
35
|
+
comments[0]['title'].should == "This line should be found in the tests"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should find the comment body" do
|
39
|
+
comments[0]['body'].should == "And this should be found\nas the body"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have correct properties" do
|
43
|
+
comments[1]['begin_line'].should == 8
|
44
|
+
comments[1]['title'].should == "Second comment"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should find the comment body" do
|
48
|
+
comments[1]['body'].should == nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should find the title without assignee" do
|
52
|
+
comments[2]['title'].should == "Change to 42"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should find the assignee" do
|
56
|
+
comments[2]['assignee'].should == "foobar"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: issue-beaver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Stephan Eckardt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-23 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Issue Beaver creates Github Issues for TODO comments in your source code
|
15
|
+
email:
|
16
|
+
- mail@stephaneckardt.com
|
17
|
+
executables:
|
18
|
+
- issuebeaver
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .rspec
|
23
|
+
- Gemfile
|
24
|
+
- Gemfile.lock
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- bin/issuebeaver
|
28
|
+
- issue-beaver.gemspec
|
29
|
+
- lib/enumerable/merge.rb
|
30
|
+
- lib/issue_beaver.rb
|
31
|
+
- lib/issue_beaver/grammars.rb
|
32
|
+
- lib/issue_beaver/grammars/ruby_comments.rb
|
33
|
+
- lib/issue_beaver/grammars/ruby_comments.treetop
|
34
|
+
- lib/issue_beaver/models.rb
|
35
|
+
- lib/issue_beaver/models/git.rb
|
36
|
+
- lib/issue_beaver/models/github_issue.rb
|
37
|
+
- lib/issue_beaver/models/github_issue_repository.rb
|
38
|
+
- lib/issue_beaver/models/merger.rb
|
39
|
+
- lib/issue_beaver/models/todo_comments.rb
|
40
|
+
- lib/issue_beaver/runner.rb
|
41
|
+
- lib/issue_beaver/shared.rb
|
42
|
+
- lib/issue_beaver/shared/attributes_model.rb
|
43
|
+
- lib/issue_beaver/shared/hash.rb
|
44
|
+
- lib/issue_beaver/shared/model_collection.rb
|
45
|
+
- lib/password/password.rb
|
46
|
+
- spec/fixtures/ruby.rb
|
47
|
+
- spec/fixtures/ruby2.rb
|
48
|
+
- spec/grammars/ruby_comments_spec.rb
|
49
|
+
- spec/spec_helper.rb
|
50
|
+
homepage: https://github.com/eckardt/issue-beaver
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.24
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Issue Beaver creates Github Issues for TODO comments in your source code
|
74
|
+
test_files:
|
75
|
+
- spec/fixtures/ruby.rb
|
76
|
+
- spec/fixtures/ruby2.rb
|
77
|
+
- spec/grammars/ruby_comments_spec.rb
|
78
|
+
- spec/spec_helper.rb
|