moodle-docs-theme 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/MANIFEST.in +1 -0
  2. {moodle_docs_theme-0.1.0/moodle_docs_theme.egg-info → moodle_docs_theme-0.2.0}/PKG-INFO +46 -3
  3. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/README.md +41 -2
  4. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/__init__.py +1 -1
  5. moodle_docs_theme-0.2.0/moodle_docs_theme/__main__.py +8 -0
  6. moodle_docs_theme-0.2.0/moodle_docs_theme/cli.py +305 -0
  7. moodle_docs_theme-0.2.0/moodle_docs_theme/template/__init__.py +10 -0
  8. moodle_docs_theme-0.2.0/moodle_docs_theme/template/docs/conf.py.tpl +59 -0
  9. moodle_docs_theme-0.2.0/moodle_docs_theme/template/docs/configuration.md.tpl +19 -0
  10. moodle_docs_theme-0.2.0/moodle_docs_theme/template/docs/index.md.tpl +19 -0
  11. moodle_docs_theme-0.2.0/moodle_docs_theme/template/docs/installation.md.tpl +40 -0
  12. moodle_docs_theme-0.2.0/moodle_docs_theme/template/docs/requirements.txt +3 -0
  13. moodle_docs_theme-0.2.0/moodle_docs_theme/template/docs/usage.md.tpl +21 -0
  14. moodle_docs_theme-0.2.0/moodle_docs_theme/template/workflows/docs.yml +60 -0
  15. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0/moodle_docs_theme.egg-info}/PKG-INFO +46 -3
  16. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme.egg-info/SOURCES.txt +13 -1
  17. moodle_docs_theme-0.2.0/moodle_docs_theme.egg-info/entry_points.txt +5 -0
  18. moodle_docs_theme-0.2.0/moodle_docs_theme.egg-info/requires.txt +6 -0
  19. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/pyproject.toml +14 -2
  20. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/setup.py +15 -1
  21. moodle_docs_theme-0.2.0/tests/test_cli.py +127 -0
  22. moodle_docs_theme-0.2.0/tests/test_theme.py +72 -0
  23. moodle_docs_theme-0.1.0/moodle_docs_theme.egg-info/entry_points.txt +0 -2
  24. moodle_docs_theme-0.1.0/moodle_docs_theme.egg-info/requires.txt +0 -1
  25. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/LICENSE +0 -0
  26. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/breadcrumbs.html +0 -0
  27. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/layout.html +0 -0
  28. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/page.html +0 -0
  29. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/searchbox.html +0 -0
  30. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/static/css/base.css +0 -0
  31. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/static/css/colors.css +0 -0
  32. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/static/js/theme.js +0 -0
  33. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/theme.conf +0 -0
  34. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme/theme.toml +0 -0
  35. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme.egg-info/dependency_links.txt +0 -0
  36. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/moodle_docs_theme.egg-info/top_level.txt +0 -0
  37. {moodle_docs_theme-0.1.0 → moodle_docs_theme-0.2.0}/setup.cfg +0 -0
@@ -4,3 +4,4 @@ include moodle_docs_theme/theme.conf
4
4
  include moodle_docs_theme/theme.toml
