|
| 1 | +import java.io.*; |
| 2 | +import java.nio.file.*; |
| 3 | +import java.util.*; |
| 4 | +import java.util.zip.*; |
| 5 | + |
| 6 | +public class Mod { |
| 7 | + |
| 8 | + public static void pack(File base, File src, File classes, File out) throws Exception { |
| 9 | + if (!base.exists()) throw new RuntimeException("Run setup first"); |
| 10 | + |
| 11 | + Set<String> changed = changed(base, src); |
| 12 | + if (changed.isEmpty()) { |
| 13 | + System.out.println("No changes to pack"); |
| 14 | + return; |
| 15 | + } |
| 16 | + |
| 17 | + zip(classes, changed, out); |
| 18 | + System.out.println("Packed " + changed.size() + " classes to " + out.getName()); |
| 19 | + } |
| 20 | + |
| 21 | + private static Set<String> changed(File base, File src) throws IOException { |
| 22 | + Set<String> changed = new HashSet<>(); |
| 23 | + Map<String, byte[]> orig = new HashMap<>(); |
| 24 | + |
| 25 | + try (ZipFile zf = new ZipFile(base)) { |
| 26 | + for (ZipEntry e : Collections.list(zf.entries())) { |
| 27 | + if (e.isDirectory() || !e.getName().endsWith(".java")) continue; |
| 28 | + |
| 29 | + orig.put(e.getName(), zf.getInputStream(e).readAllBytes()); |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + Path s = src.toPath(); |
| 34 | + for (String pkg : new String[]{"com", "net"}) { |
| 35 | + Path p = s.resolve(pkg); |
| 36 | + if (!Files.exists(p)) continue; |
| 37 | + |
| 38 | + Files.walk(p).filter(f -> f.toString().endsWith(".java")).forEach(f -> { |
| 39 | + String rel = s.relativize(f).toString(); |
| 40 | + try { |
| 41 | + byte[] cur = Files.readAllBytes(f); |
| 42 | + byte[] o = orig.get(rel); |
| 43 | + if (o == null || !Arrays.equals(cur, o)) changed.add(rel); |
| 44 | + } catch (IOException e) { |
| 45 | + throw new UncheckedIOException(e); |
| 46 | + } |
| 47 | + }); |
| 48 | + } |
| 49 | + |
| 50 | + return changed; |
| 51 | + } |
| 52 | + |
| 53 | + private static void zip(File classes, Set<String> srcs, File out) throws IOException { |
| 54 | + out.getParentFile().mkdirs(); |
| 55 | + |
| 56 | + try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(out))) { |
| 57 | + Path base = classes.toPath(); |
| 58 | + for (String s : srcs) { |
| 59 | + String name = s.replace(".java", ""); |
| 60 | + Path dir = base.resolve(name).getParent(); |
| 61 | + String prefix = base.resolve(name).getFileName().toString(); |
| 62 | + if (!Files.exists(dir)) continue; |
| 63 | + |
| 64 | + Files.list(dir).filter(p -> p.getFileName().toString().startsWith(prefix) && p.toString().endsWith(".class")).forEach(p -> { |
| 65 | + try { |
| 66 | + zos.putNextEntry(new ZipEntry(base.relativize(p).toString())); |
| 67 | + Files.copy(p, zos); |
| 68 | + zos.closeEntry(); |
| 69 | + } catch (IOException e) { |
| 70 | + throw new UncheckedIOException(e); |
| 71 | + } |
| 72 | + }); |
| 73 | + } |
| 74 | + } |
| 75 | + } |
| 76 | +} |
0 commit comments