ratch 1.0.0 → 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/MANIFEST +21 -4
- data/NEWS +8 -3
- data/VERSION +1 -0
- data/doc/log/basic_stats/index.html +39 -0
- data/doc/log/notes.xml +18 -0
- data/doc/log/stats.log +14 -0
- data/doc/log/syntax.log +0 -0
- data/doc/log/testunit.log +156 -0
- data/lib/ratch/commandline.rb +16 -0
- data/lib/ratch/core_ext/string.rb +1 -3
- data/lib/ratch/core_ext/to_console.rb +1 -1
- data/lib/ratch/dsl.rb +224 -301
- data/lib/ratch/emailer.rb +251 -0
- data/lib/ratch/io.rb +14 -14
- data/lib/ratch/plugin.rb +18 -8
- data/lib/ratch/script.rb +0 -38
- data/man/ratch.1 +28 -0
- data/meta/abstract +4 -0
- data/meta/author +1 -0
- data/meta/contact +1 -0
- data/meta/homepage +1 -0
- data/meta/name +1 -0
- data/meta/requires +4 -0
- data/meta/summary +1 -0
- metadata +47 -12
- data/METADATA +0 -14
- data/lib/ratch/core_ext/filetest.rb +0 -52
- data/lib/ratch/pathglob.rb +0 -73
- data/lib/ratch/runmode.rb +0 -69
@@ -0,0 +1,251 @@
|
|
1
|
+
begin
|
2
|
+
require 'facets/net/smtp_tls'
|
3
|
+
rescue LoadError
|
4
|
+
require 'net/smtp'
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
module Ratch
|
9
|
+
|
10
|
+
# Emailer class makes it easy send out an email.
|
11
|
+
#
|
12
|
+
# Settings:
|
13
|
+
#
|
14
|
+
# subject Subject of email message.
|
15
|
+
# from Message FROM address [email].
|
16
|
+
# to Email address to send announcemnt.
|
17
|
+
# server Email server to route message.
|
18
|
+
# port Email server's port.
|
19
|
+
# port_secure Email server's port.
|
20
|
+
# domain Email server's domain name.
|
21
|
+
# account Email account name if needed.
|
22
|
+
# password Password for login..
|
23
|
+
# login Login type: plain, cram_md5 or login [plain].
|
24
|
+
# secure Uses TLS security, true or false? [false]
|
25
|
+
# message Mesage to send -or-
|
26
|
+
# file File that contains message.
|
27
|
+
#
|
28
|
+
class Emailer
|
29
|
+
|
30
|
+
class << self
|
31
|
+
# Used for caching password between usages.
|
32
|
+
attr_accessor :password
|
33
|
+
|
34
|
+
#
|
35
|
+
def environment_options
|
36
|
+
options = {}
|
37
|
+
options[:server] = ENV['EMAIL_SERVER']
|
38
|
+
options[:from] = ENV['EMAIL_FROM']
|
39
|
+
options[:account] = ENV['EMAIL_ACCOUNT'] || ENV['EMAIL_FROM']
|
40
|
+
options[:password] = ENV['EMAIL_PASSWORD']
|
41
|
+
options[:port] = ENV['EMAIL_PORT']
|
42
|
+
options[:domain] = ENV['EMAIL_DOMAIN']
|
43
|
+
options[:login] = ENV['EMAIL_LOGIN']
|
44
|
+
options[:secure] = ENV['EMAIL_SECURE']
|
45
|
+
options
|
46
|
+
end
|
47
|
+
|
48
|
+
def new_with_environment(options={})
|
49
|
+
environment_options.merge(options.rekey)
|
50
|
+
new(options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_accessor :server
|
55
|
+
attr_accessor :port
|
56
|
+
attr_accessor :account
|
57
|
+
attr_accessor :passwd
|
58
|
+
attr_accessor :login
|
59
|
+
attr_accessor :secure
|
60
|
+
attr_accessor :domain
|
61
|
+
attr_accessor :from
|
62
|
+
attr_accessor :mailto
|
63
|
+
attr_accessor :subject
|
64
|
+
attr_accessor :message
|
65
|
+
|
66
|
+
#
|
67
|
+
|
68
|
+
#
|
69
|
+
def initialize(options={})
|
70
|
+
options = options.rekey
|
71
|
+
|
72
|
+
if not options[:server]
|
73
|
+
options = self.class.environment_options.merge(options)
|
74
|
+
end
|
75
|
+
|
76
|
+
@mailto = options[:to] || options[:mailto]
|
77
|
+
|
78
|
+
@from = options[:from]
|
79
|
+
@message = options[:message]
|
80
|
+
@subject = options[:subject]
|
81
|
+
@server = options[:server]
|
82
|
+
@account = options[:account]
|
83
|
+
@passwd = options[:password]
|
84
|
+
@login = options[:login]
|
85
|
+
@secure = options[:secure] #.to_b
|
86
|
+
@domain = options[:domain]
|
87
|
+
@port = options[:port]
|
88
|
+
|
89
|
+
@port ||= secure ? 465 : 25
|
90
|
+
@port = @port.to_i
|
91
|
+
|
92
|
+
@account ||= @from
|
93
|
+
|
94
|
+
@login ||= :plain
|
95
|
+
@login = @login.to_sym
|
96
|
+
|
97
|
+
@passwd ||= self.class.password
|
98
|
+
|
99
|
+
@domain ||= @server
|
100
|
+
|
101
|
+
# save the password for later use
|
102
|
+
self.class.password = @passwd
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
|
107
|
+
def email(options={})
|
108
|
+
options.rekey
|
109
|
+
|
110
|
+
message = options[:message] || self.message
|
111
|
+
subject = options[:subject] || self.subject
|
112
|
+
from = options[:from] || self.from
|
113
|
+
mailto = options[:mailto] || options[:to] || self.mailto
|
114
|
+
|
115
|
+
raise ArgumentError, "missing email field -- server" unless server
|
116
|
+
raise ArgumentError, "missing email field -- account" unless account
|
117
|
+
|
118
|
+
raise ArgumentError, "missing email field -- from" unless from
|
119
|
+
raise ArgumentError, "missing email field -- mailto" unless mailto
|
120
|
+
raise ArgumentError, "missing email field -- subject" unless subject
|
121
|
+
|
122
|
+
passwd ||= password("#{account} password:")
|
123
|
+
|
124
|
+
mailto = [mailto].flatten.compact
|
125
|
+
|
126
|
+
msg = ""
|
127
|
+
msg << "From: #{from}\n"
|
128
|
+
msg << "To: #{mailto.join(';')}\n"
|
129
|
+
msg << "Subject: #{subject}\n"
|
130
|
+
msg << ""
|
131
|
+
msg << message
|
132
|
+
|
133
|
+
#p server, port, domain, account, passwd, login, secure if verbose?
|
134
|
+
|
135
|
+
begin
|
136
|
+
if Net::SMTP.respond_to?(:enable_tls) && secure
|
137
|
+
Net::SMTP.enable_tls
|
138
|
+
Net::SMTP.start(server, port, domain, account, passwd, login, secure) do |smtp|
|
139
|
+
smtp.send_message(msg, from, mailto)
|
140
|
+
end
|
141
|
+
else
|
142
|
+
Net::SMTP.start(server, port, domain, account, passwd, login) do |smtp|
|
143
|
+
smtp.send_message(msg, from, mailto)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
return mailto
|
147
|
+
rescue Exception => e
|
148
|
+
return e
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Ask for a password.
|
153
|
+
#
|
154
|
+
# FIXME: Does not hide password.
|
155
|
+
|
156
|
+
def password(msg=nil)
|
157
|
+
msg ||= "Enter Password: "
|
158
|
+
inp = ''
|
159
|
+
|
160
|
+
$stdout << msg
|
161
|
+
|
162
|
+
inp = STDIN.gets.chomp
|
163
|
+
|
164
|
+
#begin
|
165
|
+
# system "stty -echo"
|
166
|
+
# inp = gets.chomp
|
167
|
+
#ensure
|
168
|
+
# system "stty echo"
|
169
|
+
#end
|
170
|
+
|
171
|
+
return inp
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
=begin
|
181
|
+
# Email function to easily send out an email.
|
182
|
+
#
|
183
|
+
# Settings:
|
184
|
+
#
|
185
|
+
# subject Subject of email message.
|
186
|
+
# from Message FROM address [email].
|
187
|
+
# to Email address to send announcemnt.
|
188
|
+
# server Email server to route message.
|
189
|
+
# port Email server's port.
|
190
|
+
# domain Email server's domain name.
|
191
|
+
# account Email account name if needed.
|
192
|
+
# password Password for login..
|
193
|
+
# login Login type: plain, cram_md5 or login [plain].
|
194
|
+
# secure Uses TLS security, true or false? [false]
|
195
|
+
# message Mesage to send -or-
|
196
|
+
# file File that contains message.
|
197
|
+
#
|
198
|
+
def email(message, settings)
|
199
|
+
settings ||= {}
|
200
|
+
settings.rekey!
|
201
|
+
|
202
|
+
server = settings[:server]
|
203
|
+
account = settings[:account] || ENV['EMAIL_ACCOUNT']
|
204
|
+
passwd = settings[:password] || ENV['EMAIL_PASSWORD']
|
205
|
+
login = settings[:login].to_sym
|
206
|
+
subject = settings[:subject]
|
207
|
+
mail_to = settings[:to] || settings[:mail_to]
|
208
|
+
mail_from = settings[:from] || settings[:mail_from]
|
209
|
+
secure = settings[:secure]
|
210
|
+
domain = settings[:domain] || server
|
211
|
+
|
212
|
+
port ||= (secure ? 465 : 25)
|
213
|
+
account ||= mail_from
|
214
|
+
login ||= :plain
|
215
|
+
|
216
|
+
#mail_to = nil if mail_to.empty?
|
217
|
+
|
218
|
+
raise ArgumentError, "missing email field -- server" unless server
|
219
|
+
raise ArgumentError, "missing email field -- account" unless account
|
220
|
+
raise ArgumentError, "missing email field -- subject" unless subject
|
221
|
+
raise ArgumentError, "missing email field -- to" unless mail_to
|
222
|
+
raise ArgumentError, "missing email field -- from" unless mail_from
|
223
|
+
|
224
|
+
passwd ||= password(account)
|
225
|
+
|
226
|
+
mail_to = [mail_to].flatten.compact
|
227
|
+
|
228
|
+
msg = ""
|
229
|
+
msg << "From: #{mail_from}\n"
|
230
|
+
msg << "To: #{mail_to.join(';')}\n"
|
231
|
+
msg << "Subject: #{subject}\n"
|
232
|
+
msg << ""
|
233
|
+
msg << message
|
234
|
+
|
235
|
+
begin
|
236
|
+
Net::SMTP.enable_tls if Net::SMTP.respond_to?(:enable_tls) and secure
|
237
|
+
Net::SMTP.start(server, port, domain, account, passwd, login) do |s|
|
238
|
+
s.send_message( msg, mail_from, mail_to )
|
239
|
+
end
|
240
|
+
puts "Email sent successfully to #{mail_to.join(';')}."
|
241
|
+
return true
|
242
|
+
rescue => e
|
243
|
+
if trace?
|
244
|
+
raise e
|
245
|
+
else
|
246
|
+
abort "Email delivery failed."
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
=end
|
251
|
+
|
data/lib/ratch/io.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'clio/consoleutils'
|
2
|
+
require 'clio/ansicode'
|
2
3
|
|
3
4
|
module Ratch
|
4
5
|
|
@@ -10,26 +11,25 @@ module Ratch
|
|
10
11
|
class IO
|
11
12
|
|
12
13
|
#
|
13
|
-
attr :
|
14
|
+
attr :commandline
|
14
15
|
|
15
16
|
#
|
16
|
-
def initialize(
|
17
|
-
@
|
17
|
+
def initialize(commandline)
|
18
|
+
@commandline = commandline
|
18
19
|
end
|
19
20
|
|
20
|
-
def force?
|
21
|
-
def quiet?
|
22
|
-
def trace?
|
23
|
-
def debug?
|
24
|
-
def
|
25
|
-
def noharm? ; runmode.noharm? ; end
|
21
|
+
def force? ; commandline.force? ; end
|
22
|
+
def quiet? ; commandline.quiet? ; end
|
23
|
+
def trace? ; commandline.trace? ; end
|
24
|
+
def debug? ; commandline.debug? ; end
|
25
|
+
def pretend? ; commandline.pretend? ; end
|
26
26
|
|
27
27
|
# Internal status report.
|
28
28
|
#
|
29
29
|
# Only output if dryrun or trace mode.
|
30
30
|
#
|
31
31
|
def status(message)
|
32
|
-
if
|
32
|
+
if pretend? or trace?
|
33
33
|
puts message
|
34
34
|
end
|
35
35
|
end
|
@@ -72,7 +72,7 @@ module Ratch
|
|
72
72
|
#
|
73
73
|
#
|
74
74
|
def printline(left, right='', options={})
|
75
|
-
return if
|
75
|
+
return if quiet?
|
76
76
|
|
77
77
|
separator = options[:seperator] || options[:sep] || ' '
|
78
78
|
padding = options[:padding] || options[:pad] || 0
|
@@ -101,13 +101,13 @@ module Ratch
|
|
101
101
|
if PLATFORM =~ /win/
|
102
102
|
text.to_s
|
103
103
|
else
|
104
|
-
ANSICode.send(text.color){ text.to_s }
|
104
|
+
Clio::ANSICode.send(text.color){ text.to_s }
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
#
|
109
109
|
def screen_width
|
110
|
-
ConsoleUtils.screen_width
|
110
|
+
Clio::ConsoleUtils.screen_width
|
111
111
|
end
|
112
112
|
|
113
113
|
end
|
data/lib/ratch/plugin.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Ratch
|
2
2
|
|
3
|
-
# =
|
3
|
+
# = Plugin
|
4
4
|
#
|
5
5
|
# A Plugin is essentially a delegated Service class..
|
6
6
|
#
|
@@ -12,22 +12,25 @@ module Ratch
|
|
12
12
|
# which allows them to call on the context easily.
|
13
13
|
# However this means plugins cannot be used independent
|
14
14
|
# of a batch context, and changes in the batch context
|
15
|
-
# can cause effects in
|
15
|
+
# can cause effects in plugin behvior that can be harder
|
16
16
|
# to track down and fix if a bug arises.
|
17
17
|
#
|
18
18
|
# Unless the tight coupling of a plugin is required, use the
|
19
19
|
# loose coupling of a Service class instead.
|
20
|
-
|
20
|
+
#
|
21
|
+
# The context must be a subclass of Ratch::DSL.
|
22
|
+
#
|
21
23
|
class Plugin
|
22
24
|
|
23
25
|
# The batch context.
|
24
26
|
attr :context
|
25
27
|
|
26
|
-
alias_method :project, :context
|
27
|
-
|
28
28
|
private
|
29
29
|
|
30
|
-
#
|
30
|
+
# Sets the context and assigns options to setter attributes
|
31
|
+
# if they exist and values are not nil. That last point is
|
32
|
+
# important. You must use 'false' to purposely negate an option.
|
33
|
+
# +nil+ will instead allow any default setting to be used.
|
31
34
|
def initialize(context, options=nil)
|
32
35
|
@context = context
|
33
36
|
|
@@ -37,14 +40,21 @@ module Ratch
|
|
37
40
|
|
38
41
|
options ||= {}
|
39
42
|
options.each do |k, v|
|
40
|
-
send("#{k}=", v) if respond_to?("#{k}=")
|
43
|
+
send("#{k}=", v) if respond_to?("#{k}=") && !v.nil?
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
47
|
+
# When subclassing, put default instance variable settngs here.
|
48
|
+
# Eg.
|
49
|
+
#
|
50
|
+
# def initialize_defaults
|
51
|
+
# @gravy = true
|
52
|
+
# end
|
53
|
+
#
|
44
54
|
def initialize_defaults
|
45
55
|
end
|
46
56
|
|
47
|
-
# TODO:
|
57
|
+
# TODO: Allow this to be optional? How?
|
48
58
|
def method_missing(s, *a, &b)
|
49
59
|
@context.send(s, *a, &b)
|
50
60
|
end
|
data/lib/ratch/script.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'ratch/dsl'
|
2
|
-
#require 'annotatable'
|
3
2
|
|
4
3
|
module Ratch
|
5
4
|
|
@@ -10,43 +9,6 @@ module Ratch
|
|
10
9
|
# How rare.
|
11
10
|
#
|
12
11
|
class Script < DSL
|
13
|
-
#include Annotatable
|
14
|
-
|
15
|
-
#
|
16
|
-
#annotation :cmd
|
17
|
-
|
18
|
-
#
|
19
|
-
#annotation :opt
|
20
|
-
|
21
|
-
#
|
22
|
-
#def commands
|
23
|
-
# c = {}
|
24
|
-
# self.class.annotations.each do |n, a|
|
25
|
-
# if a.key?(:cmd)
|
26
|
-
# c[n] = a[:cmd]
|
27
|
-
# end
|
28
|
-
# end
|
29
|
-
# c
|
30
|
-
#end
|
31
|
-
|
32
|
-
#
|
33
|
-
#def initialize
|
34
|
-
# @noharm = %w{-n --noharm --dryrun --dry-run}.any?{ |a| ARGV.delete(a) }
|
35
|
-
# @verbose = %w{--verbose}.any?{|a| ARGV.delete(a) }
|
36
|
-
# @quiet = %w{--quiet}.any?{|a| ARGV.delete(a) }
|
37
|
-
# @force = %w{--force}.any?{|a| ARGV.delete(a) }
|
38
|
-
# @debug = %w{--debug}.any?{|a| ARGV.delete(a) }
|
39
|
-
# @trace = %w{--trace}.any?{|a| ARGV.delete(a) }
|
40
|
-
#
|
41
|
-
# super
|
42
|
-
#end
|
43
|
-
|
44
|
-
# @noharm ||= %w{noharm n dryrun dry-run}.any?{|a| commandline.options[a] }
|
45
|
-
# @verbose ||= %w{verbose}.any?{|a| commandline.options[a] }
|
46
|
-
# @force ||= %w{force}.any?{|a| commandline.options[a] }
|
47
|
-
# @debug ||= %w{debug}.any?{|a| commandline.options[a] }
|
48
|
-
# @trace ||= %w{trace}.any?{|a| commandline.options[a] }
|
49
|
-
|
50
12
|
end
|
51
13
|
|
52
14
|
end
|
data/man/ratch.1
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
.\" NAME
|
2
|
+
.\" ratch - ruby-based batch files
|
3
|
+
.\"
|
4
|
+
.\" SYNOPSIS
|
5
|
+
.\" reap [-n] [-h] [file]
|
6
|
+
.\"
|
7
|
+
.\" DESCRIPTION
|
8
|
+
.\" Ratch is batch file system using a Ruby=based DSL.
|
9
|
+
.\"
|
10
|
+
.\" OPTIONS
|
11
|
+
.\" -h help This option displays help.
|
12
|
+
.\" -n dryrun Dry-run/no-harm mode.
|
13
|
+
.\"
|
14
|
+
.\" ENVIRONMENT
|
15
|
+
.\" PAGER name of paging command, usually more(1), or less(1). If not set
|
16
|
+
.\" falls back to more(1).
|
17
|
+
.\"
|
18
|
+
.\" EXAMPLES
|
19
|
+
.\" Try this command to format this text itself:
|
20
|
+
.\"
|
21
|
+
.\" $ txt2man -h 2>&1 | txt2man -T
|
22
|
+
.\"
|
23
|
+
.\" SEE ALSO:
|
24
|
+
.\" ruby(1).
|
25
|
+
.\"
|
26
|
+
.\" AUTHOR:
|
27
|
+
.\" 7rans <transfire@gmail,com>
|
28
|
+
|