docmachine-utils/src/build/run.cr
Glenn Y. Rolland a921acc3f9
All checks were successful
continuous-integration/drone/push Build is passing
ci: add missing libreadline-dev
2023-04-24 18:43:04 +02:00

156 lines
4.9 KiB
Crystal

require "path"
require "file_utils"
require "./config"
module DocMachine::Build
class Run
Log = DB::Log.for("docmachine.build") # Log for db.pool source
def initialize(@config : DocMachine::Build::Config)
@basehash = Digest::SHA256.hexdigest(@config.data_dir)[0..6]
@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 = #{@config.data_dir}"
puts "docker_image = #{@docker_image}"
puts "action = #{@config.action}"
self._avoid_duplicates()
self._pull_image()
end
private def _avoid_duplicates
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 _pull_image
data_cache_dir = (
if ENV["XDG_CACHE_HOME"]?
Path[ENV["XDG_CACHE_HOME"], "docmachine"]
else
Path[ENV["HOME"], ".cache", "docmachine"]
end
)
data_cache_file = data_cache_dir / "image.tar"
puts "Checking cache #{data_cache_file}..."
if ! File.exists? data_cache_file.to_s
puts "Downloading #{@docker_image} image..."
Process.run("docker", ["pull", @docker_image], output: STDOUT)
puts "Building cache for image (#{data_cache_dir})"
FileUtils.mkdir_p(data_cache_dir)
Process.run("docker", ["save", @docker_image, "-o", data_cache_file.to_s], output: STDOUT)
puts "done"
else
puts "Cache already exist. Skipping."
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 @config.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", "#{@config.data_dir}/docs:/app/docs"]
docker_opts.concat ["-v", "#{@config.data_dir}/slides:/app/slides"]
docker_opts.concat ["-v", "#{@config.data_dir}/images:/app/images"]
docker_opts.concat ["-v", "#{@config.data_dir}/_build:/app/_build"]
## Detect Marp SCSS
if File.exists?("#{@config.data_dir}/.marp/theme.scss")
docker_opt_marp_theme = ["-v", "#{@config.data_dir}/.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?("#{@config.data_dir}/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?("#{@config.data_dir}/mkdocs-patch.yml")
docker_opt_mkdocs_config = ["-v", "#{@config.data_dir}/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?("#{@config.data_dir}/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?("#{@config.data_dir}/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 << @config.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