jgvariant-tool, add-static-delta: Document better, accept modified Base64.
Change-Id: Icad477b34d074164ffdd162afd91f4abf627b979
diff --git a/README.md b/README.md
index 8254404..dc3f37f 100644
--- a/README.md
+++ b/README.md
@@ -87,13 +87,19 @@
#### Adding a static delta to an [OSTree][] summary file
-Static delta <code>3...</code> (in hex), between commits <code>1...</code> and <code>2...</code>:
+Superblock checksum `0...`, between commits `3...` and `6...`:
- $ 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
-Static delta <code>3...</code> (in hex), between the empty commit and <code>2...</code>:
+Superblock checksum `f...`, between the empty commit and `3...`:
- $ 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
+
+Checksums can be given in either hex (64 digits) or a variant of Base64 (43
+digits) where `/` is replaced by `_`. The latter format is used to identify
+the start and end commits of deltas as part of folder names below `deltas/` in
+the OSTree repository itself.
+
### Building the tool
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 @@
*
* <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.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 @@
@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 @@
@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 @@
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 @@
? 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 @@
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 @@
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 {