licos-dev-cli 0.2.13__tar.gz → 0.2.14__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.
- {licos_dev_cli-0.2.13 → licos_dev_cli-0.2.14}/PKG-INFO +1 -1
- {licos_dev_cli-0.2.13 → licos_dev_cli-0.2.14}/pyproject.toml +2 -2
- {licos_dev_cli-0.2.13 → licos_dev_cli-0.2.14}/src/licos_dev_cli/main.py +123 -77
- licos_dev_cli-0.2.14/tests/test_cli_output_paths.py +33 -0
- {licos_dev_cli-0.2.13 → licos_dev_cli-0.2.14}/.gitignore +0 -0
- {licos_dev_cli-0.2.13 → licos_dev_cli-0.2.14}/src/licos_dev_cli/__init__.py +0 -0
|
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "licos-dev-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.14"
|
|
8
8
|
description = "LICOS Dev CLI - generate files and call model capabilities"
|
|
9
9
|
requires-python = ">=3.10"
|
|
10
10
|
dependencies = [
|
|
11
|
-
"licos-dev-sdk>=0.2.14",
|
|
11
|
+
"licos-dev-sdk>=0.2.14",
|
|
12
12
|
"click>=8.1",
|
|
13
13
|
]
|
|
14
14
|
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import sys
|
|
6
|
-
import json
|
|
7
|
-
import
|
|
5
|
+
import sys
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import click
|
|
8
10
|
|
|
9
11
|
# ── Helpers ──────────────────────────────────────────────────────────────────
|
|
10
12
|
|
|
@@ -35,13 +37,57 @@ def _json_option(value: str | None, name: str) -> dict | list | None:
|
|
|
35
37
|
raise click.BadParameter(f"{name} must be valid JSON") from exc
|
|
36
38
|
|
|
37
39
|
|
|
38
|
-
def _echo_json(value: object) -> None:
|
|
39
|
-
if hasattr(value, "to_dict"):
|
|
40
|
-
value = value.to_dict()
|
|
41
|
-
click.echo(json.dumps(value, ensure_ascii=False, indent=2))
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
def _echo_json(value: object) -> None:
|
|
41
|
+
if hasattr(value, "to_dict"):
|
|
42
|
+
value = value.to_dict()
|
|
43
|
+
click.echo(json.dumps(value, ensure_ascii=False, indent=2))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _path_to_cli_output(path: object) -> str:
|
|
47
|
+
raw = str(path)
|
|
48
|
+
if not raw:
|
|
49
|
+
return raw
|
|
50
|
+
|
|
51
|
+
normalized = raw.replace("\\", "/")
|
|
52
|
+
string_roots = [
|
|
53
|
+
os.environ.get("LICOS_PROJECT_PATH"),
|
|
54
|
+
(os.path.join(os.environ["LICOS_WORKSPACE_PATH"], "projects") if os.environ.get("LICOS_WORKSPACE_PATH") else None),
|
|
55
|
+
"/workspace/projects",
|
|
56
|
+
]
|
|
57
|
+
for root in string_roots:
|
|
58
|
+
if not root:
|
|
59
|
+
continue
|
|
60
|
+
prefix = root.replace("\\", "/").rstrip("/")
|
|
61
|
+
if normalized == prefix:
|
|
62
|
+
return "."
|
|
63
|
+
if normalized.startswith(f"{prefix}/"):
|
|
64
|
+
return normalized[len(prefix) + 1 :]
|
|
65
|
+
|
|
66
|
+
p = Path(raw)
|
|
67
|
+
if not p.is_absolute():
|
|
68
|
+
return normalized
|
|
69
|
+
|
|
70
|
+
path_roots = [
|
|
71
|
+
os.environ.get("LICOS_PROJECT_PATH"),
|
|
72
|
+
(os.path.join(os.environ["LICOS_WORKSPACE_PATH"], "projects") if os.environ.get("LICOS_WORKSPACE_PATH") else None),
|
|
73
|
+
str(Path.cwd()),
|
|
74
|
+
]
|
|
75
|
+
for root in path_roots:
|
|
76
|
+
if not root:
|
|
77
|
+
continue
|
|
78
|
+
try:
|
|
79
|
+
return p.resolve().relative_to(Path(root).resolve()).as_posix()
|
|
80
|
+
except (OSError, RuntimeError, ValueError):
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
return normalized
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _echo_path(path: object) -> None:
|
|
87
|
+
click.echo(_path_to_cli_output(path))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# ── CLI Group ────────────────────────────────────────────────────────────────
|
|
45
91
|
|
|
46
92
|
@click.group()
|
|
47
93
|
def cli():
|
|
@@ -60,10 +106,10 @@ def cli():
|
|
|
60
106
|
@click.option("--page-size", default="A4", help="Page size: A4|LETTER")
|
|
61
107
|
def pdf(input_path, content, filename, output_dir, content_type, page_size):
|
|
62
108
|
"""Generate PDF from Markdown or HTML."""
|
|
63
|
-
from licos_dev_sdk import create_pdf
|
|
64
|
-
text = _read_input(input_path, content)
|
|
65
|
-
path = create_pdf(text, filename, content_type=content_type, output_dir=output_dir, page_size=page_size)
|
|
66
|
-
|
|
109
|
+
from licos_dev_sdk import create_pdf
|
|
110
|
+
text = _read_input(input_path, content)
|
|
111
|
+
path = create_pdf(text, filename, content_type=content_type, output_dir=output_dir, page_size=page_size)
|
|
112
|
+
_echo_path(path)
|
|
67
113
|
|
|
68
114
|
|
|
69
115
|
# ── DOCX ─────────────────────────────────────────────────────────────────────
|
|
@@ -78,10 +124,10 @@ def pdf(input_path, content, filename, output_dir, content_type, page_size):
|
|
|
78
124
|
@click.option("--font-size", default=11, type=int)
|
|
79
125
|
def docx(input_path, content, filename, output_dir, content_type, font, font_size):
|
|
80
126
|
"""Generate DOCX from Markdown or HTML."""
|
|
81
|
-
from licos_dev_sdk import create_docx
|
|
82
|
-
text = _read_input(input_path, content)
|
|
83
|
-
path = create_docx(text, filename, content_type=content_type, output_dir=output_dir, font_name=font, font_size=font_size)
|
|
84
|
-
|
|
127
|
+
from licos_dev_sdk import create_docx
|
|
128
|
+
text = _read_input(input_path, content)
|
|
129
|
+
path = create_docx(text, filename, content_type=content_type, output_dir=output_dir, font_name=font, font_size=font_size)
|
|
130
|
+
_echo_path(path)
|
|
85
131
|
|
|
86
132
|
|
|
87
133
|
@cli.command("docx-template")
|
|
@@ -94,10 +140,10 @@ def docx_template(template_path, input_path, data_content, filename, output_dir)
|
|
|
94
140
|
"""Generate DOCX by rendering a DOCX template with JSON data."""
|
|
95
141
|
from licos_dev_sdk import create_docx_from_template
|
|
96
142
|
data = _read_json(input_path, data_content)
|
|
97
|
-
if not isinstance(data, dict):
|
|
98
|
-
raise click.BadParameter("template data must be a JSON object")
|
|
99
|
-
path = create_docx_from_template(template_path, data, filename, output_dir=output_dir)
|
|
100
|
-
|
|
143
|
+
if not isinstance(data, dict):
|
|
144
|
+
raise click.BadParameter("template data must be a JSON object")
|
|
145
|
+
path = create_docx_from_template(template_path, data, filename, output_dir=output_dir)
|
|
146
|
+
_echo_path(path)
|
|
101
147
|
|
|
102
148
|
|
|
103
149
|
# ── XLSX ─────────────────────────────────────────────────────────────────────
|
|
@@ -111,10 +157,10 @@ def docx_template(template_path, input_path, data_content, filename, output_dir)
|
|
|
111
157
|
@click.option("--header-color", default="4472C4")
|
|
112
158
|
def xlsx(input_path, content, filename, output_dir, sheet_name, header_color):
|
|
113
159
|
"""Generate XLSX from JSON data."""
|
|
114
|
-
from licos_dev_sdk import create_xlsx
|
|
115
|
-
data = _read_json(input_path, content)
|
|
116
|
-
path = create_xlsx(data, filename, output_dir=output_dir, sheet_name=sheet_name, header_color=header_color)
|
|
117
|
-
|
|
160
|
+
from licos_dev_sdk import create_xlsx
|
|
161
|
+
data = _read_json(input_path, content)
|
|
162
|
+
path = create_xlsx(data, filename, output_dir=output_dir, sheet_name=sheet_name, header_color=header_color)
|
|
163
|
+
_echo_path(path)
|
|
118
164
|
|
|
119
165
|
|
|
120
166
|
@cli.command("xlsx-workbook")
|
|
@@ -134,10 +180,10 @@ def xlsx_workbook(input_path, content, filename, output_dir, header_color, freez
|
|
|
134
180
|
filename,
|
|
135
181
|
output_dir=output_dir,
|
|
136
182
|
header_color=header_color,
|
|
137
|
-
freeze_header=freeze_header,
|
|
138
|
-
autofilter=autofilter,
|
|
139
|
-
)
|
|
140
|
-
|
|
183
|
+
freeze_header=freeze_header,
|
|
184
|
+
autofilter=autofilter,
|
|
185
|
+
)
|
|
186
|
+
_echo_path(path)
|
|
141
187
|
|
|
142
188
|
|
|
143
189
|
# ── CSV ──────────────────────────────────────────────────────────────────────
|
|
@@ -149,10 +195,10 @@ def xlsx_workbook(input_path, content, filename, output_dir, header_color, freez
|
|
|
149
195
|
@click.option("-o", "--output-dir", default=None)
|
|
150
196
|
def csv(input_path, content, filename, output_dir):
|
|
151
197
|
"""Generate CSV from JSON data."""
|
|
152
|
-
from licos_dev_sdk import create_csv
|
|
153
|
-
data = _read_json(input_path, content)
|
|
154
|
-
path = create_csv(data, filename, output_dir=output_dir)
|
|
155
|
-
|
|
198
|
+
from licos_dev_sdk import create_csv
|
|
199
|
+
data = _read_json(input_path, content)
|
|
200
|
+
path = create_csv(data, filename, output_dir=output_dir)
|
|
201
|
+
_echo_path(path)
|
|
156
202
|
|
|
157
203
|
|
|
158
204
|
# ── PPTX ─────────────────────────────────────────────────────────────────────
|
|
@@ -165,10 +211,10 @@ def csv(input_path, content, filename, output_dir):
|
|
|
165
211
|
@click.option("--format", "content_type", default="markdown")
|
|
166
212
|
def pptx(input_path, content, filename, output_dir, content_type):
|
|
167
213
|
"""Generate PPTX from Markdown."""
|
|
168
|
-
from licos_dev_sdk import create_pptx
|
|
169
|
-
text = _read_input(input_path, content)
|
|
170
|
-
path = create_pptx(text, filename, content_type=content_type, output_dir=output_dir)
|
|
171
|
-
|
|
214
|
+
from licos_dev_sdk import create_pptx
|
|
215
|
+
text = _read_input(input_path, content)
|
|
216
|
+
path = create_pptx(text, filename, content_type=content_type, output_dir=output_dir)
|
|
217
|
+
_echo_path(path)
|
|
172
218
|
|
|
173
219
|
|
|
174
220
|
# ── Chart ────────────────────────────────────────────────────────────────────
|
|
@@ -185,10 +231,10 @@ def pptx(input_path, content, filename, output_dir, content_type):
|
|
|
185
231
|
@click.option("--height", default=600, type=int)
|
|
186
232
|
def chart(input_path, content, filename, output_dir, chart_type, fmt, title, width, height):
|
|
187
233
|
"""Generate chart image from JSON data."""
|
|
188
|
-
from licos_dev_sdk import create_chart
|
|
189
|
-
data = _read_json(input_path, content)
|
|
190
|
-
path = create_chart(chart_type, data, filename, output_dir=output_dir, format=fmt, title=title, width=width, height=height)
|
|
191
|
-
|
|
234
|
+
from licos_dev_sdk import create_chart
|
|
235
|
+
data = _read_json(input_path, content)
|
|
236
|
+
path = create_chart(chart_type, data, filename, output_dir=output_dir, format=fmt, title=title, width=width, height=height)
|
|
237
|
+
_echo_path(path)
|
|
192
238
|
|
|
193
239
|
|
|
194
240
|
# ── Diagram ──────────────────────────────────────────────────────────────────
|
|
@@ -201,10 +247,10 @@ def chart(input_path, content, filename, output_dir, chart_type, fmt, title, wid
|
|
|
201
247
|
@click.option("--format", "fmt", default="png", help="png|svg|pdf")
|
|
202
248
|
def diagram(input_path, content, filename, output_dir, fmt):
|
|
203
249
|
"""Generate diagram from Graphviz DOT source."""
|
|
204
|
-
from licos_dev_sdk import create_diagram
|
|
205
|
-
text = _read_input(input_path, content)
|
|
206
|
-
path = create_diagram(text, filename, output_dir=output_dir, format=fmt)
|
|
207
|
-
|
|
250
|
+
from licos_dev_sdk import create_diagram
|
|
251
|
+
text = _read_input(input_path, content)
|
|
252
|
+
path = create_diagram(text, filename, output_dir=output_dir, format=fmt)
|
|
253
|
+
_echo_path(path)
|
|
208
254
|
|
|
209
255
|
|
|
210
256
|
# ── QR Code ──────────────────────────────────────────────────────────────────
|
|
@@ -216,9 +262,9 @@ def diagram(input_path, content, filename, output_dir, fmt):
|
|
|
216
262
|
@click.option("--size", default=300, type=int)
|
|
217
263
|
def qrcode(data, filename, output_dir, size):
|
|
218
264
|
"""Generate QR code PNG image."""
|
|
219
|
-
from licos_dev_sdk import create_qrcode
|
|
220
|
-
path = create_qrcode(data, filename, output_dir=output_dir, size=size)
|
|
221
|
-
|
|
265
|
+
from licos_dev_sdk import create_qrcode
|
|
266
|
+
path = create_qrcode(data, filename, output_dir=output_dir, size=size)
|
|
267
|
+
_echo_path(path)
|
|
222
268
|
|
|
223
269
|
|
|
224
270
|
# ── Barcode ──────────────────────────────────────────────────────────────────
|
|
@@ -230,9 +276,9 @@ def qrcode(data, filename, output_dir, size):
|
|
|
230
276
|
@click.option("--type", "barcode_type", default="code128", help="code128|ean13|ean8|isbn13|upc")
|
|
231
277
|
def barcode(data, filename, output_dir, barcode_type):
|
|
232
278
|
"""Generate barcode PNG image."""
|
|
233
|
-
from licos_dev_sdk import create_barcode
|
|
234
|
-
path = create_barcode(data, filename, output_dir=output_dir, barcode_type=barcode_type)
|
|
235
|
-
|
|
279
|
+
from licos_dev_sdk import create_barcode
|
|
280
|
+
path = create_barcode(data, filename, output_dir=output_dir, barcode_type=barcode_type)
|
|
281
|
+
_echo_path(path)
|
|
236
282
|
|
|
237
283
|
|
|
238
284
|
# ── ZIP ──────────────────────────────────────────────────────────────────────
|
|
@@ -243,10 +289,10 @@ def barcode(data, filename, output_dir, barcode_type):
|
|
|
243
289
|
@click.option("-o", "--output-dir", default=None)
|
|
244
290
|
def zip_cmd(paths, filename, output_dir):
|
|
245
291
|
"""Create ZIP archive."""
|
|
246
|
-
from licos_dev_sdk import create_zip
|
|
247
|
-
source_paths = [p.strip() for p in paths.split(",")]
|
|
248
|
-
path = create_zip(source_paths, filename, output_dir=output_dir)
|
|
249
|
-
|
|
292
|
+
from licos_dev_sdk import create_zip
|
|
293
|
+
source_paths = [p.strip() for p in paths.split(",")]
|
|
294
|
+
path = create_zip(source_paths, filename, output_dir=output_dir)
|
|
295
|
+
_echo_path(path)
|
|
250
296
|
|
|
251
297
|
|
|
252
298
|
# ── TAR.GZ ───────────────────────────────────────────────────────────────────
|
|
@@ -257,10 +303,10 @@ def zip_cmd(paths, filename, output_dir):
|
|
|
257
303
|
@click.option("-o", "--output-dir", default=None)
|
|
258
304
|
def tar_cmd(paths, filename, output_dir):
|
|
259
305
|
"""Create TAR.GZ archive."""
|
|
260
|
-
from licos_dev_sdk import create_tar_gz
|
|
261
|
-
source_paths = [p.strip() for p in paths.split(",")]
|
|
262
|
-
path = create_tar_gz(source_paths, filename, output_dir=output_dir)
|
|
263
|
-
|
|
306
|
+
from licos_dev_sdk import create_tar_gz
|
|
307
|
+
source_paths = [p.strip() for p in paths.split(",")]
|
|
308
|
+
path = create_tar_gz(source_paths, filename, output_dir=output_dir)
|
|
309
|
+
_echo_path(path)
|
|
264
310
|
|
|
265
311
|
|
|
266
312
|
# ── JSON ─────────────────────────────────────────────────────────────────────
|
|
@@ -276,11 +322,11 @@ def json_cmd(input_path, content, filename, output_dir):
|
|
|
276
322
|
raw = _read_input(input_path, content)
|
|
277
323
|
try:
|
|
278
324
|
data = json.loads(raw)
|
|
279
|
-
except json.JSONDecodeError:
|
|
280
|
-
import yaml
|
|
281
|
-
data = yaml.safe_load(raw)
|
|
282
|
-
path = create_json(data, filename, output_dir=output_dir)
|
|
283
|
-
|
|
325
|
+
except json.JSONDecodeError:
|
|
326
|
+
import yaml
|
|
327
|
+
data = yaml.safe_load(raw)
|
|
328
|
+
path = create_json(data, filename, output_dir=output_dir)
|
|
329
|
+
_echo_path(path)
|
|
284
330
|
|
|
285
331
|
|
|
286
332
|
# ── YAML ─────────────────────────────────────────────────────────────────────
|
|
@@ -297,10 +343,10 @@ def yaml_cmd(input_path, content, filename, output_dir):
|
|
|
297
343
|
raw = _read_input(input_path, content)
|
|
298
344
|
try:
|
|
299
345
|
data = json.loads(raw)
|
|
300
|
-
except json.JSONDecodeError:
|
|
301
|
-
data = yaml_lib.safe_load(raw)
|
|
302
|
-
path = create_yaml(data, filename, output_dir=output_dir)
|
|
303
|
-
|
|
346
|
+
except json.JSONDecodeError:
|
|
347
|
+
data = yaml_lib.safe_load(raw)
|
|
348
|
+
path = create_yaml(data, filename, output_dir=output_dir)
|
|
349
|
+
_echo_path(path)
|
|
304
350
|
|
|
305
351
|
|
|
306
352
|
# ── XML ──────────────────────────────────────────────────────────────────────
|
|
@@ -313,10 +359,10 @@ def yaml_cmd(input_path, content, filename, output_dir):
|
|
|
313
359
|
@click.option("--root-tag", default="root")
|
|
314
360
|
def xml_cmd(input_path, content, filename, output_dir, root_tag):
|
|
315
361
|
"""Generate XML file from JSON data."""
|
|
316
|
-
from licos_dev_sdk import create_xml
|
|
317
|
-
data = _read_json(input_path, content)
|
|
318
|
-
path = create_xml(data, filename, output_dir=output_dir, root_tag=root_tag)
|
|
319
|
-
|
|
362
|
+
from licos_dev_sdk import create_xml
|
|
363
|
+
data = _read_json(input_path, content)
|
|
364
|
+
path = create_xml(data, filename, output_dir=output_dir, root_tag=root_tag)
|
|
365
|
+
_echo_path(path)
|
|
320
366
|
|
|
321
367
|
|
|
322
368
|
# ── HTML ─────────────────────────────────────────────────────────────────────
|
|
@@ -329,10 +375,10 @@ def xml_cmd(input_path, content, filename, output_dir, root_tag):
|
|
|
329
375
|
@click.option("--format", "content_type", default="markdown", help="markdown|html")
|
|
330
376
|
def html_cmd(input_path, content, filename, output_dir, content_type):
|
|
331
377
|
"""Generate HTML file from Markdown or raw HTML."""
|
|
332
|
-
from licos_dev_sdk import create_html
|
|
333
|
-
text = _read_input(input_path, content)
|
|
334
|
-
path = create_html(text, filename, output_dir=output_dir, content_type=content_type)
|
|
335
|
-
|
|
378
|
+
from licos_dev_sdk import create_html
|
|
379
|
+
text = _read_input(input_path, content)
|
|
380
|
+
path = create_html(text, filename, output_dir=output_dir, content_type=content_type)
|
|
381
|
+
_echo_path(path)
|
|
336
382
|
|
|
337
383
|
|
|
338
384
|
# ── Model Catalog ────────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from licos_dev_cli.main import _path_to_cli_output
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_project_absolute_path_is_printed_relative(tmp_path, monkeypatch):
|
|
8
|
+
project = tmp_path / "projects"
|
|
9
|
+
monkeypatch.setenv("LICOS_PROJECT_PATH", str(project))
|
|
10
|
+
|
|
11
|
+
assert _path_to_cli_output(project / "reports" / "demo.docx") == "reports/demo.docx"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_project_root_is_printed_as_dot(tmp_path, monkeypatch):
|
|
15
|
+
project = tmp_path / "projects"
|
|
16
|
+
monkeypatch.setenv("LICOS_PROJECT_PATH", str(project))
|
|
17
|
+
|
|
18
|
+
assert _path_to_cli_output(project) == "."
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_external_absolute_path_is_not_trimmed(tmp_path, monkeypatch):
|
|
22
|
+
project = tmp_path / "projects"
|
|
23
|
+
external = tmp_path / "other" / "demo.docx"
|
|
24
|
+
monkeypatch.setenv("LICOS_PROJECT_PATH", str(project))
|
|
25
|
+
|
|
26
|
+
assert _path_to_cli_output(external) == external.as_posix()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_agent_default_project_path_is_printed_relative(monkeypatch):
|
|
30
|
+
monkeypatch.delenv("LICOS_PROJECT_PATH", raising=False)
|
|
31
|
+
monkeypatch.delenv("LICOS_WORKSPACE_PATH", raising=False)
|
|
32
|
+
|
|
33
|
+
assert _path_to_cli_output("/workspace/projects/output/demo.docx") == "output/demo.docx"
|
|
File without changes
|
|
File without changes
|