mattock 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ require 'mattock/configurable'
2
+
3
+ module Mattock
4
+ module CascadingDefinition
5
+ include Configurable
6
+
7
+ def initialize(*tasklibs)
8
+ setup_defaults
9
+ default_configuration(*tasklibs)
10
+
11
+ yield self if block_given?
12
+
13
+ resolve_configuration
14
+ confirm_configuration
15
+
16
+ define
17
+ end
18
+
19
+ def default_configuration(*tasklibs)
20
+ end
21
+
22
+ def resolve_configuration
23
+ end
24
+
25
+ def confirm_configuration
26
+ check_required
27
+ end
28
+
29
+ def define
30
+ end
31
+ end
32
+ end
@@ -1,16 +1,8 @@
1
- require 'mattock/tasklib'
1
+ require 'mattock/task'
2
2
  require 'mattock/command-line'
3
3
 
4
4
  module Mattock
5
- module NeededPredicate
6
- def needed_predicate(&block)
7
- (class << self; self; end).instance_eval do
8
- define_method(:needed?, &block)
9
- end
10
- end
11
- end
12
-
13
- class CommandTask < TaskLib
5
+ class CommandTask < Task
14
6
  setting(:task_name, :run)
15
7
  setting(:command)
16
8
  setting(:verify_command, nil)
@@ -26,25 +18,15 @@ module Mattock
26
18
  cmd
27
19
  end
28
20
 
29
- def command_task
30
- @command_task ||=
31
- begin
32
- task task_name do
33
- decorated(command).must_succeed!
34
- end
35
- end
21
+ def action
22
+ decorated(command).must_succeed!
36
23
  end
37
24
 
38
- def define
39
- in_namespace do
40
- command_task
41
- unless verify_command.nil?
42
- needed = decorated(verify_command)
43
- command_task.extend NeededPredicate
44
- command_task.needed_predicate do
45
- !needed.succeeds?
46
- end
47
- end
25
+ def needed?
26
+ unless verify_command.nil?
27
+ !decorated(verify_command).succeeds?
28
+ else
29
+ super
48
30
  end
49
31
  end
50
32
  end
@@ -50,6 +50,19 @@ module Mattock
50
50
  return missing
51
51
  end
52
52
 
53
+ def copy_settings(from, to)
54
+ if Configurable > superclass
55
+ superclass.copy_settings(from, to)
56
+ end
57
+ default_values.keys.each do |field|
58
+ begin
59
+ to.__send__("#{field}=", from.__send__(field))
60
+ rescue NoMethodError
61
+ #shrug it off
62
+ end
63
+ end
64
+ end
65
+
53
66
  def nested(hash=nil)
54
67
  obj = Class.new(Struct).new
55
68
  obj.settings(hash || {})
@@ -85,10 +98,15 @@ module Mattock
85
98
  end
86
99
  return self
87
100
  end
101
+
102
+ def included(mod)
103
+ mod.extend ClassMethods
104
+ end
88
105
  end
106
+ extend ClassMethods
89
107
 
90
- def self.included(mod)
91
- mod.extend ClassMethods
108
+ def copy_settings_to(other)
109
+ self.class.copy_settings(self, other)
92
110
  end
93
111
 
94
112
  def setup_defaults
@@ -99,7 +117,7 @@ module Mattock
99
117
  def check_required
100
118
  missing = self.class.missing_required_fields_on(self)
101
119
  unless missing.empty?
102
- raise "Required field#{missing.length > 1 ? "s" : ""} #{missing.join(", ")} unset on #{self.inspect}"
120
+ raise "Required field#{missing.length > 1 ? "s" : ""} #{missing.map{|field| field.to_s.inspect}.join(", ")} unset on #{self.inspect}"
103
121
  end
104
122
  self
105
123
  end
@@ -122,6 +140,12 @@ module Mattock
122
140
  end
123
141
  alias required_field required_fields
124
142
 
143
+ def nil_fields(*names)
144
+ self.class.nil_fields(*names)
145
+ self
146
+ end
147
+ alias nil_field nil_fields
148
+
125
149
  class Struct
126
150
  include Configurable
127
151
  end
@@ -0,0 +1,35 @@
1
+ require 'mattock/cascading-definition'
2
+ require 'rake/task'
3
+
4
+ module Mattock
5
+ class Task < Rake::Task
6
+ include CascadingDefinition
7
+
8
+ setting :task_name
9
+
10
+ def action
11
+ end
12
+
13
+ def task_args
14
+ [task_name]
15
+ end
16
+
17
+ def task_class
18
+ return @task_class if @task_class
19
+ @task_class = Class.new(self.class) do
20
+ define_method :initialize, Rake::Task.instance_method(:initialize)
21
+ end
22
+ end
23
+
24
+ def inspect
25
+ "Mattock::Task"
26
+ end
27
+
28
+ def define
29
+ task =task_class.define_task(*task_args) do
30
+ action
31
+ end
32
+ copy_settings_to(task)
33
+ end
34
+ end
35
+ end
@@ -1,47 +1,28 @@
1
- require 'ostruct'
2
1
  require 'rake/tasklib'
