gittest 0.1.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/History.txt +3 -0
- data/Manifest.txt +6 -0
- data/README.txt +65 -0
- data/Rakefile +12 -0
- data/bin/gittest +81 -0
- data/lib/gittest.rb +138 -0
- metadata +107 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
= Gittest
|
2
|
+
|
3
|
+
* https://github.com/thickpaddy/gittest
|
4
|
+
|
5
|
+
== Description:
|
6
|
+
|
7
|
+
Gittest uses your autotest mappings to run tests based on the files
|
8
|
+
you've created or changed, according to git diff.
|
9
|
+
|
10
|
+
== Usage:
|
11
|
+
|
12
|
+
Typically, you just execute gittest on the command line. Run it with
|
13
|
+
the help option to see what other options are available:
|
14
|
+
|
15
|
+
gittest --help
|
16
|
+
|
17
|
+
Of note is the --commit option. You can use this to customise the
|
18
|
+
commit argument to git diff, which defaults to 'HEAD', i.e. the last
|
19
|
+
commit. This is really handy when you're working on a topic branch
|
20
|
+
and want to run tests based on all the files you've changed in that
|
21
|
+
branch, not just those that have been created or modified since the
|
22
|
+
last commit. For example:
|
23
|
+
|
24
|
+
gittest --commit origin/master
|
25
|
+
|
26
|
+
You can also create a Gittest instance and both interrogate it and ask
|
27
|
+
it to run the tests (this is exactly what the executable does). Have a
|
28
|
+
look at the code, it's pretty simple.
|
29
|
+
|
30
|
+
== Install:
|
31
|
+
|
32
|
+
The latest release should be available from rubygems.org
|
33
|
+
|
34
|
+
sudo gem install gittest
|
35
|
+
|
36
|
+
To install directly from source...
|
37
|
+
|
38
|
+
git clone git://github.com/thickpaddy/gittest.git
|
39
|
+
cd gittest
|
40
|
+
rake install_gem
|
41
|
+
|
42
|
+
== License:
|
43
|
+
|
44
|
+
(The MIT License)
|
45
|
+
|
46
|
+
Copyright (c) 2010 Mark Woods
|
47
|
+
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
49
|
+
a copy of this software and associated documentation files (the
|
50
|
+
'Software'), to deal in the Software without restriction, including
|
51
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
52
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
53
|
+
permit persons to whom the Software is furnished to do so, subject to
|
54
|
+
the following conditions:
|
55
|
+
|
56
|
+
The above copyright notice and this permission notice shall be
|
57
|
+
included in all copies or substantial portions of the Software.
|
58
|
+
|
59
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
60
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
61
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
62
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
63
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
64
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
65
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
3
|
+
require 'hoe'
|
4
|
+
require 'fileutils'
|
5
|
+
require './lib/gittest'
|
6
|
+
|
7
|
+
Hoe.spec 'gittest' do
|
8
|
+
self.developer 'Mark Woods', 'mark dot woods at jgp, a company in the uk'
|
9
|
+
self.rubyforge_name = self.name # TODO this is default value
|
10
|
+
self.extra_deps = [['ZenTest', '>= 0']]
|
11
|
+
end
|
12
|
+
|
data/bin/gittest
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'gittest'
|
6
|
+
|
7
|
+
options = {:commit => 'HEAD'}
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
opts.banner = "Usage: gittest [options]"
|
10
|
+
opts.on("-c MANDATORY", "--commit MANDATORY", "Commit argument for git diff command used to check for new or modified files (defaults to HEAD)") do |o|
|
11
|
+
options[:commit] = o
|
12
|
+
end
|
13
|
+
opts.on("-l", "--load", "Run pending migrations and load test database from schema before running tests (Rails only)") do |o|
|
14
|
+
options[:load] = o
|
15
|
+
end
|
16
|
+
opts.on("-p", "--prepare", "Purge test database and re-create by running all migrations before running tests (Rails only)") do |o|
|
17
|
+
options[:prepare] = o
|
18
|
+
end
|
19
|
+
opts.on("-t", "--trace", "Enable full backtrace on exception") do |o|
|
20
|
+
options[:trace] = o
|
21
|
+
end
|
22
|
+
end.parse!
|
23
|
+
|
24
|
+
# create an instance of Gittest to do the dirty work
|
25
|
+
begin
|
26
|
+
gt = Gittest.new(options[:commit])
|
27
|
+
rescue LoadError => e
|
28
|
+
puts "LoadError: #{e.message}, exiting"
|
29
|
+
if options[:trace]
|
30
|
+
puts e.backtrace
|
31
|
+
else
|
32
|
+
puts "(see full trace by running command with --trace option)"
|
33
|
+
end
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
|
37
|
+
rake_options = options[:trace] ? '--trace' : ''
|
38
|
+
if options[:prepare]
|
39
|
+
puts "Preparing test database..."
|
40
|
+
exit $?.exitstatus unless system "rake db:test:purge #{rake_options}"
|
41
|
+
exit $?.exitstatus unless system "rake db:migrate RAILS_ENV=test #{rake_options}"
|
42
|
+
end
|
43
|
+
if options[:load]
|
44
|
+
puts "Loading test database..."
|
45
|
+
exit $?.exitstatus unless system "rake db:migrate RAILS_ENV=test #{rake_options}"
|
46
|
+
exit $?.exitstatus unless system "rake db:test:load #{rake_options}"
|
47
|
+
end
|
48
|
+
|
49
|
+
# look for modified files
|
50
|
+
if gt.new_or_modified_files.empty?
|
51
|
+
puts "No modified files, exiting"
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
msg = "#{gt.new_or_modified_files.size} new or modified file"
|
55
|
+
msg << "s" unless gt.new_or_modified_files.size == 1
|
56
|
+
puts msg + ":"
|
57
|
+
gt.new_or_modified_files.each {|f| puts "\t#{f}"}
|
58
|
+
|
59
|
+
# look for files to test
|
60
|
+
if gt.files_to_test.empty?
|
61
|
+
puts "No matching files to test, exiting"
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
msg = "#{gt.files_to_test.size} file"
|
65
|
+
msg << "s" unless gt.files_to_test.size == 1
|
66
|
+
msg << " to test"
|
67
|
+
puts msg + ":"
|
68
|
+
puts "\t" + gt.files_to_test.map{|k,v| k}.sort.join("\n\t")
|
69
|
+
|
70
|
+
# give user an option to quit now, before running the tests/specs
|
71
|
+
puts "Press ENTER to continue, or CTRL+C to quit"
|
72
|
+
begin
|
73
|
+
$stdin.gets # note: Kernel#gets assumes that ARGV contains a list of files from which to read next line
|
74
|
+
rescue Interrupt
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
|
78
|
+
# run those tests baby
|
79
|
+
puts "Running tests and/or specs, please wait..."
|
80
|
+
gt.run_tests
|
81
|
+
|
data/lib/gittest.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'autotest'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
class Gittest
|
6
|
+
|
7
|
+
VERSION = '0.1.2'
|
8
|
+
|
9
|
+
attr_reader :commit, :test_mappings
|
10
|
+
|
11
|
+
# Create a new Gittest instance. Raises LoadError if current working directory not within a git repository. Changes current working directory to root of git repository.
|
12
|
+
def initialize(commit='HEAD')
|
13
|
+
# Force fast start option for autotest. Although not used directly here, hooks might
|
14
|
+
# do things like preparing test databases unless the fast start option is enabled.
|
15
|
+
Autotest.respond_to?(:options) ? Autotest.options[:no_full_after_start] = true : $f = true
|
16
|
+
raise LoadError, "Not in a git repository" unless silence_stream(STDERR) { system("git rev-parse") } # note: git rev-parse will exit 0 if it's in a repo
|
17
|
+
cd_to_repository_root # note: I'm assuming that the repository root is the project root, and any .autotest file will be in the project root
|
18
|
+
@at = Autotest.new
|
19
|
+
@at.hook :initialize
|
20
|
+
@at.find_files # find known files on initialisation
|
21
|
+
@test_mappings = @at.instance_eval { @test_mappings }
|
22
|
+
@commit = commit
|
23
|
+
end
|
24
|
+
|
25
|
+
# Reset the known files and both new_or_modified_files and files_to_test values
|
26
|
+
def reset
|
27
|
+
@at.find_files
|
28
|
+
@new_or_modified_files = nil
|
29
|
+
@files_to_test = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the new or modified files, initially found by calling find_new_or_modified_files
|
33
|
+
def new_or_modified_files
|
34
|
+
@new_or_modified_files ||= find_new_or_modified_files
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the files to test, initially found by calling find_files_to_test
|
38
|
+
def files_to_test
|
39
|
+
@files_to_test ||= find_files_to_test
|
40
|
+
end
|
41
|
+
|
42
|
+
# Finds new or modified files by executing git diff and parsing output
|
43
|
+
def find_new_or_modified_files
|
44
|
+
`git diff --name-only #{@commit}`.split("\n").uniq
|
45
|
+
end
|
46
|
+
|
47
|
+
# Finds files to test by checking if the autotest test mappings match any of the new or modified files
|
48
|
+
def find_files_to_test
|
49
|
+
files_to_test = @at.new_hash_of_arrays
|
50
|
+
new_or_modified_files.each do |f|
|
51
|
+
next if f =~ @at.exceptions # skip exceptions
|
52
|
+
result = @test_mappings.find { |file_re, ignored| f =~ file_re }
|
53
|
+
unless result.nil?
|
54
|
+
[result.last.call(f, $~)].flatten.each {|match| files_to_test[match] if File.exist?(match)}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return files_to_test
|
58
|
+
end
|
59
|
+
|
60
|
+
# Runs tests and ask autotest to handle the results. Also calls autotest :run_command and :ran_command hooks appropriately.
|
61
|
+
def run_tests
|
62
|
+
@at.hook :run_command
|
63
|
+
cmd = @at.make_test_cmd(files_to_test)
|
64
|
+
# copied from Autotest#run_tests and updated to use ansi colours in TURN enabled test output and specs run with the format option set to specdoc
|
65
|
+
colors = { :red => 31, :green => 32, :yellow => 33 }
|
66
|
+
old_sync = $stdout.sync
|
67
|
+
$stdout.sync = true
|
68
|
+
results = []
|
69
|
+
line = []
|
70
|
+
begin
|
71
|
+
open("| #{cmd}", "r") do |f|
|
72
|
+
until f.eof? do
|
73
|
+
c = f.getc or break
|
74
|
+
# putc c
|
75
|
+
line << c
|
76
|
+
if c == ?\n then
|
77
|
+
str = if RUBY_VERSION >= "1.9" then
|
78
|
+
line.join
|
79
|
+
else
|
80
|
+
line.pack "c*"
|
81
|
+
end
|
82
|
+
results << str
|
83
|
+
line.clear
|
84
|
+
if str.match(/(PASS|FAIL|ERROR)$/)
|
85
|
+
# test output
|
86
|
+
case $1
|
87
|
+
when 'PASS' ; color = :green
|
88
|
+
when 'FAIL' ; color = :red
|
89
|
+
when 'ERROR' ; color = :yellow
|
90
|
+
end
|
91
|
+
print "\e[#{colors[color]}m" + str + "\e[0m"
|
92
|
+
elsif str.match(/^\- /)
|
93
|
+
# spec output
|
94
|
+
if str.match(/^\- .*(ERROR|FAILED) \- [0-9]+/)
|
95
|
+
color = $1 == 'FAILED' ? :red : :yellow
|
96
|
+
print "\e[#{colors[color]}m" + str + "\e[0m"
|
97
|
+
else
|
98
|
+
print "\e[#{colors[:green]}m" + str + "\e[0m"
|
99
|
+
end
|
100
|
+
else
|
101
|
+
print str
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
ensure
|
107
|
+
$stdout.sync = old_sync
|
108
|
+
end
|
109
|
+
@at.hook :ran_command
|
110
|
+
@at.handle_results(results.join)
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
# Changes the working directory to the root path for the repository (assumes current working directory is within a repository)
|
116
|
+
def cd_to_repository_root #:nodoc:
|
117
|
+
loop do
|
118
|
+
begin
|
119
|
+
Dir.entries('.git')
|
120
|
+
break
|
121
|
+
rescue SystemCallError
|
122
|
+
Dir.chdir('..')
|
123
|
+
next
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Silences a stream for the duration of the block - copied directly from Rails Kernel extensions
|
129
|
+
def silence_stream(stream) #:nodoc:
|
130
|
+
old_stream = stream.dup
|
131
|
+
stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
|
132
|
+
stream.sync = true
|
133
|
+
yield
|
134
|
+
ensure
|
135
|
+
stream.reopen(old_stream)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gittest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mark Woods
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-14 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: ZenTest
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hoe
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 5
|
44
|
+
segments:
|
45
|
+
- 2
|
46
|
+
- 3
|
47
|
+
- 3
|
48
|
+
version: 2.3.3
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
description: |-
|
52
|
+
Gittest uses your autotest mappings to run tests based on the files
|
53
|
+
you've created or changed, according to git diff.
|
54
|
+
email:
|
55
|
+
- mark dot woods at jgp, a company in the uk
|
56
|
+
executables:
|
57
|
+
- gittest
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
extra_rdoc_files:
|
61
|
+
- History.txt
|
62
|
+
- Manifest.txt
|
63
|
+
- README.txt
|
64
|
+
files:
|
65
|
+
- History.txt
|
66
|
+
- Manifest.txt
|
67
|
+
- README.txt
|
68
|
+
- Rakefile
|
69
|
+
- bin/gittest
|
70
|
+
- lib/gittest.rb
|
71
|
+
has_rdoc: true
|
72
|
+
homepage: https://github.com/thickpaddy/gittest
|
73
|
+
licenses: []
|
74
|
+
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options:
|
77
|
+
- --main
|
78
|
+
- README.txt
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 3
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project: gittest
|
102
|
+
rubygems_version: 1.4.1
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Gittest uses your autotest mappings to run tests based on the files you've created or changed, according to git diff.
|
106
|
+
test_files: []
|
107
|
+
|