fudge 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/lib/fudge.rb +5 -0
- data/lib/fudge/build.rb +6 -5
- data/lib/fudge/cli.rb +2 -13
- data/lib/fudge/description.rb +11 -7
- data/lib/fudge/file_finder.rb +35 -0
- data/lib/fudge/generator.rb +42 -0
- data/lib/fudge/output_checker.rb +55 -0
- data/{spec/support → lib/fudge/rspec}/matchers.rb +12 -7
- data/lib/fudge/runner.rb +19 -6
- data/lib/fudge/tasks.rb +2 -0
- data/lib/fudge/tasks/cane.rb +16 -4
- data/lib/fudge/tasks/clean_bundler_env.rb +3 -10
- data/lib/fudge/tasks/composite_task.rb +20 -8
- data/lib/fudge/tasks/each_directory.rb +13 -15
- data/lib/fudge/tasks/flay.rb +64 -0
- data/lib/fudge/tasks/flog.rb +89 -0
- data/lib/fudge/tasks/in_directory.rb +2 -13
- data/lib/fudge/tasks/rspec.rb +5 -5
- data/lib/fudge/tasks/shell.rb +8 -35
- data/lib/fudge/version.rb +1 -1
- data/lib/fudge/with_directory.rb +27 -0
- data/spec/lib/fudge/build_spec.rb +28 -0
- data/spec/lib/fudge/output_checker_spec.rb +31 -0
- data/spec/lib/fudge/runner_spec.rb +19 -0
- data/spec/lib/fudge/tasks/bundler_spec.rb +8 -0
- data/spec/lib/fudge/tasks/composite_task_spec.rb +15 -0
- data/spec/lib/fudge/tasks/flay_spec.rb +48 -0
- data/spec/lib/fudge/tasks/flog_spec.rb +89 -0
- data/spec/lib/fudge/tasks/shell_spec.rb +21 -0
- data/spec/lib/fudge/with_directory_spec.rb +17 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/dummy_task.rb +2 -1
- metadata +96 -80
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MmE4MjI5YjRiMjU5MDBjMDliOTJiODJjOGQyYzk0MmE5MzFkYTgxMg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2UzMGEyNDAxZGM2MDBhNWNlNTQwYWNlM2U4MTYxYzQ3MTU0MDM3Yg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzZiMGNjZGNlZjk2MDgxNzVjMTBmMGNlZmQxMDQ3Zjg4YWM1OTIwOWI3ZTE1
|
10
|
+
MDY3NjFhMjlmNmE1NTEyZmNmNDM2NzVhMWFiMTAyZDZmNjYyNTA1MjE4ODBm
|
11
|
+
ZDc2ZjlkYWZkNmFjYWIwNWYwNzA3YWQ2MjcxZDQ0ZGRjYTYwYTE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NzgxOTI4ZjI5YzY3MDk5ZDc2ZTljOGZiNjg1OTFjNTIxZTcxZWZhZmJjNTk5
|
14
|
+
YWI3ZGViNjliZWU4NDRkZjExZTA2MmFkNTc3YWU2Yjg1MjU3MjVkMGY3Y2Nm
|
15
|
+
ZjhlOTQ3ODIwZTc2NDg1MzM0M2MzZDA5OTNkOTYwMDk0OTc3Yjc=
|
data/lib/fudge.rb
CHANGED
@@ -7,9 +7,14 @@ module Fudge
|
|
7
7
|
autoload :Cli, 'fudge/cli'
|
8
8
|
autoload :Description, 'fudge/description'
|
9
9
|
autoload :Exceptions, 'fudge/exceptions'
|
10
|
+
autoload :Generator, 'fudge/generator'
|
10
11
|
autoload :Helpers, 'fudge/helpers'
|
11
12
|
autoload :Parser, 'fudge/parser'
|
12
13
|
autoload :Runner, 'fudge/runner'
|
13
14
|
autoload :Tasks, 'fudge/tasks'
|
14
15
|
autoload :TaskDSL, 'fudge/task_dsl'
|
16
|
+
autoload :WithDirectory, 'fudge/with_directory'
|
17
|
+
autoload :OutputChecker, 'fudge/output_checker.rb'
|
18
|
+
autoload :FileFinder, 'fudge/file_finder.rb'
|
15
19
|
end
|
20
|
+
|
data/lib/fudge/build.rb
CHANGED
@@ -13,16 +13,17 @@ module Fudge
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def run(options={})
|
16
|
+
output = options[:output] || $stdout
|
16
17
|
success = super
|
17
18
|
if callbacks
|
18
|
-
message "Running #{success ? 'success' : 'failure'} callbacks..."
|
19
|
+
message "Running #{success ? 'success' : 'failure'} callbacks...", output
|
19
20
|
hooks = success ? @success_hooks : @failure_hooks
|
20
21
|
|
21
22
|
hooks.each do |hook|
|
22
|
-
return false unless hook.run
|
23
|
+
return false unless hook.run :output => output
|
23
24
|
end
|
24
25
|
else
|
25
|
-
message "Skipping callbacks..."
|
26
|
+
message "Skipping callbacks...", output
|
26
27
|
end
|
27
28
|
|
28
29
|
success
|
@@ -30,8 +31,8 @@ module Fudge
|
|
30
31
|
|
31
32
|
private
|
32
33
|
|
33
|
-
def message(message)
|
34
|
-
puts message.foreground(:cyan).bright
|
34
|
+
def message(message, output)
|
35
|
+
output.puts message.foreground(:cyan).bright
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
data/lib/fudge/cli.rb
CHANGED
@@ -6,19 +6,8 @@ module Fudge
|
|
6
6
|
desc "init", "Initialize a blank Fudgefile"
|
7
7
|
# Initalizes the blank Fudgefile
|
8
8
|
def init
|
9
|
-
|
10
|
-
|
11
|
-
if File.exists?(path)
|
12
|
-
puts "Fudgefile already exists."
|
13
|
-
else
|
14
|
-
contents = ""
|
15
|
-
contents << "build :default do\n"
|
16
|
-
contents << " task :rspec\n"
|
17
|
-
contents << "end"
|
18
|
-
|
19
|
-
File.open(path, 'w') { |f| f.write(contents) }
|
20
|
-
puts "Fudgefile created."
|
21
|
-
end
|
9
|
+
generator = Fudge::Generator.new(Dir.pwd)
|
10
|
+
generator.write_fudgefile
|
22
11
|
end
|
23
12
|
|
24
13
|
desc "build [BUILD_NAME]",
|
data/lib/fudge/description.rb
CHANGED
@@ -37,17 +37,21 @@ module Fudge
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# Add actions to be invoked upon success
|
40
|
-
def on_success
|
41
|
-
|
42
|
-
current_scope.success_hooks << task
|
43
|
-
|
44
|
-
with_scope(task) { yield }
|
40
|
+
def on_success(&block)
|
41
|
+
apply_hook(:success, &block)
|
45
42
|
end
|
46
43
|
|
47
44
|
# Add actions to be invoked upon failure
|
48
|
-
def on_failure
|
45
|
+
def on_failure(&block)
|
46
|
+
apply_hook(:failure, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def apply_hook(event)
|
49
52
|
task = Fudge::Tasks::CompositeTask.new
|
50
|
-
current_scope.
|
53
|
+
hooks = current_scope.public_send("#{event}_hooks")
|
54
|
+
hooks << task
|
51
55
|
|
52
56
|
with_scope(task) { yield }
|
53
57
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Fudge
|
2
|
+
# Allows building of commands which run against a set of files
|
3
|
+
class FileFinder
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
# Generates a command line with command and any tty_option
|
11
|
+
def generate_command(name, tty_options)
|
12
|
+
cmd = []
|
13
|
+
cmd << name
|
14
|
+
cmd += tty_options
|
15
|
+
cmd << "`#{find_filters.join(' | ')}`"
|
16
|
+
cmd.join(' ')
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def find_filters
|
22
|
+
filters = []
|
23
|
+
filters << 'find .'
|
24
|
+
filters << "grep -e '\\.rb$'"
|
25
|
+
filters << exclude_filter
|
26
|
+
filters.compact
|
27
|
+
end
|
28
|
+
|
29
|
+
def exclude_filter
|
30
|
+
if (pattern = options[:exclude])
|
31
|
+
"grep -v -e '#{pattern}'"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Fudge
|
2
|
+
#Generator for default Fudgefile
|
3
|
+
class Generator
|
4
|
+
attr_reader :pwd
|
5
|
+
|
6
|
+
def initialize(pwd)
|
7
|
+
@pwd = pwd
|
8
|
+
end
|
9
|
+
|
10
|
+
#Writes the fudgefile to initialized directory unless on present
|
11
|
+
def write_fudgefile
|
12
|
+
if exists?
|
13
|
+
puts "Fudgefile already exists."
|
14
|
+
else
|
15
|
+
writer { |file| file << build_templated }
|
16
|
+
puts "Fudgefile created."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def writer
|
23
|
+
File.open(path, 'w') { |f| yield f }
|
24
|
+
end
|
25
|
+
|
26
|
+
def path
|
27
|
+
@path ||= File.expand_path('Fudgefile', pwd)
|
28
|
+
end
|
29
|
+
|
30
|
+
def exists?
|
31
|
+
File.exists?(path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_templated
|
35
|
+
contents = ""
|
36
|
+
contents << "build :default do\n"
|
37
|
+
contents << " task :rspec\n"
|
38
|
+
contents << "end"
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#Task Output Checker
|
2
|
+
class Fudge::OutputChecker
|
3
|
+
attr_reader :checker, :regex, :pass_block, :match, :output_io
|
4
|
+
|
5
|
+
def initialize(checker, output_io)
|
6
|
+
@checker = checker
|
7
|
+
@output_io = output_io
|
8
|
+
end
|
9
|
+
|
10
|
+
#Validates output against initialized checker
|
11
|
+
def check(output)
|
12
|
+
return true unless checker # We're ok if no output defined
|
13
|
+
extract_matchers
|
14
|
+
matches?(output) && block_passes?
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def block_passes?
|
20
|
+
return true unless pass_block
|
21
|
+
|
22
|
+
# If we've got a callable, call it to check on regex matches
|
23
|
+
result = pass_block.call(match)
|
24
|
+
if success?(result)
|
25
|
+
true
|
26
|
+
else
|
27
|
+
output_io.puts error_message(result)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def success?(result)
|
32
|
+
result === true
|
33
|
+
end
|
34
|
+
|
35
|
+
def error_message(result)
|
36
|
+
result || "Output matched #{@regex} but condition failed."
|
37
|
+
end
|
38
|
+
|
39
|
+
def extract_matchers
|
40
|
+
# Check if we have a callable to parse the regex matches
|
41
|
+
if checker.is_a? Enumerable
|
42
|
+
@regex, @pass_block = checker
|
43
|
+
else
|
44
|
+
@regex = checker
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def matches?(output)
|
49
|
+
# Do regex match and fail if no match
|
50
|
+
return true if (@match = output.match(regex))
|
51
|
+
output_io.puts "Output didn't match #{regex}."
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
@@ -4,19 +4,21 @@ RSpec::Matchers.define :be_registered_as do |key|
|
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
7
|
-
|
7
|
+
# Collection of matchers for use in a test environment
|
8
8
|
module FudgeMatchers
|
9
|
+
# Run matcher
|
9
10
|
class Run
|
10
11
|
attr_reader :args, :expected, :task
|
11
12
|
|
12
13
|
def initialize(expected, args={})
|
13
14
|
@expected = expected
|
14
15
|
@args = args
|
16
|
+
@args[:output] ||= $stdout
|
15
17
|
end
|
16
18
|
|
17
19
|
def matches?(task)
|
18
20
|
@task = task
|
19
|
-
ran =
|
21
|
+
ran = []
|
20
22
|
|
21
23
|
if task.is_a?(Fudge::Tasks::Shell)
|
22
24
|
to_stub = task
|
@@ -24,21 +26,23 @@ module FudgeMatchers
|
|
24
26
|
to_stub = Fudge::Tasks::Shell.any_instance
|
25
27
|
end
|
26
28
|
|
27
|
-
to_stub.stub(:run_command) do |cmd|
|
28
|
-
|
29
|
+
to_stub.stub(:run_command) do |cmd, outputio|
|
30
|
+
raise "Run Command requires an output IOStream" unless outputio
|
31
|
+
ran << cmd
|
29
32
|
['dummy output', true]
|
30
33
|
end
|
31
34
|
|
32
|
-
task.run(args
|
35
|
+
task.run(args)
|
33
36
|
|
34
37
|
@actual = ran
|
35
38
|
if expected.is_a? Regexp
|
36
|
-
ran =~ expected
|
39
|
+
ran.any? {|cmd| cmd =~ expected}
|
37
40
|
else
|
38
|
-
ran
|
41
|
+
ran.include? expected
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
45
|
+
# Failure message
|
42
46
|
def failure_message_for_should
|
43
47
|
message = ""
|
44
48
|
message << "Expected task :#{@task.class.name} "
|
@@ -48,6 +52,7 @@ module FudgeMatchers
|
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
55
|
+
# Matcher to test a command has been run by the task
|
51
56
|
def run_command(cmd, options={})
|
52
57
|
FudgeMatchers::Run.new cmd, options
|
53
58
|
end
|
data/lib/fudge/runner.rb
CHANGED
@@ -9,19 +9,32 @@ module Fudge
|
|
9
9
|
#
|
10
10
|
# @param [String] which_build Defaults to 'default'
|
11
11
|
def run_build(which_build='default', options={})
|
12
|
-
|
12
|
+
output = options[:output] || $stdout
|
13
|
+
output_start(which_build, output)
|
14
|
+
status = run(which_build, options)
|
15
|
+
output_status(status, output)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def output_start(which, output)
|
21
|
+
which_build = String.new(which)
|
13
22
|
|
14
|
-
puts "Running build ".foreground(:cyan) +
|
23
|
+
output.puts "Running build ".foreground(:cyan) +
|
15
24
|
which_build.bright.foreground(:yellow)
|
25
|
+
end
|
16
26
|
|
27
|
+
def run(which, options)
|
17
28
|
# Run the build
|
18
|
-
build = @description.builds[
|
29
|
+
build = @description.builds[which.to_sym]
|
19
30
|
build.callbacks = options[:callbacks]
|
20
|
-
|
31
|
+
build.run :output => options[:output]
|
32
|
+
end
|
21
33
|
|
34
|
+
def output_status(success, output)
|
22
35
|
# Output status
|
23
|
-
if
|
24
|
-
puts "Build SUCCEEDED!".foreground(:green).bright
|
36
|
+
if success
|
37
|
+
output.puts "Build SUCCEEDED!".foreground(:green).bright
|
25
38
|
else
|
26
39
|
raise Exceptions::BuildFailed
|
27
40
|
end
|
data/lib/fudge/tasks.rb
CHANGED
data/lib/fudge/tasks/cane.rb
CHANGED
@@ -17,12 +17,24 @@ module Fudge
|
|
17
17
|
|
18
18
|
def tty_options
|
19
19
|
args = []
|
20
|
-
args <<
|
21
|
-
args <<
|
20
|
+
args << doc_options
|
21
|
+
args << style_options
|
22
|
+
args << style_width_options
|
23
|
+
args.compact
|
24
|
+
end
|
25
|
+
|
26
|
+
def doc_options
|
27
|
+
"--no-doc" unless options.fetch(:doc, true)
|
28
|
+
end
|
29
|
+
|
30
|
+
def style_options
|
31
|
+
"--no-style" unless options.fetch(:style, true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def style_width_options
|
22
35
|
if options.has_key?(:max_width)
|
23
|
-
|
36
|
+
"--style-measure #{options.fetch(:max_width)}"
|
24
37
|
end
|
25
|
-
args
|
26
38
|
end
|
27
39
|
end
|
28
40
|
|
@@ -3,16 +3,9 @@ module Fudge
|
|
3
3
|
# Provides a sanitized running environment for Bundler
|
4
4
|
class CleanBundlerEnv < CompositeTask
|
5
5
|
def run(options={})
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
keys.each { |k| ENV[k] = nil }
|
10
|
-
|
11
|
-
result = super(options.merge(:bundler => true))
|
12
|
-
|
13
|
-
keys.each { |k| ENV[k] = old_env[k] }
|
14
|
-
|
15
|
-
result
|
6
|
+
Bundler.with_clean_env do
|
7
|
+
super(options.merge(:bundler => true))
|
8
|
+
end
|
16
9
|
end
|
17
10
|
end
|
18
11
|
|
@@ -11,8 +11,9 @@ module Fudge
|
|
11
11
|
|
12
12
|
# Runs the task (by default running all other tasks in order)
|
13
13
|
def run(options={})
|
14
|
+
output = options[:output] || $stdout
|
14
15
|
tasks.each do |t|
|
15
|
-
output_message(t)
|
16
|
+
output_message(t, output)
|
16
17
|
|
17
18
|
return unless t.run(options)
|
18
19
|
end
|
@@ -24,14 +25,25 @@ module Fudge
|
|
24
25
|
t.respond_to?(:args) && t.args ? t.args.join(', ') : ''
|
25
26
|
end
|
26
27
|
|
27
|
-
def output_message(t)
|
28
|
-
|
28
|
+
def output_message(t, output)
|
29
|
+
message = []
|
30
|
+
message << running_coloured
|
31
|
+
message << task_name_coloured(t)
|
32
|
+
message << args_coloured(t)
|
33
|
+
output.puts message.join(' ')
|
34
|
+
end
|
35
|
+
|
36
|
+
def running_coloured
|
37
|
+
"Running task".foreground(:blue)
|
38
|
+
end
|
39
|
+
|
40
|
+
def task_name_coloured(t)
|
41
|
+
t.class.name.to_s.foreground(:yellow).bright
|
42
|
+
end
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
args_text.foreground(:yellow).bright
|
34
|
-
].join(' ')
|
44
|
+
def args_coloured(t)
|
45
|
+
args_text = join_arguments(t)
|
46
|
+
args_text.foreground(:yellow).bright
|
35
47
|
end
|
36
48
|
end
|
37
49
|
end
|