--- a/src/main/java/de/unixwork/uwproj/Main.java Wed Oct 11 20:41:26 2023 +0200 +++ b/src/main/java/de/unixwork/uwproj/Main.java Sun Oct 15 19:20:41 2023 +0200 @@ -5,6 +5,12 @@ import org.slf4j.LoggerFactory; import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.util.Arrays; +import java.util.Objects; +import java.util.Set; public class Main { @@ -33,17 +39,73 @@ new VelocityEngine().getTemplate(tplFileName).merge(context, out); } + private static void abort() { + System.err.println("Abort."); + System.exit(1); + } + private static void printUsage() { System.err.println("Usage: uwproj [OPTIONS]"); System.err.println(); System.err.println("OPTIONS:"); System.err.println(" -h --help Print help text and exit"); + System.err.println(" --init Creates default files in directory 'make'"); System.err.println(" -o --output <file> Path to the output file"); System.err.printf(" (default: %s)\n", OUT_FILE_DEFAULT); System.err.println(" -p --project <file> Path to the project.xml file"); System.err.printf(" (default: %s)\n", IN_FILE_DEFAULT); System.err.println(" -t --template <file> Path to the velocity template"); System.err.printf(" (default: %s)\n", TPL_FILE_DEFAULT); + System.err.println(" --update Same as --init, but overwrites existing files"); + } + + private static void extract(Path path) { + try (final var res = Objects.requireNonNull(Main.class.getClassLoader().getResourceAsStream(path.toString()))) { + Files.copy(res, path, StandardCopyOption.REPLACE_EXISTING); + } catch (Throwable t) { + System.err.printf("Cannot extract '%s': %s\n", path, t.getMessage()); + abort(); + } + } + + private static void init(boolean force) { + final var files = new String[]{ + "cc.mk", "gcc.mk", "clang.mk", "suncc.mk", + "configure.vm", "toolchain.sh", "uwproj.xsd" + }; + + // (1) create the make dir if it does not exist + final var make = Paths.get("make"); + if (Files.exists(make)) { + if (!Files.isDirectory(make)) { + System.err.println("A file with name 'make' already exists, but it's not a directory."); + abort(); + } + if (!force) { + System.err.println("uwproj files already exist. You can use --update instead."); + abort(); + } + } else { + try { + Files.createDirectory(make); + } catch (Throwable t) { + System.err.printf("Creating directory failed: %s\n", t.getMessage()); + abort(); + } + } + + // (2) create project.xml ONLY if it does not exist + final var project = make.resolve("project.xml"); + if (Files.notExists(project)) { + extract(project); + } + + // (3) create or update remaining uwproj files + Arrays.stream(files).map(make::resolve).forEach(Main::extract); + + // (4) stop + System.out.printf("uwproj files %s.\n", force ? "updated" : "created"); + System.exit(0); } private static void checkOneMoreArg(int i, int length) { @@ -57,6 +119,9 @@ var inFileName = IN_FILE_DEFAULT; var tplFileName = TPL_FILE_DEFAULT; var outFileName = OUT_FILE_DEFAULT; + boolean opsOptionsUsed = false; + boolean doInit = false; + boolean forceInit = false; for (int i = 0 ; i < args.length ; i++) { switch (args[i]) { @@ -64,17 +129,27 @@ case "--output": checkOneMoreArg(i, args.length); outFileName = args[++i]; + opsOptionsUsed = true; break; case "-p": case "--project": checkOneMoreArg(i, args.length); inFileName = args[++i]; + opsOptionsUsed = true; break; case "-t": case "--template": checkOneMoreArg(i, args.length); tplFileName = args[++i]; + opsOptionsUsed = true; + break; + case "--init": + doInit = true; + break; + case "--update": + doInit = true; + forceInit = true; break; case "--help": case "-h": @@ -86,18 +161,30 @@ } } + if (opsOptionsUsed && doInit) { + System.err.println("Cannot use --init or --update with other options."); + abort(); + } + + if (doInit) { + init(forceInit); + } + System.out.println("In: " + inFileName); System.out.println("Tpl: " + tplFileName); try (var out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFileName)))) { writeConfigureScript(out, tplFileName, loadProjectFile(inFileName)); - } catch (Exception ex) { - LoggerFactory.getLogger(Main.class).error( - "Uncaught Exception", - ex - ); + } catch (Throwable t) { + System.err.printf("Unexpected error: %s\n", t.getMessage()); + abort(); } System.out.println("Out: " + outFileName); + try { + Files.setPosixFilePermissions(Path.of(outFileName), PosixFilePermissions.fromString("rwxr-xr-x")); + } catch (Throwable t) { + System.err.printf("WARN: Setting file permissions failed: %s\n", t.getMessage()); + } } }