require'unix_socks'require'tins/xt'require'term/ansicolor'classStringincludeTerm::ANSIColorendmoduleUtilsclassProcessJobdefinitialize(args:,probe_server: nil)@id=probe_server&.next_job_id@args=Array(args)endattr_reader:idattr_reader:argsattr_writer:okdeftype'process_job'enddefokcase@okwhenfalsethen'n'whentruethen'y'else'…'endenddefok_colorize(string)case@okwhenfalsethenstring.white.on_redwhentruethenstring.black.on_greenelsestringendenddefinspectok_colorize("#{id}#{args.map{|a|a.include?(' ')?a.inspect:a} * ' '}")endaliasto_sinspectdefas_json(*){type:,id:,args:,}enddefto_json(*)as_json.to_json(*)endendclassProbeClientclassEnvProxydefinitialize(server)@server=serverenddef[]=(key,value)response=@server.transmit_with_response(type: 'set_env',key:,value:)response.envenddef[](key)response=@server.transmit_with_response(type: 'get_env',key:)response.envendattr_reader:envenddefinitialize@server=UnixSocks::Server.new(socket_name: 'probe.sock',runtime_dir: Dir.pwd)enddefenvEnvProxy.new(@server)enddefenqueue(args)@server.transmit({type: 'process_job',args: })endendclassProbeServerdefinitialize@server=UnixSocks::Server.new(socket_name: 'probe.sock',runtime_dir: Dir.pwd)@history=[].freeze@jobs_queue=Queue.new@current_job_id=0enddefprint(*msg)ifmsg.first!~/^irb: warn: can't alias /# shut your god d*mn wh*re mouthsuperendenddefstartoutput_message"Starting probe server listening to #{@server.server_socket_path}.",type: :infowork_loop=Thread.newdoloopdojob=@jobs_queue.poprun_jobjobendendbeginreceive_loop.joinrescueInterruptARGV.clear<<'-f'output_message%{\nEntering interactive mode.},type: :infohelpbeginold,$VERBOSE=$VERBOSE,nilexamine(self)ensure$VERBOSE=oldend@server.remove_socket_pathoutput_message"Quitting interactive mode, but still listening to #{@server.server_socket_path}.",type: :inforetryendenddefinspect"#<Probe #queue=#{@jobs_queue.size}>"endaliasto_sinspectannotate:docannotate:shortcutdoc'Display this help.'shortcut:hdefhelpdocs=doc_annotations.sort_by(&:first)docs_size=docs.map{|a|a.first.size}.maxformat="%-#{docs_size}s %-3s %s"output_message[(format%%w[ command sho description ]).on_color(20).white]<<docs.map{|cmd,doc|shortcut=shortcut_of(cmd)andshortcut="(#{shortcut})"format%[cmd,shortcut,doc]}enddoc'Enqueue a new job with the argument array <args>.'shortcut:edefjob_enqueue(args)job=ProcessJob.new(args:,probe_server: self)output_message" → #{job.inspect} enqueued.",type: :info@jobs_queue.pushjobendaliasenqueuejob_enqueuedoc'Send the <signal> to the process that is working on the current job, if any.'doc'Quit the server.'shortcut:qdefshutdownoutput_message"Server was shutdown down – HARD!",type: :warnexit23enddoc'Repeat the job with <job_id> or the last, it will be assigned a new id, though.'shortcut:rdefjob_repeat(job_id=@history.last)ProcessJob===job_idandjob_id=job_id.idifold_job=@history.find{|job|job.id==job_id}job_enqueueold_job.argstrueelsefalseendenddoc'List the history of run jobs.'shortcut:ldefhistory_listoutput_message@historyenddoc'Clear the history of run jobs.'defhistory_clear@history=[]trueendclassLogWrapper<BasicObjectdefinitialize(server,object)@server,@object=server,objectenddef[]=(name,value)name,value=name.to_s,value.to_s@server.output_message("Setting #{name}=#{value.inspect}.",type: :info)@object[name]=valueenddefmethod_missing(*a,&b)@object.__send__(*a,&b)endenddoc"The environment of the server process, use env['a'] = 'b' and env['a']."memoize_methoddefenvLogWrapper.new(self,ENV)enddoc"Clear the terminal screen"shortcut:cdefclearsystem"clear"endfor(method_name,shortcut)inshortcut_annotationsalias_methodshortcut,method_nameenddefnext_job_id@current_job_id+=1enddefoutput_message(msg,type: nil)msg.respond_to?(:to_a)andmsg=msg.to_a*"\n"msg=casetypewhen:successmsg.on_color(22).whitewhen:infomsg.on_color(20).whitewhen:warnmsg.on_color(94).whitewhen:failuremsg.on_color(124).blink.whiteelsemsgendSTDOUT.putsmsgSTDOUT.flushselfendprivatedefrun_job(job)output_message" → #{job.inspect} now running.",type: :infosystem(*cmd(job.args))message=" → #{job.inspect} was just run"if$?.success?job.ok=truemessage<<" successfully."output_messagemessage,type: :successelsejob.ok=falsemessage<<" and failed with exit status #{$?.exitstatus}!"output_messagemessage,type: :failureend@history+=[job.freeze]@history.freezeenddefreceive_loop@server.receive_in_backgrounddo|job|casejob.typewhen'process_job'enqueuejob.argswhen'set_env'env[job.key]=job.valuejob.respond(env: env[job.key])when'get_env'job.respond(env: env[job.key])endendenddefcmd(job)call=[]ifENV.key?('BUNDLE_GEMFILE')andbundle=`which bundle`.full?(:chomp)call<<bundle<<'exec'endcall.push($0,*job)output_message"Executing #{call.inspect} now.",type: :infocallendendend