aboutsummaryrefslogtreecommitdiff
path: root/jgvariant-tool/src
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2023-12-05 21:12:16 +0100
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2023-12-05 21:14:54 +0100
commita1e8443c417249dc6ff9a24c7c9d8fb2fce07c88 (patch)
tree35ac3b7251ed5e3a8909d79f259e2392a8506052 /jgvariant-tool/src
parentfe42f326920d078f4e05afa0907258a6160c4834 (diff)
jgvariant-tool: New module.
Adds a command line tool that can read and (in the future) manipulate GVariant-formatted files. Change-Id: Icc92eb409a97e7cf72dfd7535f6a8b3587dd4a48
Diffstat (limited to 'jgvariant-tool/src')
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java28
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java115
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteArraySerializer.java24
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteStringSerializer.java24
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ChecksumAdapter.java27
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/SignatureSerializer.java24
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/VariantSerializer.java43
-rw-r--r--jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/package-info.java8
-rw-r--r--jgvariant-tool/src/main/java/module-info.java20
9 files changed, 313 insertions, 0 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
new file mode 100644
index 0000000..64e375a
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java
@@ -0,0 +1,28 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool;
+
+import static java.util.logging.Level.WARNING;
+
+import java.util.logging.Logger;
+import picocli.CommandLine;
+
+/**
+ * A command line tool to read and manipulate GVariant-formatted files.
+ *
+ * <p>Also provides ways to manipulate OSTree repositories.
+ */
+public final class Main {
+ static {
+ Logger.getGlobal().setLevel(WARNING);
+ }
+
+ public static void main(String[] args) {
+ int exitCode = new CommandLine(new MainCommand()).execute(args);
+ System.exit(exitCode);
+ }
+
+ private 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
new file mode 100644
index 0000000..7b25dfc
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java
@@ -0,0 +1,115 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool;
+
+import static java.util.logging.Level.*;
+
+import eu.mulk.jgvariant.ostree.Summary;
+import eu.mulk.jgvariant.tool.jsonb.*;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.ByteBuffer;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.util.logging.Logger;
+import org.jetbrains.annotations.VisibleForTesting;
+import picocli.AutoComplete;
+import picocli.CommandLine;
+import picocli.CommandLine.*;
+
+@Command(
+ name = "jgvariant",
+ mixinStandardHelpOptions = true,
+ description = "Manipulate files in GVariant format.",
+ subcommands = {MainCommand.OstreeCommand.class, AutoComplete.GenerateCompletion.class})
+final class MainCommand {
+
+ private static final Logger LOG = Logger.getLogger("eu.mulk.jgvariant.tool");
+
+ private static final Jsonb jsonb =
+ JsonbBuilder.newBuilder()
+ .withConfig(
+ new JsonbConfig()
+ .withFormatting(true)
+ .withAdapters(ChecksumAdapter.INSTANCE)
+ .withSerializers(
+ ByteStringSerializer.INSTANCE,
+ ByteArraySerializer.INSTANCE,
+ SignatureSerializer.INSTANCE,
+ VariantSerializer.INSTANCE))
+ .build();
+
+ @Option(
+ names = {"-v", "--verbose"},
+ description = "Enable verbose logging.",
+ scope = CommandLine.ScopeType.INHERIT)
+ void setVerbose(boolean[] verbose) {
+ Logger.getGlobal()
+ .setLevel(
+ switch (verbose.length) {
+ case 0 -> WARNING;
+ case 1 -> INFO;
+ case 2 -> FINE;
+ default -> ALL;
+ });
+ }
+
+ @Command(
+ name = "ostree",
+ mixinStandardHelpOptions = true,
+ description = "Manipulate OSTree files.",
+ subcommands = {OstreeCommand.SummaryCommand.class})
+ static final class OstreeCommand {
+
+ @Command(
+ name = "summary",
+ mixinStandardHelpOptions = true,
+ description = "Manipulate OSTree summary files.")
+ static final class SummaryCommand extends BaseCommand {
+
+ @Command(mixinStandardHelpOptions = true)
+ void read(@Parameters(paramLabel = "<file>") File file) throws IOException {
+ LOG.fine(() -> "Reading file %s".formatted(file));
+ var fileBytes = ByteBuffer.wrap(Files.readAllBytes(fs().getPath(file.getPath())));
+ var decoder = Summary.decoder();
+ var thing = decoder.decode(fileBytes);
+ out().println(jsonb.toJson(thing));
+ }
+
+ SummaryCommand() {}
+ }
+
+ OstreeCommand() {}
+ }
+
+ @Command
+ abstract static class BaseCommand {
+
+ @Spec CommandLine.Model.CommandSpec spec;
+
+ @VisibleForTesting FileSystem fs = FileSystems.getDefault();
+
+ protected BaseCommand() {}
+
+ protected PrintWriter out() {
+ return spec.commandLine().getOut();
+ }
+
+ protected PrintWriter err() {
+ return spec.commandLine().getErr();
+ }
+
+ protected FileSystem fs() {
+ return fs;
+ }
+ }
+
+ MainCommand() {}
+}
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteArraySerializer.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteArraySerializer.java
new file mode 100644
index 0000000..7f80440
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteArraySerializer.java
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool.jsonb;
+
+import jakarta.json.bind.serializer.JsonbSerializer;
+import jakarta.json.bind.serializer.SerializationContext;
+import jakarta.json.stream.JsonGenerator;
+import java.util.HexFormat;
+
+@SuppressWarnings("java:S6548")
+public final class ByteArraySerializer implements JsonbSerializer<byte[]> {
+
+ public static final ByteArraySerializer INSTANCE = new ByteArraySerializer();
+
+ private ByteArraySerializer() {}
+
+ @Override
+ public void serialize(
+ byte[] o, JsonGenerator jsonGenerator, SerializationContext serializationContext) {
+ jsonGenerator.write(HexFormat.of().formatHex(o));
+ }
+}
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteStringSerializer.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteStringSerializer.java
new file mode 100644
index 0000000..3537c3d
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ByteStringSerializer.java
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool.jsonb;
+
+import eu.mulk.jgvariant.ostree.ByteString;
+import jakarta.json.bind.serializer.JsonbSerializer;
+import jakarta.json.bind.serializer.SerializationContext;
+import jakarta.json.stream.JsonGenerator;
+
+@SuppressWarnings("java:S6548")
+public final class ByteStringSerializer implements JsonbSerializer<ByteString> {
+
+ public static final ByteStringSerializer INSTANCE = new ByteStringSerializer();
+
+ private ByteStringSerializer() {}
+
+ @Override
+ public void serialize(
+ ByteString o, JsonGenerator jsonGenerator, SerializationContext serializationContext) {
+ jsonGenerator.write(o.hex());
+ }
+}
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ChecksumAdapter.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ChecksumAdapter.java
new file mode 100644
index 0000000..58a8951
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/ChecksumAdapter.java
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool.jsonb;
+
+import eu.mulk.jgvariant.ostree.ByteString;
+import eu.mulk.jgvariant.ostree.Checksum;
+import jakarta.json.bind.adapter.JsonbAdapter;
+
+@SuppressWarnings("java:S6548")
+public final class ChecksumAdapter implements JsonbAdapter<Checksum, ByteString> {
+
+ public static final ChecksumAdapter INSTANCE = new ChecksumAdapter();
+
+ private ChecksumAdapter() {}
+
+ @Override
+ public ByteString adaptToJson(Checksum obj) throws Exception {
+ return obj.byteString();
+ }
+
+ @Override
+ public Checksum adaptFromJson(ByteString obj) throws Exception {
+ return new Checksum(obj);
+ }
+}
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/SignatureSerializer.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/SignatureSerializer.java
new file mode 100644
index 0000000..dca1044
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/SignatureSerializer.java
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool.jsonb;
+
+import eu.mulk.jgvariant.core.Signature;
+import jakarta.json.bind.serializer.JsonbSerializer;
+import jakarta.json.bind.serializer.SerializationContext;
+import jakarta.json.stream.JsonGenerator;
+
+@SuppressWarnings("java:S6548")
+public final class SignatureSerializer implements JsonbSerializer<Signature> {
+
+ public static final SignatureSerializer INSTANCE = new SignatureSerializer();
+
+ private SignatureSerializer() {}
+
+ @Override
+ public void serialize(
+ Signature o, JsonGenerator jsonGenerator, SerializationContext serializationContext) {
+ jsonGenerator.write(o.toString());
+ }
+}
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/VariantSerializer.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/VariantSerializer.java
new file mode 100644
index 0000000..99ff553
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/jsonb/VariantSerializer.java
@@ -0,0 +1,43 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package eu.mulk.jgvariant.tool.jsonb;
+
+import com.google.common.primitives.Bytes;
+import eu.mulk.jgvariant.core.Signature;
+import eu.mulk.jgvariant.core.Variant;
+import jakarta.json.bind.serializer.JsonbSerializer;
+import jakarta.json.bind.serializer.SerializationContext;
+import jakarta.json.stream.JsonGenerator;
+import java.text.ParseException;
+import java.util.List;
+
+@SuppressWarnings("java:S6548")
+public final class VariantSerializer implements JsonbSerializer<Variant> {
+
+ public static final VariantSerializer INSTANCE = new VariantSerializer();
+
+ private final ByteArraySerializer byteArraySerializer = ByteArraySerializer.INSTANCE;
+
+ private final Signature byteArraySignature;
+
+ private VariantSerializer() {
+ try {
+ byteArraySignature = Signature.parse("ay");
+ } catch (ParseException e) {
+ // impossible
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void serialize(Variant obj, JsonGenerator generator, SerializationContext ctx) {
+ if (obj.signature().equals(byteArraySignature)) {
+ byteArraySerializer.serialize(Bytes.toArray((List<Byte>) obj.value()), generator, ctx);
+ } else {
+ ctx.serialize(obj.value(), generator);
+ }
+ }
+}
diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/package-info.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/package-info.java
new file mode 100644
index 0000000..da5c3ba
--- /dev/null
+++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/package-info.java
@@ -0,0 +1,8 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+@API(status = API.Status.INTERNAL)
+package eu.mulk.jgvariant.tool;
+
+import org.apiguardian.api.API;
diff --git a/jgvariant-tool/src/main/java/module-info.java b/jgvariant-tool/src/main/java/module-info.java
new file mode 100644
index 0000000..e66981c
--- /dev/null
+++ b/jgvariant-tool/src/main/java/module-info.java
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: © 2023 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+module eu.mulk.jgvariant.tool {
+ requires transitive eu.mulk.jgvariant.ostree;
+ requires com.google.common;
+ requires info.picocli;
+ requires jakarta.json;
+ requires jakarta.json.bind;
+ requires java.logging;
+ requires static com.google.errorprone.annotations;
+ requires static org.apiguardian.api;
+ requires static org.jetbrains.annotations;
+
+ opens eu.mulk.jgvariant.tool to
+ info.picocli;
+
+ exports eu.mulk.jgvariant.tool;
+}