fudge 0.0.5 → 0.1.0
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.
- 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
|