Top Level Namespace
Constant Summary collapse
- COLOR_RED =
31
- COLOR_GREEN =
32
Instance Method Summary collapse
-
#abs(path) ⇒ Object
absolute path.
-
#chdir(dir) ⇒ Object
change current working directory.
-
#check_tool(name, check) ⇒ Object
function used to check that system has all required tools installed.
-
#chmod(path, permissions, recursive: false) ⇒ Object
change file permissions.
-
#color(message, color) ⇒ Object
putsc, puts with color.
-
#compare_file(from, to) ⇒ Object
compare_file.
-
#copy(from, to) ⇒ Object
copy.
-
#copy_file(from, to) ⇒ Object
copy_file.
-
#curl(url, path, content_length_check: false, verbose: false, flags: '-L -s -S') ⇒ Object
download url into a path using curl.
-
#curl_headers(url, method: 'HEAD', verbose: false, flags: '-L -s -S') ⇒ Object
get url response headers as Hash using curl.
-
#dir_entries(path) ⇒ Object
get directory entries.
-
#dir_exists?(path) ⇒ Boolean
check if directory exists.
-
#erb(file, output_file = nil, monitor = true) ⇒ Object
process erb template into an output_file.
-
#error(message, param = nil) ⇒ Object
error.
-
#extract(path, todir) ⇒ Object
extract archive, supports tar, zip, 7z.
-
#fail(message, param = nil) ⇒ Object
fail, print message to stderr and exit with 1.
-
#file_ctime(path) ⇒ Object
get file creation time.
-
#file_dir(path) ⇒ Object
get directory name of a path.
-
#file_exists?(path) ⇒ Boolean
check if file exists.
-
#file_mtime(path) ⇒ Object
get file modification time.
-
#file_name(path, strip_suffix: '') ⇒ Object
get file name of a path, optionally strip suffix if needed.
-
#file_size(path) ⇒ Object
get file size.
-
#file_suffix(path) ⇒ Object
get file suffix of a path.
- #freebsd? ⇒ Boolean
-
#git(url, path, branch: nil, silent: true, depth: nil) ⇒ Object
git clone url into a path.
-
#hostname ⇒ Object
get hostname.
-
#info(message, param = nil) ⇒ Object
info.
- #linux? ⇒ Boolean
-
#ls(path, dotfiles: false, grep: '', dir: true, file: true) ⇒ Object
list directory content.
- #macos? ⇒ Boolean
-
#mirror(from, to) ⇒ Object
mirror.
-
#mkdir(path) ⇒ Object
make directory including intermediate directories.
-
#monitor(file, &block) ⇒ Object
monitor file for changes and execute proc if file changed.
-
#option(opt) ⇒ Object
get option, returns Array if multiple or nil if none.
-
#os ⇒ Object
get operating system.
- #osx? ⇒ Boolean
-
#pwd ⇒ Object
current working directory.
-
#read(file) ⇒ Object
read content of a file.
-
#rm(path, recursive: false) ⇒ Object
remove file/directory.
-
#rmdir(path) ⇒ Object
remove directory recursively.
-
#run(file) ⇒ Object
run configuration.rb file.
-
#run_central(configurations, colored = true) ⇒ Object
run central configuration.
-
#run_if_exists(file) ⇒ Object
run configuration.rb file only if it exists.
-
#run_monitors ⇒ Object
run monitors.
-
#sha2(file) ⇒ Object
calculate SHA2 digest for a file.
-
#shell(command, verbose: false, silent: true) ⇒ Object
run shell command and get output, optionaly can print command running if verbose and if not silent will also print to stdout and stderr.
- #solaris? ⇒ Boolean
-
#source(file, source) ⇒ Object
source file in sh/bash/zsh script.
-
#sudo(command, verbose:, silent:) ⇒ Object
run shell command with sudo prefix, acts same as shell.
-
#symlink(from, to) ⇒ Object
symlink path.
-
#symlink?(symlink) ⇒ Boolean
check if file is symlink.
-
#symlink_path(symlink) ⇒ Object
get full path of symlink.
-
#touch(path) ⇒ Object
touch file.
-
#write(file, content) ⇒ Object
write content into a file.
Instance Method Details
#abs(path) ⇒ Object
absolute path
169 170 171 |
# File 'lib/central.rb', line 169 def abs(path) File.absolute_path(File.(path)) end |
#chdir(dir) ⇒ Object
change current working directory
174 175 176 |
# File 'lib/central.rb', line 174 def chdir(dir) Dir.chdir(abs(dir)) end |
#check_tool(name, check) ⇒ Object
function used to check that system has all required tools installed
147 148 149 150 151 152 153 154 |
# File 'lib/central.rb', line 147 def check_tool(name, check) _, output, = shell(check + ' 2>&1') if output == '' || output.downcase.include?('command not found') fail "#{name} not found, please install it to use central" end rescue Errno::ENOENT fail "#{name} not found, please install it to use central" end |
#chmod(path, permissions, recursive: false) ⇒ Object
change file permissions
295 296 297 298 299 |
# File 'lib/central.rb', line 295 def chmod(path, , recursive: false) path = abs(path) recursive = recursive ? '-R ' : '' shell("chmod #{recursive}#{} \"#{path}\"") end |
#color(message, color) ⇒ Object
putsc, puts with color
38 39 40 41 42 43 44 |
# File 'lib/central.rb', line 38 def color(, color) if $colored "\e[#{color}m#{}\e[0m" else end end |
#compare_file(from, to) ⇒ Object
compare_file
458 459 460 461 462 |
# File 'lib/central.rb', line 458 def compare_file(from, to) from = abs(from) to = abs(to) FileUtils.compare_file(from, to) end |
#copy(from, to) ⇒ Object
copy
477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/central.rb', line 477 def copy(from, to) from = abs(from) to = abs(to) if dir_exists?(from) dir_entries(from).each do |f| FileUtils.mkdir_p(to) copy("#{from}/#{f}", "#{to}/#{f}") end else copy_file(from, to) end end |
#copy_file(from, to) ⇒ Object
copy_file
465 466 467 468 469 470 471 472 473 474 |
# File 'lib/central.rb', line 465 def copy_file(from, to) from = abs(from) to = abs(to) fail "Couldn't access file", from unless file_exists?(from) return if file_exists?(to) && FileUtils.compare_file(from, to) FileUtils.copy_file(from, to) info 'Copied file', "#{from} → #{to}" end |
#curl(url, path, content_length_check: false, verbose: false, flags: '-L -s -S') ⇒ Object
download url into a path using curl
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/central.rb', line 381 def curl(url, path, content_length_check: false, verbose: false, flags: '-L -s -S') path = abs(path) if content_length_check and file_exists?(path) content_length = curl_headers(url, verbose: verbose, flags: flags)['content-length'].to_i return if file_size(path) == content_length end info 'Downloading', "#{url} → #{path}" exit_code, output, = shell("curl #{flags} \"#{url}\"", verbose: verbose, silent: true) unless exit_code.success? error output fail "Couldn't download file from", url end File.write(path, output) info 'Downloaded', "#{url} → #{path}" end |
#curl_headers(url, method: 'HEAD', verbose: false, flags: '-L -s -S') ⇒ Object
get url response headers as Hash using curl
399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/central.rb', line 399 def curl_headers(url, method: 'HEAD', verbose: false, flags: '-L -s -S') exit_code, output, = shell("curl -I -X #{method} #{flags} \"#{url}\"", verbose: verbose, silent: true) unless exit_code.success? error output fail "Couldn't get headers from", url end headers = {} output.scan(/^(?!HTTP)([^:]+):(.*)$/).each do |m| headers[m[0].strip.downcase] = m[1].sub("\r","").strip end headers end |
#dir_entries(path) ⇒ Object
get directory entries
200 201 202 |
# File 'lib/central.rb', line 200 def dir_entries(path) Dir.entries(abs(path)).select { |f| f != '.' && f != '..' } end |
#dir_exists?(path) ⇒ Boolean
check if directory exists
205 206 207 208 |
# File 'lib/central.rb', line 205 def dir_exists?(path) path = abs(path) Dir.exist?(path) end |
#erb(file, output_file = nil, monitor = true) ⇒ Object
process erb template into an output_file
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/central.rb', line 511 def erb(file, output_file = nil, monitor = true) file = abs(file) fail 'No erb file found', file unless file_exists?(file) if output_file.nil? output_file = file.end_with?('.erb') ? file[0...-4] : file + '.out' end $monitors[file] = proc { erb(file, output_file, false) } if monitor out = ERB.new(File.read(file)).result return if File.exist?(output_file) && File.read(output_file) == out File.write(output_file, out) info 'Processed erb', "#{file} → #{output_file}" end |
#error(message, param = nil) ⇒ Object
error
53 54 55 56 |
# File 'lib/central.rb', line 53 def error(, param = nil) puts color(, COLOR_RED) + (param.nil? ? '' : ': ' + param) end |
#extract(path, todir) ⇒ Object
extract archive, supports tar, zip, 7z
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/central.rb', line 325 def extract(path, todir) path = abs(path) todir = abs(todir) unless file_exists?(path) fail "Archive file #{path} does not exists" end mkdir(todir) info 'Extracting archive', "#{path} → #{todir}" exit_code = nil, output = nil if path.end_with?('.zip') exit_code, output, = shell("unzip \"#{path}\" -d \"#{todir}\" 2>&1") elsif path.end_with?('.7z') exit_code, output, = shell("7z x -o\"#{todir}\" \"#{path}\" 2>&1") else exit_code, output, = shell("tar -xf \"#{path}\" -C \"#{todir}\" 2>&1") end unless exit_code.success? error output fail "Couldn't extract archive", path end end |
#fail(message, param = nil) ⇒ Object
fail, print message to stderr and exit with 1
59 60 61 62 |
# File 'lib/central.rb', line 59 def fail(, param = nil) error , param exit 1 end |
#file_ctime(path) ⇒ Object
get file creation time
190 191 192 |
# File 'lib/central.rb', line 190 def file_ctime(path) File.new(abs(path)).ctime end |
#file_dir(path) ⇒ Object
get directory name of a path
223 224 225 |
# File 'lib/central.rb', line 223 def file_dir(path) File.dirname(abs(path)) end |
#file_exists?(path) ⇒ Boolean
check if file exists
179 180 181 182 |
# File 'lib/central.rb', line 179 def file_exists?(path) path = abs(path) File.file?(path) && File.readable?(path) end |
#file_mtime(path) ⇒ Object
get file modification time
195 196 197 |
# File 'lib/central.rb', line 195 def file_mtime(path) File.new(abs(path)).mtime end |
#file_name(path, strip_suffix: '') ⇒ Object
get file name of a path, optionally strip suffix if needed
211 212 213 |
# File 'lib/central.rb', line 211 def file_name(path, strip_suffix: '') File.basename(abs(path), strip_suffix) end |
#file_size(path) ⇒ Object
get file size
185 186 187 |
# File 'lib/central.rb', line 185 def file_size(path) File.new(abs(path)).size end |
#file_suffix(path) ⇒ Object
get file suffix of a path
216 217 218 219 220 |
# File 'lib/central.rb', line 216 def file_suffix(path) path = file_name(path) suffix_index = path =~ /\.[^.]+$/ return path[suffix_index, path.size - suffix_index] if suffix_index end |
#git(url, path, branch: nil, silent: true, depth: nil) ⇒ Object
git clone url into a path
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/central.rb', line 348 def git(url, path, branch: nil, silent: true, depth: nil) path = abs(path) if dir_exists?(path) && dir_exists?("#{path}/.git") cwd = pwd chdir path out = nil if branch _, out, = shell('git fetch 2>&1', silent: silent) puts out if silent && out.size.positive? _, out, = shell("git checkout #{branch} 2>&1", silent: silent) unless out.downcase.include? 'is now at' puts out if silent end _, out, = shell("git pull origin #{branch} 2>&1", silent: silent) else _, out, = shell('git pull 2>&1', silent: silent) end unless out.downcase.include? 'already up' puts out if silent info 'Git repository pulled', "#{url} → #{path}" end chdir cwd else branch = branch ? "-b #{branch} " : '' depth = depth ? "--depth #{depth} " : '' _, out, = shell("git clone #{depth}#{branch}#{url} \"#{path}\" 2>&1", silent: silent) puts out if silent info 'Git repository cloned', "#{url} → #{path}" end end |
#hostname ⇒ Object
get hostname
65 66 67 |
# File 'lib/central.rb', line 65 def hostname Socket.gethostname end |
#info(message, param = nil) ⇒ Object
info
47 48 49 50 |
# File 'lib/central.rb', line 47 def info(, param = nil) puts color(, COLOR_GREEN) + (param.nil? ? '' : ': ' + param) end |
#ls(path, dotfiles: false, grep: '', dir: true, file: true) ⇒ Object
list directory content
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 |
# File 'lib/central.rb', line 440 def ls(path, dotfiles: false, grep: '', dir: true, file: true) path = abs(path) dotfiles = dotfiles ? '-a ' : '' command = "ls -1 #{dotfiles}\"#{path}\" 2>&1" command += " | grep #{grep}" unless grep.empty? _, output, = shell(command) if output.downcase.end_with?('no such file or directory') fail "Couldn't ls directory", path end ls = output.split("\n") ls = ls.keep_if { |f| !File.directory?("#{path}/#{f}") } unless dir ls = ls.keep_if { |f| !File.file?("#{path}/#{f}") } unless file ls end |
#mirror(from, to) ⇒ Object
mirror
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/central.rb', line 491 def mirror(from, to) from = abs(from) to = abs(to) if dir_exists?(from) from_entries = dir_entries(from) if dir_exists?(to) dir_entries(to).each do |f| rm("#{to}/#{f}", recursive: true) unless from_entries.include?(f) end end from_entries.each do |f| FileUtils.mkdir_p(to) copy("#{from}/#{f}", "#{to}/#{f}") end else copy_file(from, to) end end |
#mkdir(path) ⇒ Object
make directory including intermediate directories
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/central.rb', line 244 def mkdir(path) path = abs(path) return if dir_exists?(path) exit_code, out, = shell("mkdir -p \"#{path}\" 2>&1") unless exit_code.success? error out fail "Couldn't create directory", path end info 'Created directory', path end |
#monitor(file, &block) ⇒ Object
monitor file for changes and execute proc if file changed
529 530 531 532 533 534 |
# File 'lib/central.rb', line 529 def monitor(file, &block) file = abs(file) fail 'No file found', file unless file_exists?(file) $monitors[file] = block end |
#option(opt) ⇒ Object
get option, returns Array if multiple or nil if none
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/central.rb', line 18 def option(opt) = $options.filter { |option| option.index(opt) == 0 } if .size == 0 return nil elsif .size == 1 return [0] else return end end |
#os ⇒ Object
get operating system
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/central.rb', line 70 def os if RUBY_PLATFORM.include?('linux') 'linux' elsif RUBY_PLATFORM.include?('darwin') 'osx' elsif RUBY_PLATFORM.include?('freebsd') 'freebsd' elsif RUBY_PLATFORM.include?('solaris') 'solaris' end end |
#pwd ⇒ Object
current working directory
164 165 166 |
# File 'lib/central.rb', line 164 def pwd Dir.pwd end |
#read(file) ⇒ Object
read content of a file
414 415 416 417 418 419 |
# File 'lib/central.rb', line 414 def read(file) file = abs(file) return File.read(file) if file_exists?(file) fail "Couldn't read file", file end |
#rm(path, recursive: false) ⇒ Object
remove file/directory
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/central.rb', line 257 def rm(path, recursive: false) path = abs(path) recursive = recursive ? '-R ' : '' is_dir = dir_exists?(path) is_symlink = symlink?(path) exit_code, out, = shell("rm #{recursive}-f \"#{path}\" 2>&1") unless exit_code.success? error out fail "Couldn't remove path", path end if is_dir info 'Removed directory', path elsif is_symlink info 'Removed symlink', path else info 'Removed file', path end end |
#rmdir(path) ⇒ Object
remove directory recursively
277 278 279 |
# File 'lib/central.rb', line 277 def rmdir(path) rm(path, recursive: true) end |
#run(file) ⇒ Object
run configuration.rb file
537 538 539 540 541 542 543 544 545 546 547 548 |
# File 'lib/central.rb', line 537 def run(file) cwd = pwd file = abs(file) file = File.join(file,'configuration.rb') if not file_exists?(file) and dir_exists?(file) fail 'No configuration file found', file unless file_exists?(file) info 'Running configuration', file file_cwd = file_dir(file) chdir file_cwd load file chdir cwd end |
#run_central(configurations, colored = true) ⇒ Object
run central configuration
556 557 558 559 560 561 562 563 564 565 |
# File 'lib/central.rb', line 556 def run_central(configurations, colored = true) $colored = colored if configurations.instance_of?(Array) && !configurations.empty? configurations.each { |configuration| run configuration } elsif configurations.instance_of?(String) run configurations else run 'configuration.rb' end end |
#run_if_exists(file) ⇒ Object
run configuration.rb file only if it exists
551 552 553 |
# File 'lib/central.rb', line 551 def run_if_exists(file) run file if file_exists?(file) end |
#run_monitors ⇒ Object
run monitors
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/central.rb', line 568 def run_monitors info 'Monitoring files for changes (press Ctrl-C to stop)' file_mtimes = {} $monitors.keys.each { |f| file_mtimes[f] = File.mtime(f) } loop do $monitors.keys.each do |f| file_mtime = File.mtime(f) next if file_mtime == file_mtimes[f] info 'File modified', f $monitors[f].call file_mtimes[f] = file_mtime end begin sleep(0.5) rescue Interrupt exit 0 end end end |
#sha2(file) ⇒ Object
calculate SHA2 digest for a file
239 240 241 |
# File 'lib/central.rb', line 239 def sha2(file) Digest::SHA256.hexdigest read(file) end |
#shell(command, verbose: false, silent: true) ⇒ Object
run shell command and get output, optionaly can print command running if verbose and if not silent will also print to stdout and stderr
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/central.rb', line 104 def shell(command, verbose: false, silent: true) info 'Executing', command if verbose exit_code = nil stdout = String.new stderr = String.new Open3.popen3(command) do |_, o, e, t| stdout_open = true stderr_open = true while stdout_open || stderr_open if stdout_open begin buffer = o.read_nonblock(4096) stdout << buffer STDOUT.write(buffer) unless silent rescue IO::WaitReadable IO.select([o], nil, nil, 0.01) unless stderr_open rescue EOFError stdout_open = false end end next unless stderr_open begin buffer = e.read_nonblock(4096) stderr << buffer STDERR.write(buffer) unless silent rescue IO::WaitReadable IO.select([e], nil, nil, 0.01) unless stdout_open rescue EOFError stderr_open = false end end exit_code = t.value end [exit_code, stdout, stderr] end |
#source(file, source) ⇒ Object
source file in sh/bash/zsh script
428 429 430 431 432 433 434 435 436 437 |
# File 'lib/central.rb', line 428 def source(file, source) file = abs(file) source = abs(source) source_line = "source \"#{source}\"" _, out, = shell("grep -Fx '#{source_line}' \"#{file}\"") return unless out == '' shell("echo '#{source_line}' >> \"#{file}\"") info 'Added source', "#{source} line to #{file}" end |
#sudo(command, verbose:, silent:) ⇒ Object
run shell command with sudo prefix, acts same as shell
142 143 144 |
# File 'lib/central.rb', line 142 def sudo(command, verbose:, silent:) shell('sudo ' + command, verbose: verbose, silent: silent) end |
#symlink(from, to) ⇒ Object
symlink path
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/central.rb', line 302 def symlink(from, to) from = abs(from) to = abs(to) if symlink?(from) if symlink_path(from) != to rm from symlink from, to end elsif file_exists?(from) fail "File #{from} exists in place of symlink..." elsif dir_exists?(from) fail "Directory #{from} exists in place of symlink..." else exit_code, out, = shell("ln -s \"#{to}\" \"#{from}\" 2>&1") unless exit_code.success? error out fail "Couldn't create symlink", "#{from} → #{to}" end info 'Created symlink', "#{from} → #{to}" end end |
#symlink?(symlink) ⇒ Boolean
check if file is symlink
228 229 230 |
# File 'lib/central.rb', line 228 def symlink?(symlink) File.symlink?(abs(symlink)) end |
#symlink_path(symlink) ⇒ Object
get full path of symlink
233 234 235 236 |
# File 'lib/central.rb', line 233 def symlink_path(symlink) _, out, = shell("readlink \"#{abs(symlink)}\" 2>&1") out.strip end |
#touch(path) ⇒ Object
touch file
282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/central.rb', line 282 def touch(path) path = abs(path) return if file_exists?(path) exit_code, out, = shell("touch \"#{path}\" 2>&1") unless exit_code.success? error out fail "Couldn't touch file", path end info 'Touched file', path end |
#write(file, content) ⇒ Object
write content into a file
422 423 424 425 |
# File 'lib/central.rb', line 422 def write(file, content) file = abs(file) File.write(file, content) end |