ztk 0.3.1 → 1.0.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -4,10 +4,12 @@ rvm:
4
4
  - 1.9.2
5
5
  - 1.9.3
6
6
 
7
- branches:
8
- only:
9
- - master
7
+ before_install:
8
+ - sudo apt-get -qq update
9
+
10
+ bundler_args: --binstubs
11
+
12
+ script: "rake spec"
10
13
 
11
14
  notifications:
12
- irc:
13
- - "irc.freenode.org#jovelabs"
15
+ irc: "irc.freenode.net#jovelabs"
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ --markup-provider=redcarpet
2
+ --markup=markdown
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ZTK
4
4
 
5
- Zachary's Tool Kit is a general purpose utility gem, featuring a collection of classes meant to simplify development of complex systems in Ruby.
5
+ Zachary's (DevOp) Tool Kit is a general purpose utility gem, featuring a collection of classes meant to simplify development of complex systems in Ruby.
6
6
 
7
7
  # RESOURCES
8
8
 
@@ -16,7 +16,7 @@ Issues:
16
16
 
17
17
  Documentation:
18
18
 
19
- * http://rubydoc.info/gems/ztk
19
+ * http://jovelabs.github.com/ztk/
20
20
 
21
21
  Wiki:
22
22
 
@@ -24,7 +24,7 @@ Wiki:
24
24
 
25
25
  # LICENSE
26
26
 
27
- ZTK - Zachary's Tool Kit
27
+ ZTK - Zachary's (DevOp) Tool Kit
28
28
 
29
29
  * Author: Zachary Patten <zachary@jovelabs.net>
30
30
  * Copyright: Copyright (c) Jove Labs
data/Rakefile CHANGED
@@ -41,3 +41,42 @@ task :coverage do
41
41
  end
42
42
 
43
43
  ################################################################################
44
+
45
+ require 'yard'
46
+ require 'yard/rake/yardoc_task'
47
+
48
+ GEM_NAME = File.basename(Dir.pwd)
49
+ DOC_PATH = File.expand_path(File.join("..", "/", "#{GEM_NAME}.doc"))
50
+
51
+ namespace :doc do
52
+ YARD::Rake::YardocTask.new(:pages) do |t|
53
+
54
+ # t.files = ['lib/**/*.rb']
55
+ t.options = ['--verbose', '-o', DOC_PATH]
56
+ end
57
+
58
+ namespace :pages do
59
+
60
+ desc 'Generate and publish YARD Documentation to GitHub pages'
61
+ task :publish => ['doc:pages'] do
62
+ describe = %x(git describe).chomp
63
+ stats = %x(bundle exec yard stats).chomp
64
+
65
+ commit_message = Array.new
66
+ commit_message << "Generated YARD Documentation for #{GEM_NAME.upcase} #{describe}\n\n"
67
+ commit_message << stats
68
+
69
+ Dir.chdir(DOC_PATH) do
70
+ puts(%x{git add -Av})
71
+ puts(%x{git commit -m"#{commit_message.join}"})
72
+ puts(%x{git push origin gh-pages})
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+ desc 'Alias to doc:yard'
80
+ task 'doc' => 'doc:yard'
81
+
82
+ ################################################################################
@@ -17,7 +17,6 @@
17
17
  # limitatIOns under the License.
18
18
  #
19
19
  ################################################################################
20
-
21
20
  require "base64"
22
21
 
23
22
  module ZTK
@@ -63,10 +62,7 @@ module ZTK
63
62
  # Result Set
64
63
  attr_accessor :pid, :result
65
64
 
66
- # @param [Hash] config Configuration options hash.
67
- # @option config [Integer] :max_forks Maximum number of forks to use.
68
- # @option config [Proc] :before_fork (nil) Proc to call before forking.
69
- # @option config [Proc] :after_fork (nil) Proc to call after forking.
65
+ # @param [Hash] configuration Configuration options hash.
70
66
  def initialize(configuration={})
