mattock 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ module Mattock
2
+ module Configurable
3
+ class FieldProcessor
4
+ def initialize(source)
5
+ @source = source
6
+ @field_names = filter(source.class.field_names)
7
+ end
8
+ attr_accessor :field_names
9
+ attr_reader :source
10
+
11
+ def filter_attribute
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def filter(field_names)
16
+ field_names.find_all do |name|
17
+ source.class.field_metadata(name).is?(filter_attribute)
18
+ end
19
+ end
20
+
21
+ def value(field)
22
+ source.__send__(field.reader_method)
23
+ end
24
+
25
+ def to(target)
26
+ field_names.each do |name|
27
+ field = source.class.field_metadata(name)
28
+ next unless target.respond_to?(field.writer_method)
29
+ target.__send__(field.writer_method, value(field))
30
+ end
31
+ end
32
+ end
33
+
34
+ class SettingsCopier < FieldProcessor
35
+ def filter_attribute
36
+ :copiable
37
+ end
38
+
39
+ def value(field)
40
+ field.immediate_value_on(source)
41
+ end
42
+ end
43
+
44
+ class SettingsProxier < FieldProcessor
45
+ def filter_attribute
46
+ :proxiable
47
+ end
48
+
49
+ def value(field)
50
+ ProxyValue.new(source, field)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,75 @@
1
+ module Mattock
2
+ module Configurable
3
+ def copy_settings
4
+ SettingsCopier.new(self)
5
+ end
6
+
7
+ def copy_settings_to(other)
8
+ copy_settings.to(other)
9
+ self
10
+ end
11
+
12
+ def proxy_settings
13
+ SettingsProxier.new(self)
14
+ end
15
+
16
+ def proxy_settings_to(other)
17
+ proxy_settings.to(other)
18
+ end
19
+
20
+ def to_hash
21
+ self.class.to_hash(self)
22
+ end
23
+
24
+ def unset_defaults_guard
25
+ raise "Tried to check required settings before running setup_defaults"
26
+ end
27
+
28
+ #Call during initialize to set default values on settings - if you're using
29
+ #Configurable outside of Mattock, be sure this gets called.
30
+ def setup_defaults
31
+ def self.unset_defaults_guard
32
+ end
33
+
34
+ self.class.set_defaults_on(self)
35
+ self
36
+ end
37
+
38
+ #Checks that all required fields have be set, otherwise raises an error
39
+ #@raise RuntimeError if any required fields are unset
40
+ def check_required
41
+ unset_defaults_guard
42
+ missing = self.class.missing_required_fields_on(self)
43
+ unless missing.empty?
44
+ raise "Required field#{missing.length > 1 ? "s" : ""} #{missing.map{|field| field.to_s.inspect}.join(", ")} unset on #{self.inspect}"
45
+ end
46
+ self
47
+ end
48
+
49
+ def proxy_value
50
+ ProxyDecorator.new(self)
51
+ end
52
+
53
+ #XXX deprecate
54
+ def unset?(value)
55
+ value.nil?
56
+ end
57
+
58
+ def field_unset?(name)
59
+ self.class.field_metadata(name).unset_on?(self)
60
+ end
61
+
62
+ #Requires that a named field be set
63
+ def fail_unless_set(name)
64
+ if field_unset?(name)
65
+ raise "Assertion failed: Field #{name} unset"
66
+ end
67
+ true
68
+ end
69
+ alias fail_if_unset fail_unless_set
70
+
71
+ class Struct
72
+ include Configurable
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,30 @@
1
+ module Mattock
2
+ module Configurable
3
+ class ProxyValue
4
+ def initialize(source, field)
5
+ @source, @field = source, field
6
+ end
7
+ attr_reader :source, :field
8
+
9
+ def inspect
10
+ "#{self.class.name.split(':').last}: #{source.class.name}.#{field.inspect}"
11
+ end
12
+ end
13
+
14
+ class ProxyDecorator
15
+ def initialize(configurable)
16
+ @configurable = configurable
17
+ end
18
+
19
+ def method_missing(name, *args, &block)
20
+ unless block.nil? and args.empty?
21
+ raise NoMethodError, "method `#{name}' not defined with arguments or block when proxied"
22
+ end
23
+ unless @configurable.respond_to?(name)
24
+ raise NoMethodError, "cannot proxy `#{name}' - undefined on #{@configurable}"
25
+ end
26
+ return ProxyValue.new(@configurable, @configurable.class.field_metadata(name))
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,18 +2,15 @@ require 'mattock/command-task'
2
2
  module Mattock
3
3
  module Rake
4
4
  class RemoteCommandTask < CommandTask
5
- runtime_setting(:remote_server, nested(
6
- :address => nil,
7
- :user => nil
8
- ))
5
+ setting(:remote_server, nested{
6
+ setting :address
7
+ setting :port, 22
8
+ setting :user, nil
9
+ })
10
+
9
11
  setting(:ssh_options, [])
