10
10
package org .truffleruby .launcher ;
11
11
12
12
import java .io .PrintStream ;
13
+ import java .io .IOException ;
13
14
import java .util .ArrayList ;
14
15
import java .util .Arrays ;
15
16
import java .util .Collections ;
16
17
import java .util .List ;
17
18
import java .util .Map ;
18
19
import java .util .Set ;
20
+ import java .lang .ProcessBuilder .Redirect ;
19
21
20
22
import org .graalvm .launcher .AbstractLanguageLauncher ;
21
23
import org .graalvm .nativeimage .ProcessProperties ;
@@ -33,6 +35,7 @@ public class RubyLauncher extends AbstractLanguageLauncher {
33
35
34
36
private CommandLineOptions config ;
35
37
private String implementationName = null ;
38
+ private boolean helpOptionUsed = false ; // Any --help* option
36
39
37
40
public static void main (String [] args ) {
38
41
new RubyLauncher ().launch (args );
@@ -54,8 +57,8 @@ protected void validateArguments(Map<String, String> polyglotOptions) {
54
57
55
58
@ Override
56
59
protected void printVersion () {
57
- System . out .println (TruffleRuby .getVersionString (getImplementationNameFromEngine ()));
58
- System . out .println ();
60
+ getOutput () .println (TruffleRuby .getVersionString (getImplementationNameFromEngine ()));
61
+ getOutput () .println ();
59
62
printPolyglotVersions ();
60
63
}
61
64
@@ -109,9 +112,9 @@ protected List<String> preprocessArguments(List<String> args, Map<String, String
109
112
}
110
113
111
114
} catch (CommandLineException commandLineException ) {
112
- System . err .println ("truffleruby: " + commandLineException .getMessage ());
115
+ getError () .println ("truffleruby: " + commandLineException .getMessage ());
113
116
if (commandLineException .isUsageError ()) {
114
- printHelp (System . err );
117
+ printHelp (getError () );
115
118
}
116
119
System .exit (1 );
117
120
}
@@ -163,7 +166,7 @@ protected void collectArguments(Set<String> options) {
163
166
164
167
@ Override
165
168
protected void printHelp (OptionCategory maxCategory ) {
166
- printHelp (System . out );
169
+ printHelp (getOutput () );
167
170
}
168
171
169
172
@ Override
@@ -173,6 +176,43 @@ protected AbortException abortUnrecognizedArgument(String argument) {
173
176
"truffleruby: invalid option " + argument + " (Use --help for usage instructions.)" );
174
177
}
175
178
179
+ @ Override
180
+ protected boolean parseCommonOption (String defaultOptionPrefix , Map <String , String > polyglotOptions ,
181
+ boolean experimentalOptions , String arg ) {
182
+ if (arg .startsWith ("--help" )) {
183
+ helpOptionUsed = true ;
184
+ }
185
+
186
+ return super .parseCommonOption (defaultOptionPrefix , polyglotOptions , experimentalOptions , arg );
187
+ }
188
+
189
+ @ Override
190
+ protected boolean runLauncherAction () {
191
+ String pager ;
192
+ if (helpOptionUsed && System .console () != null && !(pager = getPagerFromEnv ()).isEmpty ()) {
193
+ try {
194
+ Process process = new ProcessBuilder (pager .split (" " ))
195
+ .redirectOutput (Redirect .INHERIT ) // set the output of the pager to the terminal and not a pipe
196
+ .redirectError (Redirect .INHERIT ) // set the error of the pager to the terminal and not a pipe
197
+ .start ();
198
+ PrintStream out = new PrintStream (process .getOutputStream ());
199
+
200
+ setOutput (out );
201
+ boolean code = super .runLauncherAction ();
202
+
203
+ out .flush ();
204
+ out .close ();
205
+ process .waitFor ();
206
+
207
+ return code ;
208
+ } catch (IOException | InterruptedException e ) {
209
+ throw abort (e );
210
+ }
211
+ } else {
212
+ return super .runLauncherAction ();
213
+ }
214
+ }
215
+
176
216
private int runRubyMain (Context .Builder contextBuilder , CommandLineOptions config ) {
177
217
if (config .executionAction == ExecutionAction .UNSET ) {
178
218
switch (config .defaultExecutionAction ) {
@@ -184,7 +224,7 @@ private int runRubyMain(Context.Builder contextBuilder, CommandLineOptions confi
184
224
case IRB :
185
225
config .executionAction = ExecutionAction .PATH ;
186
226
if (System .console () != null ) {
187
- System . err .println (
227
+ getError () .println (
188
228
"[ruby] WARNING: truffleruby starts IRB when stdin is a TTY instead of reading from stdin, use '-' to read from stdin" );
189
229
config .executionAction = ExecutionAction .PATH ;
190
230
config .toExecute = "irb" ;
@@ -203,7 +243,7 @@ private int runRubyMain(Context.Builder contextBuilder, CommandLineOptions confi
203
243
// Apply options to run gem/bundle more efficiently
204
244
contextBuilder .option ("engine.Mode" , "latency" );
205
245
if (Boolean .getBoolean ("truffleruby.launcher.log" )) {
206
- System . err .println ("[ruby] CONFIG: detected gem or bundle command, using --engine.Mode=latency" );
246
+ getError () .println ("[ruby] CONFIG: detected gem or bundle command, using --engine.Mode=latency" );
207
247
}
208
248
}
209
249
@@ -241,7 +281,7 @@ private int runContext(Context.Builder builder, CommandLineOptions config) {
241
281
if (file .isString ()) {
242
282
config .toExecute = file .asString ();
243
283
} else {
244
- System . err
284
+ getError ()
245
285
.println ("truffleruby: No such file or directory -- " + config .toExecute + " (LoadError)" );
246
286
return 1 ;
247
287
}
@@ -270,9 +310,9 @@ private int runContext(Context.Builder builder, CommandLineOptions config) {
270
310
return exitCode ;
271
311
} catch (PolyglotException e ) {
272
312
if (e .isHostException ()) { // GR-22071
273
- System . err .println ("truffleruby: a host exception reached the top level:" );
313
+ getError () .println ("truffleruby: a host exception reached the top level:" );
274
314
} else {
275
- System . err .println (
315
+ getError () .println (
276
316
"truffleruby: an exception escaped out of the interpreter - this is an implementation bug" );
277
317
}
278
318
e .printStackTrace ();
@@ -299,24 +339,36 @@ private static List<String> getPathListFromEnvVariable(String name) {
299
339
return Collections .emptyList ();
300
340
}
301
341
342
+ private static String getPagerFromEnv () {
343
+ String pager = System .getenv ("RUBY_PAGER" );
344
+ if (pager != null ) {
345
+ return pager .strip ();
346
+ }
347
+
348
+ pager = System .getenv ("PAGER" );
349
+ if (pager != null ) {
350
+ return pager .strip ();
351
+ }
352
+
353
+ return "" ;
354
+ }
355
+
302
356
private void printPreRunInformation (CommandLineOptions config ) {
303
357
if (config .showVersion ) {
304
- System . out .println (TruffleRuby .getVersionString (getImplementationNameFromEngine ()));
358
+ getOutput () .println (TruffleRuby .getVersionString (getImplementationNameFromEngine ()));
305
359
}
306
360
307
361
if (config .showCopyright ) {
308
- System . out .println (TruffleRuby .RUBY_COPYRIGHT );
362
+ getOutput () .println (TruffleRuby .RUBY_COPYRIGHT );
309
363
}
310
364
311
365
switch (config .showHelp ) {
312
366
case NONE :
313
367
break ;
314
368
case SHORT :
315
- printShortHelp (System .out );
316
- break ;
317
- case LONG :
318
- printHelp (System .out );
369
+ printShortHelp (getOutput ());
319
370
break ;
371
+ // --help is handled by org.graalvm.launcher.Launcher#printDefaultHelp
320
372
}
321
373
}
322
374
0 commit comments