2023-12-29 15:53:54 +01:00
|
|
|
|
2023-12-29 14:13:20 +01:00
|
|
|
# vim: set ts=2 sw=2 et ft=crystal:
|
|
|
|
|
2024-01-04 16:35:39 +01:00
|
|
|
require "colorize"
|
2023-12-29 14:13:20 +01:00
|
|
|
require "file"
|
|
|
|
require "option_parser"
|
2023-12-31 13:47:16 +01:00
|
|
|
require "magic"
|
2023-12-29 14:13:20 +01:00
|
|
|
|
2023-12-29 15:53:54 +01:00
|
|
|
require "./config"
|
2024-01-02 12:32:00 +01:00
|
|
|
require "./filelist"
|
2023-12-29 15:53:54 +01:00
|
|
|
|
2023-12-29 14:13:20 +01:00
|
|
|
# The CodePreloader module organizes classes and methods related to preloading code files.
|
|
|
|
module CodePreloader
|
|
|
|
# The Cli class handles command-line interface operations for the CodePreloader.
|
|
|
|
class Cli
|
2023-12-29 15:53:54 +01:00
|
|
|
@config : Config
|
2023-12-29 14:13:20 +01:00
|
|
|
|
|
|
|
# Initializes the Cli class with default values.
|
2023-12-29 15:53:54 +01:00
|
|
|
def initialize(args)
|
2023-12-29 14:13:20 +01:00
|
|
|
@output_file_path = ""
|
2023-12-29 15:53:54 +01:00
|
|
|
@config = Config.new()
|
2024-01-04 11:53:50 +01:00
|
|
|
@config.detect_config()
|
2023-12-29 15:53:54 +01:00
|
|
|
@config.parse_arguments(args)
|
2023-12-29 14:13:20 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# Executes the main functionality of the CLI application.
|
|
|
|
def exec
|
2024-01-04 11:53:50 +01:00
|
|
|
case @config.subcommand
|
|
|
|
when Config::Subcommand::Init then exec_init(@config.init_options)
|
|
|
|
when Config::Subcommand::Pack then exec_pack(@config.pack_options)
|
|
|
|
when Config::Subcommand::Version then exec_version
|
|
|
|
when Config::Subcommand::Help then exec_help
|
|
|
|
when Config::Subcommand::None then exec_none
|
|
|
|
else
|
|
|
|
abort("Unknown subcommand #{@config.subcommand}!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def exec_init(init_options)
|
|
|
|
abort("Unexpected nil value for init_options!") if init_options.nil?
|
2024-01-04 12:57:05 +01:00
|
|
|
|
|
|
|
# Default path for the .code_preloader.yml file
|
|
|
|
default_config_path = "example.code_preloader.yml"
|
|
|
|
|
|
|
|
# Use the specified path if provided, otherwise use the default
|
|
|
|
config_file_path = init_options.config_file_path || default_config_path
|
|
|
|
|
|
|
|
# Content of the .code_preloader.yml file
|
|
|
|
config_content = [
|
|
|
|
"---",
|
|
|
|
"# Example configuration for Code-Preloader",
|
|
|
|
"",
|
|
|
|
"# List of repository paths to preload",
|
|
|
|
"# repository_path_list:",
|
|
|
|
"# - \"path/to/repo1\"",
|
|
|
|
"# - \"path/to/repo2\"",
|
|
|
|
"",
|
|
|
|
"# List of patterns to ignore during preloading",
|
|
|
|
"ignore_list:",
|
2024-01-04 16:35:39 +01:00
|
|
|
" - ^\\.git/.*",
|
2024-01-04 12:57:05 +01:00
|
|
|
"",
|
|
|
|
"# Path to the output file (if null, output to STDOUT)",
|
|
|
|
"output_file_path: null",
|
|
|
|
"",
|
|
|
|
"# Optional: Path to a file containing the header prompt",
|
|
|
|
"header_prompt_file_path: null",
|
|
|
|
"",
|
|
|
|
"# Optional: Path to a file containing the footer prompt",
|
2024-01-04 13:00:08 +01:00
|
|
|
"footer_prompt_file_path: null",
|
|
|
|
""
|
2024-01-04 12:57:05 +01:00
|
|
|
].join("\n")
|
|
|
|
|
2024-01-04 13:05:41 +01:00
|
|
|
# Writing the configuration content to the file
|
|
|
|
File.write(config_file_path, config_content)
|
|
|
|
puts "Configuration file created at: #{config_file_path}"
|
2024-01-04 12:57:05 +01:00
|
|
|
rescue e : Exception
|
2024-01-04 13:05:41 +01:00
|
|
|
abort("ERROR: Unable to create the configuration file: #{e.message}")
|
|
|
|
end
|
2024-01-04 11:53:50 +01:00
|
|
|
|
|
|
|
def exec_version
|
2024-01-04 13:05:41 +01:00
|
|
|
puts "#{PROGRAM_NAME} v#{VERSION}"
|
|
|
|
exit(0)
|
2024-01-04 11:53:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def exec_none
|
2024-01-04 13:05:41 +01:00
|
|
|
STDERR.puts @config.parser
|
|
|
|
abort("ERROR: No command specified!")
|
2024-01-04 11:53:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def exec_help
|
2024-01-04 13:05:41 +01:00
|
|
|
puts @config.parser
|
|
|
|
exit(0)
|
2024-01-04 11:53:50 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def exec_pack(pack_options)
|
|
|
|
abort("Unexpected nil value for pack_options!") if pack_options.nil?
|
|
|
|
|
|
|
|
output_file_path = pack_options.output_file_path
|
|
|
|
repository_path_list = pack_options.repository_path_list
|
|
|
|
header_prompt_file_path = pack_options.header_prompt_file_path
|
|
|
|
footer_prompt_file_path = pack_options.footer_prompt_file_path
|
|
|
|
regular_output_file = false
|
2024-01-04 16:35:39 +01:00
|
|
|
header_prompt = ""
|
|
|
|
footer_prompt = ""
|
2024-01-02 12:32:00 +01:00
|
|
|
|
|
|
|
filelist = FileList.new()
|
|
|
|
filelist.add(repository_path_list)
|
2024-01-04 11:53:50 +01:00
|
|
|
pack_options.ignore_list.each do |ignore_pattern|
|
2024-01-02 12:32:00 +01:00
|
|
|
filelist.reject { |path| !!(path =~ Regex.new(ignore_pattern)) }
|
2023-12-29 14:13:20 +01:00
|
|
|
end
|
|
|
|
|
2024-01-02 12:32:00 +01:00
|
|
|
if !header_prompt_file_path.nil?
|
2024-01-04 16:35:39 +01:00
|
|
|
STDERR.puts "Loading header prompt from: #{header_prompt_file_path}".colorize(:yellow)
|
2024-01-02 12:32:00 +01:00
|
|
|
header_prompt = File.read(header_prompt_file_path)
|
2023-12-29 14:13:20 +01:00
|
|
|
end
|
|
|
|
|
2024-01-02 12:32:00 +01:00
|
|
|
if !footer_prompt_file_path.nil?
|
2024-01-04 16:35:39 +01:00
|
|
|
STDERR.puts "Loading footer prompt from: #{footer_prompt_file_path}".colorize(:yellow)
|
2024-01-02 12:32:00 +01:00
|
|
|
footer_prompt = File.read(footer_prompt_file_path)
|
|
|
|
end
|
2023-12-29 14:57:11 +01:00
|
|
|
|
2024-01-04 16:35:39 +01:00
|
|
|
output_file = STDOUT
|
2024-01-04 11:53:50 +01:00
|
|
|
output_file_path.try do |path|
|
|
|
|
break if path.empty?
|
|
|
|
break if path == "-"
|
|
|
|
regular_output_file = true
|
|
|
|
output_file = File.open(path, "w")
|
|
|
|
end
|
2024-01-04 16:35:39 +01:00
|
|
|
STDERR.puts "Writing output to: #{regular_output_file ? output_file_path : "stdout" }".colorize(:yellow)
|
2023-12-29 14:57:11 +01:00
|
|
|
|
2023-12-29 14:13:20 +01:00
|
|
|
|
2024-01-04 16:35:39 +01:00
|
|
|
header_prompt_file_path.try { output_file.puts header_prompt }
|
2023-12-29 14:57:11 +01:00
|
|
|
|
2024-01-04 16:35:39 +01:00
|
|
|
STDERR.puts "Processing repository: #{repository_path_list}".colorize(:yellow)
|
2024-01-02 12:32:00 +01:00
|
|
|
filelist.each do |file_path|
|
2024-01-04 16:35:39 +01:00
|
|
|
STDERR.puts "Processing file: #{file_path}".colorize(:yellow)
|
2024-01-02 12:32:00 +01:00
|
|
|
process_file(file_path, output_file)
|
2023-12-29 16:31:17 +01:00
|
|
|
end
|
2023-12-29 14:57:11 +01:00
|
|
|
|
2024-01-04 16:35:39 +01:00
|
|
|
footer_prompt_file_path.try { output_file.puts footer_prompt }
|
2023-12-29 14:57:11 +01:00
|
|
|
|
2024-01-04 11:53:50 +01:00
|
|
|
output_file.close if regular_output_file
|
2024-01-04 16:35:39 +01:00
|
|
|
STDERR.puts "Processing completed.".colorize(:yellow)
|
2023-12-29 14:13:20 +01:00
|
|
|
|
|
|
|
rescue e : Exception
|
|
|
|
STDERR.puts "An error occurred during execution: #{e.message}"
|
|
|
|
exit(1)
|
|
|
|
end
|
|
|
|
|
2024-01-02 12:32:00 +01:00
|
|
|
private def process_file(file_path : String, output_file : IO::FileDescriptor)
|
2024-01-04 16:35:39 +01:00
|
|
|
mime = ""
|
|
|
|
clean_content = ""
|
|
|
|
File.open(file_path) do |fh|
|
|
|
|
mime = Magic.mime_type.of(fh)
|
|
|
|
clean_content = (
|
|
|
|
fh.gets_to_end
|
|
|
|
.strip
|
|
|
|
.gsub(/\n\s*\n\s*\n/,"\n\n")
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2024-01-02 12:32:00 +01:00
|
|
|
output_file.puts "@@ File \"#{file_path}\" (Mime-Type: #{mime.inspect})"
|
2023-12-29 14:13:20 +01:00
|
|
|
output_file.puts ""
|
2024-01-04 16:35:39 +01:00
|
|
|
if clean_content !~ /^\s*$/
|
|
|
|
output_file.puts(clean_content)
|
|
|
|
output_file.puts ""
|
|
|
|
end
|
2023-12-29 14:13:20 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|