71
67
  super({
72
68
  }.merge(configuration))
@@ -80,7 +76,7 @@ module ZTK
80
76
  #
81
77
  # @yield Block should execute tasks to be performed in background.
82
78
  # @yieldreturn [Object] Block can return any object to be marshalled back to
83
- # the parent processes result set.
79
+ # the parent processes.
84
80
  # @return [Integer] Returns the pid of the child process forked.
85
81
  def process(&block)
86
82
  !block_given? and log_and_raise(BackgroundError, "You must supply a block to the process method!")
@@ -121,6 +117,10 @@ module ZTK
121
117
  # If a process successfully finished, it's return value from the *process*
122
118
  # block is stored into the result set.
123
119
  #
120
+ # It's advisable to use something like the *at_exit* hook to ensure you don't
121
+ # leave orphaned processes. For example, in the *at_exit* hook you could
122
+ # call *wait* to block until the child process finishes up.
123
+ #
124
124
  # @return [Array<pid, status, data>] An array containing the pid,
125
125
  # status and data returned from the process block. If wait2() fails nil
126
126
  # is returned.
@@ -140,6 +140,14 @@ module ZTK
140
140
  nil
141
141
  end
142
142
 
143
+ def alive?
144
+ (Process.getpgid(@pid).is_a?(Integer) rescue false)
145
+ end
146
+
147
+ def dead?
148
+ !alive?
149
+ end
150
+
143
151
  end
144
152
 
145
153
  end
data/lib/ztk/base.rb CHANGED
@@ -17,7 +17,6 @@
17
17
  # limitations under the License.
18
18
  #
19
19
  ################################################################################
20
-
21
20
  require "ostruct"
22
21
 
23
22
  module ZTK
@@ -37,7 +36,7 @@ module ZTK
37
36
 
38
37
  class << self
39
38
 
40
- # @param [Hash] config Configuration options hash.
39
+ # @param [Hash] configuration Configuration options hash.
41
40
  # @option config [IO] :stdout Instance of IO to be used for STDOUT.
42
41
  # @option config [IO] :stderr Instance of IO to be used for STDERR.
43
42
  # @option config [IO] :stdin Instance of IO to be used for STDIN.
@@ -81,6 +80,14 @@ module ZTK
81
80
  config
82
81
  end
83
82
 
83
+ # Logs an exception and then raises it.
84
+ #
85
+ # @param [Logger] logger An instance of a class based off the Ruby
86
+ # *Logger* class.
87
+ # @param [Exception] exception The exception class to raise.
88
+ # @param [String] message The message to display with the exception.
89
+ # @param [Integer] shift (1) How many places to shift the caller stack in
90
+ # the log statement.
84
91
  def log_and_raise(logger, exception, message, shift=1)
85
92
  if logger.is_a?(ZTK::Logger)
86
93
  logger.shift(:fatal, shift) { "EXCEPTION: #{exception.inspect} - #{message.inspect}" }
@@ -117,8 +124,16 @@ module ZTK
117
124
  end
118
125
  end
119
126
 
120
- def log_and_raise(exception, message)
121
- Base.log_and_raise(config.logger, exception, message, 2)
127
+ # Logs an exception and then raises it.
128
+ #
129
+ # @see Base.log_and_raise
130
+ #
131
+ # @param [Exception] exception The exception class to raise.
132
+ # @param [String] message The message to display with the exception.
133
+ # @param [Integer] shift (2) How many places to shift the caller stack in
134
+ # the log statement.
135
+ def log_and_raise(exception, message, shift=2)
136
+ Base.log_and_raise(config.logger, exception, message, shift)
122
137
  end
123
138
 
124
139
  # Direct logging method.
@@ -130,7 +145,7 @@ module ZTK
130
145
  # The value returned in the block is passed down to the logger specified in
131
146
  # the classes configuration.
132
147
  #
