This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new cfe5dcad7c GROOVY-11791: Support unquoted URLs in groovysh
cfe5dcad7c is described below
commit cfe5dcad7c422290d5ab93142ecbc17b115fb292
Author: Paul King <[email protected]>
AuthorDate: Thu Oct 23 12:10:46 2025 +1000
GROOVY-11791: Support unquoted URLs in groovysh
---
.../groovy/org/apache/groovy/groovysh/Main.groovy | 3 ++-
.../groovy/groovysh/jline/GroovyCommands.groovy | 25 +++++++++++++---------
.../apache/groovy/groovysh/jline/GroovyEngine.java | 3 ++-
.../src/main/resources/nanorc/groovy.nanorc | 5 +++--
4 files changed, 22 insertions(+), 14 deletions(-)
diff --git
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
index cca9464657..1aa8308cc2 100644
---
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
+++
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy
@@ -471,8 +471,9 @@ class Main {
line = line.readLines().collect{ s ->
// remove Groovy continuation character for repl not
Groovy's sake
s.endsWith(' \\') ? s[0..-3] : s
- }.join('\n')
+ }.join('\n').replaceAll($/(/[a-z]+\s+)(https?://\S+)/$,
'$1"$2"') // quote URLs after commands
if (line.startsWith(':')) {
+ // some simple legacy support for ':' commands
def maybeCmd = line.split()[0].replaceFirst(':', '/')
if (systemRegistry.hasCommand(maybeCmd) ||
systemRegistry.isCommandAlias(maybeCmd)) {
line = line.replaceFirst(':', '/')
diff --git
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyCommands.groovy
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyCommands.groovy
index 75929369e0..d5e6693c70 100644
---
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyCommands.groovy
+++
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyCommands.groovy
@@ -376,7 +376,9 @@ class GroovyCommands extends JlineCommandRegistry
implements CommandRegistry {
try {
path = workDir.get().resolve(arg)
} catch(Exception ignore) { }
+ Reader source = null
if (path && Files.exists(path)) {
+ source = Files.newBufferedReader(path, encoding)
if (!format) {
def ext = path.extension
if (ext.equalsIgnoreCase('json')) {
@@ -397,23 +399,26 @@ class GroovyCommands extends JlineCommandRegistry
implements CommandRegistry {
format = 'TEXT'
}
}
+ }
+ if (!source && (arg.startsWith('http://') ||
arg.startsWith('https://'))) {
+ URL url = new URL(arg)
+ source = new InputStreamReader(url.openStream(), encoding)
+ }
+ if (source) {
if (format == 'TEXT') {
- out = Files.readAllLines(path, encoding)
+ out = source.readLines()
} else if (format in engine.deserializationFormats) {
- byte[] encoded = Files.readAllBytes(path)
- out = engine.deserialize(new String(encoded, encoding),
format)
+ out = engine.deserialize(source.text, format)
} else if (format in slurpers.keySet()) {
def parser = getParser(format, slurpers[format])
- out = parser.parse(path)
+ out = parser.parse(source)
} else if (format == 'CSV') {
def parser = getCsvParser(format)
- out =
parser.parse(path.newReader(encoding.displayName())).toList()*.toMap()
+ out = parser.parse(source).toList()*.toMap()
} else if (format == 'PROPERTIES') {
- out = path.withInputStream{ is ->
- new Properties().tap {load(is) }
- }
+ out = new Properties().tap {load(source) }
} else {
- out = engine.deserialize(Files.readString(path, encoding),
'NONE')
+ out = engine.deserialize(source.text, 'AUTO')
}
} else {
if (format == 'TEXT') {
@@ -427,7 +432,7 @@ class GroovyCommands extends JlineCommandRegistry
implements CommandRegistry {
def parser = getCsvParser(format)
out = parser.parse(new StringReader(arg)).toList()*.toMap()
} else {
- out = engine.deserialize(arg, 'NONE')
+ out = engine.deserialize(arg, 'AUTO')
}
}
} catch (Exception ignore) {
diff --git
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyEngine.java
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyEngine.java
index 3117c22744..aecfa63e9d 100644
---
a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyEngine.java
+++
b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/jline/GroovyEngine.java
@@ -90,7 +90,8 @@ public class GroovyEngine implements ScriptEngine {
public enum Format {
JSON,
GROOVY,
- NONE
+ NONE,
+ AUTO
}
public static final String CANONICAL_NAMES = "canonicalNames";
diff --git
a/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
b/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
index c4d570877e..557f54cb3f 100644
--- a/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
+++ b/subprojects/groovy-groovysh/src/main/resources/nanorc/groovy.nanorc
@@ -19,7 +19,8 @@ TYPE:
"\<(boolean|byte|char|def|double|float|int|it|long|new|short|this|t
KEYWORD:
"\<(case|catch|default|do|else|finally|for|if|return|switch|throw|try|while)\>"
KEYWORD:
"\<(abstract|class|extends|final|implements|import|instanceof|interface|native|non-sealed|package)\>"
KEYWORD:
"\<(permits|private|protected|public|record|sealed|static|strictfp|super|synchronized|throws|trait|volatile)\>"
-PACKAGE: "(([a-z0-9]{2,}[.]{1}){2,10}([a-z0-9]{2,}){0,1})"
+PATH: "\<https?://\S*\>"
+PACKAGE: "(?<!://\w{0,99})(([a-z0-9]{2,}[.]{1}){2,10}([a-z0-9]{2,}){0,1})"
CLASS: "\<[A-Z]{0,2}([A-Z]{1}[a-z0-9]+){1,}\>"
# Annotation
@@ -37,7 +38,7 @@ OPERATOR: "[-+/*=<>?:!~%&|]"
~NUMBER: "\b-?(([1-9][0-9_]*)|0)\.[0-9_e]+[dfg]?\b"
"\b-?([1-9][0-9_]*)?[0-9][ilg]?\b" "\b0[0-7_]*[ilg]?\b"
"\b0x([1-9a-f][0-9a-f_]*)?[0-9a-f][lg]?\b" "\b0b([01][01_]*)?[01]\b"
#STRING: "['][^']*[^\\][']" "[']{3}.*[^\\][']{3}"
$BALANCED_DELIMITERS: """", ''', ', ""
-$LINE_COMMENT: "//"
+$LINE_COMMENT: "(?<!:)//"
$BLOCK_COMMENT: "/*, */"
REGEXP: "~/[^/]*/"