3
- require 'mattock/configurable'
2
+ require 'mattock/cascading-definition'
4
3
 
5
4
  module Mattock
6
5
  class TaskLib < Rake::TaskLib
7
- include Configurable
6
+ include CascadingDefinition
8
7
 
9
8
  attr_writer :namespace_name
10
9
  def self.default_namespace(name)
11
10
  setting(:namespace_name, name)
12
11
  end
13
12
 
14
- def initialize(*tasklibs)
15
- @tasks = []
16
-
17
- default_configuration(*tasklibs)
18
-
19
- yield self if block_given?
20
-
21
- resolve_configuration
13
+ attr_reader :tasks
22
14
 
23
- define
15
+ def initialize(*toolkits)
16
+ @tasks = []
17
+ super
24
18
  end
25
19
 
26
- attr_reader :tasks
27
-
28
20
  def task(*args)
29
21
  a_task = super
30
22
  @tasks << a_task
31
23
  return a_task
32
24
  end
33
25
 
34
- def default_configuration(*tasklibs)
35
- setup_defaults
36
- end
37
-
38
- def resolve_configuration
39
- check_required
40
- end
41
-
42
- def define
43
- end
44
-
45
26
  def in_namespace(*tasknames)
46
27
  if tasknames.empty?
47
28
  if block_given?
@@ -23,4 +23,45 @@ module Mattock
23
23
 
24
24
  alias exit_status exit_code
25
25
  end
26
+
27
+ module CommandLineExampleGroup
28
+ def self.included(group)
29
+ group.class_eval do
30
+ let :pairs do
31
+ []
32
+ end
33
+
34
+ before :each do
35
+ Mattock::CommandLine.should_receive(:execute) do |cmd|
36
+ pattern, res = pairs.shift
37
+ pattern =~ cmd
38
+ Mattock::MockCommandResult.create(*res)
39
+ end.any_number_of_times
40
+ end
41
+
42
+ after :each do
43
+ pairs.should have_all_been_called
44
+ end
45
+ end
46
+ end
47
+
48
+ def expect_command(cmd, *result)
49
+ pairs << [cmd, result]
50
+ end
51
+
52
+ module Matchers
53
+ extend RSpec::Matchers::DSL
54
+
55
+ define :have_all_been_called do
56
+ match do |list|
57
+ list.empty?
58
+ end
59
+
60
+ failure_message_for_should do |list|
61
+ "Expected all commands to be run, but: #{list.map{|item| item[0].source.inspect}.join(", ")} #{list.length > 1 ? "were" : "was"} not."
62
+ end
63
+ end
64
+ end
65
+ include Matchers
66
+ end
26
67
  end
@@ -0,0 +1,38 @@
1
+ require 'mattock/command-line'
2
+
3
+ module Mattock
4
+ class CommandLine
5
+ @@commands = []
6
+ class << self
7
+ alias original_execute execute
8
+
9
+ def execute(command)
10
+ result = original_execute(command)
11
+ @@commands << [command, result]
12
+ return result
13
+ end
14
+
15
+ attr_accessor :command_recording_path
16
+
17
+ def command_recording_path
18
+ @command_recording_path ||= ENV['MATTOCK_CMDREC']
19
+ end
20
+
21
+ def emit_recording
22
+ io = $stderr
23
+ if command_recording_path
24
+ io = File.open(command_recording_path, "w")
25
+ else
26
+ io.puts "Set MATTOCK_CMDREC to write to a path"
27
+ end
28
+ @@commands.each do |pair|
29
+ io.puts "[/#{pair[0]}/, #{[pair[1].exit_code, pair[1].streams].inspect}]"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ at_exit do
37
+ Mattock::CommandLine.emit_recording
38
+ end
data/spec/command-line.rb CHANGED
@@ -2,6 +2,10 @@ require 'mattock/command-line'
2
2
  require 'mattock/testing/rake-example-group'
3
3
  require 'mattock/testing/mock-command-line'
4
4
 
5
+ require 'mattock/testing/record-commands'
6
+
7
+ Mattock::CommandLine.command_recording_path = "/dev/null"
8
+
5
9
  describe Mattock::CommandLine do
6
10
  let :commandline do
7
11
  Mattock::CommandLine.new('echo', "-n") do |cmd|
data/spec/command-task.rb CHANGED
@@ -5,35 +5,33 @@ require 'mattock/testing/mock-command-line'
5
5
  describe Mattock::RemoteCommandTask do
6
6
  include Mattock::RakeExampleGroup
7
7
  let! :remote_task do