133
- # @param [Symbol] method_name This should be any one of [:debug, :info, :warn, :error, :fatal].
148
+ # @param [Symbol] log_level This should be any one of [:debug, :info, :warn, :error, :fatal].
134
149
  # @yield No value is passed to the block.
135
150
  # @yieldreturn [String] The message to log.
136
151
  def direct_log(log_level, &blocK)
data/lib/ztk/benchmark.rb CHANGED
@@ -26,13 +26,45 @@ module ZTK
26
26
  # @author Zachary Patten <zachary@jovelabs.net>
27
27
  class BenchmarkError < Error; end
28
28
 
29
- # Benchmark Class
29
+ # ZTK Benchmark Class
30
+ #
31
+ # This class contains a benchmarking tool which doubles to supply indications
32
+ # of activity to the console user during long running tasks.
33
+ #
34
+ # It can be run strictly for benchmarking (the default) or if supplied with
35
+ # the appropriate options it will display output to the user while
36
+ # benchmarking the supplied block.
30
37
  #
31
38
  # @author Zachary Patten <zachary@jovelabs.net>
32
39
  class Benchmark
33
40
 
34
41
  class << self
35
42
 
43
+ # Benchmark the supplied block.
44
+ #
45
+ # If *message* and *mark* options are used, then the *message* text will
46
+ # be displayed to the user. The the supplied *block* is yielded inside
47
+ # a *ZTK::Spinner.spin* call. This will provide the spinning cursor while
48
+ # the block executes. It is advisable to not have output sent to the
49
+ # console during this period.
50
+ #
51
+ # Once the block finishes executing, the *mark* text is displayed with
52
+ # the benchmark supplied to it as a sprintf option. One could use "%0.4f"
53
+ # in a *String* for example to get the benchmark time embedded in it
54
+ #
55
+ # @see Kernel#sprintf
56
+ #
57
+ # @param [Hash] options Configuration options hash.
58
+ # @option options [String] :message The *String* to be displayed to the
59
+ # user before the block is yielded.
60
+ # @option options [String] :mark The *String* to be displayed to the user
61
+ # after the block is yielded. This *String* should have an *sprintf*
62
+ # floating point macro in it if the benchmark is desired to be embedded
63
+ # in the given *String*.
64
+ #
65
+ # @yield Block should execute the tasks to be benchmarked.
66
+ # @yieldreturn [Object] The return value of the block is ignored.
67
+ # @return [Float] The benchmark time.
36
68
  def bench(options={}, &block)
37
69
  options = Base.build_config(options)
38
70
  options.logger.debug { "options=#{options.send(:table).inspect}" }
data/lib/ztk/command.rb CHANGED
@@ -17,7 +17,6 @@
17
17
  # limitations under the License.
18
18
  #
19
19
  ################################################################################
20
-
21
20
  require "ostruct"
22
21
  require "timeout"
23
22
 
@@ -50,11 +49,6 @@ module ZTK
50
49
  config.logger.debug { "config=#{config.send(:table).inspect}" }
51
50
  end
52
51
 
53
- def inspect
54
- @hostname ||= %x(hostname -f).chomp
55
- "#{ENV['USER']}@#{@hostname}"
56
- end
57
-
58
52
  # Executes a local command.
59
53
  #
60
54
  # @param [String] command The command to execute.
@@ -69,20 +63,17 @@ module ZTK
69
63
  # cmd = ZTK::Command.new
70
64
  # puts cmd.exec("hostname -f").inspect
71
65
  def exec(command, options={})
72
-
73
- def log_header(tag)
74
- count = 8
75
- sep = ("=" * count)
76
- header = [sep, "[ #{tag} ]", sep, "[ #{self.inspect} ]", sep, "[ #{tag} ]", sep].join
77
- "#{header}\n"
78
- end
79
-
80
66
  options = OpenStruct.new({ :exit_code => 0, :silence => false }.merge(options))
