diff --git a/modules/nf-lang/src/main/java/nextflow/script/control/ScriptToGroovyHelper.java b/modules/nf-lang/src/main/java/nextflow/script/control/ScriptToGroovyHelper.java index e9f44c49e3..e1e545fa9a 100644 --- a/modules/nf-lang/src/main/java/nextflow/script/control/ScriptToGroovyHelper.java +++ b/modules/nf-lang/src/main/java/nextflow/script/control/ScriptToGroovyHelper.java @@ -180,8 +180,14 @@ public String getSourceText(Statement node) { builder.append( line.substring(0, k) ); } + // determine range of current line var begin = (i == first) ? colx - 1 : 0; var end = (i == last) ? colz - 1 : line.length(); + + // skip trailing newline (e.g. for block statements) + if( i == last && begin == end ) + continue; + builder.append( line.substring(begin, end) ).append('\n'); } return builder.toString(); diff --git a/modules/nf-lang/src/test/groovy/nextflow/script/control/ScriptToGroovyHelperTest.groovy b/modules/nf-lang/src/test/groovy/nextflow/script/control/ScriptToGroovyHelperTest.groovy new file mode 100644 index 0000000000..f96ccc905f --- /dev/null +++ b/modules/nf-lang/src/test/groovy/nextflow/script/control/ScriptToGroovyHelperTest.groovy @@ -0,0 +1,61 @@ +/* + * Copyright 2024-2025, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nextflow.script.control + +import spock.lang.Shared +import spock.lang.Specification +import test.TestUtils + +/** + * + * @author Ben Sherman + */ +class ScriptToGroovyHelperTest extends Specification { + + @Shared + ScriptParser scriptParser + + def setupSpec() { + scriptParser = new ScriptParser() + } + + def parse(String contents) { + scriptParser.compiler().getSources().clear() + def source = scriptParser.parse('main.nf', contents.stripIndent()) + assert !TestUtils.hasSyntaxErrors(source) + return source + } + + def 'should get source text of process body' () { + given: + def source = parse('''\ + process hello { + script: + """ + echo 'hello!' + """ + } + ''') + def sgh = new ScriptToGroovyHelper(source) + + when: + def process = source.getAST().getProcesses().first() + then: + sgh.getSourceText(process.exec) == ' """\n echo \'hello!\'\n """\n' + } + +} diff --git a/tests/checks/resume-syntax-parser-v1-v2.nf/.checks b/tests/checks/resume-syntax-parser-v1-v2.nf/.checks new file mode 100644 index 0000000000..178c51e370 --- /dev/null +++ b/tests/checks/resume-syntax-parser-v1-v2.nf/.checks @@ -0,0 +1,18 @@ +set -e + +# +# run normal mode +# +echo '' + +NXF_SYNTAX_PARSER=v1 $NXF_RUN | tee stdout + +[[ `< .nextflow.log grep -c 'Submitted process > hello'` == 1 ]] || false + +# +# RESUME mode +# +echo '' +NXF_SYNTAX_PARSER=v2 $NXF_RUN -resume | tee stdout + +[[ `< .nextflow.log grep -c 'Cached process > hello'` == 1 ]] || false diff --git a/tests/resume-syntax-parser-v1-v2.nf b/tests/resume-syntax-parser-v1-v2.nf new file mode 100644 index 0000000000..a31dcbdd5d --- /dev/null +++ b/tests/resume-syntax-parser-v1-v2.nf @@ -0,0 +1,33 @@ +#!/usr/bin/env nextflow +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +process hello { + input: + val greeting + + output: + stdout + + script: + """ + echo '${greeting}' + """ +} + +workflow { + hello( 'ciao' ).view() +}