fudge 0.0.1
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/bin/fudge +9 -0
- data/lib/fudge.rb +16 -0
- data/lib/fudge/build.rb +31 -0
- data/lib/fudge/cli.rb +29 -0
- data/lib/fudge/description.rb +53 -0
- data/lib/fudge/exceptions.rb +31 -0
- data/lib/fudge/helpers.rb +5 -0
- data/lib/fudge/helpers/bundle_aware.rb +14 -0
- data/lib/fudge/parser.rb +12 -0
- data/lib/fudge/railtie.rb +17 -0
- data/lib/fudge/runner.rb +25 -0
- data/lib/fudge/task_dsl.rb +41 -0
- data/lib/fudge/tasks.rb +31 -0
- data/lib/fudge/tasks/clean_bundler_env.rb +24 -0
- data/lib/fudge/tasks/composite_task.rb +24 -0
- data/lib/fudge/tasks/each_directory.rb +34 -0
- data/lib/fudge/tasks/in_directory.rb +24 -0
- data/lib/fudge/tasks/rake.rb +19 -0
- data/lib/fudge/tasks/rspec.rb +29 -0
- data/lib/fudge/tasks/shell.rb +76 -0
- data/lib/fudge/tasks/task.rb +18 -0
- data/lib/fudge/tasks/yard.rb +29 -0
- data/lib/fudge/version.rb +3 -0
- data/lib/tasks/fudge.rake +7 -0
- data/spec/lib/fudge/build_spec.rb +5 -0
- data/spec/lib/fudge/cli_spec.rb +76 -0
- data/spec/lib/fudge/description_spec.rb +241 -0
- data/spec/lib/fudge/exceptions_spec.rb +36 -0
- data/spec/lib/fudge/parser_spec.rb +23 -0
- data/spec/lib/fudge/runner_spec.rb +25 -0
- data/spec/lib/fudge/tasks/bundler_spec.rb +39 -0
- data/spec/lib/fudge/tasks/composite_task_spec.rb +60 -0
- data/spec/lib/fudge/tasks/each_directory_spec.rb +57 -0
- data/spec/lib/fudge/tasks/in_directory_spec.rb +39 -0
- data/spec/lib/fudge/tasks/rake_spec.rb +18 -0
- data/spec/lib/fudge/tasks/rspec_spec.rb +36 -0
- data/spec/lib/fudge/tasks/shell_spec.rb +38 -0
- data/spec/lib/fudge/tasks/task_spec.rb +14 -0
- data/spec/lib/fudge/tasks/yard_spec.rb +25 -0
- data/spec/lib/fudge/tasks_spec.rb +33 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/dummy_task.rb +40 -0
- data/spec/support/matchers.rb +47 -0
- data/spec/support/tmpdir.rb +12 -0
- metadata +302 -0
data/bin/fudge
ADDED
data/lib/fudge.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rainbow'
|
2
|
+
require 'active_support/all'
|
3
|
+
|
4
|
+
require 'fudge/railtie' if defined?(Rails)
|
5
|
+
|
6
|
+
module Fudge
|
7
|
+
autoload :Build, 'fudge/build'
|
8
|
+
autoload :Cli, 'fudge/cli'
|
9
|
+
autoload :Description, 'fudge/description'
|
10
|
+
autoload :Exceptions, 'fudge/exceptions'
|
11
|
+
autoload :Helpers, 'fudge/helpers'
|
12
|
+
autoload :Parser, 'fudge/parser'
|
13
|
+
autoload :Runner, 'fudge/runner'
|
14
|
+
autoload :Tasks, 'fudge/tasks'
|
15
|
+
autoload :TaskDSL, 'fudge/task_dsl'
|
16
|
+
end
|
data/lib/fudge/build.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fudge
|
2
|
+
# Represents a build defined in the FudgeFile
|
3
|
+
#
|
4
|
+
class Build < Tasks::CompositeTask
|
5
|
+
attr_accessor :callbacks
|
6
|
+
attr_reader :success_hooks, :failure_hooks
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
@success_hooks = []
|
10
|
+
@failure_hooks = []
|
11
|
+
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(options={})
|
16
|
+
success = super
|
17
|
+
if callbacks
|
18
|
+
puts "Running #{success ? 'success' : 'failure'} callbacks...".foreground(:cyan).bright
|
19
|
+
hooks = success ? @success_hooks : @failure_hooks
|
20
|
+
|
21
|
+
hooks.each do |hook|
|
22
|
+
return false unless hook.run
|
23
|
+
end
|
24
|
+
else
|
25
|
+
puts "Skipping callbacks...".foreground(:cyan).bright
|
26
|
+
end
|
27
|
+
|
28
|
+
success
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/fudge/cli.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Fudge
|
4
|
+
class Cli < Thor
|
5
|
+
desc "init", "Initialize a blank Fudgefile"
|
6
|
+
def init
|
7
|
+
path = File.expand_path('Fudgefile', Dir.pwd)
|
8
|
+
|
9
|
+
if File.exists?(path)
|
10
|
+
puts "Fudgefile already exists."
|
11
|
+
else
|
12
|
+
contents = <<RUBY
|
13
|
+
build :default do
|
14
|
+
task :rspec
|
15
|
+
end
|
16
|
+
RUBY
|
17
|
+
File.open(path, 'w') { |f| f.write(contents) }
|
18
|
+
puts "Fudgefile created."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "build [BUILD_NAME]", "Run a build with the given name (default: 'default')"
|
23
|
+
method_option :callbacks, :type => :boolean, :default => false
|
24
|
+
def build(build_name='default')
|
25
|
+
description = Fudge::Parser.new.parse('Fudgefile')
|
26
|
+
Fudge::Runner.new(description).run_build(build_name, options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Fudge
|
2
|
+
# A class that represents a FudgeFile definition in Ruby class form.
|
3
|
+
#
|
4
|
+
class Description
|
5
|
+
include TaskDSL
|
6
|
+
|
7
|
+
attr_reader :builds
|
8
|
+
|
9
|
+
# Sets builds to an initial empty array
|
10
|
+
def initialize(file)
|
11
|
+
@path = file.path
|
12
|
+
@builds = {}
|
13
|
+
@task_groups = {}
|
14
|
+
instance_eval(file.read, __FILE__, __LINE__)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Adds a build to the current description
|
18
|
+
def build(name)
|
19
|
+
@builds[name] = build = Build.new
|
20
|
+
with_scope(build) { yield }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Adds a task group to the current description or includes a task group
|
24
|
+
def task_group(name, *args, &block)
|
25
|
+
if block
|
26
|
+
@task_groups[name] = block
|
27
|
+
else
|
28
|
+
find_task_group(name).call(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Gets a task group of the given name
|
33
|
+
def find_task_group(name)
|
34
|
+
@task_groups[name].tap do |block|
|
35
|
+
raise Exceptions::TaskGroupNotFound.new(name) unless block
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_success
|
40
|
+
task = Fudge::Tasks::CompositeTask.new
|
41
|
+
current_scope.success_hooks << task
|
42
|
+
|
43
|
+
with_scope(task) { yield }
|
44
|
+
end
|
45
|
+
|
46
|
+
def on_failure
|
47
|
+
task = Fudge::Tasks::CompositeTask.new
|
48
|
+
current_scope.failure_hooks << task
|
49
|
+
|
50
|
+
with_scope(task) { yield }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fudge
|
2
|
+
module Exceptions
|
3
|
+
class Base < StandardError; end
|
4
|
+
|
5
|
+
class BuildFailed < Base
|
6
|
+
def message
|
7
|
+
"Build FAILED!".foreground(:red).bright
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class TaskNotFound < Base
|
12
|
+
def initialize(task)
|
13
|
+
@task = task
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
"No task found with name '#{@task}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class TaskGroupNotFound < Base
|
22
|
+
def initialize(name)
|
23
|
+
@name = name
|
24
|
+
end
|
25
|
+
|
26
|
+
def message
|
27
|
+
"No task group found with name '#{@name}'"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/fudge/parser.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'fudge'
|
3
|
+
|
4
|
+
module Fudge
|
5
|
+
|
6
|
+
# Adds behaviours to Rails
|
7
|
+
class Railtie < Rails::Railtie
|
8
|
+
railtie_name :fudge
|
9
|
+
rake_tasks do
|
10
|
+
begin
|
11
|
+
|
12
|
+
Dir[ File.join(File.dirname(__FILE__), '../tasks/*.rake')] .each { |f| load f } #Load static tasks
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/fudge/runner.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fudge
|
2
|
+
class Runner
|
3
|
+
def initialize(description)
|
4
|
+
@description = description
|
5
|
+
end
|
6
|
+
|
7
|
+
def run_build(which_build='default', options={})
|
8
|
+
which_build = String.new(which_build)
|
9
|
+
|
10
|
+
puts "Running build ".foreground(:cyan) + which_build.bright.foreground(:yellow)
|
11
|
+
|
12
|
+
# Run the build
|
13
|
+
build = @description.builds[which_build.to_sym]
|
14
|
+
build.callbacks = options[:callbacks]
|
15
|
+
status = build.run
|
16
|
+
|
17
|
+
# Output status
|
18
|
+
if status
|
19
|
+
puts "Build SUCCEEDED!".foreground(:green).bright
|
20
|
+
else
|
21
|
+
raise Exceptions::BuildFailed
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fudge
|
2
|
+
module TaskDSL
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
attr_writer :scope
|
7
|
+
end
|
8
|
+
|
9
|
+
def scope
|
10
|
+
@scope ||= [self]
|
11
|
+
end
|
12
|
+
|
13
|
+
# Adds a task to the current scope
|
14
|
+
def task(name, *args)
|
15
|
+
klass = Fudge::Tasks.discover(name)
|
16
|
+
|
17
|
+
task = klass.new(*args)
|
18
|
+
current_scope.tasks << task
|
19
|
+
|
20
|
+
with_scope(task) { yield if block_given? }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Delegate to the current object scope
|
24
|
+
def method_missing(meth, *args, &block)
|
25
|
+
task meth, *args, &block
|
26
|
+
rescue Fudge::Exceptions::TaskNotFound
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def current_scope
|
32
|
+
scope.last
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_scope(task)
|
36
|
+
scope << task
|
37
|
+
yield
|
38
|
+
scope.pop
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/fudge/tasks.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fudge
|
2
|
+
module Tasks
|
3
|
+
# Registers a task under a given name
|
4
|
+
def self.register(task_class)
|
5
|
+
registered_tasks[task_class.name] = task_class
|
6
|
+
end
|
7
|
+
|
8
|
+
# Finds a task with a given name
|
9
|
+
def self.discover(name)
|
10
|
+
task = registered_tasks[name]
|
11
|
+
raise Fudge::Exceptions::TaskNotFound.new(name) unless task
|
12
|
+
task
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def self.registered_tasks
|
17
|
+
@registered_tasks ||= {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# Require all my tasks
|
21
|
+
require 'fudge/tasks/task'
|
22
|
+
require 'fudge/tasks/shell'
|
23
|
+
require 'fudge/tasks/composite_task'
|
24
|
+
require 'fudge/tasks/each_directory'
|
25
|
+
require 'fudge/tasks/in_directory'
|
26
|
+
require 'fudge/tasks/clean_bundler_env'
|
27
|
+
require 'fudge/tasks/rake'
|
28
|
+
require 'fudge/tasks/rspec'
|
29
|
+
require 'fudge/tasks/yard'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Fudge
|
2
|
+
module Tasks
|
3
|
+
class CleanBundlerEnv < CompositeTask
|
4
|
+
def self.name
|
5
|
+
:clean_bundler_env
|
6
|
+
end
|
7
|
+
|
8
|
+
def run(options={})
|
9
|
+
old_env = ENV
|
10
|
+
keys = ENV.keys.grep(/BUNDLE|RUBY/)
|
11
|
+
|
12
|
+
keys.each { |k| ENV[k] = nil }
|
13
|
+
|
14
|
+
result = super(options.merge(:bundler => true))
|
15
|
+
|
16
|
+
keys.each { |k| ENV[k] = old_env[k] }
|
17
|
+
|
18
|
+
result
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
register CleanBundlerEnv
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Fudge
|
2
|
+
module Tasks
|
3
|
+
class CompositeTask < Task
|
4
|
+
attr_accessor :description
|
5
|
+
|
6
|
+
def tasks
|
7
|
+
@tasks ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
# Runs the task (by default running all other tasks in order)
|
11
|
+
def run(options={})
|
12
|
+
tasks.each do |t|
|
13
|
+
args_text = t.respond_to?(:args) && t.args ? t.args.join(', ') : ''
|
14
|
+
|
15
|
+
puts "Running task ".foreground(:blue) +
|
16
|
+
t.class.name.to_s.foreground(:yellow).bright + ' ' +
|
17
|
+
args_text.foreground(:yellow).bright
|
18
|
+
|
19
|
+
return unless t.run(options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Fudge
|
2
|
+
module Tasks
|
3
|
+
# A task which runs a number of other tasks in a given directory (relative to the current directory)
|
4
|
+
class EachDirectory < CompositeTask
|
5
|
+
attr_accessor :exclude
|
6
|
+
|
7
|
+
def self.name
|
8
|
+
:each_directory
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(pattern, *args)
|
12
|
+
super(*args)
|
13
|
+
|
14
|
+
@pattern = pattern
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(options={})
|
18
|
+
# Allow either a string (usually "*") or an array of strings with directories
|
19
|
+
redir = @pattern.kind_of?(String) ? Dir[@pattern] : Dir[*@pattern]
|
20
|
+
|
21
|
+
redir.select { |path| File.directory? path }.each do |dir|
|
22
|
+
next if exclude && exclude.include?(dir)
|
23
|
+
|
24
|
+
Dir.chdir dir do
|
25
|
+
puts "--> In directory".foreground(:cyan) + " #{dir}:".foreground(:cyan).bright
|
26
|
+
return false unless super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
register EachDirectory
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Fudge
|
2
|
+
module Tasks
|
3
|
+
# A task which runs a number of other tasks in a given directory (relative to the current directory)
|
4
|
+
class InDirectory < CompositeTask
|
5
|
+
def self.name
|
6
|
+
:in_directory
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(directory, *args)
|
10
|
+
super
|
11
|
+
@directory = directory
|
12
|
+
end
|
13
|
+
|
14
|
+
def run(options={})
|
15
|
+
Dir.chdir @directory do
|
16
|
+
puts "--> In directory".foreground(:cyan) + " #{@directory}:".foreground(:cyan).bright
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
register InDirectory
|
23
|
+
end
|
24
|
+
end
|