3 import org.apache.velocity.VelocityContext; |
3 import org.apache.velocity.VelocityContext; |
4 import org.apache.velocity.app.VelocityEngine; |
4 import org.apache.velocity.app.VelocityEngine; |
5 import org.slf4j.LoggerFactory; |
5 import org.slf4j.LoggerFactory; |
6 |
6 |
7 import java.io.*; |
7 import java.io.*; |
|
8 import java.nio.file.*; |
|
9 import java.nio.file.attribute.PosixFilePermission; |
|
10 import java.nio.file.attribute.PosixFilePermissions; |
|
11 import java.util.Arrays; |
|
12 import java.util.Objects; |
|
13 import java.util.Set; |
8 |
14 |
9 public class Main { |
15 public class Main { |
10 |
16 |
11 public final static String IN_FILE_DEFAULT = "make/project.xml"; |
17 public final static String IN_FILE_DEFAULT = "make/project.xml"; |
12 public final static String TPL_FILE_DEFAULT = "make/configure.vm"; |
18 public final static String TPL_FILE_DEFAULT = "make/configure.vm"; |
31 context.put("vars", project.getVars()); |
37 context.put("vars", project.getVars()); |
32 context.put("languages", project.getLang()); |
38 context.put("languages", project.getLang()); |
33 new VelocityEngine().getTemplate(tplFileName).merge(context, out); |
39 new VelocityEngine().getTemplate(tplFileName).merge(context, out); |
34 } |
40 } |
35 |
41 |
|
42 private static void abort() { |
|
43 System.err.println("Abort."); |
|
44 System.exit(1); |
|
45 } |
|
46 |
36 private static void printUsage() { |
47 private static void printUsage() { |
37 System.err.println("Usage: uwproj [OPTIONS]"); |
48 System.err.println("Usage: uwproj [OPTIONS]"); |
38 System.err.println(); |
49 System.err.println(); |
39 System.err.println("OPTIONS:"); |
50 System.err.println("OPTIONS:"); |
40 System.err.println(" -h --help Print help text and exit"); |
51 System.err.println(" -h --help Print help text and exit"); |
|
52 System.err.println(" --init Creates default files in directory 'make'"); |
41 System.err.println(" -o --output <file> Path to the output file"); |
53 System.err.println(" -o --output <file> Path to the output file"); |
42 System.err.printf(" (default: %s)\n", OUT_FILE_DEFAULT); |
54 System.err.printf(" (default: %s)\n", OUT_FILE_DEFAULT); |
43 System.err.println(" -p --project <file> Path to the project.xml file"); |
55 System.err.println(" -p --project <file> Path to the project.xml file"); |
44 System.err.printf(" (default: %s)\n", IN_FILE_DEFAULT); |
56 System.err.printf(" (default: %s)\n", IN_FILE_DEFAULT); |
45 System.err.println(" -t --template <file> Path to the velocity template"); |
57 System.err.println(" -t --template <file> Path to the velocity template"); |
46 System.err.printf(" (default: %s)\n", TPL_FILE_DEFAULT); |
58 System.err.printf(" (default: %s)\n", TPL_FILE_DEFAULT); |
|
59 System.err.println(" --update Same as --init, but overwrites existing files"); |
|
60 } |
|
61 |
|
62 private static void extract(Path path) { |
|
63 try (final var res = Objects.requireNonNull(Main.class.getClassLoader().getResourceAsStream(path.toString()))) { |
|
64 Files.copy(res, path, StandardCopyOption.REPLACE_EXISTING); |
|
65 } catch (Throwable t) { |
|
66 System.err.printf("Cannot extract '%s': %s\n", path, t.getMessage()); |
|
67 abort(); |
|
68 } |
|
69 } |
|
70 |
|
71 private static void init(boolean force) { |
|
72 final var files = new String[]{ |
|
73 "cc.mk", "gcc.mk", "clang.mk", "suncc.mk", |
|
74 "configure.vm", "toolchain.sh", "uwproj.xsd" |
|
75 }; |
|
76 |
|
77 // (1) create the make dir if it does not exist |
|
78 final var make = Paths.get("make"); |
|
79 if (Files.exists(make)) { |
|
80 if (!Files.isDirectory(make)) { |
|
81 System.err.println("A file with name 'make' already exists, but it's not a directory."); |
|
82 abort(); |
|
83 } |
|
84 if (!force) { |
|
85 System.err.println("uwproj files already exist. You can use --update instead."); |
|
86 abort(); |
|
87 } |
|
88 } else { |
|
89 try { |
|
90 Files.createDirectory(make); |
|
91 } catch (Throwable t) { |
|
92 System.err.printf("Creating directory failed: %s\n", t.getMessage()); |
|
93 abort(); |
|
94 } |
|
95 } |
|
96 |
|
97 // (2) create project.xml ONLY if it does not exist |
|
98 final var project = make.resolve("project.xml"); |
|
99 if (Files.notExists(project)) { |
|
100 extract(project); |
|
101 } |
|
102 |
|
103 // (3) create or update remaining uwproj files |
|
104 Arrays.stream(files).map(make::resolve).forEach(Main::extract); |
|
105 |
|
106 // (4) stop |
|
107 System.out.printf("uwproj files %s.\n", force ? "updated" : "created"); |
|
108 System.exit(0); |
47 } |
109 } |
48 |
110 |
49 private static void checkOneMoreArg(int i, int length) { |
111 private static void checkOneMoreArg(int i, int length) { |
50 if (i+1 >= length) { |
112 if (i+1 >= length) { |
51 printUsage(); |
113 printUsage(); |
55 |
117 |
56 public static void main(String[] args) { |
118 public static void main(String[] args) { |
57 var inFileName = IN_FILE_DEFAULT; |
119 var inFileName = IN_FILE_DEFAULT; |
58 var tplFileName = TPL_FILE_DEFAULT; |
120 var tplFileName = TPL_FILE_DEFAULT; |
59 var outFileName = OUT_FILE_DEFAULT; |
121 var outFileName = OUT_FILE_DEFAULT; |
|
122 boolean opsOptionsUsed = false; |
|
123 boolean doInit = false; |
|
124 boolean forceInit = false; |
60 |
125 |
61 for (int i = 0 ; i < args.length ; i++) { |
126 for (int i = 0 ; i < args.length ; i++) { |
62 switch (args[i]) { |
127 switch (args[i]) { |
63 case "-o": |
128 case "-o": |
64 case "--output": |
129 case "--output": |
65 checkOneMoreArg(i, args.length); |
130 checkOneMoreArg(i, args.length); |
66 outFileName = args[++i]; |
131 outFileName = args[++i]; |
|
132 opsOptionsUsed = true; |
67 break; |
133 break; |
68 case "-p": |
134 case "-p": |
69 case "--project": |
135 case "--project": |
70 checkOneMoreArg(i, args.length); |
136 checkOneMoreArg(i, args.length); |
71 inFileName = args[++i]; |
137 inFileName = args[++i]; |
|
138 opsOptionsUsed = true; |
72 break; |
139 break; |
73 |
140 |
74 case "-t": |
141 case "-t": |
75 case "--template": |
142 case "--template": |
76 checkOneMoreArg(i, args.length); |
143 checkOneMoreArg(i, args.length); |
77 tplFileName = args[++i]; |
144 tplFileName = args[++i]; |
|
145 opsOptionsUsed = true; |
|
146 break; |
|
147 case "--init": |
|
148 doInit = true; |
|
149 break; |
|
150 case "--update": |
|
151 doInit = true; |
|
152 forceInit = true; |
78 break; |
153 break; |
79 case "--help": |
154 case "--help": |
80 case "-h": |
155 case "-h": |
81 printUsage(); |
156 printUsage(); |
82 System.exit(0); |
157 System.exit(0); |
84 printUsage(); |
159 printUsage(); |
85 System.exit(1); |
160 System.exit(1); |
86 } |
161 } |
87 } |
162 } |
88 |
163 |
|
164 if (opsOptionsUsed && doInit) { |
|
165 System.err.println("Cannot use --init or --update with other options."); |
|
166 abort(); |
|
167 } |
|
168 |
|
169 if (doInit) { |
|
170 init(forceInit); |
|
171 } |
|
172 |
89 System.out.println("In: " + inFileName); |
173 System.out.println("In: " + inFileName); |
90 System.out.println("Tpl: " + tplFileName); |
174 System.out.println("Tpl: " + tplFileName); |
91 |
175 |
92 try (var out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFileName)))) { |
176 try (var out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFileName)))) { |
93 writeConfigureScript(out, tplFileName, loadProjectFile(inFileName)); |
177 writeConfigureScript(out, tplFileName, loadProjectFile(inFileName)); |
94 } catch (Exception ex) { |
178 } catch (Throwable t) { |
95 LoggerFactory.getLogger(Main.class).error( |
179 System.err.printf("Unexpected error: %s\n", t.getMessage()); |
96 "Uncaught Exception", |
180 abort(); |
97 ex |
|
98 ); |
|
99 } |
181 } |
100 |
182 |
101 System.out.println("Out: " + outFileName); |
183 System.out.println("Out: " + outFileName); |
|
184 try { |
|
185 Files.setPosixFilePermissions(Path.of(outFileName), PosixFilePermissions.fromString("rwxr-xr-x")); |
|
186 } catch (Throwable t) { |
|
187 System.err.printf("WARN: Setting file permissions failed: %s\n", t.getMessage()); |
|
188 } |
102 } |
189 } |
103 } |
190 } |