81
67
 
82
68
  config.logger.debug { "config=#{config.send(:table).inspect}" }
83
69
  config.logger.debug { "options=#{options.send(:table).inspect}" }
84
70
  config.logger.info { "command(#{command.inspect})" }
85
71
 
72
+ if config.replace_current_process
73
+ config.logger.fatal { "REPLACING CURRENT PROCESS - GOODBYE!" }
74
+ Kernel.exec(command)
75
+ end
76
+
86
77
  output = ""
87
78
  exit_code = -1
88
79
  stdout_header = false
@@ -169,14 +160,33 @@ module ZTK
169
160
  OpenStruct.new(:output => output, :exit_code => exit_code)
170
161
  end
171
162
 
163
+ # Not Supported
164
+ # @raise [CommandError] Not Supported
172
165
  def upload(*args)
173
166
  log_and_raise(CommandError, "Not Supported")
174
167
  end
175
168
 
169
+ # Not Supported
170
+ # @raise [CommandError] Not Supported
176
171
  def download(*args)
177
172
  log_and_raise(CommandError, "Not Supported")
178
173
  end
179
174
 
175
+
176
+ private
177
+
178
+ def tag
179
+ @hostname ||= %x(hostname -f).chomp
180
+ "#{ENV['USER']}@#{@hostname}"
181
+ end
182
+
183
+ def log_header(what)
184
+ count = 8
185
+ sep = ("=" * count)
186
+ header = [sep, "[ #{what} ]", sep, "[ #{tag} ]", sep, "[ #{what} ]", sep].join
187
+ "#{header}\n"
188
+ end
189
+
180
190
  end
181
191
 
182
192
  end
data/lib/ztk/config.rb CHANGED
@@ -17,7 +17,6 @@
17
17
  # limitations under the License.
18
18
  #
19
19
  ################################################################################
20
-
21
20
  require 'ostruct'
22
21
 
23
22
  module ZTK
