Skip to content

Commit fe908bc

Browse files
authored
Add generate-schema command for JSON schema generation (#63)
## Description This PR adds a new `generate-schema` command that generates JSON schema definitions for available structure templates. ## Features - **New Command**: `struct generate-schema` command - **Flexible Input**: Supports scanning built-in contribs directory and custom structures path - **Output Options**: Can output to stdout or save to a specified file - **JSON Schema Generation**: Creates a properly formatted JSON schema with PluginList enum ## Usage ```bash # Generate schema to stdout struct generate-schema # Generate schema with custom structures path struct generate-schema -s /path/to/structures # Save schema to file struct generate-schema -o schema.json # Combine custom path and output file struct generate-schema -s /path/to/structures -o schema.json ``` ## Implementation Details - Scans YAML files in the contribs directory and optional custom structures path - Removes file extensions and creates relative paths for structure names - Generates JSON schema with sorted enum values for consistency - Includes proper error handling and logging - Creates output directories if they don't exist ## Files Changed - `struct_module/commands/generate_schema.py` - New command implementation - `struct_module/main.py` - Updated to register the new command - `docs/generate-schema.md` - Added documentation for the new command This enhancement makes it easier for users and tools to discover available structure templates programmatically.
1 parent 58d341f commit fe908bc

File tree

5 files changed

+460
-3
lines changed

5 files changed

+460
-3
lines changed

README.es.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct structure.yaml .
102102
Ejecuta el script con el siguiente comando usando uno de los siguientes subcomandos:
103103

104104
- `generate`: Genera la estructura del proyecto basada en la configuración YAML.
105+
- `generate-schema`: Genera esquema JSON para las plantillas de estructura disponibles.
105106
- `validate`: Valida la configuración YAML para asegurarte de que sea válida.
106107
- `info`: Muestra información sobre el script y sus dependencias.
107108
- `list`: Lista las estructuras disponibles.
@@ -133,6 +134,37 @@ struct generate \
133134

134135
```
135136

137+
### Comando Generate Schema
138+
139+
El comando `generate-schema` crea definiciones de esquema JSON para las plantillas de estructura disponibles, facilitando que las herramientas e IDEs proporcionen autocompletado y validación.
140+
141+
#### Uso Básico
142+
143+
```sh
144+
# Generar esquema a stdout
145+
struct generate-schema
146+
147+
# Generar esquema con ruta de estructuras personalizada
148+
struct generate-schema -s /ruta/a/estructuras/personalizadas
149+
150+
# Guardar esquema en archivo
151+
struct generate-schema -o schema.json
152+
153+
# Combinar ruta personalizada y archivo de salida
154+
struct generate-schema -s /ruta/a/estructuras/personalizadas -o schema.json
155+
```
156+
157+
#### Opciones del Comando
158+
159+
- `-s, --structures-path`: Ruta a definiciones de estructura adicionales (opcional)
160+
- `-o, --output`: Ruta del archivo de salida para el esquema (predeterminado: stdout)
161+
162+
El esquema generado incluye todas las estructuras disponibles tanto del directorio contribs integrado como de cualquier ruta de estructuras personalizada que especifiques. Esto es útil para:
163+
164+
- Autocompletado IDE al escribir archivos `.struct.yaml`
165+
- Validación de referencias de estructura en tus configuraciones
166+
- Descubrimiento programático de plantillas disponibles
167+
136168
## 📄 Configuración YAML
137169

138170
Aquí tienes un ejemplo de un archivo de configuración YAML:
@@ -402,7 +434,7 @@ Puedes referenciar valores del mapping en tus plantillas usando la variable `map
402434

403435
Esto se renderizará como:
404436

405-
```
437+
```text
406438
987654321
407439
```
408440

README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct generate structure.yaml .
9797
Run the script with the following command using one of the following subcommands:
9898

9999
- `generate`: Generate the project structure based on the YAML configuration.
100+
- `generate-schema`: Generate JSON schema for available structure templates.
100101
- `validate`: Validate the YAML configuration file.
101102
- `info`: Display information about the script and its dependencies.
102103
- `list`: List the available structs
@@ -128,6 +129,37 @@ struct generate \
128129
./my-terraform-module
129130
```
130131

132+
### Generate Schema Command
133+
134+
The `generate-schema` command creates JSON schema definitions for available structure templates, making it easier for tools and IDEs to provide autocompletion and validation.
135+
136+
#### Basic Usage
137+
138+
```sh
139+
# Generate schema to stdout
140+
struct generate-schema
141+
142+
# Generate schema with custom structures path
143+
struct generate-schema -s /path/to/custom/structures
144+
145+
# Save schema to file
146+
struct generate-schema -o schema.json
147+
148+
# Combine custom path and output file
149+
struct generate-schema -s /path/to/custom/structures -o schema.json
150+
```
151+
152+
#### Command Options
153+
154+
- `-s, --structures-path`: Path to additional structure definitions (optional)
155+
- `-o, --output`: Output file path for the schema (default: stdout)
156+
157+
The generated schema includes all available structures from both the built-in contribs directory and any custom structures path you specify. This is useful for:
158+
159+
- IDE autocompletion when writing `.struct.yaml` files
160+
- Validation of structure references in your configurations
161+
- Programmatic discovery of available templates
162+
131163
## 📝 YAML Configuration
132164

133165
### Configuration Properties
@@ -471,7 +503,7 @@ You can reference mapping values in your templates using the `mappings` variable
471503

472504
This will render as:
473505

474-
```
506+
```text
475507
987654321
476508
```
477509

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from struct_module.commands import Command
2+
import os
3+
import json
4+
5+
# Generate Schema command class
6+
class GenerateSchemaCommand(Command):
7+
def __init__(self, parser):
8+
super().__init__(parser)
9+
parser.add_argument('-s', '--structures-path', type=str, help='Path to structure definitions')
10+
parser.add_argument('-o', '--output', type=str, help='Output file path for the schema (default: stdout)')
11+
parser.set_defaults(func=self.execute)
12+
13+
def execute(self, args):
14+
self.logger.info("Generating JSON schema for available structures")
15+
self._generate_schema(args)
16+
17+
def _generate_schema(self, args):
18+
# Get the path to contribs directory (built-in structures)
19+
this_file = os.path.dirname(os.path.realpath(__file__))
20+
contribs_path = os.path.join(this_file, "..", "contribs")
21+
22+
# Determine paths to scan
23+
if args.structures_path:
24+
final_path = args.structures_path
25+
paths_to_list = [final_path, contribs_path]
26+
else:
27+
paths_to_list = [contribs_path]
28+
29+
# Collect all available structures
30+
all_structures = set()
31+
for path in paths_to_list:
32+
if os.path.exists(path):
33+
for root, _, files in os.walk(path):
34+
for file in files:
35+
if file.endswith(".yaml"):
36+
file_path = os.path.join(root, file)
37+
rel_path = os.path.relpath(file_path, path)
38+
# Remove .yaml extension
39+
rel_path = rel_path[:-5]
40+
all_structures.add(rel_path)
41+
42+
# Create JSON schema
43+
schema = {
44+
"definitions": {
45+
"PluginList": {
46+
"enum": sorted(list(all_structures))
47+
}
48+
}
49+
}
50+
51+
# Convert to JSON string
52+
json_output = json.dumps(schema, indent=2)
53+
54+
# Output to file or stdout
55+
if args.output:
56+
# Create output directory if it doesn't exist
57+
output_dir = os.path.dirname(args.output)
58+
if output_dir and not os.path.exists(output_dir):
59+
os.makedirs(output_dir)
60+
61+
with open(args.output, 'w') as f:
62+
f.write(json_output)
63+
self.logger.info(f"Schema written to {args.output}")
64+
print(f"✅ Schema successfully generated at: {args.output}")
65+
else:
66+
print(json_output)

struct_module/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from struct_module.commands.info import InfoCommand
77
from struct_module.commands.validate import ValidateCommand
88
from struct_module.commands.list import ListCommand
9+
from struct_module.commands.generate_schema import GenerateSchemaCommand
910
from struct_module.logging_config import configure_logging
1011

1112

@@ -26,6 +27,7 @@ def main():
2627
ValidateCommand(subparsers.add_parser('validate', help='Validate the YAML configuration file'))
2728
GenerateCommand(subparsers.add_parser('generate', help='Generate the project structure'))
2829
ListCommand(subparsers.add_parser('list', help='List available structures'))
30+
GenerateSchemaCommand(subparsers.add_parser('generate-schema', help='Generate JSON schema for available structures'))
2931

3032
argcomplete.autocomplete(parser)
3133

0 commit comments

Comments
 (0)