<commit_before># vim: foldmethod=marker
#from methadone (error.rb, exit_now.rb, process_status.rb, run.rb;
#last import 4626a2bca9b6e54077a06a0f8e11a04fadc6e7ae, 2017-01-19
require 'shell_helpers/logger'
require 'shell_helpers/run'
require 'forwardable'

begin
	require 'simplecolor'
rescue LoadError
	#fallback, don't colorize
	module SimpleColor
		def self.color(s,**opts)
			puts s
		end
	end
end

module ShellHelpers
	# ExitNow {{{
	# Standard exception you can throw to exit with a given status code.
	# Generally, you should prefer SH::ExitNow.exit_now! over using this
	# directly, however you may wish to create a rich hierarchy of exceptions
	# that extend from this in your app, so this is provided if you wish to
	# do so.
	class ExitError < StandardError
		attr_reader :exit_code
		# Create an Error with the given status code and message
		def initialize(exit_code,message=nil)
			super(message)
			@exit_code = exit_code
		end
	end

	# Provides #exit_now! You might mix this into your business logic classes
	# if they will need to exit the program with a human-readable error
	# message.
	module ExitNow
		# Call this to exit the program immediately
		# with the given error code and message.
		# +exit_code+:: exit status you'd like to exit with
		# +message+:: message to display to the user explaining the problem
		# If +exit_code+ is a String and +message+ is omitted, +exit_code+ will
		# === Examples
		#			exit_now!(4,"Oh noes!")
		#				# => exit app with status 4 and show the user "Oh noes!" on stderr
		#			exit_now!("Oh noes!")
		#				# => exit app with status 1 and show the user "Oh noes!" on stderr
		#			exit_now!(4)
		#				# => exit app with status 4 and dont' give the user a message (how rude of you)
		def exit_now!(exit_code,message=nil)
			if exit_code.kind_of?(String) && message.nil?
				raise ExitError.new(1,exit_code)
			else
				raise ExitError.new(exit_code,message)
			end
		end
	end
	# }}}
	
	# SudoLoop {{{
	# extend SudoLoop.configure to run a sudo loop
	# SH.sh("ls /", sudo: "sudo".extend(SH::SudoLoop.configure(**opts))
	module SudoLoop
		extend self
		def configure(**opts)
			return Module.new do |m|
				m.define_method(:sudo_loop) do
					SudoLoop.instance_method(:run_sudo_loop).bind(self).call(**opts)
				end
				m.define_method(:stop_sudo_loop) do
					SudoLoop.instance_method(:stop_sudo_loop).bind(self).call
				end
			end
		end

		def run_sudo_loop(command: "sudo -v", interval: 30, init_command: command)
			if @sudo_loop_thread.nil? or !@sudo_loop_thread.alive?
				Sh.sh_or_proc(init_command, log: false)
				#require 'pry'; binding.pry
				@sudo_loop_thread = Thread.new do
					loop do
						Sh.sh_or_proc(command, log: false)
						sleep(interval)
					end
				end
				@sudo_loop_thread.run
			end
		end

		def stop_sudo_loop
			@sudo_loop_thread&.kill
		end
	end #}}}

	# Sh {{{
	# Module with various helper methods for executing external commands.
	# In most cases, you can use #sh to run commands and have decent logging
	# done.
	# == Examples
	#
	#		 extend SH::Sh
	#
	#		 sh 'cp foo.txt /tmp'
	#		 # => logs the command to DEBUG, executes the command, logs its output to DEBUG and its error output to WARN, returns 0
	#
	#		 sh 'cp non_existent_file.txt /nowhere_good'
	#		 # => logs the command to DEBUG, executes the command, logs its output to INFO and its error output to WARN, returns the nonzero exit status of the underlying command
	#
	#		 sh! 'cp non_existent_file.txt /nowhere_good'
	#		 # => same as above, EXCEPT, raises a Methadone::FailedCommandError
	#
	#		 sh 'cp foo.txt /tmp' do
	#			 # Behaves exactly as before, but this block is called after
	#		 end
	#
	#		 sh 'cp non_existent_file.txt /nowhere_good' do
	#			 # This block isn't called, since the command failed
	#		 end
	#
	#		 sh 'ls -l /tmp/' do |stdout|
	#			 # stdout contains the output of the command
	#		 end
	#		 sh 'ls -l /tmp/ /non_existent_dir' do |stdout,stderr|
	#			 # stdout contains the output of the command,
	#			 # stderr contains the standard error output.
	#			end

	# FailedCommandError {{{
	# Thrown by certain methods when an externally-called command exits nonzero
	class FailedCommandError < StandardError
		# The command that caused the failure<commit_msg>sh.rb: correct examples<commit_after># vim: foldmethod=marker
