Skip to content

Commit 77876e7

Browse files
committed
support stdin inputs, enable tests from gradle
1 parent 3a786aa commit 77876e7

File tree

5 files changed

+80
-16
lines changed

5 files changed

+80
-16
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ To see the full results:
5555

5656
```shell
5757
./gradlew installDist
58-
./build/install/subpop/bin/subpop --input src/test/resources/data/mushrooms.csv --min-ratio .4 --class-value EDIBLE
58+
./build/install/subpop/bin/subpop --input src/test/resources/data/mushrooms.csv --input-header --min-ratio .4 --class-value EDIBLE
59+
# or
60+
cat src/test/resources/data/mushrooms.csv | ./build/install/subpop/bin/subpop --input-header --min-ratio .4 --class-value EDIBLE
5961
```
6062

6163
## CLI Options

build.gradle.kts

+6-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import java.util.*
1111

1212
plugins {
1313
id("com.github.johnrengelman.shadow") version "8.1.1"
14-
id("io.micronaut.application") version "4.4.2"
14+
id("io.micronaut.application") version "4.4.3"
1515
}
1616

1717
val versionProperties = Properties().apply {
@@ -34,13 +34,13 @@ repositories {
3434

3535
dependencies {
3636
annotationProcessor("info.picocli:picocli-codegen:4.7.6")
37-
annotationProcessor("io.micronaut.serde:micronaut-serde-processor:2.11.0")
37+
annotationProcessor("io.micronaut.serde:micronaut-serde-processor:2.11.1")
3838

3939
implementation("org.jetbrains:annotations:24.1.0")
4040
implementation("info.picocli:picocli:4.7.6")
4141
implementation("com.opencsv:opencsv:5.9")
4242
implementation("io.micronaut.picocli:micronaut-picocli:5.5.0")
43-
implementation("io.micronaut.serde:micronaut-serde-jackson:2.11.0")
43+
implementation("io.micronaut.serde:micronaut-serde-jackson:2.11.1")
4444
implementation("com.google.guava:guava:33.2.1-jre")
4545
implementation("org.barfuin.texttree:text-tree:2.1.2")
4646

@@ -59,7 +59,8 @@ java {
5959
}
6060

6161
tasks.withType<Test> {
62-
maxHeapSize = "2g" // Set the desired maximum heap size
62+
useJUnitPlatform()
63+
maxHeapSize = "5g" // Set the desired maximum heap size
6364
}
6465

6566
tasks.named<ProcessResources>("processResources") {
@@ -70,6 +71,7 @@ tasks.named<ProcessResources>("processResources") {
7071
}
7172

7273
micronaut {
74+
version.set("4.6.0")
7375
testRuntime("junit5")
7476
processing {
7577
incremental(true)

settings.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
plugins {
1010
// Apply the foojay-resolver plugin to allow automatic download of JDKs
1111
id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0"
12+
id("io.micronaut.platform.catalog") version "4.4.3"
1213
}
1314

1415
rootProject.name = "subpop"

src/main/java/io/clusterless/subpop/Main.java

+66-7
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717
import io.clusterless.subpop.options.OutputOptions;
1818
import io.clusterless.subpop.util.Verbosity;
1919
import io.clusterless.subpop.util.VersionProvider;
20-
import io.micronaut.configuration.picocli.PicocliRunner;
2120
import org.slf4j.Logger;
2221
import org.slf4j.LoggerFactory;
2322
import picocli.CommandLine;
2423
import picocli.CommandLine.Command;
2524

2625
import java.io.IOException;
26+
import java.io.UncheckedIOException;
27+
import java.util.Arrays;
2728
import java.util.List;
29+
import java.util.concurrent.Callable;
2830

2931
@Command(
3032
name = "subpop",
@@ -33,7 +35,7 @@
3335
versionProvider = VersionProvider.class,
3436
sortOptions = false
3537
)
36-
public class Main implements Runnable {
38+
public class Main implements Callable<Integer> {
3739
private static final Logger LOG = LoggerFactory.getLogger(Main.class);
3840

3941
@CommandLine.Mixin
@@ -57,10 +59,50 @@ public class Main implements Runnable {
5759
protected Float supportRatio = null;
5860

5961
public static void main(String[] args) throws Exception {
60-
PicocliRunner.run(Main.class, args);
62+
Main main = new Main();
63+
64+
CommandLine commandLine = new CommandLine(main);
65+
66+
try {
67+
commandLine.parseArgs(args);
68+
} catch (CommandLine.MissingParameterException | CommandLine.UnmatchedArgumentException e) {
69+
System.err.println(e.getMessage());
70+
commandLine.usage(System.out);
71+
System.exit(-1);
72+
}
73+
74+
if (commandLine.isUsageHelpRequested()) {
75+
commandLine.usage(System.out);
76+
return;
77+
} else if (commandLine.isVersionHelpRequested()) {
78+
commandLine.printVersionHelp(System.out);
79+
return;
80+
}
81+
82+
int exitCode = 0;
83+
84+
try {
85+
exitCode = commandLine.execute(args);
86+
} catch (Exception e) {
87+
System.err.println(e.getMessage());
88+
89+
if (main.verbosity.isVerbose()) {
90+
e.printStackTrace(System.err);
91+
}
92+
93+
System.exit(-1); // get exit code from exception
94+
}
95+
96+
System.exit(exitCode);
6197
}
6298

63-
public void run() {
99+
@Override
100+
public Integer call() throws Exception {
101+
if (inputOptions.inputs().isEmpty() && hasStdIn() == 0) {
102+
LOG.info("no input data");
103+
throw new IllegalArgumentException("no input data");
104+
}
105+
64106
ItemStoreReader itemStoreReader = ItemStoreReader.builder()
65107
.withSeparator(inputOptions.delimiter())
66108
.withHasHeader(inputOptions.hasHeader())
@@ -75,10 +117,17 @@ public void run() {
75117
.build();
76118

77119
try {
78-
ItemStore itemStore = itemStoreReader.read(inputOptions.inputs());
120+
ItemStore itemStore;
121+
if (inputOptions.inputs().isEmpty()) {
122+
LOG.info("reading from stdin");
123+
itemStore = itemStoreReader.read(System.in);
124+
} else {
125+
LOG.info("reading from files: {}", inputOptions.inputs());
126+
itemStore = itemStoreReader.read(inputOptions.inputs());
127+
}
79128

80-
if(!itemStore.containsAllClasses(classValue)) {
81-
throw new IllegalArgumentException("class value not found");
129+
if (!itemStore.containsAllClasses(classValue)) {
130+
throw new IllegalArgumentException("class value not found: {}" + Arrays.toString(classValue));
82131
}
83132

84133
CPTree cpTree = new CPTree(itemStore);
@@ -92,5 +141,15 @@ public void run() {
92141
} catch (CsvValidationException | IOException e) {
93142
throw new RuntimeException(e);
94143
}
144+
145+
return 0;
146+
}
147+
148+
private static int hasStdIn() {
149+
try {
150+
return System.in.available();
151+
} catch (IOException e) {
152+
throw new UncheckedIOException(e.getMessage(), e);
153+
}
95154
}
96155
}

src/test/java/io/clusterless/subpop/MainTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
import java.io.*;
1818

19-
import static org.junit.jupiter.api.Assertions.assertTrue;
20-
2119
public class MainTest {
2220

2321
@Test
@@ -29,11 +27,13 @@ public void testWithCommandLineOption() throws Exception {
2927
String[] args = new String[]{
3028
"--input", "src/test/resources/data/mushrooms.csv",
3129
"--input-header",
30+
"--output-header",
3231
"--class-col", "0",
3332
"--class-value", "EDIBLE",
34-
"--min-ratio", ".4",
33+
"--min-ratio", ".4"
3534
};
36-
PicocliRunner.run(Main.class, ctx, args);
35+
36+
PicocliRunner.call(Main.class, ctx, args);
3737

3838
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
3939
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(bais));

0 commit comments

Comments
 (0)