diff --git a/src/cli.cr b/src/cli.cr new file mode 100644 index 0000000..038addf --- /dev/null +++ b/src/cli.cr @@ -0,0 +1,66 @@ +require "option_parser" +require "digest/sha256" +require "colorize" + +require "./launcher" + +module DocMachine + class Cli + def initialize + end + + def start(argv) + options = {} of Symbol => String + + parser = OptionParser.new do |opts| + opts.banner = "Usage: script.cr [options]" + + opts.on("-d", "--data-dir DIR", "Content directory") do |dir| + options[:data_dir] = dir + end + + opts.on("-a", "--action ACTION", "Action (watch, build, shell, etc.)") do |action| + options[:action] = action + end + + opts.on("-t", "--tty", "Enable TTY mode (needed for shell)") do |tty| + options[:tty] = tty + end + + opts.on("-v", "--verbose", "Enable verbosity") do |verbose| + options[:verbose] = true.to_s + end + + opts.on("-h", "--help", "Show this help") do + puts opts + exit + end + end + + parser.parse(ARGV) + + + basedir = options[:data_dir]? ? options[:data_dir] : Dir.current + basehash = Digest::SHA256.hexdigest(basedir)[0..6] + action = options[:action]? ? options[:action] : "watch" + verbosity = options[:verbose]? ? options[:verbose] : 0 + docker_image = "glenux/docmachine:latest" + + if options[:help]? + puts "Usage: script.cr [options]" + puts "" + puts "-d, --data-dir DIR Content directory" + puts "-a, --action ACTION Action (watch, build, shell, etc.)" + puts "-t, --tty Enable TTY mode (needed for shell)" + puts "-v, --verbose Enable verbosity" + puts "-h, --help Show this help" + exit + end + + launcher = DocMachine::Launcher.new(options) + launcher.prepare + launcher.start + launcher.wait + end + end +end diff --git a/src/launcher.cr b/src/launcher.cr new file mode 100644 index 0000000..9e06b66 --- /dev/null +++ b/src/launcher.cr @@ -0,0 +1,124 @@ + +module DocMachine + class Launcher + def initialize(config) + @basedir = config[:data_dir]? ? config[:data_dir] : Dir.current + @basehash = Digest::SHA256.hexdigest(@basedir)[0..6] + @action = config[:action]? ? config[:action] : "watch" + # @verbosity = config[:verbose]? ? config[:verbose] : 0 + @docker_name = "docmachine-#{@basehash}" + @docker_image = "glenux/docmachine:latest" + @docker_opts = [] of String + @enable_tty = !!config[:tty]? + @process = nil + end + + + # cleanup environment + # create directories + # setup permissions + def prepare() + puts "basedir = #{@basedir}" + puts "docker_image = #{@docker_image}" + puts "action = #{@action}" + + docker_cid = %x{docker ps -f "name=#{@docker_name}" -q}.strip + + puts "docker_name: #{@docker_name}" + puts "docker_cid: #{docker_cid}" + + if !docker_cid.empty? + Process.run("docker", ["kill", @docker_name]) + end + end + + def start() + uid = %x{id -u}.strip + gid = %x{id -g}.strip + puts "uid: #{uid}" + puts "cid: #{gid}" + + docker_opts = [] of String + docker_opts << "run" + docker_opts << "-i" + # add tty support + docker_opts << "-t" if @enable_tty + # add container name + docker_opts.concat ["--name", @docker_name] + docker_opts << "--rm" + docker_opts << "--shm-size=1gb" + docker_opts.concat ["-e", "EXT_UID=#{uid}"] + docker_opts.concat ["-e", "EXT_GID=#{gid}"] + docker_opts.concat ["-v", "#{@basedir}/docs:/app/docs"] + docker_opts.concat ["-v", "#{@basedir}/slides:/app/slides"] + docker_opts.concat ["-v", "#{@basedir}/images:/app/images"] + docker_opts.concat ["-v", "#{@basedir}/_build:/app/_build"] + + ## Detect Marp SCSS + if File.exists?("#{@basedir}/.marp/theme.scss") + docker_opt_marp_theme = ["-v", "#{@basedir}/.marp:/app/.marp"] + docker_opts.concat docker_opt_marp_theme + puts "Theme: detected Marp files. Adding option to command line (#{docker_opt_marp_theme})" + else + puts "Theme: no theme detected. Using default files" + end + + ## Detect Mkdocs configuration - old format (full) + if File.exists?("#{@basedir}/mkdocs.yml") + puts "Mkdocs: detected mkdocs.yml file. Please rename to mkdocs-patch.yml" + exit 1 + end + + ## Detect Mkdocs configuration - new format (patch) + if File.exists?("#{@basedir}/mkdocs-patch.yml") + docker_opt_mkdocs_config = ["-v", "#{@basedir}/mkdocs-patch.yml:/app/mkdocs-patch.yml"] + docker_opts.concat docker_opt_mkdocs_config + puts "Mkdocs: detected mkdocs-patch.yml file. Adding option to command line (#{docker_opt_mkdocs_config})" + else + puts "Mkdocs: no mkdocs-patch.yml detected. Using default files" + end + + ## Detect slides + if Dir.exists?("#{@basedir}/slides") + docker_opt_marp_port = ["-p", "5200:5200"] + docker_opts.concat docker_opt_marp_port + puts "Slides: detected slides directory. Adding option to command line (#{docker_opt_marp_port})" + else + puts "Slides: no slides directory detected." + end + + ## Detect docs + if Dir.exists?("#{@basedir}/docs") + docker_opt_marp_port = ["-p", "5100:5100"] + docker_opts.concat docker_opt_marp_port + puts "Slides: detected docs directory. Adding option to command line (#{docker_opt_marp_port})" + else + puts "Slides: no slides docs detected." + end + + docker_opts << @docker_image + docker_opts << @action + + puts docker_opts.inspect.colorize(:yellow) + @process = Process.new("docker", docker_opts, output: STDOUT, error: STDERR) + end + + def wait() + process = @process + return if process.nil? + + Signal::INT.trap do + STDERR.puts "Received CTRL-C" + process.signal(Signal::KILL) + Process.run("docker", ["kill", @docker_name]) + end + process.wait + end + + def stop() + end + + def docker_opts() + end + end +end diff --git a/src/main.cr b/src/main.cr index 7160f6f..c426b18 100644 --- a/src/main.cr +++ b/src/main.cr @@ -1,140 +1,6 @@ -require "option_parser" -require "digest/sha256" -require "colorize" -options = {} of Symbol => String +require "./cli" -parser = OptionParser.new do |opts| - opts.banner = "Usage: script.cr [options]" - - opts.on("-d", "--data-dir DIR", "Content directory") do |dir| - options[:data_dir] = dir - end - - opts.on("-a", "--action ACTION", "Action (watch, build, shell, etc.)") do |action| - options[:action] = action - end - - opts.on("-t", "--tty", "Enable TTY mode (needed for shell)") do |tty| - options[:tty] = tty - end - - opts.on("-v", "--verbose", "Enable verbosity") do |verbose| - options[:verbose] = verbose.to_s - end - - opts.on("-h", "--help", "Show this help") do - puts opts - exit - end -end - -parser.parse(ARGV) - - -basedir = options[:data_dir]? ? options[:data_dir] : Dir.current -basehash = Digest::SHA256.hexdigest(basedir)[0..6] -action = options[:action]? ? options[:action] : "watch" -verbosity = options[:verbose]? ? options[:verbose] : 0 -docker_image = "glenux/docmachine:latest" -docker_opts = [] of String - -if options[:help]? - puts "Usage: script.cr [options]" - puts "" - puts "-d, --data-dir DIR Content directory" - puts "-a, --action ACTION Action (watch, build, shell, etc.)" - puts "-t, --tty Enable TTY mode (needed for shell)" - puts "-v, --verbose Enable verbosity" - puts "-h, --help Show this help" - exit -end - -puts "basedir = #{basedir}" -puts "docker_image = #{docker_image}" -puts "action = #{action}" - -docker_name = "docmachine-#{basehash}" -docker_cid = %x{docker ps -f "name=#{docker_name}" -q}.strip -uid = %x{id -u}.strip -gid = %x{id -g}.strip -puts "uid: #{uid}" -puts "cid: #{gid}" - -puts "docker_name: #{docker_name}" -puts "docker_cid: #{docker_cid}" - -if !docker_cid.empty? - Process.run("docker", ["kill", docker_name]) -end - -docker_opts << "run" -docker_opts << "-i" -# add tty support -docker_opts << "-t" if options[:tty]? -# add container name -docker_opts.concat ["--name", docker_name] -docker_opts << "--rm" -docker_opts << "--shm-size=1gb" -docker_opts.concat ["-e", "EXT_UID=#{uid}"] -docker_opts.concat ["-e", "EXT_GID=#{gid}"] -docker_opts.concat ["-v", "#{basedir}/docs:/app/docs"] -docker_opts.concat ["-v", "#{basedir}/slides:/app/slides"] -docker_opts.concat ["-v", "#{basedir}/images:/app/images"] -docker_opts.concat ["-v", "#{basedir}/_build:/app/_build"] - -## Detect Marp SCSS -if File.exists?("#{basedir}/.marp/theme.scss") - docker_opt_marp_theme = ["-v", "#{basedir}/.marp:/app/.marp"] - docker_opts.concat docker_opt_marp_theme - puts "Theme: detected Marp files. Adding option to command line (#{docker_opt_marp_theme})" -else - puts "Theme: no theme detected. Using default files" -end - -## Detect Mkdocs configuration - old format (full) -if File.exists?("#{basedir}/mkdocs.yml") - puts "Mkdocs: detected mkdocs.yml file. Please rename to mkdocs-patch.yml" - exit 1 -end - -## Detect Mkdocs configuration - new format (patch) -if File.exists?("#{basedir}/mkdocs-patch.yml") - docker_opt_mkdocs_config = ["-v", "#{basedir}/mkdocs-patch.yml:/app/mkdocs-patch.yml"] - docker_opts.concat docker_opt_mkdocs_config - puts "Mkdocs: detected mkdocs-patch.yml file. Adding option to command line (#{docker_opt_mkdocs_config})" -else - puts "Mkdocs: no mkdocs-patch.yml detected. Using default files" -end - -## Detect slides -if Dir.exists?("#{basedir}/slides") - docker_opt_marp_port = ["-p", "5200:5200"] - docker_opts.concat docker_opt_marp_port - puts "Slides: detected slides directory. Adding option to command line (#{docker_opt_marp_port})" -else - puts "Slides: no slides directory detected." -end - -## Detect docs -if Dir.exists?("#{basedir}/docs") - docker_opt_marp_port = ["-p", "5100:5100"] - docker_opts.concat docker_opt_marp_port - puts "Slides: detected docs directory. Adding option to command line (#{docker_opt_marp_port})" -else - puts "Slides: no slides docs detected." -end - -docker_opts << docker_image -docker_opts << action - -puts docker_opts.inspect.colorize(:yellow) -process = Process.new("docker", docker_opts, output: STDOUT, error: STDERR) - -Signal::INT.trap do - STDERR.puts "Received CTRL-C" - process.signal(Signal::KILL) - Process.run("docker", ["kill", docker_name]) -end -process.wait +app = DocMachine::Cli.new +app.start(ARGV)