mattock 0.0.1 → 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.
@@ -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"