|
17 | 17 | collect_subcrate_metadata |
18 | 18 | ) |
19 | 19 |
|
| 20 | +from fairscape_models.rocrate import ROCrateV1_2 |
| 21 | +from fairscape_models.conversion.converter import ROCToTargetConverter |
| 22 | +from fairscape_models.conversion.mapping.croissant import MAPPING_CONFIGURATION as CROISSANT_MAPPING |
| 23 | + |
20 | 24 |
|
21 | 25 | @click.group('build') |
22 | 26 | def build_group(): |
23 | | - """Build derived artifacts from RO-Crates (datasheets, previews, graphs).""" |
| 27 | + """Build derived artifacts from RO-Crates (datasheets, previews, graphs, Croissants).""" |
24 | 28 | pass |
25 | 29 |
|
26 | 30 | @build_group.command('release') |
@@ -373,6 +377,49 @@ def generate_evidence_graph( |
373 | 377 | click.echo(f"ERROR: {str(e)}") |
374 | 378 | ctx.exit(1) |
375 | 379 |
|
| 380 | +@build_group.command('croissant') |
| 381 | +@click.argument('rocrate-path', type=click.Path(exists=True, path_type=pathlib.Path)) |
| 382 | +@click.option('--output', required=False, type=click.Path(path_type=pathlib.Path), help="Output Croissant JSON file path (defaults to croissant.json in crate dir).") |
| 383 | +@click.pass_context |
| 384 | +def build_croissant(ctx, rocrate_path, output): |
| 385 | + """Convert an RO-Crate to Croissant JSON-LD format.""" |
| 386 | + |
| 387 | + if rocrate_path.is_dir(): |
| 388 | + metadata_file = rocrate_path / "ro-crate-metadata.json" |
| 389 | + crate_dir = rocrate_path |
| 390 | + elif rocrate_path.name == "ro-crate-metadata.json": |
| 391 | + metadata_file = rocrate_path |
| 392 | + crate_dir = rocrate_path.parent |
| 393 | + else: |
| 394 | + click.echo(f"ERROR: Input path must be an RO-Crate directory or a ro-crate-metadata.json file.", err=True) |
| 395 | + ctx.exit(1) |
| 396 | + |
| 397 | + if not metadata_file.exists(): |
| 398 | + click.echo(f"ERROR: Metadata file not found: {metadata_file}", err=True) |
| 399 | + ctx.exit(1) |
| 400 | + |
| 401 | + output_path = output if output else crate_dir / "croissant.json" |
| 402 | + |
| 403 | + click.echo(f"Converting RO-Crate to Croissant: {metadata_file}") |
| 404 | + click.echo(f"Outputting to: {output_path}") |
| 405 | + |
| 406 | + try: |
| 407 | + with open(metadata_file, 'r') as f: |
| 408 | + metadata = json.load(f) |
| 409 | + |
| 410 | + source_crate = ROCrateV1_2(**metadata) |
| 411 | + croissant_converter = ROCToTargetConverter(source_crate, CROISSANT_MAPPING) |
| 412 | + croissant_result = croissant_converter.convert() |
| 413 | + |
| 414 | + with open(output_path, 'w') as f: |
| 415 | + json.dump(croissant_result.model_dump(by_alias=True, exclude_none=True), f, indent=2) |
| 416 | + |
| 417 | + click.echo(f"Croissant conversion completed successfully: {output_path}") |
| 418 | + except Exception as e: |
| 419 | + click.echo(f"ERROR: Failed to convert RO-Crate to Croissant: {e}", err=True) |
| 420 | + traceback.print_exc() |
| 421 | + ctx.exit(1) |
| 422 | + |
376 | 423 | # Placeholder for explicit preview generation |
377 | 424 | # @build_group.command('preview') |
378 | 425 | # @click.argument('rocrate-path', type=click.Path(exists=True, path_type=pathlib.Path)) |
|
0 commit comments