12
+ setting(:verbose, 0)
10
13
  nil_fields(:id_file, :free_arguments)
11
- runtime_setting(:remote_target)
12
-
13
- def resolve_runtime_configuration
14
- super
15
- self.remote_target ||= [remote_server.user, remote_server.address].compact.join('@') unless remote_server.address.nil?
16
- end
17
14
 
18
15
  def ssh_option(name, value)
19
16
  ssh_options << "\"#{name}=#{value}\""
@@ -26,12 +23,16 @@ module Mattock
26
23
  Mattock::WrappingChain.new do |cmd|
27
24
  cmd.add Mattock::CommandLine.new("ssh") do |cmd|
28
25
  cmd.options << "-i #{id_file}" if id_file
26
+ cmd.options << "-l #{remote_server.user}" unless remote_server.user.nil?
27
+ cmd.options << remote_server.address
28
+ cmd.options << "-p #{remote_server.port}" #ok
29
+ cmd.options << "-n"
30
+ cmd.options << "-#{'v'*verbose}" if verbose > 0
29
31
  unless ssh_options.empty?
30
32
  ssh_options.each do |opt|
31
33
  cmd.options << "-o #{opt}"
32
34
  end
33
35
  end
34
- cmd.options << remote_target
35
36
  end
36
37
  cmd.add Mattock::ShellEscaped.new(command_on_remote)
37
38
  end
data/lib/mattock/task.rb CHANGED
@@ -13,6 +13,7 @@ module Mattock
13
13
  include Configurable
14
14
  include CascadingDefinition
15
15
  include DeferredDefinition
16
+ include Configurable::DirectoryStructure
16
17
 
17
18
  module ClassMethods
18
19
  def default_taskname(name)
@@ -35,6 +36,9 @@ module Mattock
35
36
  task.action(args)
36
37
  end
37
38
 
39
+ #XXX ?? Dilemma: this prevents an existing task action from being
40
+ #enriched with this one, but not v/v - it also doesn't prevent double
41
+ #-definition of this task...
38
42
  unless self === task
39
43
  raise "Task already defined for #{task.name} - attempted to redefine with #{self.name}"
40
44
  end
@@ -53,6 +57,7 @@ module Mattock
53
57
  def self.included(sub)
54
58
  sub.extend ClassMethods
55
59
  Configurable.included(sub)
60
+ Configurable::DirectoryStructure.included(sub)
56
61
  DeferredDefinition.add_settings(sub)
57
62
  end
58
63
 
@@ -39,6 +39,7 @@ module Mattock
39
39
  #configuration options are built using {Configurable}
40
40
  class TaskLib < ::Rake::TaskLib
41
41
  include CascadingDefinition
42
+ include Configurable::DirectoryStructure
42
43
 
43
44
  attr_writer :namespace_name
44
45
 
@@ -67,8 +68,8 @@ module Mattock
67
68
  # task after => name
68
69
  #Which ensures that if "after" is ever invoked,
69
70
  #the execution will be before, name, then after
70
- def bracket_task(before, name, after)
71
- task self[name] => before
71
+ def bracket_task(before, name, after, &block)
72
+ task self[name] => before, &block
72
73
  task after => self[name]
73
74
  end
74
75
 
@@ -112,6 +113,25 @@ module Mattock
112
113
  nil
113
114
  end
114
115
 
116
+ #Default define defines some tasks related to debugging Rakefiles -
117
+ #subclasses can get these just by remembering to call 'super' in their
118
+ #define
119
+ def define
120
+ debug_settings_task
121
+ end
122
+
123
+ def debug_settings_task
124
+ in_namespace do
125
+ task :debug_settings do
126
+ require 'pp'
127
+ puts self.class.name
128
+ pp self.to_hash
129
+ end
130
+ end
131
+
132
+ task :debug_settings => self[:debug_settings]
133
+ end
134
+
115
135
  #Wraps a single task in lib's namespace
116
136
  def [](taskname)
117
137
  in_namespace(taskname).first
@@ -14,6 +14,7 @@ module Mattock
14
14
  public :rel_dir, :default_valise
15
15
  end
16
16
 
17
+ #@deprecated Use {Valise::Set#templates} instead
17
18
  module TemplateHost
18
19
  attr_accessor :valise
19
20
 
@@ -44,9 +45,11 @@ module Mattock
44
45
  end
45
46
  end
46
47
 
48
+ #@deprecated Use {Valise::Set#templates} instead
47
49
  module TemplateTaskLib
48
50
  include TemplateHost
49
51
 
52
+ #@deprecated Use {Valise::Set#templates} instead
50
53
  def template_task(template_source, destination_path, template_options = nil)
51
54
  unless template_options.nil?
52
55
  valise.add_serialization_handler(template_source, :tilt, :template_options => template_options)
@@ -1,7 +1,7 @@
1
1
  require 'mattock/command-line'
2
2
 
3
3
  module Mattock
4
- class MockCommandResult < CommandRunResult
4
+ class MockCommandResult < CommandLine::CommandRunResult
5
5
  def self.create(*args)
6
6
  if args.length == 1
7
7
  args = [args[0], {1 => ""}]
data/spec/command-line.rb CHANGED
@@ -31,7 +31,7 @@ describe Mattock::CommandLine do
31
31
  end.to_not raise_error
32
32
  end
33
33
 
34
- describe Mattock::CommandRunResult do
34
+ describe Mattock::CommandLine::CommandRunResult do
35
35
  let :result do
36
36
  commandline.run
37
37
  end
data/spec/command-task.rb CHANGED
@@ -27,6 +27,10 @@ describe Mattock::RemoteCommandTask do
27
27
  end
28
28
  end
29
29
 
30
+ it "should inspect cleanly" do
31
+ rake["test:run"].inspect.should be_a(String)
32
+ end
33
+
30
34
  describe "when verification indicates command should proceed" do
31
35
  it "should run both commands" do
32
36
  expect_command(/should_do/, 1)
data/spec/configurable.rb CHANGED
@@ -6,11 +6,16 @@ describe Mattock::Configurable do
6
6
 
7
7
  setting(:three, 3)
8
8
  required_field(:four)
9
+ required_field(:override)
9
10
  end
10
11
 
11
12
  class TestStruct < TestSuperStruct
12
13
  settings(:one => 1, :two => nested(:a => "a"){ required_field(:b)} )
13
14
  nil_field(:five)
15
+
16
+ def override
17
+ 17
18
+ end
14
19
  end
15
20
 
16
21
  subject do
@@ -49,6 +54,11 @@ describe Mattock::Configurable do
49
54
  expect do
50
55
  subject.check_required
51
56
  end.to_not raise_error
57
+ subject.override.should == 17
58
+ end
59
+
60
+ it "should inspect cleanly" do
61
+ subject.inspect.should be_a(String)
52
62
  end
53
63
 
54
64
  describe "with DirectoryStructure" do
@@ -66,6 +76,10 @@ describe Mattock::Configurable do
66
76
  )
67
77
  )
68
78
  )
79
+
80
+ dir(:next_to_me, "rainbow", dir(:in_there, "a_place", path(:nearby, "a.file")))
81
+
82
+ path(:loose_path, "here")
69
83
  end
70
84
 
71
85
  def subject
@@ -80,6 +94,10 @@ describe Mattock::Configurable do
80
94
  end.to raise_error /Required field/
81
95
  end
82
96
 
97
+ it "should inspect cleanly" do
98
+ subject.inspect.should be_a(String)
99
+ end
100
+
83
101
  describe "with root path configured, but missing a relative path" do
84
102
  def subject
85
103
  DirectoryThing.new.tap do |thing|
@@ -112,6 +130,9 @@ describe Mattock::Configurable do
112
130
  end.not_to raise_error
113
131
  end
114
132
 
133
+ its("nearby.absolute_path"){ should =~ %r"rainbow/a_place/a.file$"}
134
+ its("nearby.absolute_path"){ should =~ %r"^#{subject.absolute_path}"}
135
+
115
136
  its("certificate_file.absolute_path"){ should == "/tmp/bundle_workdir/aws-creds/cert.pem" }
116
137
  its("bundle_manifest.absolute_path"){ should == "/tmp/bundle_workdir/image.manifest.xml" }
117
138
  its("credentials_dir.absolute_path"){ should == "/tmp/bundle_workdir/aws-creds" }
@@ -184,7 +205,7 @@ describe Mattock::Configurable do
184
205
  end
185
206
 
186
207
  it "should not copy no_copy" do
187
- left.copy_settings.to(right)
208
+ left.copy_settings_to(right)
188
209
  right.unset?(right.normal).should be_false
189
210
  right.normal.should == 1
190
211
  right.unset?(right.no_copy).should be_true
@@ -9,7 +9,7 @@ describe Mattock::TemplateHost do
9
9
  end
10
10
 
11
11
  it "should handle relative paths nicely" do
12
- Mattock::ValiseManager.rel_dir(__FILE__, "spec").should =~ /.*spec$/
12
+ Mattock::ValiseManager.rel_dir(__FILE__, "spec").to_s.should =~ /.*spec$/
13
13
  end
14
14
 
15
15
  it "should be able to do easy templating" do
@@ -1,2 +1,9 @@
1
1
  require 'rspec'
2
2
  require 'file-sandbox'
