10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package org.openjdk.jigsaw.cli; 27 28 import java.lang.module.*; 29 import java.io.*; 30 import java.security.SignatureException; 31 import java.util.*; 32 33 import static java.lang.System.out; 34 import static java.lang.System.err; 35 36 import org.openjdk.jigsaw.*; 37 import org.openjdk.jigsaw.SimpleLibrary.StorageOption; 38 import org.openjdk.internal.joptsimple.*; 39 40 /* Interface: 41 42 jpkg [-v] [-L <library>] [-r <resource-dir>] [-i include-dir] \ 43 [-m <module_dir>] [-d <output_dir>] [-c <command>] [-n <name>] \ 44 [-e <e-mail@address>] [-s <short description>] [-l <long description>] \ 45 [-x <extra metadata>] [deb|jmod] <module_name>* 46 47 -v : verbose output 48 -L : library the modules are installed to 49 -i : directory with files to include as part of the package 50 -m : directory with modules to package 51 -d : destination directory to put the package in 52 -c : command name for launcher invoking main class 53 -n : maintainer name 54 -e : maintainer e-mail address 55 -s : short description 56 -l : long description 57 -x : additional metadata - for Debian packages, a file whose 58 contents gets appended to DEBIAN/control 59 --fast : use fastest, rather then best compression 60 */ 61 62 public class Packager { 63 64 private static JigsawModuleSystem jms 65 = JigsawModuleSystem.instance(); 66 67 private static boolean jigsawDevMode 68 = System.getenv("JIGSAW_DEV_MODE") != null; 69 70 /** Temp dir for modules to be pre-installed into */ 71 private static File tmp_dst; 72 73 /** Directory where the classes to package are stored on disk. */ 74 private File classes = new File(System.getProperty("user.dir")); 75 76 /** Default destination dir is current directory */ 77 private File destination = new File(System.getProperty("user.dir")); 78 79 /** The default location to install modules to */ 80 private File library = new File("/usr/lib/java/modules"); 81 82 /** The JRE to use in control scripts */ 83 private File javaHome = new File(System.getProperty("java.home")); 84 85 private boolean verbose; 86 87 private boolean fast; 118 = " This package was automatically generated from the corresponding Jigsaw module.\n" 119 + " Information on Jigsaw is available at http://openjdk.java.net/projects/jigsaw."; 120 121 /** Packaging-system dependent additional metadata */ 122 private File extra_metadata; 123 124 private File natlibs; 125 private File natcmds; 126 private File config_dir; 127 128 // Installed size 129 private Integer installedSize = null; 130 131 // Platform boot module 132 private static final String BOOT_MODULE = "jdk.base"; 133 134 private static void createTempWorkDir() 135 throws Command.Exception 136 { 137 try { 138 tmp_dst = File.createTempFile("jigsaw",null); 139 Files.delete(tmp_dst); 140 Files.mkdirs(tmp_dst, "jigsaw temp directory"); 141 } 142 catch (IOException x) { 143 throw new Command.Exception(x); 144 } 145 } 146 147 148 class Jmod extends Command<SimpleLibrary> { 149 private String getModuleVersion(String modulename) 150 throws Command.Exception 151 { 152 Manifest mf = Manifest.create(modulename, classes); 153 ModuleInfo info = getModuleInfo(mf); 154 return info.id().version().toString(); 155 } 156 157 protected void go(SimpleLibrary lib) 158 throws Command.Exception 159 { 160 while (hasArg()) { 161 File outputfile = null; 162 try { 163 String modulename = takeArg(); 164 String version = getModuleVersion(modulename); 165 String outputfilename = modulename + '@'+ version + ".jmod"; 166 if (verbose) 574 if (verbose) 575 System.out.println("Creating binary Debian package for " + manifest.module()); 576 577 createTempWorkDir(); 578 if (null != includes) { 579 try { 580 Files.copyTree(includes, tmp_dst); 581 } catch (IOException x) { 582 throw new Command.Exception(x); 583 } 584 } 585 preinstallModule(manifest); 586 packModule(manifest); 587 writeMetaData(manifest); 588 buildPackage(); 589 cleanup(); 590 } 591 } 592 } 593 594 private static Map<String,Class<? extends Command<SimpleLibrary>>> commands 595 = new HashMap<>(); 596 597 static { 598 commands.put("deb", Deb.class); 599 commands.put("jmod", Jmod.class); 600 } 601 602 private OptionParser parser; 603 604 private static OptionSpec<File> resourcePath; // ## 605 606 private void usage() { 607 out.format("%n"); 608 out.format("usage: jpkg [-v] [-L <library>] [-r <resource-dir>] [-i <include-dir>] [-m <module-dir>] [-d <output-dir>] [-c <command>] [-n <name>] [-e <e-mail@address>] [-s <short description>] [-l <long description>] [-x <extra metadata>] [deb|jmod] <module-name>%n"); 609 out.format("%n"); 610 try { 611 parser.printHelpOn(out); 612 } catch (IOException x) { 613 throw new AssertionError(x); 614 } 615 out.format("%n"); 616 } 617 618 public static void run(String[] args) 619 throws OptionException, Command.Exception { 620 621 new Packager().exec(args); 622 } 623 624 private void exec(String[] args) 625 throws OptionException, Command.Exception { 626 627 parser = new OptionParser(); 628 797 extra_metadata = opts.valueOf(extraMetadata); 798 if (opts.has(nativeLibs)) { 799 natlibs = opts.valueOf(nativeLibs); 800 checkPathArgument(natlibs, "Native library"); 801 } 802 if (opts.has(nativeCmds)) { 803 natcmds = opts.valueOf(nativeCmds); 804 checkPathArgument(natcmds, "Native command"); 805 } 806 if (opts.has(config)) { 807 config_dir = opts.valueOf(config); 808 checkPathArgument(config_dir, "Config"); 809 } 810 if (opts.has(isize)) 811 installedSize = opts.valueOf(isize); 812 813 if (cmd == Deb.class) 814 (new Deb()).run(null, opts); 815 else if (cmd == Jmod.class) 816 (new Jmod()).run(null, opts); 817 } 818 819 /** 820 * Helper method to check if a path exists before using it further. 821 * 822 * @param path to check 823 * @param type of path being checked 824 * 825 * @throws Command.Exception if path doesn't exist 826 */ 827 private static final void checkIfPathExists(File path, String type) 828 throws Command.Exception { 829 830 if (!path.exists()) 831 throw new Command.Exception("%s path doesn't exist: %s", 832 type, path); 833 } 834 835 /** 836 * Helper method to check if a path is readable before using it further. 837 * 838 * @param path to check 839 * @param type of path being checked 840 * 841 * @throws Command.Exception if path isn't readable 842 */ 843 private static final void checkIfPathIsReadable(File path, String type) 844 throws Command.Exception { 845 846 if (!path.canRead()) 847 throw new Command.Exception("%s path isn't readable: %s", 848 type, path); 849 } 850 851 /** 852 * Helper method to check if a path is a directory before using it further. 853 * 854 * @param path to check 855 * @param type of path being checked 856 * 857 * @throws Command.Exception if path is not a directory 858 */ 859 private static final void checkIfPathIsDirectory(File path, String type) 860 throws Command.Exception { 861 862 if (!path.isDirectory()) 863 throw new Command.Exception("%s path is not a directory: %s", 864 type, path); 865 } 866 867 /** 868 * Helper method to check if a path argument is valid. 869 * 870 * @param path to check 871 * @param type of path being checked 872 * 873 * @throws Command.Exception if path is not a directory 874 */ 875 private static final void checkPathArgument(File path, String type) 876 throws Command.Exception { 877 878 checkIfPathExists(path, type); 879 checkIfPathIsReadable(path, type); 880 checkIfPathIsDirectory(path, type); 881 } 882 883 private Packager() { } 884 885 public static void main(String[] args) throws Exception { 886 try { 887 run(args); 888 } catch (OptionException | Command.Exception x) { 889 err.println(x.getMessage()); 890 System.exit(1); 891 } 892 } 893 894 } | 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package org.openjdk.jigsaw.cli; 27 28 import java.lang.module.*; 29 import java.io.*; 30 import java.util.*; 31 32 import static java.lang.System.out; 33 import static java.lang.System.err; 34 35 import org.openjdk.jigsaw.*; 36 import org.openjdk.jigsaw.SimpleLibrary.StorageOption; 37 import org.openjdk.internal.joptsimple.*; 38 39 /* Interface: 40 41 jpkg [-v] [-L <library>] [-r <resource-dir>] [-i include-dir] \ 42 [-m <module_dir>] [-d <output_dir>] [-c <command>] [-n <name>] \ 43 [-e <e-mail@address>] [-s <short description>] [-l <long description>] \ 44 [-x <extra metadata>] [deb|jmod] <module_name>* 45 46 -v : verbose output 47 -L : library the modules are installed to 48 -i : directory with files to include as part of the package 49 -m : directory with modules to package 50 -d : destination directory to put the package in 51 -c : command name for launcher invoking main class 52 -n : maintainer name 53 -e : maintainer e-mail address 54 -s : short description 55 -l : long description 56 -x : additional metadata - for Debian packages, a file whose 57 contents gets appended to DEBIAN/control 58 --fast : use fastest, rather then best compression 59 */ 60 61 public class Packager { 62 63 private static final JigsawModuleSystem jms 64 = JigsawModuleSystem.instance(); 65 66 private static final boolean jigsawDevMode 67 = System.getenv("JIGSAW_DEV_MODE") != null; 68 69 /** Temp dir for modules to be pre-installed into */ 70 private static File tmp_dst; 71 72 /** Directory where the classes to package are stored on disk. */ 73 private File classes = new File(System.getProperty("user.dir")); 74 75 /** Default destination dir is current directory */ 76 private File destination = new File(System.getProperty("user.dir")); 77 78 /** The default location to install modules to */ 79 private File library = new File("/usr/lib/java/modules"); 80 81 /** The JRE to use in control scripts */ 82 private File javaHome = new File(System.getProperty("java.home")); 83 84 private boolean verbose; 85 86 private boolean fast; 117 = " This package was automatically generated from the corresponding Jigsaw module.\n" 118 + " Information on Jigsaw is available at http://openjdk.java.net/projects/jigsaw."; 119 120 /** Packaging-system dependent additional metadata */ 121 private File extra_metadata; 122 123 private File natlibs; 124 private File natcmds; 125 private File config_dir; 126 127 // Installed size 128 private Integer installedSize = null; 129 130 // Platform boot module 131 private static final String BOOT_MODULE = "jdk.base"; 132 133 private static void createTempWorkDir() 134 throws Command.Exception 135 { 136 try { 137 tmp_dst = File.createTempFile("jigsaw", null); 138 Files.delete(tmp_dst); 139 Files.mkdirs(tmp_dst, "jigsaw temp directory"); 140 } catch (IOException x) { 141 throw new Command.Exception(x); 142 } 143 } 144 145 class Contents extends Command<SimpleLibrary> { 146 protected void go(SimpleLibrary lib) 147 throws Command.Exception 148 { 149 String jmodName = takeArg(); 150 finishArgs(); 151 try (FileInputStream fis = new FileInputStream(jmodName); 152 DataInputStream dis = new DataInputStream(fis); 153 ModuleFile.Reader reader = new ModuleFile.Reader(dis)) { 154 List<String> contents = reader.getContents(); 155 for (String fn : contents) 156 out.format(" %s%n", fn); 157 } catch (IOException x) { 158 throw new Command.Exception(x); 159 } 160 } 161 } 162 163 class Show extends Command<SimpleLibrary> { 164 protected void go(SimpleLibrary lib) 165 throws Command.Exception 166 { 167 String jmodName = takeArg(); 168 finishArgs(); 169 try (FileInputStream fis = new FileInputStream(jmodName); 170 DataInputStream dis = new DataInputStream(fis); 171 ModuleFile.Reader reader = new ModuleFile.Reader(dis)) { 172 ModuleInfo mi = jms.parseModuleInfo(reader.readStart()); 173 Commands.formatModule(out, mi, verbose); 174 } catch (IOException x) { 175 throw new Command.Exception(x); 176 } 177 } 178 } 179 180 class Jmod extends Command<SimpleLibrary> { 181 private String getModuleVersion(String modulename) 182 throws Command.Exception 183 { 184 Manifest mf = Manifest.create(modulename, classes); 185 ModuleInfo info = getModuleInfo(mf); 186 return info.id().version().toString(); 187 } 188 189 protected void go(SimpleLibrary lib) 190 throws Command.Exception 191 { 192 while (hasArg()) { 193 File outputfile = null; 194 try { 195 String modulename = takeArg(); 196 String version = getModuleVersion(modulename); 197 String outputfilename = modulename + '@'+ version + ".jmod"; 198 if (verbose) 606 if (verbose) 607 System.out.println("Creating binary Debian package for " + manifest.module()); 608 609 createTempWorkDir(); 610 if (null != includes) { 611 try { 612 Files.copyTree(includes, tmp_dst); 613 } catch (IOException x) { 614 throw new Command.Exception(x); 615 } 616 } 617 preinstallModule(manifest); 618 packModule(manifest); 619 writeMetaData(manifest); 620 buildPackage(); 621 cleanup(); 622 } 623 } 624 } 625 626 private static final Map<String,Class<? extends Command<SimpleLibrary>>> commands 627 = new HashMap<>(); 628 629 static { 630 commands.put("contents", Contents.class); 631 commands.put("deb", Deb.class); 632 commands.put("jmod", Jmod.class); 633 commands.put("show", Show.class); 634 } 635 636 private OptionParser parser; 637 638 private static OptionSpec<File> resourcePath; // ## 639 640 private void usage() { 641 out.format("%n"); 642 out.format("usage: jpkg contents <module-file>%n"); 643 out.format(" jpkg show [-v] <module-file>%n"); 644 out.format(" jpkg [-v] [-L <library>] [-r <resource-dir>] "); 645 out.format( "[-i <include-dir>] [-m <module-dir>] "); 646 out.format( "[-d <output-dir>] [-c <command>] [-n <name>] "); 647 out.format( "[-e <e-mail@address>] [-s <short description>] "); 648 out.format( "[-l <long description>] [-x <extra metadata>] "); 649 out.format( "[deb|jmod] <module-name>%n"); 650 out.format("%n"); 651 try { 652 parser.printHelpOn(out); 653 } catch (IOException x) { 654 throw new AssertionError(x); 655 } 656 out.format("%n"); 657 } 658 659 public static void run(String[] args) 660 throws OptionException, Command.Exception { 661 662 new Packager().exec(args); 663 } 664 665 private void exec(String[] args) 666 throws OptionException, Command.Exception { 667 668 parser = new OptionParser(); 669 838 extra_metadata = opts.valueOf(extraMetadata); 839 if (opts.has(nativeLibs)) { 840 natlibs = opts.valueOf(nativeLibs); 841 checkPathArgument(natlibs, "Native library"); 842 } 843 if (opts.has(nativeCmds)) { 844 natcmds = opts.valueOf(nativeCmds); 845 checkPathArgument(natcmds, "Native command"); 846 } 847 if (opts.has(config)) { 848 config_dir = opts.valueOf(config); 849 checkPathArgument(config_dir, "Config"); 850 } 851 if (opts.has(isize)) 852 installedSize = opts.valueOf(isize); 853 854 if (cmd == Deb.class) 855 (new Deb()).run(null, opts); 856 else if (cmd == Jmod.class) 857 (new Jmod()).run(null, opts); 858 else if (cmd == Contents.class) 859 (new Contents()).run(null, opts); 860 else if (cmd == Show.class) 861 (new Show()).run(null, opts); 862 } 863 864 /** 865 * Helper method to check if a path exists before using it further. 866 * 867 * @param path to check 868 * @param type of path being checked 869 * 870 * @throws Command.Exception if path doesn't exist 871 */ 872 private static void checkIfPathExists(File path, String type) 873 throws Command.Exception { 874 875 if (!path.exists()) 876 throw new Command.Exception("%s path doesn't exist: %s", 877 type, path); 878 } 879 880 /** 881 * Helper method to check if a path is readable before using it further. 882 * 883 * @param path to check 884 * @param type of path being checked 885 * 886 * @throws Command.Exception if path isn't readable 887 */ 888 private static void checkIfPathIsReadable(File path, String type) 889 throws Command.Exception { 890 891 if (!path.canRead()) 892 throw new Command.Exception("%s path isn't readable: %s", 893 type, path); 894 } 895 896 /** 897 * Helper method to check if a path is a directory before using it further. 898 * 899 * @param path to check 900 * @param type of path being checked 901 * 902 * @throws Command.Exception if path is not a directory 903 */ 904 private static void checkIfPathIsDirectory(File path, String type) 905 throws Command.Exception { 906 907 if (!path.isDirectory()) 908 throw new Command.Exception("%s path is not a directory: %s", 909 type, path); 910 } 911 912 /** 913 * Helper method to check if a path argument is valid. 914 * 915 * @param path to check 916 * @param type of path being checked 917 * 918 * @throws Command.Exception if path is not a directory 919 */ 920 private static void checkPathArgument(File path, String type) 921 throws Command.Exception { 922 923 checkIfPathExists(path, type); 924 checkIfPathIsReadable(path, type); 925 checkIfPathIsDirectory(path, type); 926 } 927 928 private Packager() { } 929 930 public static void main(String[] args) throws Exception { 931 try { 932 run(args); 933 } catch (OptionException | Command.Exception x) { 934 err.println(x.getMessage()); 935 System.exit(1); 936 } 937 } 938 939 } |