5
5
  include moodle_docs_theme/*.html
6
6
  recursive-include moodle_docs_theme/static *
7
+ recursive-include moodle_docs_theme/template *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moodle-docs-theme
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Um tema Sphinx reutilizável inspirado visualmente na documentação oficial do Moodle (docs.moodle.org)
5
5
  Home-page: https://github.com/moodle-by-kelsoncm/moodle-docs-theme
6
6
  Author: KelsonCM
@@ -25,6 +25,10 @@ Requires-Python: >=3.8
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
27
  Requires-Dist: sphinx>=4.0
28
+ Requires-Dist: myst-parser>=2.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-cov; extra == "dev"
28
32
  Dynamic: author
29
33
  Dynamic: home-page
30
34
  Dynamic: license-file
@@ -128,6 +132,35 @@ para a lista completa de opções.
128
132
 
129
133
  ---
130
134
 
135
+ ## Template de documentação para repositórios
136
+
137
+ O `moodle-docs-theme` inclui um template completo e padronizado para estruturar a documentação de qualquer repositório ou plugin Moodle da organização:
138
+
139
+ ### Inicialização via CLI
140
+
141
+ ```bash
142
+ # No diretório raiz do plugin
143
+ moodle-docs-theme init
144
+ ```
145
+
146
+ O comando detecta o tipo de plugin, configura o `docs/conf.py` (com suporte a Markdown nativo via `myst-parser`), cria as páginas modelo (`index.md`, `installation.md`, `configuration.md`, `usage.md`), `docs/requirements.txt` e o workflow do GitHub Actions em `.github/workflows/docs.yml`.
147
+
148
+ ### Compilando a documentação
149
+
150
+ Para compilar a documentação do projeto atual:
151
+
152
+ ```bash
153
+ moodle-docs-theme build
154
+ ```
155
+
156
+ Ou para compilar a documentação do próprio tema:
157
+
158
+ ```bash
159
+ python build_docs.py
160
+ ```
161
+
162
+ ---
163
+
131
164
  ## Estrutura do repositório
132
165
 
133
166
  ```
@@ -140,7 +173,8 @@ moodle-docs-theme/
140
173
  │ ├── conf.py
141
174
  │ ├── index.rst
142
175
  │ ├── installation.rst
143
- │ └── configuration.rst
176
+ │ ├── configuration.rst
177
+ │ └── template.rst # Guia de uso do template
144
178
  ├── moodle_docs_theme/ # Código fonte do tema Sphinx
145
179
  │ ├── static/
146
180
  │ │ ├── css/
@@ -148,6 +182,11 @@ moodle-docs-theme/
148
182
  │ │ │ └── colors.css
149
183
  │ │ └── js/
150
184
  │ │ └── theme.js
185
+ │ ├── template/ # Arquivos modelo do template de documentação
186
+ │ │ ├── docs/
187
+ │ │ └── workflows/
188
+ │ ├── cli.py # CLI moodle-docs-theme (init, build)
189
+ │ ├── __main__.py
151
190
  │ ├── layout.html
152
191
  │ ├── page.html
153
192
  │ ├── searchbox.html
@@ -155,6 +194,9 @@ moodle-docs-theme/
155
194
  │ ├── theme.conf
156
195
  │ ├── theme.toml
157
196
  │ └── __init__.py
197
+ ├── template/ # Template de documentação exposto na raiz
198
+ ├── tests/ # Testes automatizados (pytest)
199
+ ├── build_docs.py # Script para gerar a própria documentação
158
200
  ├── setup.py
159
201
  ├── pyproject.toml
160
202
  ├── MANIFEST.in
@@ -168,9 +210,10 @@ moodle-docs-theme/
168
210
 
169
211
  ```bash
170
212
  pip install -e .
171
- sphinx-build -b html docs docs/_build/html
213
+ python build_docs.py --clean
172
214
  ```
173
215
 
216
+
174
217
  ---
175
218
 
176
219
  ## Licença
@@ -96,6 +96,35 @@ para a lista completa de opções.
96
96
 
97
97
  ---
98
98
 
99
+ ## Template de documentação para repositórios
100
+
101
+ O `moodle-docs-theme` inclui um template completo e padronizado para estruturar a documentação de qualquer repositório ou plugin Moodle da organização:
102
+
103
+ ### Inicialização via CLI
104
+
105
+ ```bash
106
+ # No diretório raiz do plugin
107
+ moodle-docs-theme init
108
+ ```
109
+
110
+ O comando detecta o tipo de plugin, configura o `docs/conf.py` (com suporte a Markdown nativo via `myst-parser`), cria as páginas modelo (`index.md`, `installation.md`, `configuration.md`, `usage.md`), `docs/requirements.txt` e o workflow do GitHub Actions em `.github/workflows/docs.yml`.
111
+
112
+ ### Compilando a documentação
113
+
114
+ Para compilar a documentação do projeto atual:
115
+
116
+ ```bash
117
+ moodle-docs-theme build
118
+ ```
119
+
120
+ Ou para compilar a documentação do próprio tema:
121
+
122
+ ```bash
123
+ python build_docs.py
124
+ ```
125
+
126
+ ---
127
+
99
128
  ## Estrutura do repositório
100
129
 
101
130
  ```
@@ -108,7 +137,8 @@ moodle-docs-theme/
108
137
  │ ├── conf.py
109
138
  │ ├── index.rst
110
139
  │ ├── installation.rst
111
- │ └── configuration.rst
140
+ │ ├── configuration.rst
141
+ │ └── template.rst # Guia de uso do template
112
142
  ├── moodle_docs_theme/ # Código fonte do tema Sphinx
113
143
  │ ├── static/
114
144
  │ │ ├── css/
@@ -116,6 +146,11 @@ moodle-docs-theme/
116
146
  │ │ │ └── colors.css
117
147
  │ │ └── js/
118
148
  │ │ └── theme.js
149
+ │ ├── template/ # Arquivos modelo do template de documentação
150
+ │ │ ├── docs/
151
+ │ │ └── workflows/
152
+ │ ├── cli.py # CLI moodle-docs-theme (init, build)
153
+ │ ├── __main__.py
119
154
  │ ├── layout.html
120
155
  │ ├── page.html
121
156
  │ ├── searchbox.html
@@ -123,6 +158,9 @@ moodle-docs-theme/
123
158
  │ ├── theme.conf
124
159
  │ ├── theme.toml
125
160
  │ └── __init__.py
161
+ ├── template/ # Template de documentação exposto na raiz
162
+ ├── tests/ # Testes automatizados (pytest)
163
+ ├── build_docs.py # Script para gerar a própria documentação
126
164
  ├── setup.py
127
165
  ├── pyproject.toml
128
166
  ├── MANIFEST.in
@@ -136,9 +174,10 @@ moodle-docs-theme/
136
174
 
137
175
  ```bash
138
176
  pip install -e .
139
- sphinx-build -b html docs docs/_build/html
177
+ python build_docs.py --clean
140
178
  ```
141
179
 
180
+
142
181
  ---
143
182
 
144
183
  ## Licença
@@ -5,7 +5,7 @@ moodle_docs_theme - A reusable Sphinx HTML theme inspired by docs.moodle.org (Mo
5
5
  import os
6
6
  from typing import Dict, Any
7
7
 
8
- __version__ = "0.1.0"
8
+ __version__ = "0.2.0"
9
9
 
10
10
 
11
11
  def get_html_theme_path() -> str:
@@ -0,0 +1,8 @@
1
+ """
2
+ Executable module entrypoint for python -m moodle_docs_theme
3
+ """
4
+ import sys
5
+ from moodle_docs_theme.cli import main
6
+
7
+ if __name__ == "__main__":
8
+ sys.exit(main())
@@ -0,0 +1,305 @@
1
+ """
2
+ CLI para inicialização de templates e geração de documentação com moodle-docs-theme.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import datetime
8
+ import os
9
+ import shutil
10
+ import subprocess
11
+ import sys
12
+ from pathlib import Path
13
+ from typing import Dict, Optional, Sequence
14
+
15
+ from moodle_docs_theme import __version__
16
+ from moodle_docs_theme.template import get_template_dir
17
+
18
+
19
+ def _infer_plugin_info(folder_name: str) -> tuple[str, str]:
20
+ """
21
+ Infer Moodle plugin path and directory name based on common prefix conventions.
22
+ """
23
+ prefixes: dict[str, str] = {
24
+ "atto_": "lib/editor/atto/plugins",
25
+ "tiny_": "lib/editor/tiny/plugins",
26
+ "tool_": "admin/tool",
27
+ "block_": "blocks",
28
+ "mod_": "mod",
29
+ "local_": "local",
30
+ "format_": "course/format",
31
+ "profilefield_": "user/profile/field",
32
+ "editor_": "lib/editor",
33
+ "theme_": "theme",
34
+ }
35
+ for prefix, plugin_path in prefixes.items():
36
+ if folder_name.startswith(prefix):
37
+ dir_name = folder_name[len(prefix):]
38
+ return plugin_path, dir_name
39
+ return "local", folder_name
40
+
41
+
42
+ def _render_template(template_path: Path, context: Dict[str, str]) -> str:
43
+ """Render a template file with simple dictionary replacements."""
44
+ content = template_path.read_text(encoding="utf-8")
45
+ for key, value in context.items():
46
+ placeholder = f"{{{{ {key} }}}}"
47
+ content = content.replace(placeholder, str(value))
48
+ return content
49
+
50
+
51
+ def cmd_init(args: argparse.Namespace) -> int:
52
+ """
53
+ Inicializa a estrutura de documentação no repositório de destino usando o template moodle-docs-theme.
54
+ """
55
+ target_path = Path(args.target_dir).resolve()
56
+ folder_name = target_path.name
57
+
58
+ project_name = args.project_name or folder_name
59
+ repo_name = args.repo or f"moodle-by-kelsoncm/{folder_name}"
60
+ github_url = f"https://github.com/{repo_name.strip('/')}"
61
+ tagline = args.tagline or f"Documentação oficial de {project_name}"
62
+ version = args.version or "1.0.0"
63
+ year = str(datetime.datetime.now().year)
64
+
65
+ inferred_path, inferred_dir = _infer_plugin_info(folder_name)
66
+ plugin_path = args.plugin_path or inferred_path
67
+ plugin_dir_name = args.plugin_dir_name or inferred_dir
68
+
69
+ context: dict[str, str] = {
70
+ "project_name": project_name,
71
+ "repo_name": repo_name,
72
+ "github_url": github_url,
73
+ "github_repo": repo_name,
74
+ "tagline": tagline,
75
+ "version": version,
76
+ "year": year,
77
+ "plugin_path": plugin_path,
78
+ "plugin_dir_name": plugin_dir_name,
79
+ }
80
+
81
+ template_dir = Path(get_template_dir())
82
+ template_docs_dir = template_dir / "docs"
83
+ target_docs_dir = target_path / "docs"
84
+
85
+ target_docs_dir.mkdir(parents=True, exist_ok=True)
86
+
87
+ files_to_render = [
88
+ ("conf.py.tpl", "conf.py"),
89
+ ("index.md.tpl", "index.md"),
90
+ ("installation.md.tpl", "installation.md"),
91
+ ("configuration.md.tpl", "configuration.md"),
92
+ ("usage.md.tpl", "usage.md"),
93
+ ]
94
+
95
+ print(f"-> Inicializando template de documentação em: {target_path}")
96
+
97
+ created_files: list[str] = []
98
+ for src_name, dst_name in files_to_render:
99
+ src_file = template_docs_dir / src_name
100
+ dst_file = target_docs_dir / dst_name
101
+
102
+ if dst_file.exists() and not args.force:
103
+ print(f" [IGNORADO] Arquivo já existe: {dst_file.relative_to(target_path)} (use --force para sobrescrever)")
104
+ continue
105
+
106
+ rendered = _render_template(src_file, context)
107
+ dst_file.write_text(rendered, encoding="utf-8")
108
+ created_files.append(str(dst_file.relative_to(target_path)))
109
+ print(f" [CRIADO] {dst_file.relative_to(target_path)}")
110
+
111
+ # requirements.txt
112
+ req_src = template_docs_dir / "requirements.txt"
113
+ req_dst = target_docs_dir / "requirements.txt"
114
+ if not req_dst.exists() or args.force:
115
+ shutil.copy2(req_src, req_dst)
116
+ created_files.append(str(req_dst.relative_to(target_path)))
117
+ print(f" [CRIADO] {req_dst.relative_to(target_path)}")
118
+ else:
119
+ print(f" [IGNORADO] Arquivo já existe: {req_dst.relative_to(target_path)}")
120
+
121
+ # Workflow do GitHub Actions
122
+ if not args.no_workflow:
123
+ target_workflows_dir = target_path / ".github" / "workflows"
124
+ target_workflows_dir.mkdir(parents=True, exist_ok=True)
125
+ wf_src = template_dir / "workflows" / "docs.yml"
126
+ wf_dst = target_workflows_dir / "docs.yml"
127
+ if not wf_dst.exists() or args.force:
128
+ shutil.copy2(wf_src, wf_dst)
129
+ created_files.append(str(wf_dst.relative_to(target_path)))
130
+ print(f" [CRIADO] {wf_dst.relative_to(target_path)}")
131
+ else:
132
+ print(f" [IGNORADO] Workflow já existe: {wf_dst.relative_to(target_path)}")
133
+
134
+ print(f"\nSucesso: Template de documentação configurado ({len(created_files)} arquivos processados)!")
135
+ print("Para gerar a documentação localmente, execute:")
136
+ print(f" moodle-docs-theme build {target_docs_dir.relative_to(target_path)}\n")
137
+ return 0
138
+
139
+
140
+ def cmd_build(args: argparse.Namespace) -> int:
141
+ """
142
+ Compila a documentação usando Sphinx e moodle-docs-theme.
143
+ """
144
+ docs_dir = Path(args.docs_dir).resolve()
145
+ output_dir = Path(args.output_dir).resolve()
146
+
147
+ if not docs_dir.exists():
148
+ print(f"Erro: Diretório de documentação não encontrado: '{docs_dir}'", file=sys.stderr)
149
+ return 1
150
+
151
+ conf_file = docs_dir / "conf.py"
152
+ if not conf_file.exists():
153
+ print(f"Erro: Arquivo 'conf.py' não encontrado em: '{docs_dir}'", file=sys.stderr)
154
+ return 1
155
+
156
+ if args.clean and output_dir.exists():
157
+ print(f"-> Limpando diretório de saída: '{output_dir}'")
158
+ shutil.rmtree(output_dir)
159
+
160
+ output_dir.mkdir(parents=True, exist_ok=True)
161
+
162
+ sphinx_cmd = [
163
+ sys.executable,
164
+ "-m",
165
+ "sphinx",
166
+ "-b",
167
+ args.builder,
168
+ ]
169
+
170
+ if args.warnings_as_errors:
171
+ sphinx_cmd.append("-W")
172
+
173
+ sphinx_cmd.extend([str(docs_dir), str(output_dir)])
174
+
175
+ print(f"-> Gerando documentação: '{docs_dir}' -> '{output_dir}'")
176
+ try:
177
+ result = subprocess.run(sphinx_cmd, check=False)
178
+ if result.returncode == 0:
179
+ print(f"\nDocumentação gerada com sucesso em: {output_dir}")
180
+ index_path = output_dir / "index.html"
181
+ if index_path.exists():
182
+ print(f"Página inicial: {index_path}")
183
+ else:
184
+ print(f"\nFalha na geração da documentação (código de saída: {result.returncode})", file=sys.stderr)
185
+ return result.returncode
186
+ except Exception as exc:
187
+ print(f"Erro ao executar Sphinx: {exc}", file=sys.stderr)
188
+ return 1
189
+
190
+
191
+ def build_parser() -> argparse.ArgumentParser:
192
+ """Build the argument parser for moodle-docs-theme CLI."""
193
+ parser = argparse.ArgumentParser(
194
+ prog="moodle-docs-theme",
195
+ description="CLI do moodle-docs-theme para inicializar templates e compilar documentações.",
196
+ )
197
+ parser.add_argument(
198
+ "--version",
199
+ action="version",
200
+ version=f"%(prog)s {__version__}",
201
+ help="Exibe a versão do moodle-docs-theme.",
202
+ )
203
+
204
+ subparsers = parser.add_subparsers(dest="command", help="Comando a ser executado")
205
+
206
+ # Comando: init
207
+ init_parser = subparsers.add_parser(
208
+ "init",
209
+ help="Inicializa a estrutura de documentação em um repositório a partir do template padrão.",
210
+ )
211
+ init_parser.add_argument(
212
+ "target_dir",
213
+ nargs="?",
214
+ default=".",
215
+ help="Diretório raiz do repositório onde a documentação será inicializada (padrão: diretório atual).",
216
+ )
217
+ init_parser.add_argument(
218
+ "--project-name",
219
+ help="Nome do projeto / plugin (padrão: nome do diretório).",
220
+ )
221
+ init_parser.add_argument(
222
+ "--repo",
223
+ help="Caminho do repositório no GitHub (ex.: moodle-by-kelsoncm/atto_justify).",
224
+ )
225
+ init_parser.add_argument(
226
+ "--tagline",
227
+ help="Subtítulo ou descrição curta do projeto.",
228
+ )
229
+ init_parser.add_argument(
230
+ "--version-str",
231
+ dest="version",
232
+ help="Versão inicial da documentação (padrão: 1.0.0).",
233
+ )
234
+ init_parser.add_argument(
235
+ "--plugin-path",
236
+ help="Caminho relativo da categoria do plugin no Moodle (ex.: lib/editor/atto/plugins).",
237
+ )
238
+ init_parser.add_argument(
239
+ "--plugin-dir-name",
240
+ help="Nome da pasta do plugin dentro da categoria (ex.: justify).",
241
+ )
242
+ init_parser.add_argument(
243
+ "--force",
244
+ action="store_true",
245
+ help="Sobrescreve arquivos existentes caso já estejam presentes.",
246
+ )
247
+ init_parser.add_argument(
248
+ "--no-workflow",
249
+ action="store_true",
250
+ help="Não gera o workflow do GitHub Actions em .github/workflows/docs.yml.",
251
+ )
252
+ init_parser.set_defaults(func=cmd_init)
253
+
254
+ # Comando: build
255
+ build_cmd_parser = subparsers.add_parser(
256
+ "build",
257
+ help="Compila a documentação com Sphinx e moodle-docs-theme.",
258
+ )
259
+ build_cmd_parser.add_argument(
260
+ "docs_dir",
261
+ nargs="?",
262
+ default="docs",
263
+ help="Diretório onde reside a documentação (contendo conf.py, padrão: 'docs').",
264
+ )
265
+ build_cmd_parser.add_argument(
266
+ "output_dir",
267
+ nargs="?",
268
+ default="docs/_build/html",
269
+ help="Diretório de saída para os arquivos HTML (padrão: 'docs/_build/html').",
270
+ )
271
+ build_cmd_parser.add_argument(
272
+ "--clean",
273
+ action="store_true",
274
+ help="Limpa o diretório de saída antes de compilar.",
275
+ )
276
+ build_cmd_parser.add_argument(
277
+ "--builder",
278
+ default="html",
279
+ help="Formato de saída do Sphinx (padrão: 'html').",
280
+ )
281
+ build_cmd_parser.add_argument(
282
+ "-W",
283
+ "--warnings-as-errors",
284
+ action="store_true",
285
+ help="Trata warnings do Sphinx como erros.",
286
+ )
287
+ build_cmd_parser.set_defaults(func=cmd_build)
288
+
289
+ return parser
290
+
291
+
292
+ def main(argv: Optional[Sequence[str]] = None) -> int:
293
+ """Main CLI entry point."""
294
+ parser = build_parser()
295
+ args = parser.parse_args(argv)
296
+
297
+ if not hasattr(args, "func"):
298
+ parser.print_help()
299
+ return 0
300
+
301
+ return args.func(args)
302
+
303
+
304
+ if __name__ == "__main__":
305
+ sys.exit(main())
@@ -0,0 +1,10 @@
1
+ """
2
+ Template files for moodle-docs-theme.
3
+ This file marks the package and provides helper to locate template files.
4
+ """
5
+ import os
6
+
7
+
8
+ def get_template_dir() -> str:
9
+ """Return the absolute path to the template directory."""
10
+ return os.path.join(os.path.abspath(os.path.dirname(__file__)))
@@ -0,0 +1,59 @@
1
+ """
2
+ Sphinx configuration for {{ project_name }}.
3
+ Documentação gerada com o template moodle-docs-theme.
4
+ """
5
+ import os
6
+ import sys
7
+ import moodle_docs_theme
8
+
9
+ # -- Informações do Projeto --------------------------------------------------
10
+ project = "{{ project_name }}"
11
+ copyright = "{{ year }}, Contribuições de KelsonCM à comunidade Moodle"
12
+ author = "KelsonCM"
13
+ release = "{{ version }}"
14
+
15
+ # -- Configuração Geral ------------------------------------------------------
16
+ extensions = [
17
+ "sphinx.ext.githubpages",
18
+ "moodle_docs_theme",
19
+ "myst_parser",
20
+ ]
21
+
22
+ # Suporte a arquivos reStructuredText (.rst) e Markdown (.md)
23
+ source_suffix = {
24
+ ".rst": "restructuredtext",
25
+ ".md": "markdown",
26
+ }
27
+
28
+ # Configurações do MyST-Parser (Markdown)
29
+ myst_enable_extensions = [
30
+ "colon_fence",
31
+ "deflist",
32
+ "tasklist",
33
+ ]
34
+ myst_heading_anchors = 3
35
+
36
+ templates_path = []
37
+ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
38
+
39
+ language = "pt_BR"
40
+
41
+ # -- Opções de Saída HTML ----------------------------------------------------
42
+ html_theme = "moodle_docs_theme"
43
+ html_theme_path = [moodle_docs_theme.get_html_theme_path()]
44
+
45
+ html_theme_options = {
46
+ "primary_color": "#6c336d",
47
+ "secondary_color": "#f98012",
48
+ "project_name": "{{ project_name }}",
49
+ "tagline": "{{ tagline }}",
50
+ "github_url": "{{ github_url }}",
51
+ "github_repo": "{{ github_repo }}",
52
+ "github_version": "main",
53
+ "doc_path": "docs/",
54
+ "show_edit_on_github": True,
55
+ "enable_dark_mode": True,
56
+ "navigation_links": "Início|index, Instalação|installation, Configuração|configuration, Uso|usage",
57
+ }
58
+
59
+ html_static_path = []
@@ -0,0 +1,19 @@
1
+ # Configuração — {{ project_name }}
2
+
3
+ Após a instalação, configure as opções do plugin na administração do Moodle.
4
+
5
+ ---
6
+
7
+ ## Acessando as Configurações
8
+
9
+ 1. Acesse o Moodle com uma conta com privilégios de administrador.
10
+ 2. Navegue até **Administração do Site** > **Plugins**.
11
+ 3. Localize **{{ project_name }}** na categoria do plugin.
12
+
13
+ ---
14
+
15
+ ## Parâmetros Disponíveis
16
+
17
+ | Parâmetro | Tipo | Padrão | Descrição |
18
+ |-----------|------|--------|-----------|
19
+ | `enabled` | Booleano | Sim | Ativa ou desativa as funcionalidades do plugin. |
@@ -0,0 +1,19 @@
1
+ # Visão Geral — {{ project_name }}
2
+
3
+ O **{{ project_name }}** é um componente desenvolvido e mantido pela organização [moodle-by-kelsoncm](https://github.com/moodle-by-kelsoncm) para o ecossistema Moodle.
4
+
5
+ ---
6
+
7
+ ## 🚀 Principais Recursos
8
+
9
+ - **Recurso 1**: Descrição do primeiro recurso principal do componente.
10
+ - **Recurso 2**: Descrição do segundo recurso principal.
11
+ - **Compatibilidade**: Projetado para Moodle 4.x e versões compatíveis.
12
+
13
+ ---
14
+
15
+ ## 📚 Tópicos da Documentação
16
+
17
+ - 📦 **[Instalação](installation.md)** — Como instalar o componente manualmente ou via Git.
18
+ - ⚙️ **[Configuração](configuration.md)** — Como configurar e parametrizar o plugin no Moodle.
19
+ - 📖 **[Guia de Uso](usage.md)** — Instruções detalhadas de utilização e fluxos recomendados.
@@ -0,0 +1,40 @@
1
+ # Instalação — {{ project_name }}
2
+
3
+ Este guia descreve os passos para instalar o **{{ project_name }}** no seu ambiente Moodle.
4
+
5
+ ---
6
+
7
+ ## Requisitos
8
+
9
+ - **Moodle**: 4.0 ou superior (recomendado Moodle 4.5+).
10
+ - **PHP**: 8.1 ou superior (recomendado PHP 8.3+).
11
+ - Permissões de escrita no diretório do plugin durante a instalação.
12
+
13
+ ---
14
+
15
+ ## Métodos de Instalação
16
+
17
+ ### 1. Via Git (Recomendado para Desenvolvimento)
18
+
19
+ Clone o repositório diretamente no diretório apropriado do seu Moodle:
20
+
21
+ ```bash
22
+ cd /caminho/do/moodle/{{ plugin_path }}
23
+ git clone {{ github_url }}.git {{ plugin_dir_name }}
24
+ ```
25
+
26
+ ### 2. Via Pacote ZIP
27
+
28
+ 1. Baixe o arquivo `.zip` da release mais recente no [GitHub Releases]({{ github_url }}/releases).
29
+ 2. Extraia o conteúdo na pasta correspondente do Moodle (`{{ plugin_path }}/{{ plugin_dir_name }}`).
30
+ 3. Acesse a administração do Moodle (*Administração do Site > Notificações*) para concluir a instalação do banco de dados.
31
+
32
+ ---
33
+
34
+ ## Pós-Instalação
35
+
36
+ Após a instalação, purgue os caches do Moodle:
37
+
38
+ ```bash
39
+ php admin/cli/purge_caches.php
40
+ ```
@@ -0,0 +1,3 @@
1
+ sphinx>=7.0
2
+ myst-parser>=2.0
3
+ moodle-docs-theme>=0.1.0
@@ -0,0 +1,21 @@
1
+ # Guia de Uso — {{ project_name }}
2
+
3
+ Instruções práticas e fluxos de trabalho para o **{{ project_name }}**.
4
+
5
+ ---
6
+
7
+ ## Fluxo de Trabalho
8
+
9
+ Descreva aqui as etapas principais para utilizar o plugin no dia a dia do Moodle.
10
+
11
+ ---
12
+
13
+ ## Exemplos Práticos
14
+
15
+ ### Caso 1: Utilização Básica
16
+
17
+ Explique o cenário comum de utilização pelo usuário final ou professor.
18
+
19
+ ### Caso 2: Utilização Avançada
20
+
21
+ Explique cenários avançados de integração ou automação.
@@ -0,0 +1,60 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, master ]
6
+ pull_request:
7
+ branches: [ main, master ]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ pages: write
13
+ id-token: write
14
+
15
+ concurrency:
16
+ group: "pages-${{ github.ref }}"
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ build-docs:
21
+ name: Build Documentation
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - name: Checkout repository
26
+ uses: actions/checkout@v4
27
+
28
+ - name: Set up Python 3.12
29
+ uses: actions/setup-python@v5
30
+ with:
31
+ python-version: '3.12'
32
+
33
+ - name: Install dependencies
34
+ run: |
35
+ python -m pip install --upgrade pip
36
+ pip install sphinx myst-parser moodle-docs-theme
37
+
38
+ - name: Build Documentation with Sphinx
39
+ run: |
40
+ sphinx-build -W -b html docs docs/_build/html
41
+
42
+ - name: Upload Pages Artifact
43
+ if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') && github.event_name != 'pull_request'
44
+ uses: actions/upload-pages-artifact@v3
45
+ with:
46
+ path: docs/_build/html
47
+
48
+ deploy-docs:
49
+ name: Deploy to GitHub Pages
50
+ if: (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') && github.event_name != 'pull_request'
51
+ needs: build-docs
52
+ runs-on: ubuntu-latest
53
+ environment:
54
+ name: github-pages
55
+ url: ${{ steps.deployment.outputs.page_url }}
56
+
57
+ steps:
58
+ - name: Deploy to GitHub Pages
59
+ id: deployment
60
+ uses: actions/deploy-pages@v4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moodle-docs-theme
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Um tema Sphinx reutilizável inspirado visualmente na documentação oficial do Moodle (docs.moodle.org)
5
5
  Home-page: https://github.com/moodle-by-kelsoncm/moodle-docs-theme
6
6
  Author: KelsonCM
@@ -25,6 +25,10 @@ Requires-Python: >=3.8
25
25
  Description-Content-Type: text/markdown
26
26
  License-File: LICENSE
27
27
  Requires-Dist: sphinx>=4.0
28
+ Requires-Dist: myst-parser>=2.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-cov; extra == "dev"
28
32
  Dynamic: author
29
33
  Dynamic: home-page
30
34
  Dynamic: license-file
@@ -128,6 +132,35 @@ para a lista completa de opções.
128
132
 
129
133
  ---
130
134
 
135
+ ## Template de documentação para repositórios
136
+
137
+ O `moodle-docs-theme` inclui um template completo e padronizado para estruturar a documentação de qualquer repositório ou plugin Moodle da organização:
138
+
139
+ ### Inicialização via CLI
140
+
141
+ ```bash
142
+ # No diretório raiz do plugin
143
+ moodle-docs-theme init
144
+ ```
145
+
146
+ O comando detecta o tipo de plugin, configura o `docs/conf.py` (com suporte a Markdown nativo via `myst-parser`), cria as páginas modelo (`index.md`, `installation.md`, `configuration.md`, `usage.md`), `docs/requirements.txt` e o workflow do GitHub Actions em `.github/workflows/docs.yml`.
147
+
148
+ ### Compilando a documentação
149
+
150
+ Para compilar a documentação do projeto atual:
151
+
152
+ ```bash
153
+ moodle-docs-theme build
154
+ ```
155
+
156
+ Ou para compilar a documentação do próprio tema:
157
+
158
+ ```bash
159
+ python build_docs.py
160
+ ```
161
+
162
+ ---
163
+
131
164
  ## Estrutura do repositório
132
165
 
133
166
  ```
@@ -140,7 +173,8 @@ moodle-docs-theme/
140
173
  │ ├── conf.py
141
174
  │ ├── index.rst
142
175
  │ ├── installation.rst
143
- │ └── configuration.rst
176
+ │ ├── configuration.rst
177
+ │ └── template.rst # Guia de uso do template
144
178
  ├── moodle_docs_theme/ # Código fonte do tema Sphinx
145
179
  │ ├── static/
146
180
  │ │ ├── css/
@@ -148,6 +182,11 @@ moodle-docs-theme/
148
182
  │ │ │ └── colors.css
149
183
  │ │ └── js/
150
184
  │ │ └── theme.js
185
+ │ ├── template/ # Arquivos modelo do template de documentação
186
+ │ │ ├── docs/
187
+ │ │ └── workflows/
188
+ │ ├── cli.py # CLI moodle-docs-theme (init, build)
189
+ │ ├── __main__.py
151
190
  │ ├── layout.html
152
191
  │ ├── page.html
153
192
  │ ├── searchbox.html
@@ -155,6 +194,9 @@ moodle-docs-theme/
155
194
  │ ├── theme.conf
156
195
  │ ├── theme.toml
157
196
  │ └── __init__.py
197
+ ├── template/ # Template de documentação exposto na raiz
198
+ ├── tests/ # Testes automatizados (pytest)
199
+ ├── build_docs.py # Script para gerar a própria documentação
158
200
  ├── setup.py
159
201
  ├── pyproject.toml
160
202
  ├── MANIFEST.in
@@ -168,9 +210,10 @@ moodle-docs-theme/
168
210
 
169
211
  ```bash
170
212
  pip install -e .
171
- sphinx-build -b html docs docs/_build/html
213
+ python build_docs.py --clean
172
214
  ```
173
215
 
216
+
174
217
  ---
175
218
 
176
219
  ## Licença
@@ -4,7 +4,9 @@ README.md
4
4
  pyproject.toml
5
5
  setup.py
6
6
  moodle_docs_theme/__init__.py
7
+ moodle_docs_theme/__main__.py
7
8
  moodle_docs_theme/breadcrumbs.html
9
+ moodle_docs_theme/cli.py
8
10
  moodle_docs_theme/layout.html
9
11
  moodle_docs_theme/page.html
10
12
  moodle_docs_theme/searchbox.html
@@ -18,4 +20,14 @@ moodle_docs_theme.egg-info/requires.txt
18
20
  moodle_docs_theme.egg-info/top_level.txt
19
21
  moodle_docs_theme/static/css/base.css
20
22
  moodle_docs_theme/static/css/colors.css
21
- moodle_docs_theme/static/js/theme.js
23
+ moodle_docs_theme/static/js/theme.js
24
+ moodle_docs_theme/template/__init__.py
25
+ moodle_docs_theme/template/docs/conf.py.tpl
26
+ moodle_docs_theme/template/docs/configuration.md.tpl
27
+ moodle_docs_theme/template/docs/index.md.tpl
28
+ moodle_docs_theme/template/docs/installation.md.tpl
29
+ moodle_docs_theme/template/docs/requirements.txt
30
+ moodle_docs_theme/template/docs/usage.md.tpl
31
+ moodle_docs_theme/template/workflows/docs.yml
32
+ tests/test_cli.py
33
+ tests/test_theme.py
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ moodle-docs-theme = moodle_docs_theme.cli:main
3
+
4
+ [sphinx.html_themes]
5
+ moodle_docs_theme = moodle_docs_theme
@@ -0,0 +1,6 @@
1
+ sphinx>=4.0
2
+ myst-parser>=2.0
3
+
4
+ [dev]
5
+ pytest>=7.0
6
+ pytest-cov
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "moodle-docs-theme"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "Um tema Sphinx reutilizável inspirado visualmente na documentação oficial do Moodle (docs.moodle.org)"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -13,7 +13,8 @@ authors = [
13
13
  license = "BSD-3-Clause"
14
14
  requires-python = ">=3.8"
15
15
  dependencies = [
16
- "sphinx>=4.0"
16
+ "sphinx>=4.0",
17
+ "myst-parser>=2.0"
17
18
  ]
18
19
  classifiers = [
19
20
  "Development Status :: 4 - Beta",
@@ -31,10 +32,19 @@ classifiers = [
31
32
  "Topic :: Software Development :: Documentation"
32
33
  ]
33
34
 
35
+ [project.optional-dependencies]
36
+ dev = [
37
+ "pytest>=7.0",
38
+ "pytest-cov"
39
+ ]
40
+
34
41
  [project.urls]
35
42
  Homepage = "https://github.com/moodle-by-kelsoncm/moodle-docs-theme"
36
43
  Repository = "https://github.com/moodle-by-kelsoncm/moodle-docs-theme"
37
44
 
45
+ [project.scripts]
46
+ moodle-docs-theme = "moodle_docs_theme.cli:main"
47
+
38
48
  [project.entry-points."sphinx.html_themes"]
39
49
  moodle_docs_theme = "moodle_docs_theme"
40
50
 
@@ -49,4 +59,6 @@ moodle_docs_theme = [
49
59
  "theme.toml",
50
60
  "static/css/*.css",
51
61
  "static/js/*.js",
62
+ "template/docs/*",
63
+ "template/workflows/*",
52
64
  ]
@@ -6,22 +6,36 @@ with open("README.md", "r", encoding="utf-8") as fh:
6
6
 
7
7
  setup(
8
8
  name="moodle-docs-theme",
9
- version="0.1.0",
9
+ version="0.2.0",
10
10
  author="KelsonCM",
11
11
  author_email="kelsoncm@gmail.com",
12
12
  description="Um tema Sphinx reutilizável inspirado visualmente na documentação oficial do Moodle (docs.moodle.org)",
13
13
  long_description=long_description,
14
14
  long_description_content_type="text/markdown",
15
15
  url="https://github.com/moodle-by-kelsoncm/moodle-docs-theme",
16
+ install_requires=[
17
+ "sphinx>=4.0",
18
+ "myst-parser>=2.0",
19
+ ],
20
+ extras_require={
21
+ "dev": [
22
+ "pytest>=7.0",
23
+ "pytest-cov",
24
+ ],
25
+ },
16
26
  packages=find_namespace_packages(include=["moodle_docs_theme*"]),
17
27
  include_package_data=True,
18
28
  package_data={
19
29
  "moodle_docs_theme": [
20
30
  "*.html", "theme.conf", "theme.toml",
21
31
  "static/css/*.css", "static/js/*.js",
32
+ "template/docs/*", "template/workflows/*",
22
33
  ],
23
34
  },
24
35
  entry_points={
36
+ "console_scripts": [
37
+ "moodle-docs-theme = moodle_docs_theme.cli:main",
38
+ ],
25
39
  "sphinx.html_themes": [
26
40
  "moodle_docs_theme = moodle_docs_theme",
27
41
  ],
@@ -0,0 +1,127 @@
1
+ """
2
+ Testes unitários para o CLI do moodle-docs-theme.
3
+ """
4
+ import os
5
+ import shutil
6
+ import tempfile
7
+ import unittest
8
+ from pathlib import Path
9
+ from unittest.mock import patch
10
+
11
+ from moodle_docs_theme.cli import (
12
+ _infer_plugin_info,
13
+ _render_template,
14
+ build_parser,
15
+ main,
16
+ )
17
+
18
+
19
+ class TestMoodleDocsThemeCLI(unittest.TestCase):
20
+
21
+ def setUp(self):
22
+ self.test_dir = tempfile.mkdtemp()
23
+
24
+ def tearDown(self):
25
+ shutil.rmtree(self.test_dir, ignore_errors=True)
26
+
27
+ def test_infer_plugin_info(self):
28
+ self.assertEqual(_infer_plugin_info("atto_justify"), ("lib/editor/atto/plugins", "justify"))
29
+ self.assertEqual(_infer_plugin_info("tiny_fontfamily"), ("lib/editor/tiny/plugins", "fontfamily"))
30
+ self.assertEqual(_infer_plugin_info("tool_ribbons"), ("admin/tool", "ribbons"))
31
+ self.assertEqual(_infer_plugin_info("block_recommendation"), ("blocks", "recommendation"))
32
+ self.assertEqual(_infer_plugin_info("mod_imagemap"), ("mod", "imagemap"))
33
+ self.assertEqual(_infer_plugin_info("local_tinytoolbar"), ("local", "tinytoolbar"))
34
+ self.assertEqual(_infer_plugin_info("format_timeline"), ("course/format", "timeline"))
35
+ self.assertEqual(_infer_plugin_info("profilefield_json"), ("user/profile/field", "json"))
36
+ self.assertEqual(_infer_plugin_info("theme_boost"), ("theme", "boost"))
37
+ self.assertEqual(_infer_plugin_info("custom_repo"), ("local", "custom_repo"))
38
+
39
+ def test_render_template(self):
40
+ tpl_path = Path(self.test_dir) / "template.txt"
41
+ tpl_path.write_text("Hello {{ name }}! Repo: {{ repo }}", encoding="utf-8")
42
+ result = _render_template(tpl_path, {"name": "World", "repo": "moodle/org"})
43
+ self.assertEqual(result, "Hello World! Repo: moodle/org")
44
+
45
+ def test_cli_init_default(self):
46
+ target_dir = Path(self.test_dir) / "tool_sample"
47
+ target_dir.mkdir()
48
+
49
+ exit_code = main(["init", str(target_dir)])
50
+ self.assertEqual(exit_code, 0)
51
+
52
+ docs_dir = target_dir / "docs"
53
+ self.assertTrue((docs_dir / "conf.py").exists())
54
+ self.assertTrue((docs_dir / "index.md").exists())
55
+ self.assertTrue((docs_dir / "installation.md").exists())
56
+ self.assertTrue((docs_dir / "configuration.md").exists())
57
+ self.assertTrue((docs_dir / "usage.md").exists())
58
+ self.assertTrue((docs_dir / "requirements.txt").exists())
59
+ self.assertTrue((target_dir / ".github" / "workflows" / "docs.yml").exists())
60
+
61
+ # Verifica conteúdo renderizado
62
+ conf_content = (docs_dir / "conf.py").read_text(encoding="utf-8")
63
+ self.assertIn('project = "tool_sample"', conf_content)
64
+ self.assertIn('"github_repo": "moodle-by-kelsoncm/tool_sample"', conf_content)
65
+ self.assertIn('"moodle_docs_theme"', conf_content)
66
+
67
+ def test_cli_init_custom_options(self):
68
+ target_dir = Path(self.test_dir) / "atto_custom"
69
+ target_dir.mkdir()
70
+
71
+ exit_code = main([
72
+ "init",
73
+ str(target_dir),
74
+ "--project-name", "moodle-atto_custom",
75
+ "--repo", "moodle-by-kelsoncm/atto_custom",
76
+ "--tagline", "Custom Atto plugin description",
77
+ "--version-str", "2.1.0",
78
+ "--no-workflow",
79
+ ])
80
+ self.assertEqual(exit_code, 0)
81
+
82
+ docs_dir = target_dir / "docs"
83
+ conf_content = (docs_dir / "conf.py").read_text(encoding="utf-8")
84
+ self.assertIn('project = "moodle-atto_custom"', conf_content)
85
+ self.assertIn('release = "2.1.0"', conf_content)
86
+ self.assertIn('Custom Atto plugin description', conf_content)
87
+
88
+ # Sem workflow
89
+ self.assertFalse((target_dir / ".github" / "workflows" / "docs.yml").exists())
90
+
91
+ def test_cli_init_skip_existing_without_force(self):
92
+ target_dir = Path(self.test_dir) / "existing_repo"
93
+ target_dir.mkdir()
94
+ docs_dir = target_dir / "docs"
95
+ docs_dir.mkdir()
96
+ (docs_dir / "conf.py").write_text("existing content", encoding="utf-8")
97
+
98
+ exit_code = main(["init", str(target_dir)])
99
+ self.assertEqual(exit_code, 0)
100
+
101
+ self.assertEqual((docs_dir / "conf.py").read_text(encoding="utf-8"), "existing content")
102
+
103
+ # Com --force deve sobrescrever
104
+ exit_code = main(["init", str(target_dir), "--force"])
105
+ self.assertEqual(exit_code, 0)
106
+ self.assertIn("moodle_docs_theme", (docs_dir / "conf.py").read_text(encoding="utf-8"))
107
+
108
+ def test_cli_build_nonexistent_directory(self):
109
+ nonexistent = str(Path(self.test_dir) / "nao_existe")
110
+ exit_code = main(["build", nonexistent])
111
+ self.assertEqual(exit_code, 1)
112
+
113
+ def test_cli_build_missing_conf_py(self):
114
+ empty_dir = str(Path(self.test_dir) / "empty")
115
+ os.makedirs(empty_dir)
116
+ exit_code = main(["build", empty_dir])
117
+ self.assertEqual(exit_code, 1)
118
+
119
+ def test_parser_version(self):
120
+ parser = build_parser()
121
+ with self.assertRaises(SystemExit) as ctx:
122
+ parser.parse_args(["--version"])
123
+ self.assertEqual(ctx.exception.code, 0)
124
+
125
+
126
+ if __name__ == "__main__":
127
+ unittest.main()
@@ -0,0 +1,72 @@
1
+ """
2
+ Testes unitários para o tema moodle_docs_theme.
3
+ """
4
+ import os
5
+ import unittest
6
+ from unittest.mock import MagicMock
7
+
8
+ import moodle_docs_theme
9
+
10
+
11
+ class TestMoodleDocsTheme(unittest.TestCase):
12
+
13
+ def test_version(self):
14
+ self.assertIsNotNone(moodle_docs_theme.__version__)
15
+ self.assertTrue(len(moodle_docs_theme.__version__) > 0)
16
+
17
+ def test_get_html_theme_path(self):
18
+ theme_path = moodle_docs_theme.get_html_theme_path()
19
+ self.assertTrue(os.path.isdir(theme_path))
20
+ self.assertTrue(os.path.exists(os.path.join(theme_path, "theme.conf")))
21
+ self.assertTrue(os.path.exists(os.path.join(theme_path, "layout.html")))
22
+
23
+ def test_setup(self):
24
+ mock_app = MagicMock()
25
+ result = moodle_docs_theme.setup(mock_app)
26
+
27
+ mock_app.add_html_theme.assert_called_once_with(
28
+ "moodle_docs_theme", moodle_docs_theme.get_html_theme_path()
29
+ )
30
+ self.assertEqual(mock_app.add_css_file.call_count, 2)
31
+ self.assertEqual(mock_app.add_js_file.call_count, 1)
32
+ self.assertTrue(result["parallel_read_safe"])
33
+ self.assertTrue(result["parallel_write_safe"])
34
+
35
+ def test_validate_github_actions_config_skipped_locally(self):
36
+ # Se GITHUB_ACTIONS não for 'true', não deve validar/lançar erro
37
+ old_val = os.environ.pop("GITHUB_ACTIONS", None)
38
+ old_run_id = os.environ.pop("GITHUB_RUN_ID", None)
39
+ try:
40
+ mock_app = MagicMock()
41
+ mock_app.config.extensions = []
42
+ # Não deve lançar exceção
43
+ moodle_docs_theme.validate_github_actions_config(mock_app)
44
+ finally:
45
+ if old_val is not None:
46
+ os.environ["GITHUB_ACTIONS"] = old_val
47
+ if old_run_id is not None:
48
+ os.environ["GITHUB_RUN_ID"] = old_run_id
49
+
50
+ def test_validate_github_actions_config_raises_when_missing(self):
51
+ from sphinx.errors import ExtensionError
52
+
53
+ old_val = os.environ.get("GITHUB_ACTIONS")
54
+ try:
55
+ os.environ["GITHUB_ACTIONS"] = "true"
56
+ mock_app = MagicMock()
57
+ mock_app.config.extensions = ["sphinx.ext.autodoc"]
58
+
59
+ with self.assertRaises(ExtensionError) as ctx:
60
+ moodle_docs_theme.validate_github_actions_config(mock_app)
61
+
62
+ self.assertIn("moodle_docs_theme", str(ctx.exception))
63
+ self.assertIn("sphinx.ext.githubpages", str(ctx.exception))
64
+ finally:
65
+ if old_val is not None:
66
+ os.environ["GITHUB_ACTIONS"] = old_val
67
+ else:
68
+ os.environ.pop("GITHUB_ACTIONS", None)
69
+
70
+
71
+ if __name__ == "__main__":
72
+ unittest.main()
@@ -1,2 +0,0 @@
1
- [sphinx.html_themes]
2
- moodle_docs_theme = moodle_docs_theme
@@ -1 +0,0 @@
1
- sphinx>=4.0