3
+ require 'cadre/rspec'
4
+
5
+ RSpec.configure do |config|
6
+ config.run_all_when_everything_filtered = true
7
+ config.add_formatter(Cadre::RSpec::NotifyOnCompleteFormatter)
8
+ config.add_formatter(Cadre::RSpec::QuickfixFormatter)
9
+ end
metadata CHANGED
@@ -1,68 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mattock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
5
4
  prerelease:
5
+ version: 0.5.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Judson Lester
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-31 00:00:00.000000000 Z
12
+ date: 2013-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
+ prerelease: false
16
+ type: :development
15
17
  name: corundum
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
+ version_requirements: !ruby/object:Gem::Requirement
18
19
  requirements:
19
20
  - - ~>
20
21
  - !ruby/object:Gem::Version
21
22
  version: 0.0.1
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
23
  none: false
24
+ requirement: !ruby/object:Gem::Requirement
26
25
  requirements:
27
26
  - - ~>
28
27
  - !ruby/object:Gem::Version
29
28
  version: 0.0.1
29
+ none: false
30
30
  - !ruby/object:Gem::Dependency
31
+ prerelease: false
32
+ type: :runtime
31
33
  name: valise
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
+ version_requirements: !ruby/object:Gem::Requirement
34
35
  requirements:
35
36
  - - ! '>='
36
37
  - !ruby/object:Gem::Version
37
38
  version: 0.9.1
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
39
  none: false
40
+ requirement: !ruby/object:Gem::Requirement
42
41
  requirements:
43
42
  - - ! '>='
44
43
  - !ruby/object:Gem::Version
45
44
  version: 0.9.1
45
+ none: false
46
46
  - !ruby/object:Gem::Dependency
47
+ prerelease: false
48
+ type: :runtime
47
49
  name: tilt
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
+ version_requirements: !ruby/object:Gem::Requirement
50
51
  requirements:
51
52
  - - ! '>'
52
53
  - !ruby/object:Gem::Version
53
54
  version: '0'
54
- segments:
55
- - 0
56
- type: :runtime
57
- prerelease: false
58
- version_requirements: !ruby/object:Gem::Requirement
59
55
  none: false
56
+ requirement: !ruby/object:Gem::Requirement
60
57
  requirements:
61
58
  - - ! '>'
62
59
  - !ruby/object:Gem::Version
63
60
  version: '0'
64
- segments:
65
- - 0
61
+ none: false
66
62
  description: ! " If Rake won't do it by itself, you oughtta Mattock.\n\n If you
67
63
  survived the pun, you might enjoy this gem.\n\n Features:\n\n * Extensions to
68
64
  Tasklibs to support powerful deerpaths.\n * A commandline library that supports
@@ -82,6 +78,7 @@ files:
82
78
  - yard_templates/default/layout/html/setup.rb
83
79
  - yard_templates/default/layout/html/tasklib_list.erb
84
80
  - lib/mattock/command-line.rb
81
+ - lib/mattock/command-line/command-run-result.rb
85
82
  - lib/mattock/command-task.rb
86
83
  - lib/mattock/testing/rake-example-group.rb
87
84
  - lib/mattock/testing/mock-command-line.rb
@@ -93,6 +90,12 @@ files:
93
90
  - lib/mattock/tasklib.rb
94
91
  - lib/mattock/task.rb
95
92
  - lib/mattock/configurable.rb
93
+ - lib/mattock/configurable/field-processor.rb
94
+ - lib/mattock/configurable/proxy-value.rb
95
+ - lib/mattock/configurable/instance-methods.rb
96
+ - lib/mattock/configurable/class-methods.rb
97
+ - lib/mattock/configurable/directory-structure.rb
98
+ - lib/mattock/configurable/field-metadata.rb
96
99
  - lib/mattock/configuration-store.rb
97
100
  - lib/mattock/cascading-definition.rb
98
101
  - lib/mattock.rb
@@ -116,24 +119,24 @@ rdoc_options:
116
119
  - --main
117
120
  - doc/README
118
121
  - --title
119
- - mattock-0.4.1 RDoc
122
+ - mattock-0.5.0 RDoc
120
123
  require_paths:
121
124
  - lib/
122
125
  required_ruby_version: !ruby/object:Gem::Requirement
123
- none: false
124
126
  requirements:
125
127
  - - ! '>='
126
128
  - !ruby/object:Gem::Version
127
- version: '0'
128
129
  segments:
129
130
  - 0
130
- hash: -492969553
131
- required_rubygems_version: !ruby/object:Gem::Requirement
131
+ hash: -700278895
132
+ version: '0'
132
133
  none: false
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
135
  requirements:
134
136
  - - ! '>='
135
137
  - !ruby/object:Gem::Version
136
138
  version: '0'
139
+ none: false
137
140
  requirements: []
138
141
  rubyforge_project: mattock
139
142
  rubygems_version: 1.8.24