8
- Mattock::RemoteCommandTask.new do |t|
9
- t.namespace_name = :test
10
- t.remote_server.address = "nowhere.com"
11
- t.command = Mattock::PrereqChain.new do |prereq|
12
- prereq.add Mattock::CommandLine.new("cd", "a_dir")
13
- prereq.add Mattock::PipelineChain.new do |pipe|
14
- pipe.add Mattock::CommandLine.new("ls")
15
- pipe.add Mattock::CommandLine.new("grep") do |cmd|
16
- cmd.options << "*.rb"
17
- cmd.redirect_stderr("/dev/null")
18
- cmd.redirect_stdout("/tmp/rubyfiles.txt")
8
+ namespace :test do
9
+ Mattock::RemoteCommandTask.new do |t|
10
+ t.remote_server.address = "nowhere.com"
11
+ t.command = Mattock::PrereqChain.new do |prereq|
12
+ prereq.add Mattock::CommandLine.new("cd", "a_dir")
13
+ prereq.add Mattock::PipelineChain.new do |pipe|
14
+ pipe.add Mattock::CommandLine.new("ls")
15
+ pipe.add Mattock::CommandLine.new("grep") do |cmd|
16
+ cmd.options << "*.rb"
17
+ cmd.redirect_stderr("/dev/null")
18
+ cmd.redirect_stdout("/tmp/rubyfiles.txt")
19
+ end
19
20
  end
20
21
  end
22
+ t.verify_command = Mattock::CommandLine.new("should_do")
21
23
  end
22
- t.verify_command = Mattock::CommandLine.new("should_do")
23
24
  end
24
25
  end
25
26
 
26
27
  describe "when verification indicates command should proceed" do
28
+ include Mattock::CommandLineExampleGroup
29
+
27
30
  it "should run both commands" do
28
- cmds = [/should_do/, /^ssh.*cd.*ls.*grep.*rubyfiles.txt/]
29
- res = [1, 0]
30
- Mattock::CommandLine.should_receive(:execute) do |cmd|
31
- cmd.should =~ cmds.shift
32
- Mattock::MockCommandResult.create(res.shift)
33
- end.exactly(2).times
31
+ expect_command(/should_do/, 1)
32
+ expect_command(/^ssh.*cd.*ls.*grep.*rubyfiles.txt/, 0)
34
33
 
35
34
  rake["test:run"].invoke
36
- cmds.should == []
37
35
  end
38
36
  end
39
37
  end
data/spec/tasklib.rb CHANGED
@@ -19,21 +19,16 @@ describe Mattock::Tasklib do
19
19
  TestTaskLib.new
20
20
  end
21
21
 
22
+ describe "defines" do
23
+ subject{ rake }
22
24
 
23
- it "should define a root task" do
24
- rake.should have_task(:test)
25
- end
26
-
27
- it "should define a namespaced task" do
28
- rake.should have_task("test:task")
25
+ it{ should have_task(:test) }
26
+ it{ should have_task("test:task") }
27
+ it{ should_not have_task("random:tasks")}
29
28
  end
30
29
 
31
30
  it "should make root task depend on namespaced" do
32
- rake.lookup(:test).should depend_on("test:task")
33
- end
34
-
35
- it "should not define random tasks" do
36
- rake.should_not have_task("random:tasks")
31
+ rake[:test].should depend_on("test:task")
37
32
  end
38
33
 
39
34
  it "should not make namespaced task depend on root task" do
@@ -1,2 +1,5 @@
1
1
  require 'rspec'
2
2
  require 'file-sandbox'
3
+ require 'mattock/testing/record-commands'
4
+
5
+ Mattock::CommandLine.command_recording_path = "/dev/null"
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mattock
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Judson Lester
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-21 00:00:00 Z
13
+ date: 2012-01-28 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: corundum
@@ -114,10 +114,13 @@ files:
114
114
  - lib/mattock/command-task.rb
115
115
  - lib/mattock/testing/rake-example-group.rb
116
116
  - lib/mattock/testing/mock-command-line.rb
117
+ - lib/mattock/testing/record-commands.rb
117
118
  - lib/mattock/template-host.rb
118
119
  - lib/mattock/remote-command-task.rb
119
120
  - lib/mattock/tasklib.rb
121
+ - lib/mattock/task.rb
120
122
  - lib/mattock/configurable.rb
123
+ - lib/mattock/cascading-definition.rb
121
124
  - lib/mattock.rb
122
125
  - doc/README
123
126
  - doc/Specifications
@@ -186,7 +189,7 @@ rdoc_options:
186
189
  - --main
187
190
  - doc/README
188
191
  - --title
189
- - mattock-0.0.1 RDoc
192
+ - mattock-0.1.0 RDoc
190
193
  require_paths:
191
194
  - lib/
192
195
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -194,7 +197,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
197
  requirements:
195
198
  - - ">="
196
199
  - !ruby/object:Gem::Version
197
- hash: 304953233
200
+ hash: 737860559
198
201
  segments:
199
202
  - 0
200
203
  version: "0"