rbatch 1.4.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/CHANGELOG +25 -0
- data/LICENSE +0 -0
- data/README.ja.md +280 -0
- data/README.md +280 -0
- data/Rakefile +66 -0
- data/VERSION +1 -0
- data/doc/rdoc/CHANGELOG.html +160 -0
- data/doc/rdoc/LICENSE.html +94 -0
- data/doc/rdoc/RBatch.html +476 -0
- data/doc/rdoc/RBatch/Cmd.html +329 -0
- data/doc/rdoc/RBatch/CmdException.html +154 -0
- data/doc/rdoc/RBatch/CmdResult.html +492 -0
- data/doc/rdoc/RBatch/Log.html +739 -0
- data/doc/rdoc/created.rid +8 -0
- data/doc/rdoc/images/brick.png +0 -0
- data/doc/rdoc/images/brick_link.png +0 -0
- data/doc/rdoc/images/bug.png +0 -0
- data/doc/rdoc/images/bullet_black.png +0 -0
- data/doc/rdoc/images/bullet_toggle_minus.png +0 -0
- data/doc/rdoc/images/bullet_toggle_plus.png +0 -0
- data/doc/rdoc/images/date.png +0 -0
- data/doc/rdoc/images/find.png +0 -0
- data/doc/rdoc/images/loadingAnimation.gif +0 -0
- data/doc/rdoc/images/macFFBgHack.png +0 -0
- data/doc/rdoc/images/package.png +0 -0
- data/doc/rdoc/images/page_green.png +0 -0
- data/doc/rdoc/images/page_white_text.png +0 -0
- data/doc/rdoc/images/page_white_width.png +0 -0
- data/doc/rdoc/images/plugin.png +0 -0
- data/doc/rdoc/images/ruby.png +0 -0
- data/doc/rdoc/images/tag_green.png +0 -0
- data/doc/rdoc/images/wrench.png +0 -0
- data/doc/rdoc/images/wrench_orange.png +0 -0
- data/doc/rdoc/images/zoom.png +0 -0
- data/doc/rdoc/index.html +124 -0
- data/doc/rdoc/js/darkfish.js +116 -0
- data/doc/rdoc/js/jquery.js +32 -0
- data/doc/rdoc/js/quicksearch.js +114 -0
- data/doc/rdoc/js/thickbox-compressed.js +10 -0
- data/doc/rdoc/lib/rbatch/cmd_rb.html +56 -0
- data/doc/rdoc/lib/rbatch/config_rb.html +56 -0
- data/doc/rdoc/lib/rbatch/log_rb.html +58 -0
- data/doc/rdoc/lib/rbatch_rb.html +58 -0
- data/doc/rdoc/rdoc.css +706 -0
- data/lib/rbatch.rb +51 -0
- data/lib/rbatch/cmd.rb +118 -0
- data/lib/rbatch/config.rb +29 -0
- data/lib/rbatch/log.rb +205 -0
- data/sample/bin/file_batch_copy.rb +9 -0
- data/sample/bin/openldap_backup.rb +7 -0
- data/sample/bin/test.rb +12 -0
- data/sample/config/file_batch_copy.yaml +5 -0
- data/sample/config/openldap_backup.yaml +2 -0
- data/sample/config/rbatch.yaml +68 -0
- data/sample/log/empty +0 -0
- data/test/cases/test_cmd.rb +120 -0
- data/test/cases/test_config.rb +34 -0
- data/test/cases/test_log.rb +594 -0
- data/test/config/rbatch.yaml +0 -0
- data/test/mocks/PrintArgs.exe +0 -0
- data/test/mocks/win_cmd.exe +0 -0
- metadata +173 -0
data/lib/rbatch.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
module RBatch
|
4
|
+
@@program_name = $PROGRAM_NAME
|
5
|
+
module_function
|
6
|
+
def program_name=(f) ; @@program_name = f ; end
|
7
|
+
def program_name ; @@program_name ; end
|
8
|
+
def tmp_dir
|
9
|
+
case RUBY_PLATFORM
|
10
|
+
when /mswin|mingw/
|
11
|
+
return ENV["TEMP"]
|
12
|
+
when /cygwin|linux/
|
13
|
+
return "/tmp/"
|
14
|
+
else
|
15
|
+
raise "Unknown RUBY_PRATFORM : " + RUBY_PLATFORM
|
16
|
+
end
|
17
|
+
end
|
18
|
+
def common_config_path
|
19
|
+
File.join(File.dirname(RBatch.program_name),"..","config","rbatch.yaml")
|
20
|
+
end
|
21
|
+
def common_config
|
22
|
+
if File.exist?(RBatch.common_config_path)
|
23
|
+
yaml = YAML::load_file(RBatch.common_config_path)
|
24
|
+
if yaml
|
25
|
+
return yaml
|
26
|
+
else
|
27
|
+
# If file is emply , YAML::load_file is false
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
else
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rbatch/log'
|
37
|
+
require 'rbatch/config'
|
38
|
+
require 'rbatch/cmd'
|
39
|
+
|
40
|
+
# double run check
|
41
|
+
if ( RBatch::common_config != nil && RBatch::common_config["forbid_double_run"] )
|
42
|
+
if Dir.exists? RBatch::tmp_dir
|
43
|
+
Dir::foreach(RBatch::tmp_dir) do |f|
|
44
|
+
if (/rbatch_lock/ =~ f)
|
45
|
+
raise "Can not start RBatch. RBatch lock file exists (#{RBatch::tmp_dir}#{f})."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# make lockfile
|
50
|
+
Tempfile::new("rbatch_lock",RBatch::tmp_dir)
|
51
|
+
end
|
data/lib/rbatch/cmd.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module RBatch
|
5
|
+
|
6
|
+
# External command runcher.
|
7
|
+
#
|
8
|
+
# * Input cmd_params into Kernel#spawn.
|
9
|
+
# * Write command's stdout and stderr to tmp file.
|
10
|
+
# * If Platform is "mswin" or "mingw" , then temp directory is ENV["TEMP"]
|
11
|
+
# * If Platform is "linux" or "cygwin" , then temp directory is "/tmp/"
|
12
|
+
# * Return hash object including stdout, stderr, and exit status.
|
13
|
+
#
|
14
|
+
# ==== Sample 1
|
15
|
+
# require 'rbatch'
|
16
|
+
# cmd = RBatch::Cmd("ls")
|
17
|
+
# r = cmd.run
|
18
|
+
# p r.stdout
|
19
|
+
# => "fileA\nfileB\n"
|
20
|
+
#
|
21
|
+
# ==== Sample 2 ( Use option)
|
22
|
+
# cmd = RBatch::Cmd("ls", {:verbose => true})
|
23
|
+
# r = cmd.run
|
24
|
+
#
|
25
|
+
# ==== Sample 3 ( Use alias)
|
26
|
+
# require 'rbatch'
|
27
|
+
# r = RBatch::cmd("ls")
|
28
|
+
# p r.stdout
|
29
|
+
# => "fileA\nfileB\n"
|
30
|
+
#
|
31
|
+
class Cmd
|
32
|
+
@@def_opt = {
|
33
|
+
:raise => false
|
34
|
+
}
|
35
|
+
@cmd_str
|
36
|
+
@opt
|
37
|
+
|
38
|
+
# Cmd instance
|
39
|
+
#
|
40
|
+
# ==== Params
|
41
|
+
# +cmd_str+ = Command string. Such ad "ls -l"
|
42
|
+
# +opt+ = Option hash object. Hash keys is follows.
|
43
|
+
# - +:raise+ (Boolean) = If command exit status is not 0, raise exception. Default is false.
|
44
|
+
def initialize(cmd_str,opt = nil)
|
45
|
+
raise(CmdException,"Command string is nil") if cmd_str.nil?
|
46
|
+
@cmd_str = cmd_str
|
47
|
+
# parse option
|
48
|
+
@opt = @@def_opt.clone
|
49
|
+
@@def_opt.each_key do |key|
|
50
|
+
if opt != nil && opt[key] != nil
|
51
|
+
# use argument
|
52
|
+
@opt[key] = opt[key]
|
53
|
+
elsif RBatch.common_config != nil \
|
54
|
+
&& RBatch.common_config["cmd_" + key.to_s] != nil
|
55
|
+
# use config
|
56
|
+
@opt[key] = RBatch.common_config["cmd_" + key.to_s]
|
57
|
+
else
|
58
|
+
# use default
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Run command
|
64
|
+
#
|
65
|
+
# ==== Return
|
66
|
+
# instance of RBatch::CmdResult
|
67
|
+
def run()
|
68
|
+
stdout_file = Tempfile::new("rbatch_tmpout",RBatch::tmp_dir)
|
69
|
+
stderr_file = Tempfile::new("rbatch_tmperr",RBatch::tmp_dir)
|
70
|
+
pid = spawn(@cmd_str,:out => [stdout_file,"w"],:err => [stderr_file,"w"])
|
71
|
+
status = Process.waitpid2(pid)[1] >> 8
|
72
|
+
result = RBatch::CmdResult.new(stdout_file,stderr_file,status,@cmd_str)
|
73
|
+
if @opt[:raise] && status != 0
|
74
|
+
raise(CmdException,"Command exit status is not 0. result: " + result.to_s)
|
75
|
+
end
|
76
|
+
return result
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class CmdResult
|
81
|
+
@stdout_file
|
82
|
+
@stderr_file
|
83
|
+
@status
|
84
|
+
@cmd_str
|
85
|
+
def initialize(stdout_file, stderr_file, status, cmd_str)
|
86
|
+
@stdout_file = stdout_file
|
87
|
+
@stderr_file = stderr_file
|
88
|
+
@status = status
|
89
|
+
@cmd_str = cmd_str
|
90
|
+
end
|
91
|
+
def stdout_file ; @stdout_file ; end
|
92
|
+
def stderr_file ; @stderr_file ; end
|
93
|
+
def status ; @status ; end
|
94
|
+
def cmd_str ; @cmd_str ; end
|
95
|
+
def stdout
|
96
|
+
File.read(@stdout_file)
|
97
|
+
end
|
98
|
+
def stderr
|
99
|
+
File.read(@stderr_file)
|
100
|
+
end
|
101
|
+
def to_h
|
102
|
+
{:cmd_str => @cmd_str,:stdout => stdout, :stderr => stderr, :status => status}
|
103
|
+
end
|
104
|
+
def to_s
|
105
|
+
to_h.to_s
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class CmdException < Exception ; end
|
110
|
+
|
111
|
+
module_function
|
112
|
+
|
113
|
+
# shortcut of RBatch::Cmd
|
114
|
+
def cmd(cmd_str,opt = nil)
|
115
|
+
Cmd.new(cmd_str,opt).run
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module RBatch
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Read config file and return hash opject.
|
9
|
+
#
|
10
|
+
# Default config file path is "../config/(Program name).yaml"
|
11
|
+
# ==== Sample
|
12
|
+
# config : ./config/sample2.yaml
|
13
|
+
# key: value
|
14
|
+
# array:
|
15
|
+
# - item1
|
16
|
+
# - item2
|
17
|
+
# - item3
|
18
|
+
# script : ./bin/sample2.rb
|
19
|
+
# require 'rbatch'
|
20
|
+
# p RBatch::config
|
21
|
+
# => {"key" => "value", "array" => ["item1", "item2", "item3"]}
|
22
|
+
def config
|
23
|
+
file = Pathname(File.basename(RBatch.program_name)).sub_ext(".yaml").to_s
|
24
|
+
dir = File.join(File.join(File.dirname(RBatch.program_name),".."),"config")
|
25
|
+
return YAML::load_file(File.join(dir,file))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
data/lib/rbatch/log.rb
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module RBatch
|
6
|
+
#=== About RBatch::Log
|
7
|
+
#
|
8
|
+
#Use Auto Logging block, RBatch automatically write to logfile.
|
9
|
+
#
|
10
|
+
#Log file default location is "../log/YYYYMMDD_HHMMSS_${PROG_NAME}.log" .
|
11
|
+
#
|
12
|
+
#If exception occuerd, then RBatch write stack trace to logfile.
|
13
|
+
#
|
14
|
+
#=== Sample
|
15
|
+
#
|
16
|
+
#script : ./bin/sample1.rb
|
17
|
+
#
|
18
|
+
# require 'rbatch'
|
19
|
+
#
|
20
|
+
# RBatch::Log.new(){ |log| # Logging block
|
21
|
+
# log.info "info string"
|
22
|
+
# log.error "error string"
|
23
|
+
# raise "exception"
|
24
|
+
# }
|
25
|
+
#
|
26
|
+
#
|
27
|
+
#logfile : ./log/20121020_005953_sample1.log
|
28
|
+
#
|
29
|
+
# # Logfile created on 2012-10-20 00:59:53 +0900 by logger.rb/25413
|
30
|
+
# I, [2012-10-20T00:59:53.895528 #3208] INFO -- : info string
|
31
|
+
# E, [2012-10-20T00:59:53.895582 #3208] ERROR -- : error string
|
32
|
+
# F, [2012-10-20T00:59:53.895629 #3208] FATAL -- : Caught exception; existing 1
|
33
|
+
# F, [2012-10-20T00:59:53.895667 #3208] FATAL -- : exception (RuntimeError)
|
34
|
+
# test.rb:6:in `block in <main>'
|
35
|
+
# /usr/local/lib/ruby192/lib/ruby/gems/1.9.1/gems/rbatch-1.0.0/lib/rbatch/auto_logger.rb:37:in `initialize'
|
36
|
+
# test.rb:3:in `new'
|
37
|
+
# test.rb:3:in `<main>'
|
38
|
+
#
|
39
|
+
class Log
|
40
|
+
@@verbose = false
|
41
|
+
@@def_opt = {
|
42
|
+
:name => "<date>_<time>_<prog>.log",
|
43
|
+
:dir => File.join(File.dirname(RBatch.program_name), ".." , "log"),
|
44
|
+
:formatter => nil,
|
45
|
+
:append => true,
|
46
|
+
:level => "info",
|
47
|
+
:stdout => false,
|
48
|
+
:quiet => false,
|
49
|
+
:delete_old_log => false,
|
50
|
+
:delete_old_log_date => 7
|
51
|
+
}
|
52
|
+
@@log_level_map = {
|
53
|
+
"debug" => Logger::DEBUG,
|
54
|
+
"info" => Logger::INFO,
|
55
|
+
"warn" => Logger::WARN,
|
56
|
+
"error" => Logger::ERROR,
|
57
|
+
"fatal" => Logger::FATAL
|
58
|
+
}
|
59
|
+
|
60
|
+
@opt # option
|
61
|
+
@log # log instance for file
|
62
|
+
@stdout_log # log instance for STDOUT
|
63
|
+
@prog_base # program file name base
|
64
|
+
@file_name # log file name
|
65
|
+
|
66
|
+
# Set verbose mode flag.
|
67
|
+
def Log.verbose=(bol); @@verbose = bol ; end
|
68
|
+
|
69
|
+
# Get verbose mode flag.
|
70
|
+
def Log.verbose ; @@verbose ; end
|
71
|
+
|
72
|
+
# Get Option
|
73
|
+
def opt; @opt ; end
|
74
|
+
|
75
|
+
# Auto Logging Block.
|
76
|
+
#
|
77
|
+
# ==== Params
|
78
|
+
# +opt+ = Option hash object. Hash keys is follows.
|
79
|
+
# - +:name+ (String) = log file name. Default is "<date>_<time>_<prog>.log"
|
80
|
+
# - +:dir+ (String) = log direcotry path. Default is "../log"
|
81
|
+
# - +:level+ (String) = log level. ["debug"|"info"|"warn"|"error"|"fatal"] . Default is "info".
|
82
|
+
# - +:append+ (Boolean) = appned to log or not(=overwrite). Default is ture.
|
83
|
+
# - +:formatter+ (Logger#formatter) = log formatter. instance of Logger#formatter
|
84
|
+
# - +:stdout+ (Boolean) = print string both logfile and STDOUT. Default is false.
|
85
|
+
# - +:quiet+ (Boolean) = run quiet mode. print STDOUT nothing. Default is true.
|
86
|
+
# ==== Block params
|
87
|
+
# +log+ = Instance of +Logger+
|
88
|
+
# ==== Sample
|
89
|
+
# RBatch::Log.new({:dir => "/tmp", :level => "info"}){ |log|
|
90
|
+
# log.info "info string"
|
91
|
+
# }
|
92
|
+
#
|
93
|
+
def initialize(opt = nil)
|
94
|
+
# parse option
|
95
|
+
@opt = @@def_opt.clone
|
96
|
+
@@def_opt.each_key do |key|
|
97
|
+
if opt != nil && opt[key] != nil
|
98
|
+
# use argument
|
99
|
+
@opt[key] = opt[key]
|
100
|
+
elsif RBatch.common_config != nil \
|
101
|
+
&& RBatch.common_config["log_" + key.to_s] != nil
|
102
|
+
# use config
|
103
|
+
@opt[key] = RBatch.common_config["log_" + key.to_s]
|
104
|
+
else
|
105
|
+
# use default
|
106
|
+
end
|
107
|
+
end
|
108
|
+
puts "option = " + @opt.to_s if @@verbose
|
109
|
+
# determine log file name
|
110
|
+
@prog_base = Pathname(File.basename(RBatch.program_name)).sub_ext("").to_s
|
111
|
+
@file_name = @opt[:name].clone
|
112
|
+
@file_name.gsub!("<date>", Time.now.strftime("%Y%m%d"))
|
113
|
+
@file_name.gsub!("<time>", Time.now.strftime("%H%M%S"))
|
114
|
+
@file_name.gsub!("<prog>", @prog_base)
|
115
|
+
path = File.join(@opt[:dir],@file_name)
|
116
|
+
# create Logger instance
|
117
|
+
begin
|
118
|
+
if @opt[:append] && File.exist?(path)
|
119
|
+
@log = Logger.new(open(path,"a"))
|
120
|
+
else
|
121
|
+
@log = Logger.new(open(path,"w"))
|
122
|
+
end
|
123
|
+
rescue Errno::ENOENT => e
|
124
|
+
STDERR.puts "RBatch ERROR: Can not open log file - #{path}" if ! @opt[:quiet]
|
125
|
+
raise e
|
126
|
+
end
|
127
|
+
# set logger option
|
128
|
+
@log.formatter = @opt[:formatter] if @opt[:formatter]
|
129
|
+
@log.level = @@log_level_map[@opt[:level]]
|
130
|
+
if @opt[:stdout]
|
131
|
+
# ccreate Logger instance for STDOUT
|
132
|
+
@stdout_log = Logger.new(STDOUT)
|
133
|
+
@stdout_log.formatter = @opt[:formatter] if @opt[:formatter]
|
134
|
+
@stdout_log.level = @@log_level_map[@opt[:level]]
|
135
|
+
end
|
136
|
+
puts "Log file: " + path if ! @opt[:quiet]
|
137
|
+
# delete old log
|
138
|
+
self.delete_old_log(@opt[:delete_old_log_date]) if @opt[:delete_old_log]
|
139
|
+
if block_given?
|
140
|
+
begin
|
141
|
+
yield self
|
142
|
+
rescue => e
|
143
|
+
self.fatal("Caught exception; existing 1")
|
144
|
+
self.fatal(e)
|
145
|
+
exit 1
|
146
|
+
ensure
|
147
|
+
self.close
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def fatal(a)
|
153
|
+
@stdout_log.fatal(a) if @opt[:stdout]
|
154
|
+
@log.fatal(a)
|
155
|
+
end
|
156
|
+
|
157
|
+
def error(a)
|
158
|
+
@stdout_log.error(a) if @opt[:stdout]
|
159
|
+
@log.error(a)
|
160
|
+
end
|
161
|
+
|
162
|
+
def warn(a)
|
163
|
+
@stdout_log.warn(a) if @opt[:stdout]
|
164
|
+
@log.warn(a)
|
165
|
+
end
|
166
|
+
|
167
|
+
def info(a)
|
168
|
+
@stdout_log.info(a) if @opt[:stdout]
|
169
|
+
@log.info(a)
|
170
|
+
end
|
171
|
+
|
172
|
+
def debug(a)
|
173
|
+
@stdout_log.debug(a) if @opt[:stdout]
|
174
|
+
@log.debug(a)
|
175
|
+
end
|
176
|
+
|
177
|
+
def close
|
178
|
+
@stdout_log.close if @opt[:stdout]
|
179
|
+
@log.close
|
180
|
+
end
|
181
|
+
|
182
|
+
# Delete old log files.
|
183
|
+
# If @opt[:name] is not include "<date>", then do nothing.
|
184
|
+
#
|
185
|
+
# ==== Params
|
186
|
+
# - +date+ (Integer): The day of leaving log files
|
187
|
+
#
|
188
|
+
def delete_old_log(date = 7)
|
189
|
+
if Dir.exists?(@opt[:dir]) && @opt[:name].include?("<date>")
|
190
|
+
Dir::foreach(@opt[:dir]) do |file|
|
191
|
+
r = Regexp.new("^" \
|
192
|
+
+ @opt[:name].gsub("<prog>",@prog_base)\
|
193
|
+
.gsub("<time>","[0-2][0-9][0-5][0-9][0-5][0-9]")\
|
194
|
+
.gsub("<date>","([0-9][0-9][0-9][0-9][0-1][0-9][0-3][0-9])")\
|
195
|
+
+ "$")
|
196
|
+
if r =~ file && Date.strptime($1,"%Y%m%d") <= Date.today - date
|
197
|
+
puts "Delete old log file: " + File.join(@opt[:dir] , file) if ! @opt[:quiet]
|
198
|
+
File::delete(File.join(@opt[:dir] , file))
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end # end class
|
204
|
+
end # end module
|
205
|
+
|
data/sample/bin/test.rb
ADDED