Repository navigation
Expand file tree
/
Copy pathredir.java
More file actions
136 lines (133 loc) · 5.9 KB
/
Copy pathredir.java
File metadata and controls
136 lines (133 loc) · 5.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/// usr/bin/env jbang "$0" "$@" ; exit $?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.*;
import java.util.regex.Pattern;
public class redir {
private static Pattern directivePattern = Pattern.compile("^//[A-Z]{3,}( .*|\\s*)$");
private static Pattern projectDirectivePattern = Pattern.compile("^[A-Z]{3,}( .*|\\s*)$");
public static void main(String[] args) throws IOException {
if (args.length < 1) {
System.err.println(
"Either strips all directives from a JBang script or only the ones specified\n" +
"and replaces them with the directives passed on the standard input.\n");
System.err.println("Usage: redir [-d|--directive <name>] [-s|--strip] [-v|--view] <filename>");
System.exit(1);
}
String inFileName = null;
String outFileName = null;
String directive = null;
boolean strip = false;
boolean list = false;
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.startsWith("-")) {
if ("-d".equals(arg) || "--directive".equals(arg)) {
if (i + 1 < args.length) {
directive = args[++i];
} else {
System.err.println("Error: Missing value for " + arg);
System.exit(1);
}
} else if ("-o".equals(arg) || "--output".equals(arg)) {
if (i + 1 < args.length) {
outFileName = args[++i];
} else {
System.err.println("Error: Missing value for " + arg);
System.exit(1);
}
} else if ("-s".equals(arg) || "--strip".equals(arg)) {
strip = true;
} else if ("-l".equals(arg) || "--list".equals(arg)) {
list = true;
} else {
System.err.println("Error: Unknown option " + arg);
System.exit(1);
}
} else {
inFileName = arg;
}
}
if (inFileName == null) {
System.err.println("Error: Missing filename");
System.exit(1);
}
Path inFile = Paths.get(inFileName);
Path outFile = Files.createTempFile("redir", ".tmp");
boolean project = inFile.getFileName().toString().equals("build.jbang");
Pattern pattern = project ? projectDirectivePattern : directivePattern;
if (directive != null) {
directive = directive.trim().toUpperCase();
if (!project && !directive.startsWith("//")) {
directive = "//" + directive;
}
}
// Copy all lines from input file to output file except the ones
// matching the directive or all directives if none specified
boolean firstRun = true;
while (true) {
boolean firstMatch = true;
boolean matched = false;
try (var reader = Files.newBufferedReader(inFile);
var writer = Files.newBufferedWriter(outFile)) {
String line;
while ((line = reader.readLine()) != null) {
boolean matches;
if (firstRun) {
// In the first run we look for JBang directives (eg //DEPS, //JAVA etc)
matches = directive != null ?
line.equals(directive) || line.startsWith(directive.toUpperCase() + " ")
: project || pattern.matcher(line).matches();
} else {
// If we didn't find any directive in the first run we just add the new
// lines to the top of the file (after any shebang)
matches = firstMatch && !line.startsWith("///");
}
if (matches) {
if (firstMatch && !strip && !list) {
// copy all lines from stdin to the output file
try (var stdin = System.in;
var stdinReader = new BufferedReader(new InputStreamReader(stdin))) {
String stdinLine;
while ((stdinLine = stdinReader.readLine()) != null) {
writer.write(stdinLine);
writer.newLine();
}
}
}
firstMatch = false;
matched = true;
if (list) {
System.out.println(line);
}
if (firstRun) {
// Prevent line from being written to output file
continue;
}
}
writer.write(line);
writer.newLine();
}
// now add the new directive if any
if (directive != null) {
writer.write("// " + directive);
writer.newLine();
}
}
if (matched || !firstRun) {
// We either got a match or we already did a second run
break;
}
firstRun = false;
}
if (strip || !list) {
// Move the temporary output file to its final location
Path outFilePath = outFileName != null ? Paths.get(outFileName) : inFile;
Files.move(outFile, outFilePath, StandardCopyOption.REPLACE_EXISTING);
} else {
// Just delete the temporary output file
Files.delete(outFile);
}
}
}