@caleuche/cli 0.5.0 → 0.5.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @caleuche/cli
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 012e4e0: Documentation improvements for spec and usage
8
+ - Updated dependencies [012e4e0]
9
+ - @caleuche/core@0.4.1
10
+
3
11
  ## 0.5.0
4
12
 
5
13
  ### Minor Changes
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Caleuche CLI
2
2
 
3
- Caleuche CLI is a command-line tool for compiling code samples and generating project files from templates. It supports multiple languages and flexible sample definitions, including inline templates and external template files.
3
+ Caleuche CLI (`che`) is a command-line tool for generating runnable code samples from templates with dynamic data inputs. It transforms template files written with EJS-style syntax (`<%= %>`) into complete, executable code projects across multiple programming languages.
4
+
5
+ The CLI supports two main workflows:
6
+
7
+ 1. **Single compilation**: Compile one template with one set of input data
8
+ 2. **Batch compilation**: Compile multiple templates with different input variants in a single operation
9
+
10
+ Whether you're creating code examples for documentation, generating starter projects, or producing multiple variations of sample code for different configurations, Caleuche CLI automates the process of turning templates into working code complete with appropriate project files and dependency manifests.
4
11
 
5
12
  ## Installation
6
13
 
@@ -10,27 +17,69 @@ npm install @caleuche/cli
10
17
 
11
18
  ## Usage
12
19
 
20
+ Caleuche CLI provides two commands: `compile` for single template compilation and `batch` for compiling multiple templates at once.
21
+
22
+ ### Compile Command
23
+
24
+ Compile a single template with input data and generate output files.
25
+
26
+ ```sh
27
+ che compile <sample-path> <data-file> <output-directory> [options]
13
28
  ```
14
- che compile <sample-directory|sample-file> <data-file> <output-directory> [options]
29
+
30
+ **Arguments:**
31
+
32
+ - `<sample-path>`: Path to a sample YAML file, or a directory containing a `sample.yaml` file
33
+ - `<data-file>`: Path to input data file (JSON or YAML format)
34
+ - `<output-directory>`: Directory where the compiled output will be written
35
+
36
+ **Options:**
37
+
38
+ - `-p, --project`: Generate language-specific project file (e.g., `package.json`, `requirements.txt`, `go.mod`, `Sample.csproj`, `pom.xml`)
39
+
40
+ **What gets generated:**
41
+
42
+ - Main code file with compiled template (e.g., `sample.py`, `sample.js`, `Sample.java`, etc.)
43
+ - Project file with dependencies (when `-p` flag is used)
44
+ - `tags.yaml` metadata file (if tags are defined in the input data)
45
+
46
+ ### Batch Command
47
+
48
+ Compile multiple templates with different input variants in a single operation.
49
+
50
+ ```sh
51
+ che batch <batch-file> [options]
15
52
  ```
16
53
 
17
- - `<sample-directory|sample-file>`: Path to a directory containing a `sample.yaml` or a direct path to a sample YAML file.
18
- - `<data-file>`: Path to the data file (JSON or YAML).
19
- - `<output-directory>`: Directory where the generated project will be placed.
54
+ **Arguments:**
20
55
 
21
- ### Options
56
+ - `<batch-file>`: Path to a batch configuration file (YAML or JSON)
22
57
 
