Skip to content

Commit ce8c59b

Browse files
authored
refactor: Make files command printing logic reusable (#165)
1 parent f715f0b commit ce8c59b

2 files changed

Lines changed: 69 additions & 24 deletions

File tree

ice/src/main/java/com/altinity/ice/cli/internal/cmd/Files.java

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
package com.altinity.ice.cli.internal.cmd;
1111

12+
import com.altinity.ice.cli.internal.util.TreePrinter;
1213
import java.io.IOException;
1314
import java.util.ArrayList;
1415
import java.util.List;
@@ -30,53 +31,49 @@ public static void run(RESTCatalog catalog, TableIdentifier tableId) throws IOEx
3031
Table table = catalog.loadTable(tableId);
3132
Snapshot snapshot = table.currentSnapshot();
3233

34+
String tableName = tableId.toString();
35+
String rootLabel = "Snapshots: " + tableName;
36+
3337
if (snapshot == null) {
34-
System.out.println("Snapshots: " + tableId);
38+
System.out.println(rootLabel);
3539
System.out.println("(no snapshots)");
3640
return;
3741
}
3842

39-
String tableName = tableId.toString();
4043
int schemaId = snapshot.schemaId() != null ? snapshot.schemaId() : 0;
4144
String manifestListLocation = snapshot.manifestListLocation();
4245
String locationStr = manifestListLocation != null ? manifestListLocation : "(embedded)";
43-
44-
System.out.println("Snapshots: " + tableName);
45-
System.out.println(
46-
"└── Snapshot " + snapshot.snapshotId() + ", schema " + schemaId + ": " + locationStr);
46+
String snapshotLabel =
47+
"Snapshot " + snapshot.snapshotId() + ", schema " + schemaId + ": " + locationStr;
4748

4849
FileIO tableIO = table.io();
4950
List<ManifestFile> manifests;
5051
try {
5152
manifests = snapshot.allManifests(tableIO);
5253
} catch (Exception e) {
54+
TreePrinter.print(
55+
new TreePrinter.Node(rootLabel, List.of(new TreePrinter.Node(snapshotLabel))));
5356
System.out.println(" (failed to read manifests: " + e.getMessage() + ")");
5457
return;
5558
}
5659

57-
for (int m = 0; m < manifests.size(); m++) {
58-
ManifestFile manifest = manifests.get(m);
59-
boolean isLastManifest = (m == manifests.size() - 1);
60-
String manifestPrefix = isLastManifest ? "└── " : "├── ";
61-
String childConnector = isLastManifest ? " " : "│ ";
62-
63-
List<String> dataFileLocations = new ArrayList<>();
60+
List<TreePrinter.Node> manifestNodes = new ArrayList<>(manifests.size());
61+
for (ManifestFile manifest : manifests) {
62+
List<TreePrinter.Node> dataFileNodes = new ArrayList<>();
6463
try (CloseableIterable<DataFile> files = ManifestFiles.read(manifest, tableIO)) {
6564
for (DataFile file : files) {
66-
dataFileLocations.add(file.location());
65+
dataFileNodes.add(new TreePrinter.Node("Datafile: " + file.location()));
6766
}
6867
} catch (Exception e) {
69-
dataFileLocations.add("(failed to read: " + e.getMessage() + ")");
70-
}
71-
72-
System.out.println(" " + manifestPrefix + "Manifest: " + manifest.path());
73-
74-
String dataFileIndent = " " + childConnector;
75-
for (int f = 0; f < dataFileLocations.size(); f++) {
76-
boolean isLastFile = (f == dataFileLocations.size() - 1);
77-
String filePrefix = isLastFile ? "└── " : "├── ";
78-
System.out.println(dataFileIndent + filePrefix + "Datafile: " + dataFileLocations.get(f));
68+
dataFileNodes.add(
69+
new TreePrinter.Node("Datafile: (failed to read: " + e.getMessage() + ")"));
7970
}
71+
manifestNodes.add(new TreePrinter.Node("Manifest: " + manifest.path(), dataFileNodes));
8072
}
73+
74+
TreePrinter.Node root =
75+
new TreePrinter.Node(
76+
rootLabel, List.of(new TreePrinter.Node(snapshotLabel, manifestNodes)));
77+
TreePrinter.print(root);
8178
}
8279
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2025 Altinity Inc and/or its affiliates. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*/
10+
package com.altinity.ice.cli.internal.util;
11+
12+
import java.io.PrintStream;
13+
import java.util.List;
14+
15+
public final class TreePrinter {
16+
17+
private TreePrinter() {}
18+
19+
public record Node(String label, List<Node> children) {
20+
public Node(String label) {
21+
this(label, List.of());
22+
}
23+
24+
public Node {
25+
children = List.copyOf(children);
26+
}
27+
}
28+
29+
public static void print(Node root) {
30+
print(root, System.out);
31+
}
32+
33+
public static void print(Node root, PrintStream out) {
34+
out.println(root.label());
35+
printChildren(root.children(), "", out);
36+
}
37+
38+
private static void printChildren(List<Node> children, String descendantIndent, PrintStream out) {
39+
for (int i = 0; i < children.size(); i++) {
40+
Node child = children.get(i);
41+
boolean isLast = (i == children.size() - 1);
42+
String connector = isLast ? "└── " : "├── ";
43+
String childDescendantIndent = descendantIndent + (isLast ? " " : "│ ");
44+
out.println(descendantIndent + connector + child.label());
45+
printChildren(child.children(), childDescendantIndent, out);
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)