From 2b117c46e42eb4ec1b9a1a53930ca12e77954a6d Mon Sep 17 00:00:00 2001 From: Cedric Zhuang Date: Fri, 8 Sep 2023 15:29:11 +0800 Subject: [PATCH] Handle quoted params in extra. Properly handle the quoted parameters in `extra` or `commonExtra`. --- .../nextflow/FloatGridExecutor.groovy | 27 ++++++- .../nextflow/FloatGridExecutorTest.groovy | 71 ++++++++++++------- 2 files changed, 73 insertions(+), 25 deletions(-) diff --git a/plugins/nf-float/src/main/com/memverge/nextflow/FloatGridExecutor.groovy b/plugins/nf-float/src/main/com/memverge/nextflow/FloatGridExecutor.groovy index 3a3001b..6eb6c55 100644 --- a/plugins/nf-float/src/main/com/memverge/nextflow/FloatGridExecutor.groovy +++ b/plugins/nf-float/src/main/com/memverge/nextflow/FloatGridExecutor.groovy @@ -28,6 +28,8 @@ import nextflow.util.ServiceName import java.nio.file.Path import java.nio.file.StandardCopyOption +import java.util.regex.Matcher +import java.util.regex.Pattern import java.util.stream.Collectors /** @@ -142,10 +144,33 @@ class FloatGridExecutor extends AbstractGridExecutor { if (common) { extra = common.trim() + " " + extra.trim() } - def ret = extra.split('\\s+') + def ret = splitWithQuotes(extra) return ret.findAll { it.length() > 0 } } + private static List splitWithQuotes(String input) { + List ret = new ArrayList() + int start = 0 + boolean inQuotes = false + for (int i = 0; i < input.size(); i++) { + if (input[i] == '"') { + inQuotes = !inQuotes + } + if ((input[i] == '\t' || input[i] == ' ') && !inQuotes) { + String token = input.substring(start, i).trim() + if (token.size() > 0) { + ret.add(token) + } + start = i + } + } + String token = input.substring(start).trim() + if (token.size() > 0) { + ret.add(token) + } + return ret + } + private List getCmdPrefixForJob(String floatJobID) { final oc = floatJobs.getOc(floatJobID) return floatConf.getCliPrefix(oc) diff --git a/plugins/nf-float/src/test/com/memverge/nextflow/FloatGridExecutorTest.groovy b/plugins/nf-float/src/test/com/memverge/nextflow/FloatGridExecutorTest.groovy index 04be163..3eea09d 100644 --- a/plugins/nf-float/src/test/com/memverge/nextflow/FloatGridExecutorTest.groovy +++ b/plugins/nf-float/src/test/com/memverge/nextflow/FloatGridExecutorTest.groovy @@ -150,6 +150,29 @@ class FloatGridExecutorTest extends FloatBaseTest { cmd.join(" ") == expected.join(" ") } + def "quoted arguments in extra"() { + given: + final exec = newTestExecutor( + [float: [address : addr, + username : user, + password : pass, + nfs : nfs, + commonExtra: '--dataVolume [opts="-o allow_other"]s3://1.2.3.4:/a:/a --rootVolSize 10']] + ) + final task = newTask(exec) + + when: + final cmd = exec.getSubmitCommandLine(task, Paths.get(script)) + final expected = submitCmd() + [ + '--dataVolume', + '[opts="-o allow_other"]s3://1.2.3.4:/a:/a', + '--rootVolSize', + '10'] + + then: + cmd == expected + } + def "add specific extras"() { given: final exec = newTestExecutor() @@ -317,10 +340,10 @@ class FloatGridExecutorTest extends FloatBaseTest { def "use timeout factor"() { given: final exec = newTestExecutor( - [float: [address : addr, - username : user, - password : pass, - nfs : nfs, + [float: [address : addr, + username : user, + password : pass, + nfs : nfs, timeFactor: 1.1]]) final task = newTask(exec, new TaskConfig( container: image, @@ -337,10 +360,10 @@ class FloatGridExecutorTest extends FloatBaseTest { def "use on-demand for retry"() { given: final exec = newTestExecutor( - [float: [address : addr, - username : user, - password : pass, - nfs : nfs]]) + [float: [address : addr, + username: user, + password: pass, + nfs : nfs]]) final task = newTask(exec, new TaskConfig( container: image, time: '1h', @@ -357,10 +380,10 @@ class FloatGridExecutorTest extends FloatBaseTest { def "use cpu factor"() { given: final exec = newTestExecutor( - [float: [address : addr, - username : user, - password : pass, - nfs : nfs, + [float: [address : addr, + username : user, + password : pass, + nfs : nfs, cpuFactor: 1.5]]) final task = newTask(exec, new TaskConfig( container: image, @@ -377,10 +400,10 @@ class FloatGridExecutorTest extends FloatBaseTest { def "use invalid cpu"() { given: final exec = newTestExecutor( - [float: [address : addr, - username : user, - password : pass, - nfs : nfs, + [float: [address : addr, + username : user, + password : pass, + nfs : nfs, cpuFactor: 0.2]]) final task = newTask(exec, new TaskConfig( container: image, @@ -397,10 +420,10 @@ class FloatGridExecutorTest extends FloatBaseTest { def "use memory factor"() { given: final exec = newTestExecutor( - [float: [address : addr, - username : user, - password : pass, - nfs : nfs, + [float: [address : addr, + username : user, + password : pass, + nfs : nfs, memoryFactor: 0.5]]) final task = newTask(exec, new TaskConfig( container: image, @@ -417,10 +440,10 @@ class FloatGridExecutorTest extends FloatBaseTest { def "use invalid memory"() { given: final exec = newTestExecutor( - [float: [address : addr, - username : user, - password : pass, - nfs : nfs, + [float: [address : addr, + username : user, + password : pass, + nfs : nfs, memoryFactor: 0.5]]) final task = newTask(exec, new TaskConfig( container: image,