Skip to content

Commit f8aa663

Browse files
Use api_deploy.create_distribution to avoid circular import
1 parent b4bbfaa commit f8aa663

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

databusclient/cli.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import List
55

66
import click
7+
import re
78

89
import databusclient.api.deploy as api_deploy
910
from databusclient.api.delete import delete as api_delete
@@ -213,5 +214,51 @@ def delete(databusuris: List[str], databus_key: str, dry_run: bool, force: bool)
213214
)
214215

215216

217+
@app.command()
218+
@click.argument("url")
219+
@click.option("--cv", "cvs", multiple=True, help="Content variant like key=value (repeatable). Keys must not contain '|' or '_'")
220+
@click.option("--format", "file_format", help="Format extension (e.g. ttl)")
221+
@click.option("--compression", help="Compression (e.g. gzip)")
222+
@click.option("--sha-length", help="sha256:length (64 hex chars followed by ':' and integer length)")
223+
@click.option("--json-output", is_flag=True, help="Output JSON distribution object instead of plain string")
224+
def mkdist(url, cvs, file_format, compression, sha_length, json_output):
225+
"""Create a distribution string from components."""
226+
# Validate CVs
227+
cvs_dict = {}
228+
for cv in cvs:
229+
if "=" not in cv:
230+
raise click.BadParameter(f"Invalid content variant '{cv}': expected key=value")
231+
key, val = cv.split("=", 1)
232+
if any(ch in key for ch in ("|", "_")):
233+
raise click.BadParameter("Invalid characters in content-variant key (forbidden: '|' and '_')")
234+
if key in cvs_dict:
235+
raise click.BadParameter(f"Duplicate content-variant key '{key}'")
236+
cvs_dict[key] = val
237+
238+
# Validate sha-length
239+
sha_tuple = None
240+
if sha_length:
241+
if not re.match(r'^[A-Fa-f0-9]{64}:\d+$', sha_length):
242+
raise click.BadParameter("Invalid --sha-length; expected SHA256HEX:length")
243+
sha, length = sha_length.split(":", 1)
244+
sha_tuple = (sha, int(length))
245+
246+
# Deterministic ordering
247+
sorted_cvs = {k: cvs_dict[k] for k in sorted(cvs_dict)}
248+
249+
dist = api_deploy.create_distribution(url=url, cvs=sorted_cvs, file_format=file_format, compression=compression, sha256_length_tuple=sha_tuple)
250+
if json_output:
251+
import json as _json
252+
click.echo(_json.dumps({"distribution": dist}))
253+
else:
254+
click.echo(dist)
255+
256+
257+
@app.command()
258+
@click.argument("shell", type=click.Choice(["bash","zsh","fish","powershell"]), required=False)
259+
def completion(shell="bash"):
260+
click.echo(f"Run: eval \"$(_DATABUSCLIENT_COMPLETE=source_{shell} python -m databusclient)\"")
261+
262+
216263
if __name__ == "__main__":
217264
app()

0 commit comments

Comments
 (0)