import 'dart:io'; import 'package:podman/podman.dart'; Future main(List args) async { if (args.isEmpty || args.contains('--help') || args.contains('-h')) { _printUsage(); return; } final flags = args .where((arg) => arg.startsWith('--')) .toList(growable: false); final positional = args .where((arg) => !arg.startsWith('--')) .toList(growable: false); if (positional.length < 2) { stderr.writeln('Provide a manifest name and at least one image reference.'); _printUsage(); exitCode = 64; return; } final manifestName = positional.first; final images = positional.sublist(1); final pushDestination = _readOption(flags, 'push'); final cleanup = flags.contains('--cleanup'); final amend = flags.contains('--amend'); final annotations = _readKeyValueOptions(flags, 'annotation'); if (annotations.isEmpty) { annotations['org.opencontainers.image.title'] = manifestName; } final client = PodmanClient(); try { final created = await client.createManifest( manifestName, options: ManifestCreateOptions( images: images, all: true, amend: amend, annotations: annotations, ), ); print('Created/updated manifest "$manifestName" (${created.id}).'); final exists = await client.manifestExists(manifestName); print('Manifest exists: $exists'); final details = await client.inspectManifest(manifestName); print('Schema version: ${details.schemaVersion}'); print('Media type: ${details.mediaType}'); print('Embedded manifests: ${details.manifests.length}'); if (pushDestination != null && pushDestination.isNotEmpty) { final pushed = await client.pushManifest(manifestName, pushDestination); print('Pushed to $pushDestination (${pushed.id}).'); } if (cleanup) { final result = await client.deleteManifest( manifestName, ignoreMissing: true, ); print( 'Deleted entries: ${result.deleted.length}; untagged: ${result.untagged.length}', ); } } finally { await client.close(); } } String? _readOption(List args, String name) { final prefix = '--$name='; for (final arg in args) { if (arg.startsWith(prefix)) { return arg.substring(prefix.length); } } return null; } Map _readKeyValueOptions(List args, String name) { final prefix = '--$name='; final output = {}; for (final arg in args) { if (!arg.startsWith(prefix)) { continue; } final raw = arg.substring(prefix.length); final index = raw.indexOf('='); if (index <= 0 || index == raw.length - 1) { continue; } final key = raw.substring(0, index); final value = raw.substring(index + 1); output[key] = value; } return output; } void _printUsage() { print(''' Manifest workflow example Usage: dart run example/manifest_workflow_example.dart [image ...] [options] Examples: dart run example/manifest_workflow_example.dart groupware-stack quay.io/groupware/api:amd64 quay.io/groupware/api:arm64 --push=quay.io/groupware/api:latest Options: --annotation= Add top-level annotation (repeatable) --push= Push manifest to destination reference --amend Amend if manifest already exists --cleanup Delete manifest at end of run --help, -h Show this help '''); }