Skip to content

Commit 13b9af5

Browse files
committed
Allow params to be loaded from stdin as JSON
Signed-off-by: Ben Sherman <[email protected]>
1 parent 54332fe commit 13b9af5

File tree

4 files changed

+205
-191
lines changed

4 files changed

+205
-191
lines changed

modules/nextflow/src/main/groovy/nextflow/cli/CmdKubeRun.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class CmdKubeRun extends CmdRun {
8888
@Override
8989
void run() {
9090
final scriptArgs = (args?.size()>1 ? args[1..-1] : []) as List<String>
91-
final pipeline = stdin ? '-' : ( args ? args[0] : null )
91+
final pipeline = args ? args[0] : null
9292
if( !pipeline )
9393
throw new AbortOperationException("No project name was specified")
9494
if( hasAnsiLogFlag() )

modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy

Lines changed: 2 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ class CmdRun extends CmdBase implements HubOptions {
156156
@Parameter(names=['-latest'], description = 'Pull latest changes before run')
157157
boolean latest
158158

159-
@Parameter(names='-stdin', hidden = true)
160-
boolean stdin
161-
162159
@Parameter(names = ['-ansi'], hidden = true, arity = 0)
163160
void setAnsi(boolean value) {
164161
launcher.options.ansiLog = value
@@ -289,18 +286,10 @@ class CmdRun extends CmdBase implements HubOptions {
289286
@Override
290287
String getName() { NAME }
291288

292-
String getParamsFile() {
293-
return paramsFile ?: sysEnv.get('NXF_PARAMS_FILE')
294-
}
295-
296-
boolean hasParams() {
297-
return params || getParamsFile()
298-
}
299-
300289
@Override
301290
void run() {
302291
final scriptArgs = (args?.size()>1 ? args[1..-1] : []) as List<String>
303-
final pipeline = stdin ? '-' : ( args ? args[0] : null )
292+
final pipeline = args ? args[0] : null
304293
if( !pipeline )
305294
throw new AbortOperationException("No project name was specified")
306295

@@ -598,20 +587,6 @@ class CmdRun extends CmdBase implements HubOptions {
598587
protected ScriptFile getScriptFile0(String pipelineName) {
599588
assert pipelineName
600589

601-
/*
602-
* read from the stdin
603-
*/
604-
if( pipelineName == '-' ) {
605-
def file = tryReadFromStdin()
606-
if( !file )
607-
throw new AbortOperationException("Cannot access `stdin` stream")
608-
609-
if( revision )
610-
throw new AbortOperationException("Revision option cannot be used when running a script from stdin")
611-
612-
return new ScriptFile(file)
613-
}
614-
615590
/*
616591
* look for a file with the specified pipeline name
617592
*/
@@ -661,171 +636,9 @@ class CmdRun extends CmdBase implements HubOptions {
661636

662637
}
663638

664-
static protected File tryReadFromStdin() {
665-
if( !System.in.available() )
666-
return null
667-
668-
getScriptFromStream(System.in)
669-
}
670-
671-
static protected File getScriptFromStream( InputStream input, String name = 'nextflow' ) {
672-
input != null
673-
File result = File.createTempFile(name, null)
674-
result.deleteOnExit()
675-
input.withReader { Reader reader -> result << reader }
676-
return result
677-
}
678-
679639
@Memoized // <-- avoid parse multiple times the same file and params
680640
Map parsedParams(Map configVars) {
681-
682-
final result = [:]
683-
684-
// apply params file
685-
final file = getParamsFile()
686-
if( file ) {
687-
def path = validateParamsFile(file)
688-
def type = path.extension.toLowerCase() ?: null
689-
if( type == 'json' )
690-
readJsonFile(path, configVars, result)
691-
else if( type == 'yml' || type == 'yaml' )
692-
readYamlFile(path, configVars, result)
693-
}
694-
695-
// apply CLI params
696-
if( !params )
697-
return result
698-
699-
for( Map.Entry<String,String> entry : params ) {
700-
addParam( result, entry.key, entry.value )
701-
}
702-
return result
703-
}
704-
705-
706-
static final private Pattern DOT_ESCAPED = ~/\\\./
707-
static final private Pattern DOT_NOT_ESCAPED = ~/(?<!\\)\./
708-
709-
static protected void addParam(Map params, String key, String value, List path=[], String fullKey=null) {
710-
if( !fullKey )
711-
fullKey = key
712-
final m = DOT_NOT_ESCAPED.matcher(key)
713-
if( m.find() ) {
714-
final p = m.start()
715-
final root = key.substring(0, p)
716-
if( !root ) throw new AbortOperationException("Invalid parameter name: $fullKey")
717-
path.add(root)
718-
def nested = params.get(root)
719-
if( nested == null ) {
720-
nested = new LinkedHashMap<>()
721-
params.put(root, nested)
722-
}
723-
else if( nested !instanceof Map ) {
724-
log.warn "Command line parameter --${path.join('.')} is overwritten by --${fullKey}"
725-
nested = new LinkedHashMap<>()
726-
params.put(root, nested)
727-
}
728-
addParam((Map)nested, key.substring(p+1), value, path, fullKey)
729-
}
730-
else {
731-
addParam0(params, key.replaceAll(DOT_ESCAPED,'.'), parseParamValue(value))
732-
}
733-
}
734-
735-
static protected void addParam0(Map params, String key, Object value) {
736-
if( key.contains('-') )
737-
key = kebabToCamelCase(key)
738-
params.put(key, value)
739-
}
740-
741-
static protected String kebabToCamelCase(String str) {
742-
final result = new StringBuilder()
743-
str.split('-').eachWithIndex { String entry, int i ->
744-
result << (i>0 ? StringUtils.capitalize(entry) : entry )
745-
}
746-
return result.toString()
747-
}
748-
749-
static protected parseParamValue(String str) {
750-
if ( SysEnv.get('NXF_DISABLE_PARAMS_TYPE_DETECTION') || NF.isSyntaxParserV2() )
751-
return str
752-
753-
if ( str == null ) return null
754-
755-
if ( str.toLowerCase() == 'true') return Boolean.TRUE
756-
if ( str.toLowerCase() == 'false' ) return Boolean.FALSE
757-
758-
if ( str==~/-?\d+(\.\d+)?/ && str.isInteger() ) return str.toInteger()
759-
if ( str==~/-?\d+(\.\d+)?/ && str.isLong() ) return str.toLong()
760-
if ( str==~/-?\d+(\.\d+)?/ && str.isDouble() ) return str.toDouble()
761-
762-
return str
763-
}
764-
765-
private Path validateParamsFile(String file) {
766-
767-
def result = FileHelper.asPath(file)
768-
def ext = result.getExtension()
769-
if( !VALID_PARAMS_FILE.contains(ext) )
770-
throw new AbortOperationException("Not a valid params file extension: $file -- It must be one of the following: ${VALID_PARAMS_FILE.join(',')}")
771-
772-
return result
773-
}
774-
775-
static private Pattern PARAMS_VAR = ~/(?m)\$\{(\p{javaJavaIdentifierStart}\p{javaJavaIdentifierPart}*)}/
776-
777-
protected String replaceVars0(String content, Map binding) {
778-
content.replaceAll(PARAMS_VAR) { List<String> matcher ->
779-
// - the regex matcher is represented as list
780-
// - the first element is the matching string ie. `${something}`
781-
// - the second element is the group content ie. `something`
782-
// - make sure the regex contains at least a group otherwise the closure
783-
// parameter is a string instead of a list of the call fail
784-
final placeholder = matcher.get(0)
785-
final key = matcher.get(1)
786-
787-
if( !binding.containsKey(key) ) {
788-
final msg = "Missing params file variable: $placeholder"
789-
if(NF.strictMode)
790-
throw new AbortOperationException(msg)
791-
log.warn msg
792-
return placeholder
793-
}
794-
795-
return binding.get(key)
796-
}
797-
}
798-
799-
private void readJsonFile(Path file, Map configVars, Map result) {
800-
try {
801-
def text = configVars ? replaceVars0(file.text, configVars) : file.text
802-
def json = (Map<String,Object>) new JsonSlurper().parseText(text)
803-
json.forEach((name, value) -> {
804-
addParam0(result, name, value)
805-
})
806-
}
807-
catch (NoSuchFileException | FileNotFoundException e) {
808-
throw new AbortOperationException("Specified params file does not exist: ${file.toUriString()}")
809-
}
810-
catch( Exception e ) {
811-
throw new AbortOperationException("Cannot parse params file: ${file.toUriString()} - Cause: ${e.message}", e)
812-
}
813-
}
814-
815-
private void readYamlFile(Path file, Map configVars, Map result) {
816-
try {
817-
def text = configVars ? replaceVars0(file.text, configVars) : file.text
818-
def yaml = (Map<String,Object>) new Yaml().load(text)
819-
yaml.forEach((name, value) -> {
820-
addParam0(result, name, value)
821-
})
822-
}
823-
catch (NoSuchFileException | FileNotFoundException e) {
824-
throw new AbortOperationException("Specified params file does not exist: ${file.toUriString()}")
825-
}
826-
catch( Exception e ) {
827-
throw new AbortOperationException("Cannot parse params file: ${file.toUriString()}", e)
828-
}
641+
return new ParamsCollector(params, paramsFile).apply(configVars)
829642
}
830643

831644
}

0 commit comments

Comments
 (0)