Skip to content

Commit f507941

Browse files
committed
feat(groovysh): entry point with binding injection
1 parent ddcd5dc commit f507941

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,14 @@ class Main {
290290
}
291291
}
292292

293-
static void main(String[] args) {
293+
/**
294+
* Programmatic entry point for embedding groovysh.
295+
*
296+
* @param args CLI-like arguments (same as {@link #main(String[])}).
297+
* @param initialBindings binding variables for the GroovyEngine
298+
* @return process exit code (0 for success)
299+
*/
300+
static int start(String[] args = new String[0], Map<String, ?> initialBindings = Collections.emptyMap()) {
294301
def cli = new CliBuilderInternal(usage: 'groovysh [options] [...]', stopAtNonOption: false,
295302
header: messages['cli.option.header'])
296303
cli.with {
@@ -311,18 +318,18 @@ class Main {
311318
OptionAccessor options = cli.parse(args)
312319

313320
if (options == null) {
314-
// CliBuilder prints error, but does not exit
315-
System.exit(22) // Invalid Args
321+
// CliBuilder prints error
322+
return 22 // Invalid Args
316323
}
317324

318325
if (options.h) {
319326
cli.usage()
320-
System.exit(0)
327+
return 0
321328
}
322329

323330
if (options.V) {
324331
println render(messages.format('cli.info.version', GroovySystem.version))
325-
System.exit(0)
332+
return 0
326333
}
327334
String evaluate = options.e ?: null
328335

@@ -359,6 +366,15 @@ class Main {
359366

360367
// ScriptEngine and command registries
361368
GroovyEngine scriptEngine = new GroovyEngine()
369+
370+
if (initialBindings) {
371+
initialBindings.each { k, v ->
372+
if (k != null) {
373+
scriptEngine.put(k, v)
374+
}
375+
}
376+
}
377+
362378
scriptEngine.put('ROOT', rootURL.toString())
363379
if (!scriptEngine.hasVariable('CONSOLE_OPTIONS')) {
364380
scriptEngine.put('CONSOLE_OPTIONS', [:])
@@ -506,6 +522,12 @@ class Main {
506522
}
507523
} catch (Throwable t) {
508524
t.printStackTrace()
525+
return 1
509526
}
527+
return 0
528+
}
529+
530+
static void main(String[] args) {
531+
System.exit(start(args))
510532
}
511533
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.groovy.groovysh
20+
21+
import groovy.test.GroovyTestCase
22+
23+
/**
24+
* Verifies the programmatic API surface exists and is callable.
25+
*/
26+
class ProgrammaticStartTest extends GroovyTestCase {
27+
28+
void testStartMethodIsPresentAndCallable() {
29+
// We just verify it accepts parameters and doesn't throw on trivial help/version paths.
30+
int rc = Main.start(['--help'] as String[], [foo: 1])
31+
assert rc == 0
32+
}
33+
}

0 commit comments

Comments
 (0)