feat: Prepare for multi-command
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Glenn Y. Rolland 2023-03-25 20:40:52 +01:00
parent 801e58ca27
commit 9a87615129
12 changed files with 247 additions and 194 deletions

View file

@ -1,138 +0,0 @@
module DocMachine
class Builder
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
def self.add_options(opts)
opts.on("build", "Build content and produce deliverables") do
opts.banner = [
"Usage: #{PROGRAM_NAME} build [options]",
"",
"Main options:"
].join("\n")
opts.separator ""
opts.separator "Builder Options:"
opts.on("-t", "--test", "Test") { puts "Test" }
end
end
end
end

33
src/builder/cli.cr Normal file
View file

@ -0,0 +1,33 @@
require "./config"
module DocMachine::Builder
class Cli
def self.add_options(opts, parent_config)
config = Config.new(parent_config)
opts.on("build", "Build content and produce deliverables") do
opts.banner = [
"Usage: #{PROGRAM_NAME} build [options]",
"",
"Main options:"
].join("\n")
opts.separator ""
opts.separator "Builder Options:"
opts.on("-d", "--data-dir DIR", "Content directory") do |dir|
config.data_dir = dir
end
opts.on("-a", "--action ACTION", "Action (watch, build, shell, etc.)") do |action|
config.action = action
end
opts.on("-t", "--tty", "Enable TTY mode (needed for shell)") do
config.enable_tty = true
end
end
end
end
end

13
src/builder/config.cr Normal file
View file

@ -0,0 +1,13 @@
module DocMachine
module Builder
class Config
property data_dir : String = Dir.current
property action : String = "watch"
property enable_tty : Bool = false
def initialize(@parent : DocMachine::Config)
end
end
end
end

128
src/builder/run.cr Normal file
View file

@ -0,0 +1,128 @@
require "./config"
module DocMachine
module Builder
class Run
def initialize(@config : DocMachine::Builder::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
@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
end

View file

@ -2,9 +2,11 @@ require "option_parser"
require "digest/sha256" require "digest/sha256"
require "colorize" require "colorize"
require "./builder/builder.cr" require "./config"
require "./scaffolder/scaffolder.cr" require "./builder/cli"
require "./planner/planner.cr" require "./builder/run"
require "./scaffolder/cli"
require "./planner/cli"
module DocMachine module DocMachine
class Cli class Cli
@ -12,7 +14,7 @@ module DocMachine
end end
def start(argv) def start(argv)
options = {} of Symbol => String config = Config.new
parser = OptionParser.new do |opts| parser = OptionParser.new do |opts|
opts.banner = [ opts.banner = [
@ -21,20 +23,8 @@ module DocMachine
"Main options:" "Main options:"
].join("\n") ].join("\n")
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| opts.on("-v", "--verbose", "Enable verbosity") do |verbose|
options[:verbose] = true.to_s config.verbose = true
end end
opts.on("-h", "--help", "Show this help") do opts.on("-h", "--help", "Show this help") do
@ -44,26 +34,15 @@ module DocMachine
opts.separator "" opts.separator ""
opts.separator "Commands:" opts.separator "Commands:"
DocMachine::Builder.add_options(opts)
DocMachine::Scaffolder.add_options(opts) DocMachine::Builder::Cli.add_options(opts, config)
DocMachine::Planner.add_options(opts) DocMachine::Scaffolder::Cli.add_options(opts, config)
DocMachine::Planner::Cli.add_options(opts, config)
end end
parser.parse(ARGV) parser.parse(ARGV)
builder = DocMachine::Builder::Run.new(config)
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 parser.to_s
exit
end
builder = DocMachine::Builder.new(options)
builder.prepare builder.prepare
builder.start builder.start
builder.wait builder.wait

10
src/config.cr Normal file
View file

@ -0,0 +1,10 @@
module DocMachine
class Config
property verbose : Bool = false
def initialize
end
end
end

17
src/planner/cli.cr Normal file
View file

@ -0,0 +1,17 @@
require "./config"
module DocMachine
module Planner
class Cli
def self.add_options(opts, parent_config)
config = Config.new(parent_config)
opts.on("content", "Generate content and structure") do
opts.banner = "Usage: #{PROGRAM_NAME} plan [options]"
opts.on("-t", "--test", "Test") { puts "Test" }
end
end
end
end
end

9
src/planner/config.cr Normal file
View file

@ -0,0 +1,9 @@
module DocMachine
module Planner
class Config
def initialize(@parent : DocMachine::Config)
end
end
end
end

View file

@ -1,11 +0,0 @@
module DocMachine
class Planner
def self.add_options(opts)
opts.on("content", "Generate content and structure") do
opts.banner = "Usage: #{PROGRAM_NAME} plan [options]"
opts.on("-t", "--test", "Test") { puts "Test" }
end
end
end
end

15
src/scaffolder/cli.cr Normal file
View file

@ -0,0 +1,15 @@
require "./config"
module DocMachine
module Scaffolder
class Cli
def self.add_options(opts, parent_config)
config = Config.new(parent_config)
opts.on("scaffold", "Scaffold directory") do
opts.banner = "Usage: #{PROGRAM_NAME} scaffold [options]"
end
end
end
end
end

10
src/scaffolder/config.cr Normal file
View file

@ -0,0 +1,10 @@
module DocMachine
module Scaffolder
class Config
def initialize(@parent : DocMachine::Config)
end
end
end
end

View file

@ -1,12 +0,0 @@
module DocMachine
class Scaffolder
def self.add_options(opts)
opts.on("scaffold", "Scaffold directory") do
opts.banner = "Usage: #{PROGRAM_NAME} scaffold [options]"
opts.on("-t", "--test", "Test") { puts "Test" }
end
end
end
end