Compare commits
6 commits
da329ab19e
...
adc96653e5
Author | SHA1 | Date | |
---|---|---|---|
adc96653e5 | |||
594b5f853a | |||
e11d2bc588 | |||
3ee2bdf5d4 | |||
ae563d781a | |||
920c58b157 |
31 changed files with 672 additions and 185 deletions
5
data/prompts/chats-sessions.md
Normal file
5
data/prompts/chats-sessions.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
# Chat sessions
|
||||
|
||||
* Formation MongoDB
|
||||
<https://chat.openai.com/c/e30a46c3-9bed-4896-bcfe-159865b501e3>
|
89
data/prompts/prompt-00-main.md
Normal file
89
data/prompts/prompt-00-main.md
Normal file
|
@ -0,0 +1,89 @@
|
|||
[TECHY is a technology expert with more than 20 years of experience. TECHY are specialized in systems, networks and infrastructures. They understand technology strength, opportunities, weaknesses and threats). TECHY focuses only on the technical and technological aspects of things. TECHY is methodical and analytical in his answers. TECHY admits his incompetence on other topics. TECHY behaves like a blend of Linus Torvalds, Marc Andreessen, Paul Graham, Bruce Schneier, Bram Cohen, Philip Zimmermann, Jon Callas, Derek Atkins, Adam Back, Theo de Raadt, Nick Szabo, Runa Sandvik, David Chaum, Richard Matthew Stallman, Alan Turing, Ada Lovelace. In all messages, you will start your reply by "TECHY:" and then you will answer to the questions or to the prompt like if TECHY was answering himself.]
|
||||
|
||||
## Contexte
|
||||
|
||||
Une formation d'excellente qualité, faite une université ou une ecole prestigieuse comme l'ENS Ulm, l'école Centrale, l'Ecole polytechnique, le MIT, l'université de Berkeley.
|
||||
|
||||
## Public concerné
|
||||
|
||||
* Administrateurs de bases de données
|
||||
* Administrateurs de systèmes
|
||||
* Professionnels des opérations et DevOps
|
||||
* et toute personne souhaitant maitriser parfaitement MongoDB
|
||||
|
||||
## Prérequis
|
||||
|
||||
* Avoir une connaissance générale des systèmes d'informations, systèmes et réseaux IP.
|
||||
* Avoir de bonnes connaissance Linux
|
||||
* Familiarité avec les concepts basiques et intermédiaires de MongoDB
|
||||
* Plusieurs années d'expérience sur l'outil MongoDB
|
||||
|
||||
## Objectifs
|
||||
|
||||
* Connaître la manipulation et l'interrogation des données à un niveau avancé
|
||||
* Connaître les bonnes pratiques d'optimisation des performances
|
||||
* Comprendre l'indexation avancée et les collections spéciales
|
||||
* Travailler sur la performance et la haute disponibilité avec le sharding et la réplication
|
||||
* Savoir détecter les causes de sous-performance et y remédier
|
||||
* Faire face à une montée en charge avec une répartition de charge.
|
||||
* Créer une stratégie de sauvegarde
|
||||
|
||||
## Programme de la formation
|
||||
|
||||
### Manipulation avancée de données
|
||||
|
||||
* Ajustement du Shell Mongo
|
||||
* Manipulation efficace des opérations CRUD (insertions, requêtes, mises à jour, suppressions)
|
||||
* Commandes d'administration utiles
|
||||
|
||||
### Optimisation des performances
|
||||
|
||||
* Outils de supervision intégrés : mongotop, mongostat
|
||||
* Analyser la mémoire et les performances des E/S
|
||||
* MongoDB Cloud Manager et Munin
|
||||
* Identifier les requêtes sous-optimales. Utiliser le profileur de requêtes.
|
||||
* Moteurs de stockage : MMAPv1 et WiredTiger
|
||||
* Les Explainable objects
|
||||
|
||||
### Indexation et collections spéciales
|
||||
|
||||
* Gestion et fonctionnement des index
|
||||
* Index des champs uniques et composés
|
||||
* Index des tableaux et des sous-documents
|
||||
* Index géo-spatiaux
|
||||
* Collections plafonnées, indexs TTL et curseurs
|
||||
|
||||
### Agrégation
|
||||
|
||||
* Agrégation à finalité unique
|
||||
* Pipelines d'agrégation
|
||||
* Map-reduce
|
||||
|
||||
### Réplication
|
||||
|
||||
* Réplication asynchrone dans MongoDB
|
||||
* Mise en place et entretien d'un replica set
|
||||
* Utilisation de "write concern" et "read preference"
|
||||
* Gérer les échecs de réplication
|
||||
|
||||
### Sharding
|
||||
|
||||
* Sharding automatique
|
||||
* Mise en place d'un cluster de shards MongoDB
|
||||
* Choisir judicieusement une shard key
|
||||
* Administration avancée d'un cluster de shards
|
||||
* Gérer un cluster de shards déséquilibré
|
||||
* Gérer les chunks (scission, fusion, migration)
|
||||
|
||||
### Sécurité
|
||||
|
||||
* Authentification et autorisation dans les replica sets et les clusters de shards
|
||||
* Gestion des privilèges et des rôles personnalisés
|
||||
* Recommandations pour un déploiement sûr
|
||||
|
||||
### Plans de sauvegarde et de restauration
|
||||
|
||||
* Stratégies basées sur le système de fichiers
|
||||
* Utilisation mongodump et mongorestore
|
||||
* Récupération de type point-in-time
|
||||
|
18
data/prompts/prompt-01-chapter-loop.md
Normal file
18
data/prompts/prompt-01-chapter-loop.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
GOAL: Build sections object containing subsections
|
||||
|
||||
PROMPT:
|
||||
|
||||
Merci.
|
||||
|
||||
Suit la structure du PROGRAMME DE FORMATION.
|
||||
|
||||
Concentre toi sur le chapitre « {{this.title}} ».
|
||||
|
||||
Focalise toi plus spécifiquement sur les sections suivantes «
|
||||
{% for child in this.children %}
|
||||
* {{ child }}
|
||||
{% endfor %}
|
||||
» de ce chapitre sur lequel on se concentre.
|
||||
|
||||
Rédige la table des matière détaillée de ces différentes sections.
|
||||
Ajoute également à la fin les différents travaux pratiques possibles pour chaque section.
|
27
data/prompts/prompt-02-section-loop.md
Normal file
27
data/prompts/prompt-02-section-loop.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
GOAL: Build subsections object containing markdown
|
||||
|
||||
PROMPT:
|
||||
|
||||
Super.
|
||||
|
||||
Suit la structure du PROGRAMME DE FORMATION.
|
||||
|
||||
Concentre toi sur le chapitre « {{this.chapter.title}} »
|
||||
|
||||
Dans ce chapitre, concentre toi sur la section « {{this.section.title}} ».
|
||||
|
||||
Focalise toi plus spécifiquement sur la sous-sections suivantes « {{this.subsection.title}} »
|
||||
qui contient les éléments suivants :
|
||||
«
|
||||
{% for child in this.children %}
|
||||
* {{ child }}
|
||||
{% endfor %}
|
||||
» sur lequel on se concentre.
|
||||
|
||||
Rédige le contenu détaillée de ces différents sous-sujets, sous forme phrases courtes et de listes à puces (bullet-points) pour remplir le contenu d'une présentation PowerPoint.
|
||||
|
||||
Donne des informations plus précises et plus techniques.
|
||||
|
||||
Précise les mots "gérer" ou "permet" quand tu les utilises.
|
||||
|
||||
Indique où trouver les informations dans MongoDB, dans la CLI ou dans d'autres outils. Donne les commandes à utiliser et des exemples de code si nécessaire.
|
18
data/prompts/prompt-03-subsection-loop.md
Normal file
18
data/prompts/prompt-03-subsection-loop.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
GOAL: provide examples and code for given subsection
|
||||
|
||||
PROMPT:
|
||||
|
||||
Super.
|
||||
Suit la structure du PROGRAMME DE FORMATION.
|
||||
|
||||
Concentre toi sur le chapitre « {{this.chapter.title}} ». Focalise toi plus spécifiquement sur la section suivante « {{this.section}} » et la sous-section « {{this.subsection.title}} »
|
||||
|
||||
Explique les sujets suivants:
|
||||
«
|
||||
{% for child in this.children %}
|
||||
* {{child}}
|
||||
{% endfor %}
|
||||
»
|
||||
|
||||
Donne également des exemples: commandes shell, extraits de code, ou extraits de configuration pour illustrer tes explications.
|
||||
|
7
data/prompts/prompt-04-fix-content.md
Normal file
7
data/prompts/prompt-04-fix-content.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
@@ TEXTE A CORRIGER
|
||||
|
||||
[[FIXME: text]]
|
||||
|
||||
@@ REQUETE
|
||||
|
||||
Dans le TEXTE A CORRIGER, indique où sont les erreurs et les approximations, et propose des corrections pour améliorer le contenu (pour une formation sur OpenStack).
|
67
data/prompts/syllabus.md
Normal file
67
data/prompts/syllabus.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
|
||||
## Programme de la formation
|
||||
|
||||
Please use the following syllabus for the 'beging to advanced Openstack administrator course'
|
||||
|
||||
Week 1: Introduction to Openstack
|
||||
|
||||
* Overview of the Openstack platform and its components
|
||||
* Setting up an Openstack development environment
|
||||
* Basic Openstack commands and usage
|
||||
|
||||
Week 2: Openstack Compute (Nova)
|
||||
|
||||
* Understanding Nova architecture and components
|
||||
* Managing virtual machines and instances
|
||||
* Configuring and managing flavors and images
|
||||
|
||||
Week 3: Openstack Networking (Neutron)
|
||||
|
||||
* Understanding Neutron architecture and components
|
||||
* Managing virtual networks and subnets
|
||||
* Configuring security groups and firewall rules
|
||||
|
||||
Week 4: Openstack Storage (Cinder and Swift)
|
||||
|
||||
* Understanding Cinder and Swift architecture and components
|
||||
* Managing block and object storage
|
||||
* Creating and managing volumes and snapshots
|
||||
|
||||
Week 5: Openstack Identity (Keystone)
|
||||
|
||||
* Understanding Keystone architecture and components
|
||||
* Managing users and projects
|
||||
* Configuring authentication and authorization
|
||||
|
||||
Week 6: Openstack Dashboard (Horizon)
|
||||
|
||||
* Understanding Horizon architecture and components
|
||||
* Navigating and using the Openstack dashboard
|
||||
* Customizing and extending the dashboard
|
||||
|
||||
Week 7: Advanced Openstack topics
|
||||
|
||||
* Deploying and managing a production Openstack environment
|
||||
* Managing and scaling an Openstack cloud
|
||||
* Troubleshooting and monitoring Openstack
|
||||
* Openstack in a multi-node environment
|
||||
|
||||
Week 8: Project and Exam
|
||||
|
||||
* Students will be given a project to deploy a multi-node OpenStack cloud, and they will need to complete it
|
||||
* Written Exam will be held to evaluate the student's understanding of the course content and their ability to apply the knowledge to real-world scenarios
|
||||
|
||||
|
||||
## ME
|
||||
|
||||
Please follow the syllabus structure and write the detailed content for "week 1 : introduction to openstack"
|
||||
|
||||
## ME
|
||||
|
||||
Follow the syllabus and the content structure above, and write the detailed course content for "Basic Openstack commands and usage"
|
||||
|
||||
## ME
|
||||
|
||||
Please provide all explanations and commands for the "Configuring and managing flavors and images" part, as the content of multiple slides in markdown, separated by "----":
|
||||
|
||||
|
3
data/samples/content.01.01.01.md
Normal file
3
data/samples/content.01.01.01.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
## SUBSECTION TITLE
|
||||
|
||||
FIXME
|
9
data/samples/content.01.01.json
Normal file
9
data/samples/content.01.01.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type": "section",
|
||||
"title": ""
|
||||
"subsections": [
|
||||
{ "type": "subsection", "title": "...", "keywords": ["...", "..."] },
|
||||
{ "type": "subsection", "title": "...", "keywords": ["...", "..."] },
|
||||
{ "type": "subsection", "title": "...", "keywords": ["...", "..."] }
|
||||
]
|
||||
}
|
10
data/samples/content.01.json
Normal file
10
data/samples/content.01.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"type": "chapter",
|
||||
"title": ""
|
||||
"keywords": ["...", "...", "..."],
|
||||
"sections": [
|
||||
{ "type": "section", "title": "...", "keywords": ["...", "..."] },
|
||||
{ "type": "section", "title": "...", "keywords": ["...", "..."] },
|
||||
{ "type": "section", "title": "...", "keywords": ["...", "..."] }
|
||||
]
|
||||
}
|
9
data/samples/content.json
Normal file
9
data/samples/content.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"type": "root-element",
|
||||
"title": ""
|
||||
"chapters": [
|
||||
{ "type": "chapter", "title": "...", "keywords": ["...", "..."] },
|
||||
{ "type": "chapter", "title": "...", "keywords": ["...", "..."] },
|
||||
{ "type": "chapter", "title": "...", "keywords": ["...", "..."] },
|
||||
]
|
||||
}
|
38
docs/config.md
Normal file
38
docs/config.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
## Usage
|
||||
|
||||
Préparer un fichier `docmachine.yaml`:
|
||||
|
||||
personae:
|
||||
- TECHY
|
||||
- GEOPOLY
|
||||
|
||||
context: |
|
||||
some text here
|
||||
|
||||
audience: |
|
||||
some text here
|
||||
|
||||
prerequisites: |
|
||||
some text here
|
||||
|
||||
goals: |
|
||||
some text here
|
||||
|
||||
pattern: "{{chapter.index}}.{{section.index}}.{{chapter.slug}}.json"
|
||||
|
||||
|
||||
Run docmachine to build the main toc
|
||||
|
||||
docmachine plan -c docmachine.yaml --level 0 --output .
|
||||
|
||||
|
||||
Run docmachine to build the toc for all chapters
|
||||
|
||||
docmachine plan -c docmachine.yaml --level 1 --output .
|
||||
|
||||
|
||||
Run docmachine to build the toc (if missing)
|
||||
|
||||
docmachine plan -c docmachine.yaml --level 0 --output .
|
||||
|
91
docs/prompts.md
Normal file
91
docs/prompts.md
Normal file
|
@ -0,0 +1,91 @@
|
|||
|
||||
[TECHY is a technology expert with more than 20 years of experience. TECHY are specialized in systems, networks and infrastructures. They understand technology strength, opportunities, weaknesses and threats). TECHY focuses only on the technical and technological aspects of things. TECHY is methodical and analytical in his answers. TECHY admits his incompetence on other topics. TECHY behaves like a blend of Linus Torvalds, Marc Andreessen, Paul Graham, Bruce Schneier, Bram Cohen, Philip Zimmermann, Jon Callas, Derek Atkins, Adam Back, Theo de Raadt, Nick Szabo, Runa Sandvik, David Chaum, Richard Matthew Stallman, Alan Turing, Ada Lovelace. In all messages, you will start your reply by "TECHY:" and then you will answer to the questions or to the prompt like if TECHY was answering himself.]
|
||||
|
||||
## Contexte
|
||||
|
||||
Une formation d'excellente qualité, faite une université ou une ecole prestigieuse comme l'ENS Ulm, l'école Centrale, l'Ecole polytechnique, le MIT, l'université de Berkeley.
|
||||
|
||||
## Public concerné
|
||||
|
||||
* Administrateurs de bases de données
|
||||
* Administrateurs de systèmes
|
||||
* Professionnels des opérations et DevOps
|
||||
* et toute personne souhaitant maitriser parfaitement MongoDB
|
||||
|
||||
## Prérequis
|
||||
|
||||
* Avoir une connaissance générale des systèmes d'informations, systèmes et réseaux IP.
|
||||
* Avoir de bonnes connaissance Linux
|
||||
* Familiarité avec les concepts basiques et intermédiaires de MongoDB
|
||||
* Plusieurs années d'expérience sur l'outil MongoDB
|
||||
|
||||
## Objectifs
|
||||
|
||||
* Connaître la manipulation et l'interrogation des données à un niveau avancé
|
||||
* Connaître les bonnes pratiques d'optimisation des performances
|
||||
* Comprendre l'indexation avancée et les collections spéciales
|
||||
* Travailler sur la performance et la haute disponibilité avec le sharding et la réplication
|
||||
* Savoir détecter les causes de sous-performance et y remédier
|
||||
* Faire face à une montée en charge avec une répartition de charge.
|
||||
* Créer une stratégie de sauvegarde
|
||||
|
||||
## Programme de la formation
|
||||
|
||||
### Manipulation avancée de données
|
||||
|
||||
* Ajustement du Shell Mongo
|
||||
* Manipulation efficace des opérations CRUD (insertions, requêtes, mises à jour, suppressions)
|
||||
* Commandes d'administration utiles
|
||||
|
||||
### Optimisation des performances
|
||||
|
||||
* Outils de supervision intégrés : mongotop, mongostat
|
||||
* Analyser la mémoire et les performances des E/S
|
||||
* MongoDB Cloud Manager et Munin
|
||||
* Identifier les requêtes sous-optimales. Utiliser le profileur de requêtes.
|
||||
* Moteurs de stockage : MMAPv1 et WiredTiger
|
||||
* Les Explainable objects
|
||||
|
||||
### Indexation et collections spéciales
|
||||
|
||||
* Gestion et fonctionnement des index
|
||||
* Index des champs uniques et composés
|
||||
* Index des tableaux et des sous-documents
|
||||
* Index géo-spatiaux
|
||||
* Collections plafonnées, indexs TTL et curseurs
|
||||
|
||||
### Agrégation
|
||||
|
||||
* Agrégation à finalité unique
|
||||
* Pipelines d'agrégation
|
||||
* Map-reduce
|
||||
|
||||
### Réplication
|
||||
|
||||
* Réplication asynchrone dans MongoDB
|
||||
* Mise en place et entretien d'un replica set
|
||||
* Utilisation de "write concern" et "read preference"
|
||||
* Gérer les échecs de réplication
|
||||
|
||||
### Sharding
|
||||
|
||||
* Sharding automatique
|
||||
* Mise en place d'un cluster de shards MongoDB
|
||||
* Choisir judicieusement une shard key
|
||||
* Administration avancée d'un cluster de shards
|
||||
* Gérer un cluster de shards déséquilibré
|
||||
* Gérer les chunks (scission, fusion, migration)
|
||||
|
||||
### Sécurité
|
||||
|
||||
* Authentification et autorisation dans les replica sets et les clusters de shards
|
||||
* Gestion des privilèges et des rôles personnalisés
|
||||
* Recommandations pour un déploiement sûr
|
||||
|
||||
### Plans de sauvegarde et de restauration
|
||||
|
||||
* Stratégies basées sur le système de fichiers
|
||||
* Utilisation mongodump et mongorestore
|
||||
* Récupération de type point-in-time
|
||||
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
version: 2.0
|
||||
shards:
|
||||
completion:
|
||||
git: https://github.com/f/completion.git
|
||||
version: 0.1.0+git.commit.d8799381b2de14430496199260eca64eb329625f
|
||||
|
||||
cor:
|
||||
git: https://github.com/watzon/cor.git
|
||||
version: 0.1.0+git.commit.9c9e51ac6168f3bd4fdc51d679b65de09ef76cac
|
||||
|
||||
crinja:
|
||||
git: https://github.com/straight-shoota/crinja.git
|
||||
version: 0.8.1
|
||||
|
||||
ioctl:
|
||||
git: https://github.com/crystal-posix/ioctl.cr.git
|
||||
version: 1.0.0
|
||||
|
|
12
shard.yml
12
shard.yml
|
@ -15,15 +15,9 @@ targets:
|
|||
dependencies:
|
||||
term-prompt:
|
||||
github: crystal-term/prompt
|
||||
crinja:
|
||||
github: straight-shoota/crinja
|
||||
|
||||
# completion:
|
||||
# github: f/completion
|
||||
# pg:
|
||||
# github: will/crystal-pg
|
||||
# version: "~> 0.5"
|
||||
|
||||
# development_dependencies:
|
||||
# webmock:
|
||||
# github: manastech/webmock.cr
|
||||
# FIXME: for prompts rendering
|
||||
|
||||
license: MIT
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
|
||||
require "./config"
|
||||
|
||||
module DocMachine::Builder
|
||||
module DocMachine::Build
|
||||
class Cli
|
||||
def self.add_options(opts, args, parent_config, commands)
|
||||
config = Config.new(parent_config)
|
||||
|
||||
opts.on("build", "Build content and produce deliverables") do
|
||||
opts.on("build", "Build content and produce HTML & PDF deliverables") do
|
||||
opts.banner = [
|
||||
"Usage: #{PROGRAM_NAME} build [options]",
|
||||
"",
|
||||
|
@ -29,7 +29,7 @@ module DocMachine::Builder
|
|||
end
|
||||
|
||||
commands << ->() : Nil do
|
||||
app = DocMachine::Builder::Run.new(config)
|
||||
app = DocMachine::Build::Run.new(config)
|
||||
app.prepare
|
||||
app.start
|
||||
app.wait
|
11
src/build/config.cr
Normal file
11
src/build/config.cr
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
module DocMachine::Build
|
||||
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
|
122
src/build/run.cr
Normal file
122
src/build/run.cr
Normal file
|
@ -0,0 +1,122 @@
|
|||
|
||||
require "./config"
|
||||
|
||||
module DocMachine::Build
|
||||
class Run
|
||||
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}"
|
||||
|
||||
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 @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
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
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
|
|
@ -1,125 +0,0 @@
|
|||
|
||||
require "./config"
|
||||
|
||||
module DocMachine
|
||||
module Builder
|
||||
|
||||
class Run
|
||||
def initialize(@config : DocMachine::Builder::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}"
|
||||
|
||||
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 @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
|
||||
end
|
19
src/cli.cr
19
src/cli.cr
|
@ -3,10 +3,14 @@ require "digest/sha256"
|
|||
require "colorize"
|
||||
|
||||
require "./config"
|
||||
require "./builder/cli"
|
||||
require "./builder/run"
|
||||
require "./scaffolder/cli"
|
||||
require "./planner/cli"
|
||||
require "./build/cli"
|
||||
require "./build/run"
|
||||
require "./scaffold/cli"
|
||||
require "./scaffold/run"
|
||||
require "./plan/cli"
|
||||
require "./plan/run"
|
||||
require "./write/cli"
|
||||
require "./write/run"
|
||||
|
||||
module DocMachine
|
||||
class Cli
|
||||
|
@ -36,9 +40,10 @@ module DocMachine
|
|||
opts.separator ""
|
||||
opts.separator "Commands:"
|
||||
|
||||
DocMachine::Builder::Cli.add_options(opts, args, config, commands)
|
||||
DocMachine::Scaffolder::Cli.add_options(opts, args, config, commands)
|
||||
DocMachine::Planner::Cli.add_options(opts, args, config, commands)
|
||||
DocMachine::Scaffold::Cli.add_options(opts, args, config, commands)
|
||||
DocMachine::Plan::Cli.add_options(opts, args, config, commands)
|
||||
DocMachine::Write::Cli.add_options(opts, args, config, commands)
|
||||
DocMachine::Build::Cli.add_options(opts, args, config, commands)
|
||||
end
|
||||
|
||||
parser.parse(args)
|
||||
|
|
15
src/plan/cli.cr
Normal file
15
src/plan/cli.cr
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
require "./config"
|
||||
|
||||
module DocMachine::Plan
|
||||
class Cli
|
||||
def self.add_options(opts, args, parent_config, command)
|
||||
config = Config.new(parent_config)
|
||||
|
||||
opts.on("plan", "Generate content structure (beta)") do
|
||||
opts.banner = "Usage: #{PROGRAM_NAME} plan [options]"
|
||||
opts.on("-t", "--test", "Test") { puts "Test" }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
module DocMachine
|
||||
module Planner
|
||||
module Plan
|
||||
class Config
|
||||
def initialize(@parent : DocMachine::Config)
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
require "./config"
|
||||
|
||||
module DocMachine
|
||||
module Planner
|
||||
class Cli
|
||||
def self.add_options(opts, args, parent_config, command)
|
||||
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
|
31
src/scaffold/cli.cr
Normal file
31
src/scaffold/cli.cr
Normal file
|
@ -0,0 +1,31 @@
|
|||
require "./config"
|
||||
require "./run"
|
||||
|
||||
module DocMachine::Scaffold
|
||||
class Cli
|
||||
def self.add_options(opts, args, parent_config, commands)
|
||||
config = Config.new(parent_config)
|
||||
|
||||
opts.on("scaffold", "Scaffold target directory (beta)") do
|
||||
opts.banner = "Usage: #{PROGRAM_NAME} scaffold [options] TARGET"
|
||||
|
||||
opts.on("-f", "--force", "Don't ask for confirmation") do
|
||||
config.force = true
|
||||
end
|
||||
|
||||
commands << ->() : Nil do
|
||||
if args.size < 1
|
||||
STDERR.puts "ERROR: No target given!"
|
||||
exit 1
|
||||
end
|
||||
config.target_directory = args[0]
|
||||
|
||||
app = DocMachine::Scaffold::Run.new(config)
|
||||
app.prepare
|
||||
app.start
|
||||
app.wait
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
module DocMachine::Scaffolder
|
||||
module DocMachine::Scaffold
|
||||
class Config
|
||||
property target_directory : String = "."
|
||||
property force : Bool = false
|
|
@ -8,9 +8,9 @@ require "./config"
|
|||
# Shards
|
||||
require "term-prompt"
|
||||
|
||||
module DocMachine::Scaffolder
|
||||
module DocMachine::Scaffold
|
||||
class Run
|
||||
private property config : DocMachine::Scaffolder::Config
|
||||
private property config : DocMachine::Scaffold::Config
|
||||
|
||||
def initialize(@config)
|
||||
end
|
|
@ -1,12 +1,12 @@
|
|||
require "./config"
|
||||
require "./run"
|
||||
|
||||
module DocMachine::Scaffolder
|
||||
module DocMachine::Write
|
||||
class Cli
|
||||
def self.add_options(opts, args, parent_config, commands)
|
||||
config = Config.new(parent_config)
|
||||
|
||||
opts.on("scaffold", "Scaffold target directory") do
|
||||
opts.on("write", "Write content target for plan (beta)") do
|
||||
opts.banner = "Usage: #{PROGRAM_NAME} scaffold [options] TARGET"
|
||||
|
||||
opts.on("-f", "--force", "Don't ask for confirmation") do
|
||||
|
@ -20,7 +20,7 @@ module DocMachine::Scaffolder
|
|||
end
|
||||
config.target_directory = args[0]
|
||||
|
||||
app = DocMachine::Scaffolder::Run.new(config)
|
||||
app = DocMachine::Write::Run.new(config)
|
||||
app.prepare
|
||||
app.start
|
||||
app.wait
|
||||
|
@ -29,3 +29,4 @@ module DocMachine::Scaffolder
|
|||
end
|
||||
end
|
||||
end
|
||||
|
11
src/write/config.cr
Normal file
11
src/write/config.cr
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
module DocMachine::Write
|
||||
class Config
|
||||
property target_directory : String = "."
|
||||
property force : Bool = false
|
||||
|
||||
def initialize(@parent : DocMachine::Config)
|
||||
end
|
||||
end
|
||||
end
|
61
src/write/run.cr
Normal file
61
src/write/run.cr
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
# Core
|
||||
require "file_utils"
|
||||
|
||||
# Internal
|
||||
require "./config"
|
||||
|
||||
# Shards
|
||||
require "term-prompt"
|
||||
|
||||
module DocMachine::Write
|
||||
class Run
|
||||
private property config : DocMachine::Write::Config
|
||||
|
||||
def initialize(@config)
|
||||
end
|
||||
|
||||
# Verify parameters
|
||||
def prepare()
|
||||
if ! File.directory? @config.target_directory
|
||||
STDERR.puts "ERROR: target must be a directory"
|
||||
exit 1
|
||||
end
|
||||
|
||||
puts "Target directory: #{@config.target_directory}"
|
||||
|
||||
if !@config.force
|
||||
prompt = Term::Prompt.new
|
||||
confirm = prompt.no?("Are you sure you want to proceed?")
|
||||
exit 1 if !confirm
|
||||
end
|
||||
end
|
||||
|
||||
def start()
|
||||
puts "== Writeing #{@config.target_directory}"
|
||||
p = Path.new(@config.target_directory)
|
||||
cwd = Dir.current
|
||||
["docs", "slides", "images"].each do |dir|
|
||||
p_sub = p.join(dir)
|
||||
puts "-- creating #{p_sub}"
|
||||
FileUtils.mkdir_p(p_sub)
|
||||
end
|
||||
["docs", "slides"].each do |dir|
|
||||
p_sub = p.join(dir)
|
||||
FileUtils.cd(p_sub)
|
||||
puts "-- creating link to images in #{p_sub}"
|
||||
if File.symlink? "images"
|
||||
FileUtils.rm "images"
|
||||
end
|
||||
FileUtils.ln_sf(Path.new("..","images"), Path.new("images"))
|
||||
FileUtils.cd(cwd)
|
||||
end
|
||||
puts "-- creating README.md"
|
||||
FileUtils.touch("README.md")
|
||||
end
|
||||
|
||||
# Verify parameters
|
||||
def wait()
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue