truckle: resume-file-support removed. exported via process-environment /etc/profile.d/cave.sh
This commit is contained in:
parent
3782f838eb
commit
82b710bf88
|
@ -2,7 +2,6 @@ TRUCKLE_RESUME_FILE="/tmp/truckle-resume-pid-${$}"
|
||||||
CAVE_all_commands_OPTIONS="--resume-file ${TRUCKLE_RESUME_FILE}"
|
CAVE_all_commands_OPTIONS="--resume-file ${TRUCKLE_RESUME_FILE}"
|
||||||
CAVE_RESOLVE_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
CAVE_RESOLVE_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
||||||
CAVE_RESUME_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
CAVE_RESUME_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
||||||
CAVE_FIX_LINKAGE_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
|
||||||
CAVE_UNINSTALL_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
CAVE_UNINSTALL_OPTIONS="${CAVE_all_commands_OPTIONS}"
|
||||||
export TRUCKLE_RESUME_FILE CAVE_all_commands_OPTIONS CAVE_RESOLVE_OPTIONS
|
export TRUCKLE_RESUME_FILE CAVE_all_commands_OPTIONS CAVE_RESOLVE_OPTIONS
|
||||||
export CAVE_RESUME_OPTIONS CAVE_FIX_LINKAGE_OPTIONS CAVE_UNINSTALL_OPTIONS
|
export CAVE_RESUME_OPTIONS CAVE_UNINSTALL_OPTIONS
|
||||||
|
|
218
truckle
218
truckle
|
@ -28,6 +28,24 @@ EOF
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class NamedProc < Proc
|
||||||
|
attr_reader :name
|
||||||
|
def initialize name, &block
|
||||||
|
@name = name.dup
|
||||||
|
@name.freeze
|
||||||
|
super &block
|
||||||
|
end
|
||||||
|
def inspect
|
||||||
|
"#<Proc:#{name} >"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Kernel
|
||||||
|
def named_proc name, &block
|
||||||
|
NamedProc.new name, &block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class GetoptLong
|
class GetoptLong
|
||||||
def argv=( v) @argv = v end
|
def argv=( v) @argv = v end
|
||||||
def argv() @argv end
|
def argv() @argv end
|
||||||
|
@ -61,8 +79,7 @@ class Commands < Hash
|
||||||
|
|
||||||
def self.new prefix, exe
|
def self.new prefix, exe
|
||||||
r = super()
|
r = super()
|
||||||
r.exe = exe
|
r.exe, r.prefix = exe, prefix
|
||||||
r.prefix = prefix
|
|
||||||
r.on {|cmd, *argv| raise UnknownCommandError, 'Unknown Command: %s' % cmd }
|
r.on {|cmd, *argv| raise UnknownCommandError, 'Unknown Command: %s' % cmd }
|
||||||
r
|
r
|
||||||
end
|
end
|
||||||
|
@ -104,7 +121,7 @@ class Commands < Hash
|
||||||
c, *argv = self.cmd( argv)
|
c, *argv = self.cmd( argv)
|
||||||
(self[c] || @fallback_cmd).call c, *argv
|
(self[c] || @fallback_cmd).call c, *argv
|
||||||
rescue CommandError
|
rescue CommandError
|
||||||
STDERR.puts $!.message, $!.backtrace
|
STDERR.puts $!.message #, $!.backtrace
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
alias call run
|
alias call run
|
||||||
|
@ -126,11 +143,11 @@ class RunCave
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :preargs, :cmd, :args, :log_level
|
attr_accessor :preargs, :cmd, :args, :log_level
|
||||||
attr_reader :dummy, :resumable
|
attr_reader :dummy
|
||||||
attr_writer :resume_file
|
attr_writer :resume_file
|
||||||
def initialize preargs = nil, cmd = nil, args = nil
|
def initialize preargs = nil, cmd = nil, args = nil
|
||||||
@resume_file, @preargs, @cmd, @args = nil, preargs || [], cmd || [], args || []
|
@resume_file, @preargs, @cmd, @args = nil, preargs || [], cmd || [], args || []
|
||||||
@colored = @dummy = @resumable = nil
|
@colored = @dummy = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_be_dummy
|
def can_be_dummy
|
||||||
|
@ -141,14 +158,6 @@ class RunCave
|
||||||
def dummy!() @dummy = true; self end
|
def dummy!() @dummy = true; self end
|
||||||
def dummy=(v) @dummy = !!v; self end
|
def dummy=(v) @dummy = !!v; self end
|
||||||
|
|
||||||
def can_be_resumable
|
|
||||||
@resumable = true unless false == @resumable
|
|
||||||
self
|
|
||||||
end
|
|
||||||
def resumable?() @resumable end
|
|
||||||
def resumable!() @resumable = true; self end
|
|
||||||
def resumable=(v) @resumable = !!v; self end
|
|
||||||
|
|
||||||
def can_be_colored
|
def can_be_colored
|
||||||
@colored = true unless false == @colored
|
@colored = true unless false == @colored
|
||||||
self
|
self
|
||||||
|
@ -157,10 +166,6 @@ class RunCave
|
||||||
def colored!() @colored = true; self end
|
def colored!() @colored = true; self end
|
||||||
def colored=(v) @colored = !!v; self end
|
def colored=(v) @colored = !!v; self end
|
||||||
|
|
||||||
def prepare_resume_file
|
|
||||||
resumable? ? ['--resume-file', @resume_file || raise(ResumeFileExpected)] : []
|
|
||||||
end
|
|
||||||
|
|
||||||
def prepare_colored
|
def prepare_colored
|
||||||
colored? ? ['--colour', 'yes'] : []
|
colored? ? ['--colour', 'yes'] : []
|
||||||
end
|
end
|
||||||
|
@ -172,8 +177,7 @@ class RunCave
|
||||||
def prepare
|
def prepare
|
||||||
raise CommandExpected, "Set #{self}.cmd = yourcommand." if @cmd.nil? or @cmd.empty?
|
raise CommandExpected, "Set #{self}.cmd = yourcommand." if @cmd.nil? or @cmd.empty?
|
||||||
[
|
[
|
||||||
:cave, prepare_colored, prepare_log_level, @preargs,
|
:cave, prepare_colored, prepare_log_level, @preargs, @cmd, @args
|
||||||
@cmd, prepare_resume_file, *@args
|
|
||||||
].flatten.select{|x|x}.map {|x| x.to_s }
|
].flatten.select{|x|x}.map {|x| x.to_s }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -213,60 +217,74 @@ class RunCave
|
||||||
alias call run_exit
|
alias call run_exit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Shelled
|
||||||
|
# =======
|
||||||
|
#
|
||||||
|
# Some helper functions like for sudo and pager
|
||||||
|
class Shelled
|
||||||
|
class ExecutionError < Exception
|
||||||
|
end
|
||||||
|
|
||||||
|
class Caller
|
||||||
|
attr_accessor :pager, :argv
|
||||||
|
def initialize *argv
|
||||||
|
@argv, @pager = argv, false
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calls exe while IRB::Pager redirect output to your PAGER.
|
||||||
|
def pager *args, &exe
|
||||||
|
if @nopager
|
||||||
|
exe.call *args
|
||||||
|
else
|
||||||
|
IRB::Pager::pager &lambda{ exe.call *args }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Restarts, if not @nosudo and not root yet, your Truckle as root
|
||||||
|
def sudo *argv, &exe
|
||||||
|
if @nosudo or 0 == Process.egid
|
||||||
|
exe.call *argv
|
||||||
|
else
|
||||||
|
argv = [:sudo, @argv, argv].flatten.select{|x|x}.map {|x| x.to_s }
|
||||||
|
Kernel.exec *argv
|
||||||
|
raise ExecutionError, "Can't exec #{argv.shelljoin}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :caller
|
||||||
|
attr_accessor :_stack_
|
||||||
|
def argv() @caller.argv end
|
||||||
|
|
||||||
|
def initialize *argv
|
||||||
|
@caller = Caller.new *argv
|
||||||
|
@_stack_ = []
|
||||||
|
end
|
||||||
|
def to_proc() method(:call).to_proc end
|
||||||
|
def _push_ exe = nil, &block
|
||||||
|
n = dup
|
||||||
|
n._stack_ = @_stack_.dup
|
||||||
|
n._stack_.push block || exe
|
||||||
|
n
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing meth, &block
|
||||||
|
n = _push_ {|*as, &b| @caller.send( meth, *as, &b) }
|
||||||
|
n = n._push_ block if block_given?
|
||||||
|
n
|
||||||
|
end
|
||||||
|
|
||||||
|
def call *args
|
||||||
|
@_stack_.reverse.inject {|s,b| lambda {|*as| b.call *as, &s } }.call *args
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Truckle
|
# Truckle
|
||||||
# =======
|
# =======
|
||||||
#
|
#
|
||||||
# cave-wrapper
|
# cave-wrapper
|
||||||
|
|
||||||
class Truckle
|
class Truckle
|
||||||
class ExecutionError < Exception
|
|
||||||
end
|
|
||||||
|
|
||||||
# Calls exe while IRB::Pager redirect output to your PAGER.
|
|
||||||
def pager *args, &exe
|
|
||||||
if @nopager
|
|
||||||
exe.call
|
|
||||||
else
|
|
||||||
IRB::Pager::pager *args, &exe
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Restarts, if not @nosudo and not root yet, your Truckle as root
|
|
||||||
def sudo *args, &exe
|
|
||||||
if @nosudo or 0 == Process.egid
|
|
||||||
exe.call
|
|
||||||
else
|
|
||||||
exepath = File.join File.dirname( @argv0), @cmds.prefix
|
|
||||||
args = [:sudo, exepath, @params, *args].flatten.select{|x|x}.map {|x| x.to_s }
|
|
||||||
Kernel.exec *args
|
|
||||||
raise ExecutionError, "Can't exec #{args.shelljoin}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Your command will be called - if it will be called - with sudo.
|
|
||||||
def sudod exe = nil, &block
|
|
||||||
exe ||= block
|
|
||||||
lambda {|*args| sudo( *args) { exe.call *args } }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Yout command will be called - if it will be called - with pager.
|
|
||||||
def pagered exe = nil, &block
|
|
||||||
exe ||= block
|
|
||||||
lambda {|*args| pager { exe.call *args } }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Yout command will be called - if it will be called - with sudo first and second pager.
|
|
||||||
#
|
|
||||||
# cmds.on :hamster, &sudo_pagered {|cmd, *args| puts "Your hamster said: \"#{args.join ' '}\"" }
|
|
||||||
#
|
|
||||||
# It is shorter than:
|
|
||||||
#
|
|
||||||
# cmds.on( :hamster) {|cmd, *args| sudo( cmd, *args) { pager { puts "Your hamster said: \"#{args.join ' '}\"" } } }
|
|
||||||
def sudo_pagered exe = nil, &block
|
|
||||||
exe ||= block
|
|
||||||
lambda {|*args| sudo( *args) { pager { exe.call *args } } }
|
|
||||||
end
|
|
||||||
|
|
||||||
def markdown_format t, colored = nil
|
def markdown_format t, colored = nil
|
||||||
if colored
|
if colored
|
||||||
t = t.gsub( /^\t+/) {|indent| ' '*indent.length}
|
t = t.gsub( /^\t+/) {|indent| ' '*indent.length}
|
||||||
|
@ -289,6 +307,7 @@ class Truckle
|
||||||
# initialize our program.
|
# initialize our program.
|
||||||
@cave = RunCave.new
|
@cave = RunCave.new
|
||||||
@cmds = Commands.new 'truckle', @exename
|
@cmds = Commands.new 'truckle', @exename
|
||||||
|
@shell = Shelled.new
|
||||||
|
|
||||||
prepare_commands
|
prepare_commands
|
||||||
end
|
end
|
||||||
|
@ -343,20 +362,18 @@ Most commands are like by cave.
|
||||||
Resumable
|
Resumable
|
||||||
=========
|
=========
|
||||||
|
|
||||||
You do not need to set a resume-file. #{cmd} will determine it automaticaly. First, you can give a first argument for tagging. Tag must be numerical!
|
Resume will be defined via environment `CAVE_*_OPTIONS='--resume-file PATH'`, which is provided by `/etc/profile.d/cave.sh`.
|
||||||
|
|
||||||
#{cmd} -t 321 resolve netcat6
|
Old resumable-options via truckle will not be provided anymore.
|
||||||
#{cmd} -t 321 do
|
So, there is no difference between truckle and cave anymore, you can mix it, both will be resumable.
|
||||||
|
|
||||||
If you do not give a tag, #{cmd} will use the actual terminal-device-number. If it isn't possible to determine terminal, the parent-pid will be used.
|
|
||||||
|
|
||||||
Like cave but different
|
Like cave but different
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
Some commands will be displayed by a pager, so you can scroll up and down like
|
Some commands will be displayed by a pager, so you can scroll up and down like
|
||||||
|
|
||||||
truckle resolve WHAT # cave -cy resolve WHAT | less -R
|
truckle resolve WHAT # cave -cy resolve WHAT | less -r
|
||||||
truckle remove WHAT # cave -cy uninstall WHAT | less -R
|
truckle remove WHAT # cave -cy uninstall WHAT | less -r
|
||||||
|
|
||||||
Some commands are not displayed by a pager, but will execute:
|
Some commands are not displayed by a pager, but will execute:
|
||||||
|
|
||||||
|
@ -373,30 +390,24 @@ EOF
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare_commands
|
def prepare_commands
|
||||||
cmds, cave = @cmds, @cave
|
cmds, cave, s = @cmds, @cave, @shell
|
||||||
|
|
||||||
# default: simple use cave
|
# default: simple use cave
|
||||||
cmds.on &sudod {|*args| cave.this(*args).() }
|
cmds.on &s.sudo {|*args| p on: args; cave.this(*args).() }
|
||||||
|
|
||||||
cmds.on :help, '-h', '--help', &pagered { STDOUT.puts helptext }
|
cmds.on :help, '-h', '--help', &s.pager { STDOUT.puts helptext }
|
||||||
cmds.on :sync, &sudod { cave.sync.() }
|
cmds.on :sync, &s.sudo {|cmd,*args| cave.this(*args).() }
|
||||||
cmds.on :search, :show, 'print-unused-distfiles', &sudo_pagered {|*args| cave.this(*args).() }
|
cmds.on :search, :show, 'print-unused-distfiles', &s.sudo.pager {|*args| cave.this(*args).() }
|
||||||
cmds.on :resolve, &sudo_pagered {|*args| cave.resumable!.this(*args).() }
|
cmds.on :resolve, 'fix-linkage', &s.sudo.pager {|*args| cave.this(*args).() }
|
||||||
cmds.on 'fix-linkage', &sudo_pagered {|*args|
|
cmds.on :remove, &s.sudo.pager {|cmd, *args| cave.uninstall(*args).()}
|
||||||
cave.resumable!.this *args
|
cmds.on :upgrade, &s.sudo.pager {|*args| cave.this( *args).() }
|
||||||
cave.args.push '--', cave.prepare_resume_file
|
cmds.on :install, &s.sudo {|cmd, *argv| cave.resolve( '-x', *argv).() }
|
||||||
cave.resumable = false
|
cmds.on :uninstall, &s.sudo {|cmd, *argv| cave.uninstall( '-x', *argv).() }
|
||||||
cave.()
|
|
||||||
}
|
|
||||||
cmds.on :remove, &sudo_pagered {|cmd, *args| cave.resumable!.uninstall(*args).()}
|
|
||||||
cmds.on :upgrade, &sudo_pagered {|*args| cave.resumable!.this( *args).() }
|
|
||||||
cmds.on :install, &sudod {|cmd, *argv| cave.resumable!.resolve( '-x', *argv).() }
|
|
||||||
cmds.on :uninstall, &sudod {|cmd, *argv| cave.resumable!.uninstall( '-x', *argv).() }
|
|
||||||
|
|
||||||
cmds.on :do, :resume, &sudod {|cmd, *args| cave.resumable!.resume( *args).() }
|
cmds.on :do, :resume, &s.sudo {|cmd, *args| cave.resume( *args).() }
|
||||||
cmds.on :retry, &sudod {|*args| cave.resumable!.this( *args).() }
|
cmds.on :retry, &s.sudo {|*args| cave.this( *args).() }
|
||||||
|
|
||||||
cmds.on '--list-commands', &pagered { puts cmds.map {|k,v| k } }
|
cmds.on '--list-commands', &s.pager { puts cmds.map {|k,v| k } }
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_params options
|
def setup_params options
|
||||||
|
@ -407,11 +418,9 @@ EOF
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
opts = GetoptLong.new(
|
opts = GetoptLong.new(
|
||||||
[ '-r', '--resume-file', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '-h', '--help', GetoptLong::NO_ARGUMENT ],
|
[ '-h', '--help', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '-C', '--list-commands', GetoptLong::NO_ARGUMENT ],
|
[ '-C', '--list-commands', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '-n', '--dummy', GetoptLong::NO_ARGUMENT ],
|
[ '-n', '--dummy', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '-t', '--tag', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '-p', '--pager', GetoptLong::REQUIRED_ARGUMENT ],
|
[ '-p', '--pager', GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
[ '-c', '--color', '--colour', GetoptLong::REQUIRED_ARGUMENT ],
|
[ '-c', '--color', '--colour', GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
[ '-L', '--log-level', GetoptLong::REQUIRED_ARGUMENT ],
|
[ '-L', '--log-level', GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
|
@ -422,10 +431,8 @@ EOF
|
||||||
opts.each do |opt, arg|
|
opts.each do |opt, arg|
|
||||||
case opt
|
case opt
|
||||||
when '-C' then options[:cmd] = '--list-commands'
|
when '-C' then options[:cmd] = '--list-commands'
|
||||||
when '-r' then options[:resume_file] = arg
|
|
||||||
when '-h' then options[:cmd] = 'help'
|
when '-h' then options[:cmd] = 'help'
|
||||||
when '-n' then options[:dummy] = true
|
when '-n' then options[:dummy] = true
|
||||||
when '-t' then options[:tag] = arg
|
|
||||||
when '-p' then options[:pager] = on_off_auto[arg]
|
when '-p' then options[:pager] = on_off_auto[arg]
|
||||||
when '-c' then options[:color] = on_off_auto[arg]
|
when '-c' then options[:color] = on_off_auto[arg]
|
||||||
when '-L' then options[:log_level] = arg
|
when '-L' then options[:log_level] = arg
|
||||||
|
@ -439,7 +446,6 @@ EOF
|
||||||
def setup_env options
|
def setup_env options
|
||||||
options[:dummy] = true if %w[1 true yes].include?( ENV['DUMMY'].to_s.downcase)
|
options[:dummy] = true if %w[1 true yes].include?( ENV['DUMMY'].to_s.downcase)
|
||||||
options[:sudo] = false if %w[1 true yes].include?( ENV['NOSUDO'].to_s.downcase)
|
options[:sudo] = false if %w[1 true yes].include?( ENV['NOSUDO'].to_s.downcase)
|
||||||
options[:resume_file] = ENV['TRUCKLE_RESUME_FILE'] unless '' == ENV['TRUCKLE_RESUME_FILE'].to_s
|
|
||||||
options[:tty] = true if STDOUT.tty?
|
options[:tty] = true if STDOUT.tty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -451,17 +457,6 @@ EOF
|
||||||
@cave.can_be_colored if on_off_auto.( options[:color]) and options[:tty]
|
@cave.can_be_colored if on_off_auto.( options[:color]) and options[:tty]
|
||||||
@nopager = true unless on_off_auto.( options[:pager]) or options[:tty]
|
@nopager = true unless on_off_auto.( options[:pager]) or options[:tty]
|
||||||
@nosudo = true unless on_off_auto.( options[:sudo])
|
@nosudo = true unless on_off_auto.( options[:sudo])
|
||||||
|
|
||||||
options[:resume_file] = if options[:tag]
|
|
||||||
"/tmp/truckle-resume-tag-#{options[:tag]}"
|
|
||||||
elsif options[:resume_file]
|
|
||||||
options[:resume_file]
|
|
||||||
elsif STDOUT.tty? and STDIN.tty? and STDOUT.stat.rdev == STDIN.stat.rdev
|
|
||||||
"/tmp/truckle-resume-dev-#{STDOUT.stat.rdev}"
|
|
||||||
else
|
|
||||||
"/tmp/truckle-resume-ppd-#{Process.ppid}"
|
|
||||||
end
|
|
||||||
@cave.resume_file = options[:resume_file]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def setup_recall options
|
def setup_recall options
|
||||||
|
@ -475,13 +470,12 @@ EOF
|
||||||
|
|
||||||
@params = [
|
@params = [
|
||||||
param.( '--dummy', options[:dummy]),
|
param.( '--dummy', options[:dummy]),
|
||||||
param.( ['--resume-file', options[:resume_file]], options[:resume_file]),
|
|
||||||
param.( ['--tag', options[:tag]], options[:tag]),
|
|
||||||
param.( ['--log-level', options[:log_level]], options[:log_level]),
|
param.( ['--log-level', options[:log_level]], options[:log_level]),
|
||||||
on_off_auto.( '--sudo', options[:sudo]),
|
on_off_auto.( '--sudo', options[:sudo]),
|
||||||
on_off_auto.( '--color', options[:color]),
|
on_off_auto.( '--color', options[:color]),
|
||||||
on_off_auto.( '--pager', options[:pager])
|
on_off_auto.( '--pager', options[:pager])
|
||||||
].flatten.select{|x|x}.map(&:to_s)
|
].flatten.select{|x|x}.map(&:to_s)
|
||||||
|
@shell.argv.push File.join( File.dirname( @argv0), @cmds.prefix), *@params
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
@ -533,5 +527,7 @@ class Shortcut < Hash
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
Shortcut.run $0
|
Shortcut.run $0
|
||||||
Truckle.run $0
|
Truckle.run $0
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in a new issue