From b3dec4b138e111fdcbf8b5b98470c40f63954924 Mon Sep 17 00:00:00 2001 From: Glenn Date: Wed, 18 Jan 2023 16:29:34 +0100 Subject: [PATCH] feat: initial import --- .gitignore | 2 + old/docmachine | 135 ++++++++++++++++++++++++++++++++++++++++ old/docmachine-scaffold | 86 +++++++++++++++++++++++++ shard.yml | 24 +++++++ src/main.cr | 131 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 378 insertions(+) create mode 100644 .gitignore create mode 100755 old/docmachine create mode 100755 old/docmachine-scaffold create mode 100644 shard.yml create mode 100644 src/main.cr diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4052fca --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/bin + diff --git a/old/docmachine b/old/docmachine new file mode 100755 index 0000000..90605d4 --- /dev/null +++ b/old/docmachine @@ -0,0 +1,135 @@ +#!/bin/sh +# vim: set ft=sh: + +# Set defaults +BASEDIR="$(pwd)" +BASEHASH="$(echo "$BASEDIR" |sha256sum |head -c7)" +ACTION="watch" +VERBOSITY="0" +DOCKER_IMAGE=glenux/docmachine:latest +DOCKER_OPT_TTY="-t" + +gxt_usage() { + echo "Usage: $0 [options]" + echo "" + echo "-d, --data-dir DIR Content directory" + echo "-a, --action ACTION Action (watch, build, shell, etc.)" + echo "-t, --tty Enable TTY mode (needed for shell)" + echo "-v, --verbose Enable verbosity" + echo "-h, --help Show this help" +} + +# Parse arguments +while [ $# -gt 0 ]; do + ARG="${1:-}" + OPT="${2:-}" + shift + + # echo "DEBUG: ARG=$ARG OPT=$OPT" + + case "$ARG" in + -a|--action) + shift # argument requires a parameter + if [ -z "$OPT" ]; then + >&2 echo "ERROR: missing argument for --action" + exit 1 + fi + ACTION="$OPT" + ;; + -d|--data-dir) + shift # argument requires a parameter + if [ -z "$OPT" ]; then + >&2 echo "ERROR: missing argument for --data-dir" + exit 1 + fi + if [ ! -d "$OPT" ]; then + >&2 echo "ERROR: argument for --data-dir must be a directory" + exit 1 + fi + BASEDIR="$(cd "$OPT" && pwd)" + ;; + -h|--help) + >&2 gxt_usage + exit 0 + ;; + -T|--no-tty) + DOCKER_OPT_TTY="" + ;; + -v|--verbosity) + VERBOSITY="$((VERBOSITY+1))" + ;; + *) + >&2 gxt_usage + >&2 echo "ERROR: unknown option '$ARG'" + exit 1 + ;; + esac +done + +echo "basedir = $BASEDIR" +echo "docker_image = $DOCKER_IMAGE" +echo "action = $ACTION" + +## Detect Marp SCSS +if [ -f "$BASEDIR/.marp/theme.scss" ]; then + eval DOCKER_OPT_MARP_THEME="-v \"$BASEDIR/.marp:/app/.marp\"" + echo "Theme: detected Marp files. Adding option to command line ($DOCKER_OPT_MARP_THEME)" +else + echo "Theme: no theme detected. Using default files" +fi + +## Detect Mkdocs configuration - old format (full) +if [ -f "$BASEDIR/mkdocs.yml" ]; then + >&2 echo "Mkdocs: detected mkdocs.yml file. Please rename to mkdocs-patch.yml" + exit 1 +fi + +## Detect Mkdocs configuration - new format (patch) +if [ -f "$BASEDIR/mkdocs-patch.yml" ]; then + eval DOCKER_OPT_MKDOCS_CONFIG="-v \"$BASEDIR/mkdocs-patch.yml:/app/mkdocs-patch.yml\"" + echo "Mkdocs: detected mkdocs-patch.yml file. Adding option to command line ($DOCKER_OPT_MKDOCS_CONFIG)" +else + echo "Mkdocs: no mkdocs-patch.yml detected. Using default files" +fi + +## Detect slides +if [ -d "$BASEDIR/slides" ]; then + DOCKER_OPT_MARP_PORT="-p 5200:5200" +fi + +## Detect docs +if [ -d "$BASEDIR/docs" ]; then + DOCKER_OPT_MKDOCS_PORT="-p 5100:5100" +fi + +if [ "$VERBOSITY" -gt 0 ]; then + set -x +fi + +DOCKER_NAME="docmachine-$BASEHASH" +DOCKER_CID="$(docker ps -f "name=$DOCKER_NAME" -q)" + +if [ -n "$DOCKER_CID" ]; then + docker kill "$DOCKER_NAME" +fi + +docker run -i $DOCKER_OPT_TTY \ + --name "$DOCKER_NAME" \ + --rm \ + --shm-size=1gb \ + -e "EXT_UID=$(id -u)" \ + -e "EXT_GID=$(id -g)" \ + -v "$BASEDIR/docs:/app/docs" \ + -v "$BASEDIR/slides:/app/slides" \ + -v "$BASEDIR/images:/app/images" \ + -v "$BASEDIR/_build:/app/_build" \ + $DOCKER_OPT_MKDOCS_CONFIG \ + $DOCKER_OPT_MARP_THEME \ + $DOCKER_OPT_MKDOCS_PORT \ + $DOCKER_OPT_MARP_PORT \ + "$DOCKER_IMAGE" "$ACTION" + +if [ "$VERBOSITY" -gt 0 ]; then + set +x +fi + diff --git a/old/docmachine-scaffold b/old/docmachine-scaffold new file mode 100755 index 0000000..c36d8ca --- /dev/null +++ b/old/docmachine-scaffold @@ -0,0 +1,86 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'fileutils' +require 'find' +require 'thor' +require 'colorize' + +EXCLUDE_LIST = ['.git', 'node_modules'].freeze +SKEL_DIR = ENV['HOME'] + '/src/Glenux.Teaching/teaching-boilerplate' + +if ! File.directory? SKEL_DIR + warn "ERROR: missing #{SKEL_DIR}" + exit 1 +end + +# TeachingCli +class TeachingCli < Thor + desc 'create PROJECT', 'Create PROJECT directory' + def create(target) + # Create dir + if target.empty? + warn 'Target not specified' + exit 1 + end + + puts "Creating project #{target}" + FileUtils.mkdir_p target + + # Create structure + Find.find(SKEL_DIR) do |path| + if EXCLUDE_LIST.include? File.basename(path) + Find.prune + next + end + next unless File.directory?(path) + + shortpath = path.gsub(SKEL_DIR, '').gsub(%r{^/}, '') + next if shortpath.empty? + + targetpath = File.join(target, shortpath) + print "Creating directory #{shortpath}… " + FileUtils.mkdir_p targetpath + puts 'ok'.green + end + + # Create files if possible + Find.find(SKEL_DIR) do |path| + if EXCLUDE_LIST.include? File.basename(path) + Find.prune + next + end + + next if File.directory?(path) + + shortpath = path.gsub(SKEL_DIR, '').gsub(%r{^/}, '') + next if shortpath.empty? + + targetpath = File.join(target, shortpath) + print "Creating file #{shortpath}… " + + # File does not exist => install it + unless File.exist? targetpath + FileUtils.cp path, targetpath + puts 'ok (installed)'.green + next + end + + # File exist & different + unless system 'cmp', '--quiet', path, targetpath + if File.exist? targetpath + '.new' + puts 'error (pease solve previous conflict)'.red + else + puts 'warning (conflict when creating file)'.yellow + FileUtils.cp path, targetpath + '.new' + end + next + end + + puts 'ok (identical)'.green + FileUtils.cp path, targetpath + end + end +end + +TeachingCli.start(ARGV) diff --git a/shard.yml b/shard.yml new file mode 100644 index 0000000..4eb42db --- /dev/null +++ b/shard.yml @@ -0,0 +1,24 @@ +--- +name: docmachine-utils +version: 0.1.0 + +authors: + - Glenn Y. Rolland + +description: | + Command line utils for docmachine + +targets: + docmachine: + main: src/main.cr + +# dependencies: +# pg: +# github: will/crystal-pg +# version: "~> 0.5" + +# development_dependencies: +# webmock: +# github: manastech/webmock.cr + +license: MIT diff --git a/src/main.cr b/src/main.cr new file mode 100644 index 0000000..a8cc767 --- /dev/null +++ b/src/main.cr @@ -0,0 +1,131 @@ +require "option_parser" +require "digest/sha256" +require "colorize" + +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] = 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 "docker_name: #{docker_name}" +puts "docker_cid: #{docker_cid}" + +if !docker_cid.empty? + Process.run("docker", ["kill", docker_cid]) +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.run("docker", docker_opts, output: STDOUT, error: STDERR) +