diff options
Diffstat (limited to 'jgvariant-tool/src/main/java')
3 files changed, 72 insertions, 25 deletions
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java index 744d902..c352e4f 100644 --- a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java +++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java @@ -61,17 +61,17 @@ import picocli.CommandLine; * * <h3>Adding a static delta to an OSTree summary file</h3> * - * <p>Static delta <code>3...</code> (in hex), between commits <code>1...</code> and <code>2... + * <p>Superblock checksum <code>0...</code>, between commits <code>3...</code> and <code>6... * </code>: * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 3333333333333333333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222222222222222222 1111111111111111111111111111111111111111111111111111111111111111 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 03738040e28e7662e9c9d2599c530ea974e642c9f87e6c00cbaa39a0cdac8d44 66ff167ff35ce87daac817447a9490a262ee75f095f017716a6eb1a9d9eb3350 3d3b3329dca38871f29aeda1bf5854d76c707fa269759a899d0985c91815fe6f * } * - * <p>Static delta <code>3...</code> (in hex), between the empty commit and <code>2...</code>: + * <p>Superblock checksum <code>f...</code>, between the empty commit and <code>3...</code>: * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 4444444444444444444444444444444444444444444444444444444444444444 2222222222222222222222222222222222222222222222222222222222222222 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary f481144629474bd88c106e45ac405ebd75b324b0655af1aec14b31786ae1fd61 31c8835d5c9d2c6687a50091c85142d1b2d853ff416a9fb81b4ee30754510d52 * } */ public final class Main { diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java index 2bea23c..db724dd 100644 --- a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java +++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java @@ -29,6 +29,7 @@ import java.text.ParseException; import java.util.*; import java.util.logging.Logger; import java.util.stream.IntStream; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; import picocli.AutoComplete; import picocli.CommandLine; @@ -37,7 +38,7 @@ import picocli.CommandLine.*; @Command( name = "jgvariant", mixinStandardHelpOptions = true, - description = "Manipulate files in GVariant format.", + header = "Manipulate files in GVariant format.", subcommands = {MainCommand.OstreeCommand.class, AutoComplete.GenerateCompletion.class}) final class MainCommand { @@ -74,35 +75,60 @@ final class MainCommand { @Command( name = "ostree", mixinStandardHelpOptions = true, - description = "Manipulate OSTree files.", + header = "Manipulate OSTree files.", subcommands = {OstreeCommand.SummaryCommand.class}) static final class OstreeCommand { @Command( name = "summary", mixinStandardHelpOptions = true, - description = "Manipulate OSTree summary files.") + header = "Manipulate OSTree summary files.") static final class SummaryCommand extends BaseDecoderCommand<Summary> { - @Command(mixinStandardHelpOptions = true) + @Command( + name = "read", + mixinStandardHelpOptions = true, + header = "Dump an OSTree summary file as human-readable JSON.") void read(@Parameters(paramLabel = "<file>", description = "Summary file to read") File file) throws IOException { read(file, Summary.decoder()); } - @Command(name = "add-static-delta", mixinStandardHelpOptions = true) + @Command( + name = "add-static-delta", + mixinStandardHelpOptions = true, + header = "Add a static delta to an OSTree summary file.", + description = + """ + Checksums can be given in either hex (64 digits) or a variant of Base64 (43 + digits) where '/' is replaced by '_'. + + In the OSTree repository, static deltas are named based on the <from> and <to> + checksums in modified Base64 when stored in the deltas/ directory. The naming + scheme is either <from[0..1]>/<from[2..42]>-<to> if <from> is an actual commit + or <to[0..1]>/<to[2..42]> if <from> is the empty commit. + + <superblock-csum> is the SHA256 checksum of the file called 'superblock' that + is part of the static delta and contains its metadata. + """) void addStaticDelta( @Parameters(paramLabel = "<file>", description = "Summary file to manipulate.") File summaryFile, - @Parameters(paramLabel = "<delta>", description = "Checksum of the static delta (hex).") - String delta, - @Parameters(paramLabel = "<to>", description = "Commit checksum the delta ends at (hex).") - String toCommit, + @Parameters( + paramLabel = "<superblock-csum>", + description = "Checksum of the static delta superblock (hex/mbase64).") + String deltaName, + @Parameters( + paramLabel = "<to>", + description = "Commit checksum the delta ends at (hex/mbase64).") + String toCommitName, @Parameters( paramLabel = "<from>", arity = "0..1", - description = "Commit checksum the delta starts from (hex).") - String fromCommit) + description = + "Commit checksum the delta starts from (hex/mbase64). Defaults to the empty commit.") + @Nullable + String fromCommitName) throws IOException, ParseException { var summaryDecoder = Summary.decoder(); @@ -111,6 +137,10 @@ final class MainCommand { var staticDeltaMapSignature = Signature.parse("a{sv}"); var checksumSignature = Signature.parse("ay"); + var delta = parseChecksum(deltaName); + var toCommit = parseChecksum(toCommitName); + var fromCommit = fromCommitName != null ? parseChecksum(fromCommitName) : null; + var metadata = summary.metadata(); var metadataFields = new LinkedHashMap<>(metadata.fields()); metadataFields.compute( @@ -121,8 +151,8 @@ final class MainCommand { ? new LinkedHashMap<>((Map<String, Variant>) v.value()) : new LinkedHashMap<>(); staticDeltas.put( - fromCommit != null ? fromCommit + "-" + toCommit : toCommit, - new Variant(checksumSignature, toByteList(ByteString.ofHex(delta).bytes()))); + fromCommit != null ? fromCommit.hex() + "-" + toCommit.hex() : toCommit.hex(), + new Variant(checksumSignature, toByteList(delta.bytes()))); return new Variant(staticDeltaMapSignature, staticDeltas); }); metadata = new Metadata(metadataFields); @@ -131,10 +161,6 @@ final class MainCommand { encodeFile(summaryFile, summaryDecoder, summary); } - private List<Byte> toByteList(byte[] bytes) { - return IntStream.range(0, bytes.length).mapToObj(i -> bytes[i]).toList(); - } - SummaryCommand() {} } @@ -185,6 +211,27 @@ final class MainCommand { out.write(thingBytes); } } + + protected static ByteString parseChecksum(String name) { + var bytes = + switch (name.length()) { + case 64 -> ByteString.ofHex(name); + case 43 -> ByteString.ofModifiedBase64(name); + default -> + throw new IllegalArgumentException( + "Checksums must be either 64 hex digits or 43 mbase64 digits."); + }; + + if (bytes.size() != 32) { + throw new IllegalArgumentException("Checksums must be 32 bytes long."); + } + + return bytes; + } + + protected static List<Byte> toByteList(byte[] bytes) { + return IntStream.range(0, bytes.length).mapToObj(i -> bytes[i]).toList(); + } } MainCommand() {} diff --git a/jgvariant-tool/src/main/java/module-info.java b/jgvariant-tool/src/main/java/module-info.java index 6faa226..3f38283 100644 --- a/jgvariant-tool/src/main/java/module-info.java +++ b/jgvariant-tool/src/main/java/module-info.java @@ -55,17 +55,17 @@ * * <h3>Adding a static delta to an OSTree summary file</h3> * - * <p>Static delta <code>3...</code> (in hex), between commits <code>1...</code> and <code>2... + * <p>Superblock checksum <code>0...</code>, between commits <code>3...</code> and <code>6... * </code>: * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 3333333333333333333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222222222222222222 1111111111111111111111111111111111111111111111111111111111111111 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 03738040e28e7662e9c9d2599c530ea974e642c9f87e6c00cbaa39a0cdac8d44 66ff167ff35ce87daac817447a9490a262ee75f095f017716a6eb1a9d9eb3350 3d3b3329dca38871f29aeda1bf5854d76c707fa269759a899d0985c91815fe6f * } * - * <p>Static delta <code>3...</code> (in hex), between the empty commit and <code>2...</code>: + * <p>Superblock checksum <code>f...</code>, between the empty commit and <code>3...</code>: * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 4444444444444444444444444444444444444444444444444444444444444444 2222222222222222222222222222222222222222222222222222222222222222 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary f481144629474bd88c106e45ac405ebd75b324b0655af1aec14b31786ae1fd61 31c8835d5c9d2c6687a50091c85142d1b2d853ff416a9fb81b4ee30754510d52 * } */ module eu.mulk.jgvariant.tool { |