Skip to content

Commit 9e24c4a

Browse files
committed
piccodescript: Add abilities for creating jar archives and printing them
1 parent 61d941e commit 9e24c4a

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

src/main/java/org/piccode/piccodescript/Piccode.java

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,32 @@
22

33
import com.github.tomaslanger.chalk.Chalk;
44
import com.github.tomaslanger.cli.choice.SingleChoice;
5+
import java.io.BufferedInputStream;
56
import java.io.File;
7+
import java.io.FileInputStream;
8+
import java.io.FileNotFoundException;
9+
import java.io.FileOutputStream;
610
import java.io.IOException;
711
import java.io.InputStream;
812
import java.io.PrintStream;
913
import java.io.UnsupportedEncodingException;
1014
import java.nio.file.Files;
1115
import java.util.ArrayList;
16+
import java.util.Date;
17+
import java.util.Enumeration;
1218
import java.util.List;
1319
import java.util.Properties;
1420
import java.util.Scanner;
21+
import java.util.jar.JarEntry;
22+
import java.util.jar.JarFile;
23+
import java.util.jar.JarOutputStream;
24+
import java.util.jar.Manifest;
1525
import java.util.logging.Level;
1626
import java.util.logging.Logger;
1727
import java.util.regex.Matcher;
1828
import java.util.regex.Pattern;
1929
import javax.sound.midi.SysexMessage;
30+
import javax.xml.crypto.Data;
2031
import net.sourceforge.argparse4j.ArgumentParsers;
2132
import net.sourceforge.argparse4j.impl.Arguments;
2233
import static net.sourceforge.argparse4j.impl.Arguments.storeTrue;
@@ -126,6 +137,22 @@ private static void run(String[] args) {
126137
.dest("extra_args")
127138
.help("Pass-through args");
128139

140+
var lib = subparsers.addParser("lib")
141+
.defaultHelp(true)
142+
.help("Build sources into a lib");
143+
144+
lib.addArgument("--new")
145+
.action(storeTrue())
146+
.help("Create a new jar file");
147+
148+
lib.addArgument("--ls")
149+
.action(storeTrue())
150+
.help("Lists the contents of the jar file");
151+
152+
lib.addArgument("file")
153+
.nargs("?") // Optional
154+
.help("The directory to build a lib from or the lib to work with");
155+
129156
parser.addArgument("--version").action(Arguments.version());
130157

131158
// optional: glmr help
@@ -148,6 +175,31 @@ private static void run(String[] args) {
148175
}
149176
}
150177

178+
if ("lib".equals(command)) {
179+
var input = res.getString("file");
180+
if (input == null) {
181+
System.out.println("No input directory or file");
182+
return;
183+
}
184+
185+
if (res.getBoolean("new")) {
186+
createJarFile(input);
187+
return;
188+
}
189+
190+
if (res.getBoolean("ls")) {
191+
if (!input.endsWith(".jar")) {
192+
System.out.println("Invalid library archive file");
193+
return;
194+
}
195+
196+
printLib(input);
197+
return;
198+
}
199+
200+
201+
}
202+
151203
if ("build".equals(command)) {
152204
/*System.out.println("==> build:");
153205
System.out.println("Emit: " + res.getBoolean("emit"));
@@ -404,4 +456,83 @@ private static void createNewProject() {
404456
return;
405457
}
406458
}
459+
460+
private static void createJarFile(String input) {
461+
var inputFile = new File(input);
462+
var outputFile = new File(inputFile.getName() + ".jar");
463+
464+
String baseName = inputFile.getName();
465+
466+
467+
// Create custom manifest
468+
Manifest manifest = new Manifest();
469+
var attr = manifest.getMainAttributes();
470+
attr.putValue("Manifest-Version", "1.0");
471+
attr.putValue("PiccodeScript-Version", "" + VERSION);
472+
attr.putValue("Library-Name", inputFile.getName());
473+
attr.putValue("Library-Type", "PiccodeScript-Native");
474+
attr.putValue("Build-Date", new Date().toString());
475+
476+
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(outputFile), manifest)) {
477+
addToJar(inputFile, baseName ,jos);
478+
} catch (FileNotFoundException ex) {
479+
} catch (IOException ex) {
480+
}
481+
482+
System.out.println("JAR with custom manifest created!");
483+
}
484+
485+
486+
private static void addToJar(File file, String baseName, JarOutputStream jos) throws IOException {
487+
String entryName = baseName + file.getPath()
488+
.substring(new File(baseName).getPath().length()) // relative to base
489+
.replace("\\", "/");
490+
491+
if (file.isDirectory()) {
492+
if (!entryName.endsWith("/")) {
493+
entryName += "/";
494+
}
495+
JarEntry dirEntry = new JarEntry(entryName);
496+
jos.putNextEntry(dirEntry);
497+
jos.closeEntry();
498+
499+
for (File child : file.listFiles()) {
500+
addToJar(child, baseName, jos);
501+
}
502+
} else {
503+
JarEntry fileEntry = new JarEntry(entryName);
504+
jos.putNextEntry(fileEntry);
505+
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
506+
byte[] buffer = new byte[1024];
507+
int count;
508+
while ((count = in.read(buffer)) != -1) {
509+
jos.write(buffer, 0, count);
510+
}
511+
}
512+
jos.closeEntry();
513+
}
514+
}
515+
516+
517+
518+
private static void printLib(String path) {
519+
File jarPath = new File(path);
520+
try (JarFile jarFile = new JarFile(jarPath)) {
521+
522+
// Print manifest entries
523+
Manifest manifest = jarFile.getManifest();
524+
System.out.println("Manifest contents:");
525+
manifest.getMainAttributes().forEach((k, v) -> System.out.println(k + ": " + v));
526+
527+
// Print files in jar
528+
System.out.println("\nSources:");
529+
Enumeration<JarEntry> entries = jarFile.entries();
530+
while (entries.hasMoreElements()) {
531+
JarEntry entry = entries.nextElement();
532+
System.out.println(" - " + entry.getName());
533+
}
534+
} catch (IOException ex) {
535+
System.getLogger(Piccode.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
536+
}
537+
}
407538
}

0 commit comments

Comments
 (0)