@@ -0,0 +1,76 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
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
+
21
+ # @author Zachary Patten <zachary@jovelabs.net>
22
+ module ZTK::DSL
23
+
24
+ class Base
25
+ include(ZTK::DSL::Core)
26
+
27
+ def self.inherited(base)
28
+ puts("inherited(#{base})")
29
+ base.send(:extend, ZTK::DSL::Base::ClassMethods)
30
+ base.instance_eval do
31
+ attribute :id
32
+ end
33
+ end
34
+
35
+ def self.included(base)
36
+ puts("included(#{base})")
37
+ end
38
+
39
+ def self.extended(base)
40
+ puts("extended(#{base})")
41
+ end
42
+
43
+ def initialize(&block)
44
+ self.id = self.class.id
45
+ self.class.dataset << self
46
+ block_given? and ((block.arity < 1) ? instance_eval(&block) : block.call(self))
47
+
48
+ primary_key_count = self.class.dataset.count do |d|
49
+ puts("d.id == #{d.id.inspect} / self.id == #{self.id.inspect}")
50
+ d.id == self.id
51
+ end
52
+ puts("primary_key_count == #{primary_key_count}")
53
+ raise StandardError, "Primary key '#{self.id}' already exists!" if (primary_key_count > 1)
54
+ end
55
+
56
+ def inspect
57
+ details = Array.new
58
+ details << "attributes=#{attributes.inspect}" if attributes.count > 0
59
+ details << "has_many_references=#{@has_many_references.count}" if @has_many_references
60
+ details << "belongs_to_references=#{@belongs_to_references.count}" if @belongs_to_references
61
+ "#<#{self.class.to_s} id=#{self.id.inspect} #{details.join(', ')}>"
62
+ end
63
+
64
+ module ClassMethods
65
+
66
+ def inspect
67
+ details = Array.new
68
+ details << "count=#{self.all.count}" if self.all.count > 0
69
+ "#<#{self.class.to_s}:#{self.id} #{details.join(', ')}>"
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,49 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
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
+
21
+ module ZTK::DSL::Core::Actions
22
+ module Find
23
+
24
+ def self.included(base)
25
+ base.class_eval do
26
+ base.send(:extend, ZTK::DSL::Core::Actions::Find::ClassMethods)
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+
32
+ def all
33
+ dataset
34
+ end
35
+
36
+ def find(*args)
37
+ logger.debug { "*args(#{args.inspect})" }
38
+ ids = [args].flatten
39
+ all.select{ |data| ids.include?(data.id) }
40
+ end
41
+
42
+ def count
43
+ all.count
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
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
+
21
+ module ZTK::DSL::Core::Actions
22
+ module Timestamps
23
+
24
+ def self.included(base)
25
+ base.class_eval do
26
+ base.send(:extend, ZTK::DSL::Core::Actions::Timestamps::ClassMethods)
27
+ end
28
+ base.instance_eval do
29
+ attribute :created_at
30
+ attribute :updated_at
31
+ end
32
+ end
33
+
34
+ module ClassMethods
35
+
36
+ def updated_at_timestamp
37
+ self.updated_at = Time.now
38
+ end
39
+
40
+ def created_at_timestamp
41
+ self.created_at ||= Time.now
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
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
+
21
+ module ZTK::DSL::Core
22
+ module Actions
23
+ autoload :Find, "ztk/dsl/core/actions/find"
24
+ autoload :Timestamps, "ztk/dsl/core/actions/timestamps"
25
+
26
+ def self.included(base)
27
+ base.class_eval do
28
+ base.send(:include, ZTK::DSL::Core::Actions::Find)
29
+ base.send(:include, ZTK::DSL::Core::Actions::Timestamps)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
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
+
21
+ module ZTK::DSL::Core
22
+ module Attributes
23
+
24
+ def self.included(base)
25
+ base.class_eval do
26
+ base.send(:extend, ZTK::DSL::Core::Attributes::ClassMethods)
27
+ end
28
+ end
29
+
30
+ def attributes
31
+ @attributes ||= {}
32
+ end
33
+
34
+ module ClassMethods
35
+
36
+ def attribute(key, options={})
37
+ send(:define_method, key) do |*args|
38
+ if args.count == 0
39
+ attributes[key]
40
+ else
41
+ send("#{key}=", *args)
42
+ end
43
+ end
44
+
45
+ send(:define_method, "#{key}=") do |value|
46
+ attributes[key] = value
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,66 @@
1
+ ################################################################################
2
+ #
3
+ # Author: Zachary Patten <zachary@jovelabs.net>
4
+ # Copyright: Copyright (c) Jove Labs
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
+
21
+ module ZTK::DSL::Core
22
+ module Dataset
23
+
24
+ def self.included(base)
25
+ base.class_eval do
26
+ base.send(:extend, ZTK::DSL::Core::Dataset::ClassMethods)
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+
32
+ def dataset
33
+ klass = self.to_s.underscore.to_sym
34
+ @@dataset ||= {}
35
+ if @@dataset.key?(klass)
36
+ @@dataset[klass]
37
+ else
38
+ @@dataset[klass] ||= []
39
+ end
40
+ end
41
+
42
+ def purge
43
+ @@dataset = nil
44
+ end
45
+
46
+ def id
47
+ @@id ||= 0
48
+ (@@id += 1)
49
+ end
50
+
51
+ # def foreign_keys(target)
52
+ # puts("==> foreign_keys(#{target.inspect})")
53
+
54
+ # target = singularize(underscore(target).to_sym)
55
+ # source = singularize(underscore(self).to_sym)
56
+
57
+ # splat = [source, target].sort
58
+
59
+ # key = [ splat[0], "references", splat[1] ].join(":")
60
+ # puts("key=#{key}")
61
+ # end
62
+
63
+ end
64
+
65
+ end
66
+ end