ztk 1.0.11 → 1.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.
- data/.gitignore +0 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/README.md +1 -0
- data/Rakefile +3 -10
- data/lib/ztk.rb +1 -0
- data/lib/ztk/dsl/core.rb +13 -13
- data/lib/ztk/dsl/core/actions/find.rb +0 -1
- data/lib/ztk/dsl/core/relations/belongs_to.rb +1 -18
- data/lib/ztk/dsl/core/relations/has_many.rb +2 -15
- data/lib/ztk/locator.rb +57 -0
- data/lib/ztk/version.rb +1 -1
- data/spec/spec_helper.rb +4 -31
- data/spec/ztk/benchmark_spec.rb +14 -6
- data/spec/ztk/command_spec.rb +32 -24
- data/spec/ztk/locator_spec.rb +51 -0
- data/spec/ztk/ssh_spec.rb +87 -79
- data/ztk.gemspec +22 -23
- metadata +141 -108
- data/.rvmrc.template +0 -1
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ztk
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[](http://badge.fury.io/rb/ztk)
|
2
2
|
[](https://gemnasium.com/zpatten/ztk)
|
3
3
|
[](http://travis-ci.org/zpatten/ztk)
|
4
|
+
[](https://coveralls.io/r/zpatten/testlab)
|
4
5
|
[](https://codeclimate.com/github/zpatten/ztk)
|
5
6
|
|
6
7
|
# ZTK
|
data/Rakefile
CHANGED
@@ -29,16 +29,9 @@ task :test => :spec
|
|
29
29
|
|
30
30
|
################################################################################
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
case RUBY_PLATFORM
|
36
|
-
when /darwin/
|
37
|
-
`open coverage/index.html`
|
38
|
-
when /linux/
|
39
|
-
`google-chrome coverage/index.html`
|
40
|
-
end
|
41
|
-
end
|
32
|
+
require 'coveralls/rake/task'
|
33
|
+
Coveralls::RakeTask.new
|
34
|
+
task :coveralls => [:spec, 'coveralls:push']
|
42
35
|
|
43
36
|
################################################################################
|
44
37
|
|
data/lib/ztk.rb
CHANGED
data/lib/ztk/dsl/core.rb
CHANGED
@@ -35,8 +35,8 @@ module ZTK::DSL
|
|
35
35
|
base.class_eval do
|
36
36
|
base.send(:extend, ZTK::DSL::Core::ClassMethods)
|
37
37
|
|
38
|
-
base.send(:extend, ZTK::DSL::Core::DualMethods)
|
39
|
-
base.send(:include, ZTK::DSL::Core::DualMethods)
|
38
|
+
# base.send(:extend, ZTK::DSL::Core::DualMethods)
|
39
|
+
# base.send(:include, ZTK::DSL::Core::DualMethods)
|
40
40
|
|
41
41
|
base.send(:include, ZTK::DSL::Core::Attributes)
|
42
42
|
base.send(:include, ZTK::DSL::Core::Actions)
|
@@ -47,19 +47,19 @@ module ZTK::DSL
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# @author Zachary Patten <zachary@jovelabs.net>
|
50
|
-
module DualMethods
|
50
|
+
# module DualMethods
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
52
|
+
# def logger
|
53
|
+
# unless defined?($logger)
|
54
|
+
# $logger = ::ZTK::Logger.new("dsl.log")
|
55
|
+
# $logger.info {"=" * 80}
|
56
|
+
# $logger.info {"=" * 80}
|
57
|
+
# $logger.info {"=" * 80}
|
58
|
+
# end
|
59
|
+
# $logger
|
60
|
+
# end
|
61
61
|
|
62
|
-
end
|
62
|
+
# end
|
63
63
|
|
64
64
|
# @author Zachary Patten <zachary@jovelabs.net>
|
65
65
|
module ClassMethods
|
@@ -36,15 +36,9 @@ module ZTK::DSL::Core::Relations
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def get_belongs_to_reference(key)
|
39
|
-
logger.debug { "key(#{key})" }
|
40
|
-
|
41
39
|
if belongs_to_references.key?(key)
|
42
|
-
logger.debug { "found key -> (#{key})" }
|
43
|
-
|
44
40
|
belongs_to_references[key]
|
45
41
|
else
|
46
|
-
logger.debug { "looking up key -> (#{key})" }
|
47
|
-
|
48
42
|
key_id = send("#{key}_id")
|
49
43
|
item = key.to_s.classify.constantize.find(key_id).first
|
50
44
|
belongs_to_references[key] = item
|
@@ -52,13 +46,11 @@ module ZTK::DSL::Core::Relations
|
|
52
46
|
end
|
53
47
|
|
54
48
|
def set_belongs_to_reference(key, value)
|
55
|
-
logger.debug { "key(#{key}), value(#{value})" }
|
56
|
-
|
57
49
|
belongs_to_references[key] = value
|
58
50
|
attributes.merge!("#{key}_id".to_sym => value.id)
|
59
51
|
|
60
52
|
klass = self.class.to_s.demodulize.downcase.pluralize
|
61
|
-
|
53
|
+
|
62
54
|
many = value.send(klass)
|
63
55
|
many << self
|
64
56
|
many.uniq!
|
@@ -80,11 +72,8 @@ module ZTK::DSL::Core::Relations
|
|
80
72
|
:class_name => key.to_s.classify,
|
81
73
|
:key => key
|
82
74
|
}.merge(options)
|
83
|
-
logger.debug { "key(#{key.inspect}), options(#{belongs_to_relations[key].inspect})" }
|
84
75
|
|
85
76
|
define_method(key) do |*args|
|
86
|
-
logger.debug { "*args(#{args.inspect})" }
|
87
|
-
|
88
77
|
if args.count == 0
|
89
78
|
get_belongs_to_reference(key)
|
90
79
|
else
|
@@ -93,14 +82,10 @@ module ZTK::DSL::Core::Relations
|
|
93
82
|
end
|
94
83
|
|
95
84
|
define_method("#{key}=") do |value|
|
96
|
-
logger.debug { "#{key}= value(#{value.inspect})" }
|
97
|
-
|
98
85
|
set_belongs_to_reference(key, value)
|
99
86
|
end
|
100
87
|
|
101
88
|
define_method("#{key}_id") do |*args|
|
102
|
-
logger.debug { "#{key}_id *args(#{args.inspect})" }
|
103
|
-
|
104
89
|
if args.count == 0
|
105
90
|
attributes["#{key}_id".to_sym]
|
106
91
|
else
|
@@ -111,8 +96,6 @@ module ZTK::DSL::Core::Relations
|
|
111
96
|
|
112
97
|
define_method("#{key}_id=") do |value|
|
113
98
|
options = self.class.belongs_to_relations[key]
|
114
|
-
logger.debug { "#{key}_id= value(#{value.inspect}), options(#{options.inspect})" }
|
115
|
-
|
116
99
|
if value != attributes["#{key}_id".to_sym]
|
117
100
|
item = options[:class_name].constantize.find(value).first
|
118
101
|
set_belongs_to_reference(key, item)
|
@@ -36,22 +36,14 @@ module ZTK::DSL::Core::Relations
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def get_has_many_reference(key)
|
39
|
-
logger.debug { "key(#{key})" }
|
40
|
-
|
41
39
|
if has_many_references.key?(key)
|
42
|
-
logger.debug { "found key -> (#{key})" }
|
43
|
-
|
44
40
|
has_many_references[key]
|
45
41
|
else
|
46
|
-
logger.debug { "looking up key -> (#{key})" }
|
47
|
-
|
48
42
|
has_many_references[key] ||= []
|
49
43
|
end
|
50
44
|
end
|
51
45
|
|
52
46
|
def set_has_many_reference(key, value)
|
53
|
-
logger.debug { "key(#{key}), value(#{value})" }
|
54
|
-
|
55
47
|
dataset = get_has_many_reference(key)
|
56
48
|
dataset.clear
|
57
49
|
dataset.concat(value)
|
@@ -73,11 +65,8 @@ module ZTK::DSL::Core::Relations
|
|
73
65
|
:class_name => key.to_s.classify,
|
74
66
|
:key => key
|
75
67
|
}.merge(options)
|
76
|
-
logger.debug { "key(#{key.inspect}), options(#{has_many_relations[key].inspect})" }
|
77
68
|
|
78
69
|
define_method(key) do |*args|
|
79
|
-
logger.debug { "#{key} *args(#{args.inspect})" }
|
80
|
-
|
81
70
|
if args.count == 0
|
82
71
|
get_has_many_reference(key)
|
83
72
|
else
|
@@ -86,18 +75,16 @@ module ZTK::DSL::Core::Relations
|
|
86
75
|
end
|
87
76
|
|
88
77
|
define_method("#{key}=") do |value|
|
89
|
-
logger.debug { "#{key}= value(#{value.inspect})" }
|
90
|
-
|
91
78
|
set_has_many_reference(key, value)
|
92
79
|
end
|
93
80
|
|
94
81
|
define_method(key.to_s.singularize) do |id=nil, &block|
|
95
82
|
options = self.class.has_many_relations[key]
|
96
|
-
logger.debug { "#{key.to_s.singularize} block(#{block.inspect}), options(#{options.inspect})" }
|
97
83
|
data = options[:class_name].constantize.new(id, &block)
|
98
84
|
get_has_many_reference(key) << data
|
85
|
+
|
99
86
|
klass = self.class.to_s.demodulize.singularize.downcase
|
100
|
-
|
87
|
+
|
101
88
|
data.send("#{klass}=", self)
|
102
89
|
data
|
103
90
|
end
|
data/lib/ztk/locator.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
################################################################################
|
2
|
+
#
|
3
|
+
# Author: Zachary Patten <zachary@jovelabs.net>
|
4
|
+
# Copyright: Copyright (c) Zachary Patten
|
5
|
+
# License: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
################################################################################
|
20
|
+
module ZTK
|
21
|
+
|
22
|
+
# ZTK::Locator Error Class
|
23
|
+
#
|
24
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
25
|
+
class LocatorError < Error; end
|
26
|
+
|
27
|
+
# @author Zachary Patten <zachary@jovelabs.net>
|
28
|
+
class Locator
|
29
|
+
|
30
|
+
class << self
|
31
|
+
|
32
|
+
# Locate a file or directory
|
33
|
+
#
|
34
|
+
# Attempts to locate the file or directory supplied, starting with
|
35
|
+
# the current working directory and crawling it up looking for a match
|
36
|
+
# at each step of the way.
|
37
|
+
#
|
38
|
+
# @param [String,Array<String>] args A string or array of strings to
|
39
|
+
# attempt to locate.
|
40
|
+
#
|
41
|
+
# @return [String] The expanded path to the located entry.
|
42
|
+
def find(*args)
|
43
|
+
pwd = Dir.pwd.split(File::SEPARATOR)
|
44
|
+
|
45
|
+
(pwd.length - 1).downto(0) do |i|
|
46
|
+
candidate = File.expand_path(File.join(pwd[0..i], args))
|
47
|
+
return candidate if File.exists?(candidate)
|
48
|
+
end
|
49
|
+
|
50
|
+
raise LocatorError, "Could not locate '#{File.join(args)}'!"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/ztk/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -17,42 +17,15 @@
|
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
19
|
################################################################################
|
20
|
+
require 'coveralls'
|
21
|
+
Coveralls.wear!
|
22
|
+
################################################################################
|
20
23
|
require 'tempfile'
|
21
|
-
|
22
|
-
require 'simplecov'
|
23
|
-
SimpleCov.start do
|
24
|
-
add_filter '/spec/'
|
25
|
-
end if ENV["COVERAGE"]
|
26
|
-
|
27
24
|
require 'ztk'
|
28
25
|
|
29
26
|
ENV['LOG_LEVEL'] = "DEBUG"
|
30
27
|
|
31
|
-
WAIT_SMALL =
|
28
|
+
WAIT_SMALL = 5
|
32
29
|
READ_PARTIAL_CHUNK = 2048
|
33
30
|
|
34
|
-
RSpec.configure do |config|
|
35
|
-
|
36
|
-
config.before(:all) do
|
37
|
-
$stdout = File.open("/dev/null", "w")
|
38
|
-
$stderr = File.open("/dev/null", "w")
|
39
|
-
$stdin = File.open("/dev/null", "r")
|
40
|
-
$logger = ZTK::Logger.new(File.join("/tmp", "test.log"))
|
41
|
-
|
42
|
-
$logger.info { "=" * 80 }
|
43
|
-
$logger.info { "STARTING ZTK v#{ZTK::VERSION} TEST RUN @ #{Time.now.utc}" }
|
44
|
-
$logger.info { "=" * 80 }
|
45
|
-
end
|
46
|
-
|
47
|
-
config.before(:each) do
|
48
|
-
$ui = ZTK::UI.new(
|
49
|
-
:stdout => StringIO.new,
|
50
|
-
:stderr => StringIO.new,
|
51
|
-
:stdin => StringIO.new
|
52
|
-
)
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
31
|
################################################################################
|
data/spec/ztk/benchmark_spec.rb
CHANGED
@@ -22,6 +22,14 @@ require "spec_helper"
|
|
22
22
|
|
23
23
|
describe ZTK::Benchmark do
|
24
24
|
|
25
|
+
before(:each) do
|
26
|
+
@ui = ZTK::UI.new(
|
27
|
+
:stdout => StringIO.new,
|
28
|
+
:stderr => StringIO.new,
|
29
|
+
:stdin => StringIO.new
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
25
33
|
subject { ZTK::Benchmark }
|
26
34
|
|
27
35
|
describe "class" do
|
@@ -49,28 +57,28 @@ describe ZTK::Benchmark do
|
|
49
57
|
|
50
58
|
it "should throw an exception if executed with a message but without a mark" do
|
51
59
|
lambda {
|
52
|
-
ZTK::Benchmark.bench(:ui =>
|
60
|
+
ZTK::Benchmark.bench(:ui => @ui, :message => "Hello World")
|
53
61
|
}.should raise_error ZTK::BenchmarkError
|
54
62
|
end
|
55
63
|
|
56
64
|
it "should throw an exception if executed without a message but with a mark" do
|
57
65
|
lambda {
|
58
|
-
ZTK::Benchmark.bench(:ui =>
|
66
|
+
ZTK::Benchmark.bench(:ui => @ui, :mark => "%0.4f")
|
59
67
|
}.should raise_error ZTK::BenchmarkError
|
60
68
|
end
|
61
69
|
|
62
70
|
it "should not write to STDOUT if not given a message or mark" do
|
63
|
-
ZTK::Benchmark.bench(:ui =>
|
71
|
+
ZTK::Benchmark.bench(:ui => @ui) do
|
64
72
|
sleep(0.1)
|
65
73
|
end
|
66
|
-
|
74
|
+
@ui.stdout.size.should == 0
|
67
75
|
end
|
68
76
|
|
69
77
|
it "should write to STDOUT if given a message and mark" do
|
70
|
-
ZTK::Benchmark.bench(:ui =>
|
78
|
+
ZTK::Benchmark.bench(:ui => @ui, :message => "Hello World", :mark => "%0.4f") do
|
71
79
|
sleep(0.1)
|
72
80
|
end
|
73
|
-
|
81
|
+
@ui.stdout.size.should > 0
|
74
82
|
end
|
75
83
|
|
76
84
|
end
|
data/spec/ztk/command_spec.rb
CHANGED
@@ -22,7 +22,15 @@ require "spec_helper"
|
|
22
22
|
|
23
23
|
describe ZTK::Command do
|
24
24
|
|
25
|
-
|
25
|
+
before(:each) do
|
26
|
+
@ui = ZTK::UI.new(
|
27
|
+
:stdout => StringIO.new,
|
28
|
+
:stderr => StringIO.new,
|
29
|
+
:stdin => StringIO.new
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
subject { ZTK::Command.new(:ui => @ui) }
|
26
34
|
|
27
35
|
describe "class" do
|
28
36
|
|
@@ -38,18 +46,18 @@ describe ZTK::Command do
|
|
38
46
|
|
39
47
|
it "should be able to execute the command \"hostname\"" do
|
40
48
|
subject.config do |config|
|
41
|
-
config.ui =
|
49
|
+
config.ui = @ui
|
42
50
|
end
|
43
51
|
hostname = %x(hostname).chomp
|
44
52
|
status = subject.exec("hostname")
|
45
53
|
status.exit_code.should == 0
|
46
|
-
|
47
|
-
|
54
|
+
@ui.stdout.rewind
|
55
|
+
@ui.stdout.read.chomp.should == hostname
|
48
56
|
end
|
49
57
|
|
50
58
|
it "should timeout after the period specified" do
|
51
59
|
subject.config do |config|
|
52
|
-
config.ui =
|
60
|
+
config.ui = @ui
|
53
61
|
config.timeout = WAIT_SMALL
|
54
62
|
end
|
55
63
|
hostname = %x(hostname).chomp
|
@@ -58,14 +66,14 @@ describe ZTK::Command do
|
|
58
66
|
|
59
67
|
it "should throw an exception if the exit status is not as expected" do
|
60
68
|
subject.config do |config|
|
61
|
-
config.ui =
|
69
|
+
config.ui = @ui
|
62
70
|
end
|
63
71
|
lambda { subject.exec("/bin/bash -c 'exit 64'") }.should raise_error ZTK::CommandError
|
64
72
|
end
|
65
73
|
|
66
74
|
it "should return a instance of an OpenStruct object" do
|
67
75
|
subject.config do |config|
|
68
|
-
config.ui =
|
76
|
+
config.ui = @ui
|
69
77
|
end
|
70
78
|
result = subject.exec(%q{echo "Hello World"})
|
71
79
|
result.should be_an_instance_of OpenStruct
|
@@ -73,7 +81,7 @@ describe ZTK::Command do
|
|
73
81
|
|
74
82
|
it "should return the exit code" do
|
75
83
|
subject.config do |config|
|
76
|
-
config.ui =
|
84
|
+
config.ui = @ui
|
77
85
|
end
|
78
86
|
data = 64
|
79
87
|
|
@@ -83,7 +91,7 @@ describe ZTK::Command do
|
|
83
91
|
|
84
92
|
it "should return the output" do
|
85
93
|
subject.config do |config|
|
86
|
-
config.ui =
|
94
|
+
config.ui = @ui
|
87
95
|
end
|
88
96
|
data = "Hello World @ #{Time.now.utc}"
|
89
97
|
|
@@ -93,7 +101,7 @@ describe ZTK::Command do
|
|
93
101
|
|
94
102
|
it "should allow us to change the expected exit code" do
|
95
103
|
subject.config do |config|
|
96
|
-
config.ui =
|
104
|
+
config.ui = @ui
|
97
105
|
end
|
98
106
|
data = 32
|
99
107
|
result = subject.exec(%Q{/bin/bash -c 'exit #{data}'}, :exit_code => data)
|
@@ -103,20 +111,20 @@ describe ZTK::Command do
|
|
103
111
|
|
104
112
|
it "should capture STDOUT and send it to the appropriate pipe" do
|
105
113
|
subject.config do |config|
|
106
|
-
config.ui =
|
114
|
+
config.ui = @ui
|
107
115
|
end
|
108
116
|
data = "Hello World @ #{Time.now.utc}"
|
109
117
|
|
110
118
|
subject.exec(%Q{echo "#{data}" >&1})
|
111
119
|
|
112
|
-
|
113
|
-
|
120
|
+
@ui.stdout.rewind
|
121
|
+
@ui.stdout.read.match(data).should_not be nil
|
114
122
|
|
115
|
-
|
116
|
-
|
123
|
+
@ui.stderr.rewind
|
124
|
+
@ui.stderr.read.match(data).should be nil
|
117
125
|
|
118
|
-
|
119
|
-
|
126
|
+
@ui.stdin.rewind
|
127
|
+
@ui.stdin.read.match(data).should be nil
|
120
128
|
end
|
121
129
|
|
122
130
|
end
|
@@ -125,20 +133,20 @@ describe ZTK::Command do
|
|
125
133
|
|
126
134
|
it "should capture STDERR and send it to the appropriate pipe" do
|
127
135
|
subject.config do |config|
|
128
|
-
config.ui =
|
136
|
+
config.ui = @ui
|
129
137
|
end
|
130
138
|
data = "Hello World @ #{Time.now.utc}"
|
131
139
|
|
132
140
|
subject.exec(%Q{echo "#{data}" >&2})
|
133
141
|
|
134
|
-
|
135
|
-
|
142
|
+
@ui.stdout.rewind
|
143
|
+
@ui.stdout.read.match(data).should be nil
|
136
144
|
|
137
|
-
|
138
|
-
|
145
|
+
@ui.stderr.rewind
|
146
|
+
@ui.stderr.read.match(data).should_not be nil
|
139
147
|
|
140
|
-
|
141
|
-
|
148
|
+
@ui.stdin.rewind
|
149
|
+
@ui.stdin.read.match(data).should be nil
|
142
150
|
end
|
143
151
|
end
|
144
152
|
|