ratch 1.1.0 → 1.2.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/.ruby +99 -0
- data/COPYING +203 -21
- data/History.rdoc +35 -0
- data/License.txt +204 -0
- data/README.rdoc +113 -0
- data/Version +1 -0
- data/bin/ludo +16 -0
- data/bin/ratch +1 -8
- data/lib/ratch.rb +28 -0
- data/lib/ratch.yml +99 -0
- data/lib/ratch/batch.rb +500 -0
- data/lib/ratch/console.rb +199 -0
- data/lib/ratch/core_ext.rb +1 -4
- data/lib/ratch/core_ext/facets.rb +15 -1
- data/lib/ratch/core_ext/filetest.rb +29 -0
- data/lib/ratch/core_ext/{string.rb → to_actual_filename.rb} +0 -23
- data/lib/ratch/core_ext/to_console.rb +30 -12
- data/lib/ratch/core_ext/{object.rb → to_yamlfrag.rb} +1 -0
- data/lib/ratch/core_ext/unfold_paragraphs.rb +27 -0
- data/lib/ratch/file_list.rb +411 -0
- data/lib/ratch/script.rb +99 -5
- data/lib/ratch/script/help.rb +84 -0
- data/lib/ratch/shell.rb +783 -0
- data/lib/ratch/system.rb +15 -0
- data/lib/ratch/utils/cli.rb +49 -0
- data/lib/ratch/utils/config.rb +52 -0
- data/lib/ratch/{emailer.rb → utils/email.rb} +43 -6
- data/lib/ratch/utils/ftp.rb +134 -0
- data/lib/ratch/utils/pom.rb +22 -0
- data/lib/ratch/utils/rdoc.rb +48 -0
- data/lib/ratch/utils/tar.rb +88 -0
- data/lib/ratch/utils/xdg.rb +39 -0
- data/lib/ratch/utils/zlib.rb +54 -0
- data/spec/01_shell.rdoc +198 -0
- data/spec/02_script.rdoc +34 -0
- data/spec/03_batch.rdoc +71 -0
- data/spec/04_system.rdoc +3 -0
- data/spec/applique/array.rb +8 -0
- data/spec/applique/setup.rb +20 -0
- data/test/case_batch.rb +63 -0
- data/test/case_shell.rb +46 -0
- data/test/core_ext/case_pathname.rb +361 -0
- data/test/helper.rb +4 -0
- data/test/utils/case_cli.rb +6 -0
- data/test/utils/case_config.rb +12 -0
- data/test/utils/case_email.rb +10 -0
- data/test/utils/case_ftp.rb +6 -0
- data/test/utils/case_pom.rb +17 -0
- data/test/utils/case_rdoc.rb +23 -0
- data/test/utils/case_tar.rb +6 -0
- data/test/utils/case_zlib.rb +11 -0
- data/test/utils/fixtures/pom_sample/Profile +4 -0
- data/test/utils/fixtures/rdoc_sample/README.rdoc +4 -0
- data/test/utils/fixtures/rdoc_sample/lib/rdoc_sample/rdoc_sample.rb +9 -0
- metadata +139 -82
- data/HISTORY +0 -6
- data/MANIFEST +0 -53
- data/NEWS +0 -12
- data/README +0 -87
- data/VERSION +0 -1
- data/demo/tryme-task.ratch +0 -12
- data/demo/tryme1.ratch +0 -6
- data/doc/log/basic_stats/index.html +0 -39
- data/doc/log/notes.xml +0 -18
- data/doc/log/stats.log +0 -14
- data/doc/log/syntax.log +0 -0
- data/doc/log/testunit.log +0 -156
- data/lib/ratch/commandline.rb +0 -16
- data/lib/ratch/core_ext/pathname.rb +0 -38
- data/lib/ratch/dsl.rb +0 -420
- data/lib/ratch/index.rb +0 -4
- data/lib/ratch/io.rb +0 -116
- data/lib/ratch/plugin.rb +0 -65
- data/lib/ratch/service.rb +0 -33
- data/lib/ratch/task.rb +0 -249
- data/lib/ratch/task2.rb +0 -298
- data/meta/abstract +0 -4
- data/meta/author +0 -1
- data/meta/contact +0 -1
- data/meta/homepage +0 -1
- data/meta/name +0 -1
- data/meta/requires +0 -4
- data/meta/summary +0 -1
- data/test/README +0 -1
- data/test/test_helper.rb +0 -4
- data/test/test_task.rb +0 -46
data/lib/ratch/system.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# TODO: Build it!
|
4
|
+
#
|
5
|
+
# The System class provides a robust interface for interacting with
|
6
|
+
# system commands. It is essenatially a wrapper around popen3 or popen4.
|
7
|
+
#
|
8
|
+
# Having a separate class rather integrating this into Shell (as
|
9
|
+
# Ruby's standard Shell class does) provides a better SOC.
|
10
|
+
#
|
11
|
+
class System
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# TODO: How best to support CLI interface?
|
4
|
+
module CLI
|
5
|
+
|
6
|
+
#
|
7
|
+
def self.included(base)
|
8
|
+
require 'facets/argvector'
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
def self.extended(base)
|
13
|
+
require 'facets/argvector'
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
def initialize(*args)
|
18
|
+
argv = ArgVector.new(ARGV)
|
19
|
+
|
20
|
+
@arguments, parameters = *argv.parameters
|
21
|
+
|
22
|
+
args << {} unless Hash === args.last
|
23
|
+
|
24
|
+
opts = args.last
|
25
|
+
|
26
|
+
opts.merge!(parameters)
|
27
|
+
|
28
|
+
super(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
def arguments
|
33
|
+
@arguments
|
34
|
+
end
|
35
|
+
|
36
|
+
# DEPRECATE!
|
37
|
+
#alias_method :commandline, :cli
|
38
|
+
|
39
|
+
# DEPRECATE!
|
40
|
+
#alias_method :command, :cli
|
41
|
+
|
42
|
+
#
|
43
|
+
#def commandline
|
44
|
+
# #@commandline ||= ArgVector.new(ARGV)
|
45
|
+
# @commandline
|
46
|
+
#end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# Utility extensions for working with configuration files.
|
4
|
+
#--
|
5
|
+
# TODO: Perhaps utilize confectionary gem in future?
|
6
|
+
#++
|
7
|
+
module ConfigUtils
|
8
|
+
|
9
|
+
#
|
10
|
+
def self.included(base)
|
11
|
+
require 'yaml'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.extended(base)
|
15
|
+
included(base)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Load configuration data from a file. Results are cached and an empty
|
19
|
+
# Hash is returned if the file is not found.
|
20
|
+
#
|
21
|
+
# Since they are YAML files, they can optionally end with '.yaml' or '.yml'.
|
22
|
+
def configuration(file)
|
23
|
+
@configuration ||= {}
|
24
|
+
@configuration[file] ||= (
|
25
|
+
begin
|
26
|
+
configuration!(file)
|
27
|
+
rescue LoadError
|
28
|
+
Hash.new{ |h,k| h[k] = {} }
|
29
|
+
end
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Load configuration data from a file. The "bang" version will raise an error
|
34
|
+
# if file is not found. It also does not cache the results.
|
35
|
+
#
|
36
|
+
# Since they are YAML files, they can optionally end with '.yaml' or '.yml'.
|
37
|
+
def configuration!(file)
|
38
|
+
@configuration ||= {}
|
39
|
+
patt = file + "{.yml,.yaml,}"
|
40
|
+
path = Dir.glob(patt, File::FNM_CASEFOLD).find{ |f| File.file?(f) }
|
41
|
+
if path
|
42
|
+
# The || {} is in case the file is empty.
|
43
|
+
data = YAML::load(File.open(path)) || {}
|
44
|
+
@configuration[file] = data
|
45
|
+
else
|
46
|
+
raise LoadError, "Missing file -- #{path}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -1,11 +1,37 @@
|
|
1
|
-
|
2
|
-
require 'facets/net/smtp_tls'
|
3
|
-
rescue LoadError
|
4
|
-
require 'net/smtp'
|
5
|
-
end
|
1
|
+
module Ratch
|
6
2
|
|
3
|
+
# The Mail utility module provides an easy to use +email+ method.
|
4
|
+
module EmailUtils
|
7
5
|
|
8
|
-
|
6
|
+
# Email function to easily send out an email.
|
7
|
+
#
|
8
|
+
# Settings:
|
9
|
+
#
|
10
|
+
# subject Subject of email message.
|
11
|
+
# from Message FROM address [email].
|
12
|
+
# to Email address to send announcemnt.
|
13
|
+
# server Email server to route message.
|
14
|
+
# port Email server's port.
|
15
|
+
# domain Email server's domain name.
|
16
|
+
# account Email account name if needed.
|
17
|
+
# password Password for login..
|
18
|
+
# login Login type: plain, cram_md5 or login [plain].
|
19
|
+
# secure Uses TLS security, true or false? [false]
|
20
|
+
# message Mesage to send -or-
|
21
|
+
# file File that contains message.
|
22
|
+
#
|
23
|
+
def email(options)
|
24
|
+
options[:file] = localize(options[:file]) if options[:file]
|
25
|
+
emailer = Emailer.new(options.rekey)
|
26
|
+
success = emailer.email
|
27
|
+
if Exception === success
|
28
|
+
puts "Email failed: #{success.message}."
|
29
|
+
else
|
30
|
+
puts "Email sent successfully to #{success.join(';')}."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
9
35
|
|
10
36
|
# Emailer class makes it easy send out an email.
|
11
37
|
#
|
@@ -67,6 +93,8 @@ module Ratch
|
|
67
93
|
|
68
94
|
#
|
69
95
|
def initialize(options={})
|
96
|
+
require_smtp
|
97
|
+
|
70
98
|
options = options.rekey
|
71
99
|
|
72
100
|
if not options[:server]
|
@@ -171,6 +199,15 @@ module Ratch
|
|
171
199
|
return inp
|
172
200
|
end
|
173
201
|
|
202
|
+
#
|
203
|
+
def require_smtp
|
204
|
+
begin
|
205
|
+
require 'facets/net/smtp_tls'
|
206
|
+
rescue LoadError
|
207
|
+
require 'net/smtp'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
174
211
|
end
|
175
212
|
|
176
213
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# FIXME: This module needs major work. Methods #ftp_files and
|
4
|
+
# ftp_stage_transfer need to either be generalized and moved to
|
5
|
+
# Shell or Script, or removed.
|
6
|
+
#
|
7
|
+
module FTPUtils
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
require 'net/ftp'
|
11
|
+
require 'net/sftp'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.extended(base)
|
15
|
+
included(base)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Use ftp to upload files.
|
19
|
+
#
|
20
|
+
def ftp(keys)
|
21
|
+
keys = upload_parameters(keys)
|
22
|
+
|
23
|
+
# set transfer rules
|
24
|
+
if keys.stage
|
25
|
+
trans = ftp_stage_transfer(keys.stage)
|
26
|
+
else
|
27
|
+
ftp_files(keys.dir, keys.copy).each do |from|
|
28
|
+
trans << [from,from]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# append location of publication dir to from
|
33
|
+
dir = keys.dir
|
34
|
+
trans.collect!{ |from,to| [File.join(dir,from), to] }
|
35
|
+
|
36
|
+
if keys.dryrun
|
37
|
+
puts "ftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
38
|
+
keys.trans.each do |f, t|
|
39
|
+
puts "ftp put #{f} #{t}"
|
40
|
+
end
|
41
|
+
else
|
42
|
+
Net::FTP.open(keys.host) do |ftp|
|
43
|
+
ftp.login(keys.user) #password?
|
44
|
+
ftp.chdir(keys.root)
|
45
|
+
keys.trans.each do |f, t|
|
46
|
+
puts "ftp #{f} #{t}" unless keys.quiet
|
47
|
+
ftp.putbinaryfile( f, t, 1024 )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Use sftp to upload files.
|
54
|
+
#
|
55
|
+
def sftp( keys )
|
56
|
+
keys = upload_parameters(keys)
|
57
|
+
|
58
|
+
# set transfer rules
|
59
|
+
if keys.stage
|
60
|
+
trans = ftp_stage_transfer(keys.stage)
|
61
|
+
else
|
62
|
+
ftp_files(keys.dir, keys.copy).each do |from|
|
63
|
+
trans << [from,from]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# append location of publication dir to from
|
68
|
+
dir = keys.dir
|
69
|
+
trans.collect!{ |from,to| [File.join(dir,from), to] }
|
70
|
+
|
71
|
+
if keys.dryrun
|
72
|
+
puts "sftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
73
|
+
keys.trans.each do |f,t|
|
74
|
+
puts "sftp put #{f} #{t}"
|
75
|
+
end
|
76
|
+
else
|
77
|
+
Net::SFTP.start(keys.host, keys.user, keys.pass) do |sftp|
|
78
|
+
#sftp.login( user )
|
79
|
+
sftp.chdir(keys.root)
|
80
|
+
keys.trans.each do |f,t|
|
81
|
+
puts "sftp #{f} #{t}" unless keys.quiet
|
82
|
+
sftp.put_file(f,t) #, 1024 )
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Put together the list of files to copy.
|
89
|
+
def ftp_files( dir, copy )
|
90
|
+
Dir.chdir(dir) do
|
91
|
+
del, add = copy.partition{ |f| /^[-]/ =~ f }
|
92
|
+
|
93
|
+
# remove - and + prefixes
|
94
|
+
del.collect!{ |f| f.sub(/^[-]/,'') }
|
95
|
+
add.collect!{ |f| f.sub(/^[+]/,'') }
|
96
|
+
|
97
|
+
#del.concat(must_exclude)
|
98
|
+
|
99
|
+
ftp_files = []
|
100
|
+
add.each{ |g| files += Dir.glob(g) }
|
101
|
+
del.each{ |g| files -= Dir.glob(g) }
|
102
|
+
|
103
|
+
files.collect!{ |f| f.sub(/^\//,'') }
|
104
|
+
|
105
|
+
return files
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Combine three part stage list into a two part from->to list.
|
110
|
+
#
|
111
|
+
# Using the stage list of three space separated fields.
|
112
|
+
#
|
113
|
+
# fromdir file todir
|
114
|
+
#
|
115
|
+
# This is used to generate a from -> to list of the form:
|
116
|
+
#
|
117
|
+
# fromdir/file todir/file
|
118
|
+
#
|
119
|
+
def ftp_stage_transfer( list )
|
120
|
+
trans = []
|
121
|
+
list.each do |line|
|
122
|
+
trans << Shellwords.shellwords(line)
|
123
|
+
end
|
124
|
+
|
125
|
+
trans.collect! do |from, base, to|
|
126
|
+
file = File.join(from,base)
|
127
|
+
to = File.join(to,base)
|
128
|
+
[from, to]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# Methods for utilizing Ruby POM.
|
4
|
+
module POMUtils
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
require 'pom'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.extended(base)
|
11
|
+
included(base)
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
def project
|
16
|
+
@project ||= ::POM::Project.new
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# Provides a pure-Ruby method for generating RDocs.
|
4
|
+
module RDocUtils
|
5
|
+
|
6
|
+
DEFAULT_RDOC_OPTIONS = {
|
7
|
+
:quiet => true
|
8
|
+
}
|
9
|
+
|
10
|
+
# RDoc command.
|
11
|
+
#
|
12
|
+
# :call-seq:
|
13
|
+
# rdoc(file1, file2, ..., :opt1 => val1, ...)
|
14
|
+
#
|
15
|
+
def rdoc(*files)
|
16
|
+
require 'rdoc/rdoc'
|
17
|
+
|
18
|
+
options = Hash===files.last ? files.pop : {}
|
19
|
+
options.rekey!(&:to_s)
|
20
|
+
|
21
|
+
options['title'] ||= options.delete('T')
|
22
|
+
|
23
|
+
options['debug'] = options['debug'] #|| debug?
|
24
|
+
options['quiet'] = options['quiet'] #|| quiet?
|
25
|
+
options['verbose'] = options['verbose'] #|| verbose?
|
26
|
+
|
27
|
+
# apply pom (todo?)
|
28
|
+
#options['title'] ||= metadata.title
|
29
|
+
|
30
|
+
options = DEFAULT_RDOC_OPTIONS.merge(options)
|
31
|
+
|
32
|
+
locally do
|
33
|
+
rdoc = RDoc::RDoc.new
|
34
|
+
opts = options.to_argv + files
|
35
|
+
$stderr.puts("rdoc " + opts.join(' ')) if ($VERBOSE || $DEBUG)
|
36
|
+
disable_warnings do
|
37
|
+
rdoc.document(options.to_argv + files)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# TODO: Implement ri doc generator.
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'ratch/utils/zlib'
|
2
|
+
|
3
|
+
module Ratch
|
4
|
+
|
5
|
+
# Utility methods for working with tarballs archives.
|
6
|
+
#--
|
7
|
+
# TODO: Add compress support ?
|
8
|
+
# TODO: Add bzip support ?
|
9
|
+
#++
|
10
|
+
module TarUtils
|
11
|
+
|
12
|
+
# When included include GZipUtils too.
|
13
|
+
def self.included(base)
|
14
|
+
#require 'zlib'
|
15
|
+
include ZLibUtils
|
16
|
+
require 'archive/tar/minitar'
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
def self.extended(base)
|
21
|
+
included(base)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Tar
|
25
|
+
def tar(folder, file=nil, options={})
|
26
|
+
noop, verbose = *util_options(options)
|
27
|
+
file ||= File.basename(File.expand_path(folder)) + '.tar'
|
28
|
+
cmd = "tar -cf #{file} #{folder}"
|
29
|
+
puts cmd if verbose
|
30
|
+
unless noop
|
31
|
+
locally do
|
32
|
+
gzIO = File.open(file, 'wb')
|
33
|
+
Archive::Tar::Minitar.pack(folder, gzIO)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
path(file)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Untar
|
40
|
+
def untar(file, options={})
|
41
|
+
noop, verbose = *util_options(options)
|
42
|
+
#file ||= File.basename(File.expand_path(folder)) + '.tar'
|
43
|
+
cmd = "untar #{file}"
|
44
|
+
puts cmd if verbose
|
45
|
+
unless noop
|
46
|
+
locally do
|
47
|
+
gzIO = File.open(file, 'wb')
|
48
|
+
Archive::Tar::Minitar.unpack(gzIO)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
path(file)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Tar Gzip
|
55
|
+
def tar_gzip(folder, file=nil, options={})
|
56
|
+
noop, verbose = *util_options(options)
|
57
|
+
file ||= File.basename(File.expand_path(folder)) + '.tar.gz' # '.tgz' which ?
|
58
|
+
cmd = "tar --gzip -czf #{file} #{folder}"
|
59
|
+
puts cmd if verbose
|
60
|
+
unless noop
|
61
|
+
locally do #folder, file = localize(folder), localize(file)
|
62
|
+
gzIO = Zlib::GzipWriter.new(File.open(file, 'wb'))
|
63
|
+
Archive::Tar::Minitar.pack(folder, gzIO)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
path(file)
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :tar_z, :tar_gzip
|
70
|
+
|
71
|
+
# Untar Gzip
|
72
|
+
#
|
73
|
+
# FIXME: Write unified untar_gzip function.
|
74
|
+
def untar_gzip(file, options={})
|
75
|
+
untar(ungzip(file, options), options)
|
76
|
+
end
|
77
|
+
|
78
|
+
alias_method :untar_z, :untar_gzip
|
79
|
+
|
80
|
+
#def tgz(folder, file=nil, options={})
|
81
|
+
# file ||= File.basename(File.expand_path(folder)) + '.tgz'
|
82
|
+
# tar_gzip(folder, file, options)
|
83
|
+
#end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|