#from methadone (error.rb, exit_now.rb, process_status.rb, run.rb;
#last import 4626a2bca9b6e54077a06a0f8e11a04fadc6e7ae, 2017-01-19
require 'shell_helpers/logger'
require 'shell_helpers/run'
require 'forwardable'

begin
	require 'simplecolor'
rescue LoadError
	#fallback, don't colorize
	module SimpleColor
		def self.color(s,**opts)
			puts s
		end
	end
end

module ShellHelpers
	# ExitNow {{{
	# Standard exception you can throw to exit with a given status code.
	# Generally, you should prefer SH::ExitNow.exit_now! over using this
	# directly, however you may wish to create a rich hierarchy of exceptions
	# that extend from this in your app, so this is provided if you wish to
	# do so.
	class ExitError < StandardError
		attr_reader :exit_code
		# Create an Error with the given status code and message
		def initialize(exit_code,message=nil)
			super(message)
			@exit_code = exit_code
		end
	end

	# Provides #exit_now! You might mix this into your business logic classes
	# if they will need to exit the program with a human-readable error
	# message.
	module ExitNow
		# Call this to exit the program immediately
		# with the given error code and message.
		# +exit_code+:: exit status you'd like to exit with
		# +message+:: message to display to the user explaining the problem
		# If +exit_code+ is a String and +message+ is omitted, +exit_code+ will
		# === Examples
		#			exit_now!(4,"Oh noes!")
		#				# => exit app with status 4 and show the user "Oh noes!" on stderr
		#			exit_now!("Oh noes!")
		#				# => exit app with status 1 and show the user "Oh noes!" on stderr
		#			exit_now!(4)
		#				# => exit app with status 4 and dont' give the user a message (how rude of you)
		def exit_now!(exit_code,message=nil)
			if exit_code.kind_of?(String) && message.nil?
				raise ExitError.new(1,exit_code)
			else
				raise ExitError.new(exit_code,message)
			end
		end
	end
	# }}}
	
	# SudoLoop {{{
	# extend SudoLoop.configure to run a sudo loop
	# SH.sh("ls /", sudo: "sudo".extend(SH::SudoLoop.configure(**opts))
	module SudoLoop
		extend self
		def configure(**opts)
			return Module.new do |m|
				m.define_method(:sudo_loop) do
					SudoLoop.instance_method(:run_sudo_loop).bind(self).call(**opts)
				end
				m.define_method(:stop_sudo_loop) do
					SudoLoop.instance_method(:stop_sudo_loop).bind(self).call
				end
			end
		end

		def run_sudo_loop(command: "sudo -v", interval: 30, init_command: command)
			if @sudo_loop_thread.nil? or !@sudo_loop_thread.alive?
				Sh.sh_or_proc(init_command, log: false)
				#require 'pry'; binding.pry
				@sudo_loop_thread = Thread.new do
					loop do
						Sh.sh_or_proc(command, log: false)
						sleep(interval)
					end
				end
				@sudo_loop_thread.run
			end
		end

		def stop_sudo_loop
			@sudo_loop_thread&.kill
		end
	end #}}}

	# Sh {{{
	# Module with various helper methods for executing external commands.
	# In most cases, you can use #sh to run commands and have decent logging
	# done.
	# == Examples
	#
	#		 extend SH::Sh
	#
	#		 sh 'cp foo.txt /tmp'
	#		 # => logs the command to DEBUG, executes the command, logs its output to DEBUG and its error output to WARN, returns 0
	#
	#		 sh 'cp non_existent_file.txt /nowhere_good'
	#		 # => logs the command to DEBUG, executes the command, logs its output to INFO and its error output to WARN, returns the nonzero exit status of the underlying command
	#
	#		 sh! 'cp non_existent_file.txt /nowhere_good'
	#		 # => same as above, EXCEPT, raises a Methadone::FailedCommandError
	#
	#		 sh 'cp foo.txt /tmp' do
	#			 # Behaves exactly as before, but this block is called after
	#		 end
	#
	#		 sh 'cp non_existent_file.txt /nowhere_good' do
	#			 # This block isn't called, since the command failed
	#		 end
	#
	#		 sh 'ls -l /tmp/', capture: true do |status, stdout|
	#			 # stdout contains the output of the command
	#		 end
	#		 sh 'ls -l /tmp/ /non_existent_dir', capture: true do |status, stdout,stderr|
	#			 # stdout contains the output of the command,
	#			 # stderr contains the standard error output.
	#			end

	# FailedCommandError {{{
	# Thrown by certain methods when an externally-called command exits nonzero
	class FailedCommandError < StandardError
		# The command that caused the failure
{'fraction_non_alphanumeric': 0.09246655714620981, 'fraction_numerical': 0.009152781037315184, 'mean_word_length': 3.5335106382978725, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1515447', 'n_tokens_mistral': 3249, 'n_tokens_neox': 2822, 'n_words': 985}