23
- - `-p, --project` Generate project file (e.g., csproj, go.mod, etc.)
58
+ **Options:**
59
+
60
+ - `-d, --output-dir <outputDir>`: Base output directory for all compiled samples (defaults to the batch file's directory)
61
+
62
+ The batch command is ideal for generating multiple variations of samples, such as producing the same template with development and production configurations, or creating examples across different scenarios.
24
63
 
25
64
  ## Examples
26
65
 
27
- ### 1. Sample with Inline Template
66
+ ### Example 1: Basic Python Sample with Inline Template
67
+
68
+ This example shows the simplest use case: a Python template with an inline template string.
69
+
70
+ **Directory structure:**
71
+
72
+ ```
73
+ my-sample/
74
+ sample.yaml
75
+ data.yaml
76
+ ```
28
77
 
29
78
  **sample.yaml**
30
79
 
31
80
  ```yaml
32
81
  template: |
33
- Hello, <%= name %>!
82
+ print("Hello, <%= name %>!")
34
83
  type: python
35
84
  dependencies: []
36
85
  input:
@@ -48,54 +97,485 @@ name: World
48
97
  **Command:**
49
98
 
50
99
  ```sh
51
- che compile ./my-sample ./data.yaml ./output
100
+ che compile ./my-sample ./my-sample/data.yaml ./output
52
101
  ```
53
102
 
54
- ### 2. Sample with Template File Reference
103
+ **Output:** Creates `./output/sample.py` containing:
104
+
105
+ ```python
106
+ print("Hello, World!")
107
+ ```
108
+
109
+ ### Example 2: JavaScript Sample with External Template File
110
+
111
+ This example demonstrates using an external template file instead of an inline template.
55
112
 
56
113
  **Directory structure:**
57
114
 
58
115
  ```
59
116
  my-sample/
60
117
  sample.yaml
61
- main.py.tmpl
118
+ main.js.tmpl
119
+ data.yaml
62
120
  ```
63
121
 
64
122
  **sample.yaml**
65
123
 
66
124
  ```yaml
67
- template: main.py.tmpl
125
+ template: main.js.tmpl
126
+ type: javascript
127
+ dependencies:
128
+ - name: axios
129
+ version: ^1.6.0
130
+ input:
131
+ - name: apiUrl
132
+ type: string
133
+ required: true
134
+ - name: timeout
135
+ type: number
136
+ required: false
137
+ default: 5000
138
+ ```
139
+
140
+ **main.js.tmpl**
141
+
142
+ ```javascript
143
+ const axios = require('axios');
144
+
145
+ const client = axios.create({
146
+ baseURL: '<%= apiUrl %>',
147
+ timeout: <%= timeout %>
148
+ });
149
+
150
+ async function fetchData() {
151
+ const response = await client.get('/data');
152
+ console.log(response.data);
153
+ }
154
+
155
+ fetchData();
156
+ ```
157
+
158
+ **data.yaml**
159
+
160
+ ```yaml
161
+ apiUrl: https://api.example.com
162
+ timeout: 10000
163
+ ```
164
+
165
+ **Command:**
166
+
167
+ ```sh
168
+ che compile ./my-sample ./data.yaml ./output --project
169
+ ```
170
+
171
+ **Output:** Creates:
172
+
173
+ - `./output/sample.js` with the compiled template
174
+ - `./output/package.json` with axios dependency
175
+
176
+ ### Example 3: C# Sample with Complex Input Types
177
+
178
+ This example shows how to use object and array input types.
179
+
180
+ **sample.yaml**
181
+
182
+ ```yaml
183
+ template: |
184
+ using System;
185
+ using System.Collections.Generic;
186
+
187
+ namespace <%= namespace %>
188
+ {
189
+ class Program
190
+ {
191
+ static void Main(string[] args)
192
+ {
193
+ var config = new Dictionary<string, object>
194
+ {
195
+ {"host", "<%= config.host %>"},
196
+ {"port", <%= config.port %>},
197
+ {"ssl", <%= config.ssl %>}
198
+ };
199
+
200
+ var features = new List<string> { <% features.forEach((f, i) => { %>"<%= f %>"<% if (i < features.length - 1) { %>, <% } }); %> };
201
+
202
+ Console.WriteLine($"Application: {config["host"]}:{config["port"]}");
203
+ }
204
+ }
205
+ }
206
+ type: csharp
207
+ dependencies:
208
+ - name: Newtonsoft.Json
209
+ version: 13.0.3
210
+ input:
211
+ - name: namespace
212
+ type: string
213
+ required: true
214
+ - name: config
215
+ type: object
216
+ required: true
217
+ - name: features
218
+ type: array
219
+ itemsType: string
220
+ required: true
221
+ ```
222
+
223
+ **data.yaml**
224
+
225
+ ```yaml
226
+ namespace: MyApplication
227
+ config:
228
+ host: localhost
229
+ port: 8080
230
+ ssl: true
231
+ features:
232
+ - authentication
233
+ - logging
234
+ - metrics
235
+ ```
236
+
237
+ **Command:**
238
+
239
+ ```sh
240
+ che compile ./my-sample ./data.yaml ./output -p
241
+ ```
242
+
243
+ **Output:** Creates:
244
+
245
+ - `./output/Sample.cs` with the compiled C# code
246
+ - `./output/Sample.csproj` with Newtonsoft.Json dependency
247
+
248
+ ### Example 4: Batch Compilation with Multiple Variants
249
+
250
+ This example demonstrates using the batch command to compile one template with different configurations.
251
+
252
+ **Directory structure:**
253
+
254
+ ```
255
+ batch-example/
256
+ sample.yaml
257
+ template.py.tmpl
258
+ batch.yaml
259
+ dev-config.yaml
260
+ prod-config.yaml
261
+ ```
262
+
263
+ **sample.yaml**
264
+
265
+ ```yaml
266
+ template: template.py.tmpl
68
267
  type: python
69
- dependencies: []
268
+ dependencies:
269
+ - name: requests
270
+ version: ^2.31.0
70
271
  input:
71
- - name: name
272
+ - name: environment
273
+ type: string
274
+ required: true
275
+ - name: debug
276
+ type: boolean
277
+ required: true
278
+ - name: apiKey
72
279
  type: string
73
280
  required: true
74
281
  ```
75
282
 
76
- **main.py.tmpl**
283
+ **template.py.tmpl**
77
284
 
78
285
  ```python
79
- print("Hello, <%= name %>!")
286
+ import os
287
+
288
+ ENVIRONMENT = "<%= environment %>"
289
+ DEBUG = <%= debug %>
290
+ API_KEY = "<%= apiKey %>"
291
+
292
+ def main():
293
+ print(f"Running in {ENVIRONMENT} mode")
294
+ if DEBUG:
295
+ print("Debug mode enabled")
296
+ # Application logic here
297
+
298
+ if __name__ == "__main__":
299
+ main()
80
300
  ```
81
301
 
82
- **data.yaml**
302
+ **dev-config.yaml**
303
+
304
+ ```yaml
305
+ environment: development
306
+ debug: true
307
+ apiKey: dev-key-12345
308
+ ```
309
+
310
+ **prod-config.yaml**
83
311
 
84
312
  ```yaml
85
- name: Alice
313
+ environment: production
314
+ debug: false
315
+ apiKey: prod-key-67890
316
+ ```
317
+
318
+ **batch.yaml**
319
+
320
+ ```yaml
321
+ variants:
322
+ - name: dev
323
+ input:
324
+ type: path
325
+ value: dev-config.yaml
326
+ - name: prod
327
+ input:
328
+ type: path
329
+ value: prod-config.yaml
330
+
331
+ samples:
332
+ - templatePath: ./sample.yaml
333
+ variants:
334
+ - output: ./out-dev/
335
+ input: dev
336
+ tags:
337
+ version: 1.0.0
338
+ environment: development
339
+ - output: ./out-prod/
340
+ input: prod
341
+ tags:
342
+ version: 1.0.0
343
+ environment: production
86
344
  ```
87
345
 
88
346
  **Command:**
89
347
 
90
348
  ```sh
91
- che compile ./my-sample ./data.yaml ./output
349
+ che batch ./batch-example/batch.yaml -d ./outputs
92
350
  ```
93
351
 
352
+ **Output:** Creates:
353
+
354
+ - `./outputs/out-dev/sample.py` and `./outputs/out-dev/requirements.txt` (dev version)
355
+ - `./outputs/out-dev/tags.yaml` with development metadata
356
+ - `./outputs/out-prod/sample.py` and `./outputs/out-prod/requirements.txt` (prod version)
357
+ - `./outputs/out-prod/tags.yaml` with production metadata
358
+
359
+ ### Example 5: Using Tags for Metadata
360
+
361
+ Tags allow you to attach custom metadata to your samples for organization and filtering.
362
+
363
+ **sample.yaml**
364
+
365
+ ```yaml
366
+ template: |
367
+ console.log("Sample code");
368
+ type: javascript
369
+ dependencies: []
370
+ input: []
371
+ tags:
372
+ category: tutorial
373
+ difficulty: beginner
374
+ language: javascript
375
+ version: 1.0.0
376
+ ```
377
+
378
+ **Command:**
379
+
380
+ ```sh
381
+ che compile ./sample.yaml ./empty-data.yaml ./output
382
+ ```
383
+
384
+ **Output:** Creates:
385
+
386
+ - `./output/sample.js` with the code
387
+ - `./output/tags.yaml` containing the metadata:
388
+ ```yaml
389
+ category: tutorial
390
+ difficulty: beginner
391
+ language: javascript
392
+ version: 1.0.0
393
+ ```
394
+
94
395
  ## Sample and Data File Structure
95
396
 
96
- - **Sample file**: YAML describing the sample, including the template (inline or file reference), language, dependencies, and input fields.
397
+ ### Sample File Schema
398
+
399
+ The sample file is a YAML document that describes a code template and its requirements. It can be named anything but is commonly named `sample.yaml`.
400
+
401
+ **Structure:**
402
+
403
+ ```yaml
404
+ template: string | path/to/template.file
405
+ type: "csharp" | "go" | "java" | "python" | "javascript"
406
+ dependencies:
407
+ - name: string
408
+ version: string
409
+ input:
410
+ - name: string
411
+ type: "string" | "number" | "boolean" | "object" | "array"
412
+ required: boolean
413
+ default?: any
414
+ itemsType?: "string" | "number" | "boolean" | "object" # only for array type
415
+ tags?:
416
+ key: value
417
+ ```
418
+
419
+ **Fields:**
420
+
421
+ - **`template`** (required): Either an inline template string (using YAML multiline syntax `|`) or a relative path to a template file. Template files can have any extension (commonly `.tmpl`).
422
+
423
+ - **`type`** (required): Target programming language. Must be one of:
424
+
425
+ - `javascript` - Generates `sample.js` and optionally `package.json`
426
+ - `python` - Generates `sample.py` and optionally `requirements.txt`
427
+ - `csharp` - Generates `Sample.cs` and optionally `Sample.csproj`
428
+ - `java` - Generates `Sample.java` and optionally `pom.xml`
429
+ - `go` - Generates `sample.go` and optionally `go.mod`
430
+
431
+ - **`dependencies`** (required): Array of package dependencies to include in the generated project file. Each dependency has:
432
+
433
+ - `name`: Package/module name
434
+ - `version`: Version string (format depends on the language/package manager)
435
+
436
+ - **`input`** (required): Array of input field definitions that describe what data the template expects. Each input has:
437
+
438
+ - `name`: Variable name used in the template
439
+ - `type`: Data type - can be `string`, `number`, `boolean`, `object`, or `array`
440
+ - `required`: Whether this input must be provided
441
+ - `default`: Optional default value if not provided
442
+ - `itemsType`: (only for `array` type) Type of array elements
443
+
444
+ - **`tags`** (optional): Key-value pairs for custom metadata. Tags are written to a `tags.yaml` file in the output directory and can be used for categorization, versioning, or filtering samples.
445
+
446
+ **Template Syntax:**
447
+
448
+ Templates use EJS-style syntax:
449
+
450
+ - `<%= expression %>` - Output escaped value
451
+ - `<%- expression %>` - Output raw/unescaped value
452
+ - `<% statement %>` - Execute JavaScript statement (for loops, conditions, etc.)
453
+
454
+ ### Data File Schema
455
+
456
+ The data file provides values for the template's input fields. It can be in JSON or YAML format.
457
+
458
+ **Structure:**
459
+
460
+ The data file must be an object where keys match the `name` fields defined in the sample's `input` array.
461
+
462
+ **Example (YAML):**
463
+
464
+ ```yaml
465
+ stringField: "some text"
466
+ numberField: 42
467
+ booleanField: true
468
+ objectField:
469
+ key1: value1
470
+ key2: value2
471
+ arrayField:
472
+ - item1
473
+ - item2
474
+ - item3
475
+ ```
476
+
477
+ **Example (JSON):**
478
+
479
+ ```json
480
+ {
481
+ "stringField": "some text",
482
+ "numberField": 42,
483
+ "booleanField": true,
484
+ "objectField": {
485
+ "key1": "value1",
486
+ "key2": "value2"
487
+ },
488
+ "arrayField": ["item1", "item2", "item3"]
489
+ }
490
+ ```
491
+
492
+ **Validation:**
493
+
494
+ - All fields marked as `required: true` in the sample must be present in the data file
495
+ - Field types in the data must match the types specified in the sample's input definitions
496
+ - Missing optional fields will use their default values if defined, or be undefined
497
+
498
+ ### Batch File Schema
499
+
500
+ The batch file enables compiling multiple templates with different input variants in a single command.
501
+
502
+ **Structure:**
503
+
504
+ ```yaml
505
+ variants: # (optional) Named input definitions that can be reused
506
+ - name: string
507
+ input:
508
+ type: object
509
+ properties:
510
+ key: value
511
+ # OR
512
+ type: path
513
+ value: path/to/input.yaml
514
+
515
+ samples: # (required) List of templates to compile
516
+ - templatePath: path/to/sample/directory/or/file
517
+ variants:
518
+ - output: path/to/output/directory
519
+ input: variant-name # reference to variants section
520
+ # OR
521
+ input:
522
+ type: object
523
+ properties:
524
+ key: value
525
+ # OR
526
+ input:
527
+ type: path
528
+ value: path/to/input.yaml
529
+ # OR
530
+ input:
531
+ type: reference
532
+ value: variant-name
533
+ tags: # (optional) Override or add tags for this variant
534
+ key: value
535
+ ```
536
+
537
+ **Fields:**
538
+
539
+ - **`variants`** (optional): Named input definitions that can be referenced by multiple sample variants. Useful for reusing the same configuration across different samples.
540
+
541
+ - **`samples`** (required): Array of templates to compile. Each sample has:
542
+ - `templatePath`: Path to sample directory or sample YAML file
543
+ - `variants`: Array of compilation variants, each defining:
544
+ - `output`: Output directory path (relative to batch file or `--output-dir`)
545
+ - `input`: Input data, can be:
546
+ - A string (shorthand for reference type)
547
+ - An object with `type: "object"` and `properties`
548
+ - An object with `type: "path"` and `value` pointing to a data file
549
+ - An object with `type: "reference"` and `value` naming a variant
550
+ - `tags`: Optional metadata to add/override for this specific variant
551
+
552
+ **Input Types:**
553
+
554
+ - **object**: Inline key-value pairs
555
+ - **path**: Reference to external YAML/JSON file
556
+ - **reference**: Reference to a named variant from the `variants` section
557
+
558
+ ### Output Structure
559
+
560
+ After compilation, the output directory will contain:
561
+
562
+ 1. **Main code file**: Named according to the language convention:
563
+
564
+ - JavaScript: `sample.js`
565
+ - Python: `sample.py`
566
+ - C#: `Sample.cs`
567
+ - Java: `Sample.java`
568
+ - Go: `sample.go`
569
+
570
+ 2. **Project file** (when `--project` flag is used or in batch mode):
571
+
572
+ - JavaScript: `package.json`
573
+ - Python: `requirements.txt`
574
+ - C#: `Sample.csproj`
575
+ - Java: `pom.xml`
576
+ - Go: `go.mod`
97
577
 
98
- - **Data file**: JSON or YAML with the data to inject into the sample.
578
+ 3. **Tags file** (when tags are defined): `tags.yaml` containing the metadata
99
579
 
100
580
  ## License
101
581
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caleuche/cli",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "che": "dist/index.js"
@@ -19,7 +19,7 @@
19
19
  "license": "MIT",
20
20
  "description": "Caleuche CLI",
21
21
  "dependencies": {
22
- "@caleuche/core": "^0.4.0",
22
+ "@caleuche/core": "^0.4.1",
23
23
  "commander": "^14.0.0",
24
24
  "yaml": "^2.8.0"
25
25
  },
package/test/bach.test.ts CHANGED
@@ -357,7 +357,7 @@ describe("batchCompile", () => {
357
357
  mockCompileSample.mockReturnValue({
358
358
  items: [
359
359
  { fileName: "file1.js", content: "console.log('1');" },
360
- { fileName: "tags.yaml", content: "tag1: value1\ntag2: value2" }
360
+ { fileName: "tags.yaml", content: "tag1: value1\ntag2: value2" },
361
361
  ],
362
362
  });
363
363
  const batchFilePath = getPath("batch.yaml");