spackle 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +166 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/bin/ruby-project-root +14 -0
- data/bin/spackle +14 -0
- data/bin/spackle-vim-load-quickfix +47 -0
- data/bin/spackle-vim-open +49 -0
- data/lib/spackle/commandline.rb +53 -0
- data/lib/spackle/configuration.rb +37 -0
- data/lib/spackle/error.rb +31 -0
- data/lib/spackle/helpers/ruby_project_root.rb +34 -0
- data/lib/spackle/output/base.rb +44 -0
- data/lib/spackle/output/vim_quickfix.rb +7 -0
- data/lib/spackle/output.rb +2 -0
- data/lib/spackle/spec/base_formatter.rb +22 -0
- data/lib/spackle/spec/spackle_formatter.rb +14 -0
- data/lib/spackle/spec.rb +1 -0
- data/lib/spackle.rb +104 -0
- data/spec/integration_spec.rb +84 -0
- data/spec/spackle/commandline_spec.rb +48 -0
- data/spec/spackle/configuration_spec.rb +43 -0
- data/spec/spackle/error_spec.rb +34 -0
- data/spec/spackle/output/base_spec.rb +53 -0
- data/spec/spackle/output/vim_quickfix_spec.rb +25 -0
- data/spec/spackle/spec/base_formatter_spec.rb +15 -0
- data/spec/spackle/spec/spackle_formatter_spec.rb +58 -0
- data/spec/spackle_error_fixture.rb +10 -0
- data/spec/spackle_spec.rb +203 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/test_app_helper.rb +55 -0
- data/support/vim/spackle.vim +17 -0
- data/test_app/lib/error_raiser.rb +7 -0
- data/test_app/lib/method_typo.rb +7 -0
- data/test_app/lib/missing_end.rb +7 -0
- data/test_app/lib/working_class.rb +7 -0
- data/test_app/spec/error_raiser_spec.rb +14 -0
- data/test_app/spec/failing_working_class_spec.rb +14 -0
- data/test_app/spec/method_typo_spec.rb +14 -0
- data/test_app/spec/missing_end_spec.rb +13 -0
- data/test_app/spec/passing_working_class_spec.rb +14 -0
- data/test_app/spec/spec_helper.rb +8 -0
- metadata +127 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Rick Lee-Morlang
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
= Spackle
|
2
|
+
|
3
|
+
<em>Smoothing out the gaps between the Rubyist and the Ruby.</em>
|
4
|
+
|
5
|
+
Well, honestly, it only fills in the gaps between RSpec and Vim right now,
|
6
|
+
but that's a good start. Cucumber support is in the works, and perhaps a
|
7
|
+
few other surprises if I make the time.
|
8
|
+
|
9
|
+
Patches supporting other editors gladly accepted. Most people aren't very
|
10
|
+
editor-agnostic, but Spackle doesn't care! (Or, at least, it wouldn't if
|
11
|
+
you patched it with support for your amazing editor that's surely better
|
12
|
+
than mine.)
|
13
|
+
|
14
|
+
== Elevator Pitch
|
15
|
+
|
16
|
+
Spackle tells your editor about the errors in your code. No more need to
|
17
|
+
visually scan your test output for errors, filenames, and line numbers.
|
18
|
+
Just tell your editor to jump to the next error location.
|
19
|
+
|
20
|
+
== Features
|
21
|
+
|
22
|
+
* custom RSpec formatters that generate output compatible with
|
23
|
+
Vim's quickfix functionality
|
24
|
+
* a simple Vim plugin to allow a quickfix list to be loaded
|
25
|
+
from a file
|
26
|
+
* shell scripts to glue Spackle's output and Vim together
|
27
|
+
* easy to use?
|
28
|
+
|
29
|
+
== Quick Installation
|
30
|
+
|
31
|
+
gem install spackle --source http://gemcutter.org
|
32
|
+
spackle --install vim # described below
|
33
|
+
echo 'Spackle.configuration.set_defaults_for :vim' > ~/.spackle
|
34
|
+
|
35
|
+
== Configuration and Usage
|
36
|
+
|
37
|
+
For a tool that doesn't do a heck of alot, it's pretty configurable.
|
38
|
+
If it <b>could</b> do something else, it'd be easy to tell it how to do
|
39
|
+
it with either a <tt>.spackle</tt> file in your home directory, or a
|
40
|
+
<tt>.spackle</tt> file in your project's root directory.
|
41
|
+
|
42
|
+
If Spackle is useful to you, I'd love to hear about it.
|
43
|
+
|
44
|
+
=== PATH
|
45
|
+
|
46
|
+
Spackle installs a few utility scripts in the bin directory where
|
47
|
+
executables are installed by your system's Rubygems. If you've installed
|
48
|
+
Spackle as root, this should be fine. If you've installed Spackle as a
|
49
|
+
regular user, you need to make sure the appropriate bin directory is
|
50
|
+
in your path.
|
51
|
+
|
52
|
+
To test your configuration, run +which spackle+ in your terminal. If
|
53
|
+
you don't see any output, your PATH variable is not correctly configured
|
54
|
+
for use with user-installed gems.
|
55
|
+
|
56
|
+
See your Rubygems documentation for more information about this.
|
57
|
+
|
58
|
+
=== Spackle dotfile
|
59
|
+
|
60
|
+
Without a dotfile configured, Spackle won't do anything. This is so
|
61
|
+
you can make Spackle a dependency of your project and integrate it
|
62
|
+
into your code, yet leave its usage up to each individual developer.
|
63
|
+
|
64
|
+
Spackle reads its configuration from a <tt>.spackle</tt> file, which it looks
|
65
|
+
for in your home directory first, and in the root directory of your
|
66
|
+
project second. Spackle configuration in your project directory takes
|
67
|
+
precedence over any in your home directory, so you can override global
|
68
|
+
settings on a per-project basis if you like.
|
69
|
+
|
70
|
+
Example <tt>.spackle</tt> for Vim users.
|
71
|
+
|
72
|
+
Spackle.configure do |c|
|
73
|
+
c.set_defaults_for :vim
|
74
|
+
end
|
75
|
+
|
76
|
+
See Spackle::Configuration for more information.
|
77
|
+
|
78
|
+
=== RSpec
|
79
|
+
|
80
|
+
Add to your spec_helper.rb:
|
81
|
+
|
82
|
+
require "spackle"
|
83
|
+
Spackle.init :with => :spec_formatter
|
84
|
+
|
85
|
+
Now whenever RSpec runs, Spackle will listen in to your test results and
|
86
|
+
relay information about any errors to your editor.
|
87
|
+
|
88
|
+
=== Vim
|
89
|
+
|
90
|
+
Spackle needs a tiny Vim plugin installed to function properly with Vim.
|
91
|
+
Simply run +spackle install vim+ and Spackle will copy its plugin into
|
92
|
+
your <tt>.vim/plugins</tt> directory.
|
93
|
+
|
94
|
+
<b>Optional:</b>
|
95
|
+
Spackle also comes with a helper script for invoking Vim with a session
|
96
|
+
named after your project's parent directory. It's called <tt>spackle-vim-open</tt>.
|
97
|
+
If you'd like to use it, you'll probably want to add an alias to your
|
98
|
+
<tt>.profile</tt> or <tt>.bashrc</tt>. Example:
|
99
|
+
|
100
|
+
alias e='spackle-vim-open'
|
101
|
+
|
102
|
+
== Architecture
|
103
|
+
|
104
|
+
Spackle's architecture consists of three components.
|
105
|
+
|
106
|
+
NOTE: Some of this information looks forward to a future version of Spackle
|
107
|
+
that, at the moment, is fictional. So if you go looking for some of the things
|
108
|
+
referenced here and you can't find them, that's probably why. (Or it could be
|
109
|
+
an error in this document!)
|
110
|
+
|
111
|
+
Error Parser Adapters
|
112
|
+
* integrate with test harnesses like RSpec and Cucumber
|
113
|
+
* or integrate with Ruby's standard Error API
|
114
|
+
* or parse Ruby's standard backtrace output
|
115
|
+
* convert error output into a generic intermediary Spackle::Error format
|
116
|
+
* pass the errors to Spackle's core for reformatting and output
|
117
|
+
* found in Spackle::Spec, Spackle::Cucumber and Spackle::Ruby
|
118
|
+
|
119
|
+
Spackle Core
|
120
|
+
* glues all the pieces together
|
121
|
+
* loads user configuration
|
122
|
+
* tries to do as much as it can automagically
|
123
|
+
* tries to stay out of your way
|
124
|
+
* routes Spackle::Error objects from the Adapters, through an
|
125
|
+
Output Formatter, and finally to an output file
|
126
|
+
* triggers a callback after every test run that can send error
|
127
|
+
information to your editor
|
128
|
+
|
129
|
+
Output Formatters
|
130
|
+
* convert the generic Error format into an output-specific format
|
131
|
+
for your callback to handle
|
132
|
+
* found in Spackle::Output
|
133
|
+
|
134
|
+
Spackle's core configuration, tries to do as much automagically as it can,
|
135
|
+
and tries to stay out of the way. It aids the models by routing Errors to the
|
136
|
+
configured output formatter.
|
137
|
+
|
138
|
+
== Known Issues
|
139
|
+
|
140
|
+
* Spackle assumes you're using something UNIXy. If you're not, it likely
|
141
|
+
won't work. I have no interest in working on this, but I'll gladly
|
142
|
+
pull your patches.
|
143
|
+
* Spackle's current implementation only catches test failures from RSpec.
|
144
|
+
Other hooks are in the works.
|
145
|
+
|
146
|
+
== Credits
|
147
|
+
|
148
|
+
Spackle was inspired by https://wincent.com/blog/running-rspec-specs-from-inside-vim
|
149
|
+
|
150
|
+
== Note on Patches/Pull Requests
|
151
|
+
|
152
|
+
This section was generated by Jeweler's boilerplate, but it seems
|
153
|
+
pretty sensible.
|
154
|
+
|
155
|
+
* Fork the project.
|
156
|
+
* Make your feature addition or bug fix.
|
157
|
+
* Add tests for it. This is important so I don't break it in a
|
158
|
+
future version unintentionally.
|
159
|
+
* Commit, do not mess with rakefile, version, or history.
|
160
|
+
(if you want to have your own version, that is fine but
|
161
|
+
bump version in a commit by itself I can ignore when I pull)
|
162
|
+
* Send me a pull request. Bonus points for topic branches.
|
163
|
+
|
164
|
+
== Copyright
|
165
|
+
|
166
|
+
Copyright (c) 2009 Rick Lee-Morlang. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "spackle"
|
8
|
+
gem.summary = %Q{Spackle tells your editor about the errors in your code}
|
9
|
+
gem.description = %Q{
|
10
|
+
Spackle tells your editor about the errors in your code. No more need to
|
11
|
+
visually scan your test output for errors, filenames, and line numbers.
|
12
|
+
Just tell your editor to jump to the next error location.
|
13
|
+
}
|
14
|
+
gem.email = "rick@lee-morlang.com"
|
15
|
+
gem.homepage = "http://github.com/rleemorlang/spackle"
|
16
|
+
gem.authors = ["Rick Lee-Morlang"]
|
17
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
18
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
|
+
end
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'spec/rake/spectask'
|
26
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
34
|
+
spec.rcov = true
|
35
|
+
end
|
36
|
+
|
37
|
+
task :spec => :check_dependencies
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "spackle #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle/helpers/ruby_project_root'
|
6
|
+
|
7
|
+
project_root = Spackle::Helpers::RubyProjectRoot.search Dir.pwd
|
8
|
+
|
9
|
+
if project_root.nil?
|
10
|
+
exit 1
|
11
|
+
else
|
12
|
+
puts project_root
|
13
|
+
end
|
14
|
+
|
data/bin/spackle
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle'
|
6
|
+
require 'spackle/commandline'
|
7
|
+
|
8
|
+
begin
|
9
|
+
Spackle::Commandline.parse ARGV
|
10
|
+
rescue => err
|
11
|
+
STDERR.puts err.message
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle/helpers/ruby_project_root'
|
6
|
+
|
7
|
+
# Load a Vim Quickfix file in an active vim session.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# spackle-vim-load-quickfix [servername] quickfix_file
|
11
|
+
#
|
12
|
+
# If servername is specified, try to use it as the vim
|
13
|
+
# server. Otherwise, assume the name for the vim server
|
14
|
+
# is the from ruby-project-root -basename, if
|
15
|
+
# successful. If no Ruby project root was found, use
|
16
|
+
# DEFAULT as the servername.
|
17
|
+
#
|
18
|
+
# If the server doesn't exist, we'll create a new
|
19
|
+
# gvim session.
|
20
|
+
#
|
21
|
+
|
22
|
+
def servername_from_arguments
|
23
|
+
ARGV.shift if ARGV.count == 2
|
24
|
+
end
|
25
|
+
|
26
|
+
def servername_from_project_root
|
27
|
+
project_root = Spackle::Helpers::RubyProjectRoot.search Dir.pwd
|
28
|
+
File.basename(project_root) if project_root
|
29
|
+
end
|
30
|
+
|
31
|
+
def servername
|
32
|
+
@servername ||= servername_from_arguments || servername_from_project_root || "DEFAULT"
|
33
|
+
end
|
34
|
+
|
35
|
+
def server_running?
|
36
|
+
!`gvim --serverlist`.grep(/#{servername}/i).empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
unless server_running?
|
40
|
+
system %{gvim --servername #{servername}}
|
41
|
+
sleep 1
|
42
|
+
end
|
43
|
+
|
44
|
+
system %{gvim --servername #{servername} --remote-send "<ESC>" &> /dev/null}
|
45
|
+
system %{gvim --servername #{servername} --remote-expr "LoadSpackleQuickfix('#{ARGV.first}')" &> /dev/null}
|
46
|
+
system %{gvim --servername #{servername} --remote-send "<ESC><C-W>p" &> /dev/null}
|
47
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
spackle_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
$LOAD_PATH.unshift(spackle_dir) unless $LOAD_PATH.include?(spackle_dir)
|
4
|
+
|
5
|
+
require 'spackle/helpers/ruby_project_root'
|
6
|
+
|
7
|
+
# Load a Vim Quickfix file in an active vim session.
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
# spackle-vim-load-quickfix [servername] quickfix_file
|
11
|
+
#
|
12
|
+
# If servername is specified, try to use it as the vim
|
13
|
+
# server. Otherwise, assume the name for the vim server
|
14
|
+
# is the from ruby-project-root -basename, if
|
15
|
+
# successful. If no Ruby project root was found, use
|
16
|
+
# DEFAULT as the servername.
|
17
|
+
#
|
18
|
+
# If the server doesn't exist, we'll create a new
|
19
|
+
# gvim session.
|
20
|
+
#
|
21
|
+
|
22
|
+
def servername_from_arguments
|
23
|
+
ARGV.count.times do |index|
|
24
|
+
if ARGV[index] == "--servername"
|
25
|
+
ARGV.delete_at index
|
26
|
+
return ARGV.delete_at_index
|
27
|
+
end
|
28
|
+
end
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def servername_from_project_root
|
33
|
+
project_root = Spackle::Helpers::RubyProjectRoot.search Dir.pwd
|
34
|
+
File.basename(project_root) if project_root
|
35
|
+
end
|
36
|
+
|
37
|
+
def servername
|
38
|
+
servername_from_arguments || servername_from_project_root || "DEFAULT"
|
39
|
+
end
|
40
|
+
|
41
|
+
def arguments
|
42
|
+
arguments = ['gvim', '--servername', servername]
|
43
|
+
unless ARGV.empty?
|
44
|
+
arguments << "--remote-silent"
|
45
|
+
arguments += ARGV
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
system *arguments
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
|
5
|
+
module Spackle
|
6
|
+
class Commandline
|
7
|
+
class << self
|
8
|
+
def install(mod)
|
9
|
+
case mod.to_sym
|
10
|
+
when :vim
|
11
|
+
src = File.join(File.dirname(__FILE__), "/../../support/vim/spackle.vim")
|
12
|
+
dest = File.expand_path "~/.vim/plugin"
|
13
|
+
raise "No such directory #{dest} -- cannot install Vim plugin" unless File.directory?(dest)
|
14
|
+
FileUtils.copy src, dest
|
15
|
+
puts "spackle.vim installed in #{dest}"
|
16
|
+
else
|
17
|
+
raise "Unrecognized module '#{mod}' -- cannot install"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def show_error(message)
|
22
|
+
puts message
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(options)
|
26
|
+
opts = OptionParser.new do |opts|
|
27
|
+
opts.banner = "Usage: spackle --install vim\n" +
|
28
|
+
" spackle [rubyscript] [args_for_script]"
|
29
|
+
|
30
|
+
opts.separator " "
|
31
|
+
opts.separator "Options:"
|
32
|
+
|
33
|
+
opts.on("-i", "--install MODULE", "Install a Spackle module.", "Choices: vim") do |mod|
|
34
|
+
install(mod)
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("-h", "--help", "-?", "this help screen") do
|
38
|
+
puts opts
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if options.empty?
|
44
|
+
puts opts
|
45
|
+
else
|
46
|
+
opts.parse!(options)
|
47
|
+
end
|
48
|
+
|
49
|
+
raise "Spackle's wrapper mode is not yet implement" unless options.empty?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Spackle
|
2
|
+
class Configuration
|
3
|
+
# The command to invoke when Spackle finds errors. It will receive
|
4
|
+
# a single argument, being the path to the Spackle errors file.
|
5
|
+
# If left unspecified, no command is invoked.
|
6
|
+
attr_accessor :callback_command
|
7
|
+
|
8
|
+
# Where to store the Spackle error files. If unspecified, Spackle will
|
9
|
+
# default to /tmp
|
10
|
+
attr_accessor :tempdir
|
11
|
+
|
12
|
+
# Which ErrorFormatter class to use when formatting errors. Specified
|
13
|
+
# as a symbol or string matching a class in spackle/error_formatters.
|
14
|
+
# i.e. config.error_formatter = :vim_quickfix
|
15
|
+
attr_accessor :error_formatter
|
16
|
+
|
17
|
+
# Filename to use when writing the formatted Spackle results. If
|
18
|
+
# unspecified, defaults to a filename based on the name of your
|
19
|
+
# project's root directory, or "default.spackle" it can't figure out
|
20
|
+
# where your root directory is
|
21
|
+
attr_accessor :spackle_file
|
22
|
+
|
23
|
+
# Configure Spackle with defaults. Currently only accepts :vim as an
|
24
|
+
# argument.
|
25
|
+
def set_defaults_for(mode)
|
26
|
+
case mode.to_sym
|
27
|
+
when :vim
|
28
|
+
self.callback_command = "spackle-vim-load-quickfix"
|
29
|
+
self.error_formatter = :vim_quickfix
|
30
|
+
else
|
31
|
+
raise ArgumentError.new("unknown Spackle mode: '#{mode}'")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Spackle
|
2
|
+
class BacktraceEntry
|
3
|
+
attr_reader :file, :line
|
4
|
+
def initialize(file, line)
|
5
|
+
@file, @line = file, line
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Error
|
10
|
+
attr_reader :message, :backtrace
|
11
|
+
|
12
|
+
def initialize(message)
|
13
|
+
@message = message
|
14
|
+
@backtrace = []
|
15
|
+
yield self if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_error(error_or_file, line = nil)
|
19
|
+
case error_or_file
|
20
|
+
when Error
|
21
|
+
@backtrace << error_or_file
|
22
|
+
when String
|
23
|
+
@backtrace << BacktraceEntry.new(error_or_file, line)
|
24
|
+
else
|
25
|
+
raise ArgumentError.new("unrecognized error input '#{error_or_file}'. Should be a filename or a Spackle::BacktraceEntry")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Spackle
|
2
|
+
module Helpers
|
3
|
+
module RubyProjectRoot
|
4
|
+
class << self
|
5
|
+
# Search recursively from the current working directory up for something
|
6
|
+
# that looks like the root directory of a Ruby project.
|
7
|
+
#
|
8
|
+
# Returns the path to the found project dir, if any. Nil otherwise.
|
9
|
+
#
|
10
|
+
# Stops looking when it reaches the top of the tree, or the user's
|
11
|
+
# home directory.
|
12
|
+
#
|
13
|
+
# Detects a project dir via any of:
|
14
|
+
# * a config/environment.rb file
|
15
|
+
# * a spec/spec_helper.rb file
|
16
|
+
# * a features/step_definitions directory
|
17
|
+
def search(directory)
|
18
|
+
directory = File.expand_path(directory)
|
19
|
+
while directory != '/'
|
20
|
+
return directory if is_project_dir?(directory)
|
21
|
+
directory = File.expand_path(directory + '/..')
|
22
|
+
end
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_project_dir?(path)
|
27
|
+
File.exists?(File.join(path, "config/environment.rb")) ||
|
28
|
+
File.exists?(File.join(path, "spec/spec_helper.rb")) ||
|
29
|
+
File.directory?(File.join(path, "features/step_definitions"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Spackle::Output
|
2
|
+
# This is the foundation of all Spackle::Output classes, but by itself
|
3
|
+
# it does nothing.
|
4
|
+
#
|
5
|
+
# Using an Output class should be simple:
|
6
|
+
# (assuming errors is an Array of Spackle::Error objects)
|
7
|
+
# puts Spackle::Output::VimQuickfix.format(errors)
|
8
|
+
#
|
9
|
+
# The child class (VimQuickfix) only needs to implement the
|
10
|
+
# format_backtrace instance method.
|
11
|
+
#
|
12
|
+
# Spackle::Output::Base is responsible for things like:
|
13
|
+
# * iterating over the backtrace collection
|
14
|
+
# * making pathnames relative
|
15
|
+
# * limiting the number of errors that are output
|
16
|
+
# * filtering the backtrace output by filename
|
17
|
+
#
|
18
|
+
# Spackle::Output::Base interacts with Spackle's Configuration
|
19
|
+
#
|
20
|
+
# If you're writing your own Output class, it should be quite
|
21
|
+
# easy to override some of the Configuration handling if your
|
22
|
+
# class requires it.
|
23
|
+
#
|
24
|
+
class Base
|
25
|
+
attr_accessor :error
|
26
|
+
def initialize(error = nil)
|
27
|
+
self.error = error || Spackle.current_error
|
28
|
+
end
|
29
|
+
|
30
|
+
def formatted_lines
|
31
|
+
error.backtrace.map do |bt|
|
32
|
+
format_backtrace_line error.message, bt.file, bt.line
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def format
|
37
|
+
formatted_lines.join("\n") + "\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.format(error = nil)
|
41
|
+
new(error || Spackle.current_error).format
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec/runner/formatter/base_formatter'
|
2
|
+
|
3
|
+
# This is just a slightly-refactored and cut down version of RSpec's
|
4
|
+
# BaseTextFormatter.
|
5
|
+
|
6
|
+
module Spackle::Spec
|
7
|
+
class BaseFormatter < ::Spec::Runner::Formatter::BaseFormatter
|
8
|
+
attr_reader :output, :options
|
9
|
+
attr_accessor :errors
|
10
|
+
|
11
|
+
def initialize(options, output)
|
12
|
+
# we ignore output, for now
|
13
|
+
Spackle.init
|
14
|
+
@options = options
|
15
|
+
self.errors = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def close
|
19
|
+
Spackle.test_finished errors
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spackle/spec/base_formatter'
|
2
|
+
|
3
|
+
module Spackle::Spec
|
4
|
+
class SpackleFormatter < BaseFormatter
|
5
|
+
def example_failed(example, counter, failure)
|
6
|
+
error = Spackle::Error.new failure.exception.message
|
7
|
+
failure.exception.backtrace.each do |frame|
|
8
|
+
file, line = frame.match(/^([^:]+):([0-9]+)/)[1,2]
|
9
|
+
error.add_error file, line
|
10
|
+
end
|
11
|
+
self.errors << error
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/spackle/spec.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'spackle/spec/spackle_formatter'
|