diff --git a/docs/cli.md b/docs/cli.md index 988a1d5586..9728ce8682 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -1502,7 +1502,8 @@ nextflow run --foo Hello Then, the parameter can be accessed in the pipeline script using the `params.foo` identifier. :::{note} -When the parameter name is formatted using `camelCase`, a second parameter is created with the same value using `kebab-case`, and vice versa. +Parameter names formatted using `camelCase`, `snake_case`, or `kebab-case` are treated as the same. For example +`--paramName`, `--param_name`, and `--param-name` can be used interchangeably. ::: :::{warning} diff --git a/modules/nextflow/src/main/groovy/nextflow/script/ScriptBinding.groovy b/modules/nextflow/src/main/groovy/nextflow/script/ScriptBinding.groovy index a95bbd5328..00e7c7b38b 100644 --- a/modules/nextflow/src/main/groovy/nextflow/script/ScriptBinding.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/script/ScriptBinding.groovy @@ -240,23 +240,23 @@ class ScriptBinding extends WorkflowBinding { private ParamsMap allowNames(Set names) { for( String name : names ) { - final name2 = name.contains('-') ? hyphenToCamelCase(name) : camelCaseToHyphen(name) - readOnlyNames.remove(name) - readOnlyNames.remove(name2) + final normalizedName = normalizeToCamelCase(name) + readOnlyNames.remove(normalizedName) } return this } @Override Object get(Object key) { - if( !target.containsKey(key) ) { + String normalizedKey = normalizeToCamelCase((String) key) + if( !target.containsKey(normalizedKey) ) { final msg = "Access to undefined parameter `$key` -- Initialise it to a default value eg. `params.$key = some_value`" if( NF.isStrictMode() ) throw new AbortOperationException(msg) log.warn1(msg, firstOnly: true) return null } - return target.get(key) + return target.get(normalizedKey) } /** @@ -285,17 +285,15 @@ class ScriptBinding extends WorkflowBinding { // keep track of the real name realNames << name - // normalize the name - def name2 = name.contains('-') ? hyphenToCamelCase(name) : camelCaseToHyphen(name) + // internally normalize the name to camelCase + name = normalizeToCamelCase(name) - final readOnly = name in readOnlyNames || name2 in readOnlyNames + final readOnly = name in readOnlyNames def result = null if( !readOnly ) { readOnlyNames << name - readOnlyNames << name2 result = target.put(name, value) - target.put(name2, value) } return result @@ -362,54 +360,18 @@ class ScriptBinding extends WorkflowBinding { * @return */ @PackageScope - static String hyphenToCamelCase( String str ) { + static String normalizeToCamelCase( String str ) { if( !str ) { return str } def result = new StringBuilder() - str.split('-').eachWithIndex{ String entry, int i -> + str.split('[-_]').eachWithIndex{ String entry, int i -> result << (i>0 ? StringUtils.capitalize(entry) : entry ) } return result.toString() } - /** - * Converts a camel-case string to a string where words are separated by hyphen character - * - * @param str The string to be converted - * @return A string where camel-case words are converted to words separated by hyphen character - */ - @PackageScope - static String camelCaseToHyphen( String str ) { - - def lower = 'a'..'z' - def upper = 'A'..'Z' - - def result = new StringBuilder() - if( !str ) { - return str - } - - result << str[0] - for( int i=1; i