Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Viash 0.8.8 (xxxx-xx-xx): xxxx

## BUG FIXES

* `NextflowRunner`: Automatically convert integers to doubles when argument type is `double` (PR #823).

# Viash 0.8.7 (2025-04-01): Backport support upcoming version of Nextflow

The upcoming release of Nextflow introduces a new class for loading scripts and renamed the old class.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,64 +66,56 @@ def _checkArgumentType(String stage, Map par, Object value, String errorIdentifi
foundClass = "List[${e.foundClass}]"
}
} else if (par.type == "string") {
// cast to string if need be
// cast to string if need be. only cast if the value is a GString
if (value instanceof GString) {
value = value.toString()
value = value as String
}
expectedClass = value instanceof String ? null : "String"
} else if (par.type == "integer") {
// cast to integer if need be
if (value instanceof String) {
if (value !instanceof Integer) {
try {
value = value.toInteger()
value = value as Integer
} catch (NumberFormatException e) {
// do nothing
expectedClass = "Integer"
}
}
if (value instanceof java.math.BigInteger) {
value = value.intValue()
}
expectedClass = value instanceof Integer ? null : "Integer"
} else if (par.type == "long") {
// cast to long if need be
if (value instanceof String) {
if (value !instanceof Long) {
try {
value = value.toLong()
value = value as Long
} catch (NumberFormatException e) {
// do nothing
expectedClass = "Long"
}
}
if (value instanceof Integer) {
value = value.toLong()
}
expectedClass = value instanceof Long ? null : "Long"
} else if (par.type == "double") {
// cast to double if need be
if (value instanceof String) {
if (value !instanceof Double) {
try {
value = value.toDouble()
value = value as Double
} catch (NumberFormatException e) {
// do nothing
expectedClass = "Double"
}
}
if (value instanceof java.math.BigDecimal) {
value = value.doubleValue()
}
if (value instanceof Float) {
value = value.toDouble()
} else if (par.type == "float") {
// cast to float if need be
if (value !instanceof Float) {
try {
value = value as Float
} catch (NumberFormatException e) {
expectedClass = "Float"
}
}
expectedClass = value instanceof Double ? null : "Double"
} else if (par.type == "boolean" | par.type == "boolean_true" | par.type == "boolean_false") {
// cast to boolean if need be
if (value instanceof String) {
def valueLower = value.toLowerCase()
if (valueLower == "true") {
value = true
} else if (valueLower == "false") {
value = false
if (value !instanceof Boolean) {
try {
value = value as Boolean
} catch (Exception e) {
expectedClass = "Boolean"
}
}
expectedClass = value instanceof Boolean ? null : "Boolean"
} else if (par.type == "file" && (par.direction == "input" || stage == "output")) {
// cast to path if need be
if (value instanceof String) {
Expand All @@ -135,10 +127,13 @@ def _checkArgumentType(String stage, Map par, Object value, String errorIdentifi
expectedClass = value instanceof Path ? null : "Path"
} else if (par.type == "file" && stage == "input" && par.direction == "output") {
// cast to string if need be
if (value instanceof GString) {
value = value.toString()
if (value !instanceof String) {
try {
value = value as String
} catch (Exception e) {
expectedClass = "String"
}
}
expectedClass = value instanceof String ? null : "String"
} else {
// didn't find a match for par.type
expectedClass = par.type
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
functionality:
name: integer_as_double
arguments:
- name: "--input"
type: file
required: true
example: input.txt
- name: "--output"
type: file
required: true
direction: output
example: output.txt
- name: "--double"
type: double
required: true
direction: input
example: 10.5
resources:
- type: bash_script
path: script.sh
platforms:
- type: native
- type: docker
image: nextflow/bash:latest
- type: nextflow
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

## VIASH START
par_input='resources/lines3.txt'
par_double='10.5'
par_output='output.txt'
## VIASH END

echo "Copying $par_input to $par_output"
cp "$par_input" "$par_output"

echo "Adding $par_double to $par_output"
echo "Double: $par_double" >> "$par_output"

exit 0
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,46 @@ class Vdsl3StandaloneTest extends AnyFunSuite with BeforeAndAfterAll {
}
}


test("Whether integers can be converted to doubles", NextflowTest) {
// create params.yaml file
val paramsPath = temporaryFolder.resolve("params.yaml")
val paramsStr = """id: foo
|input: resources/lines3.txt
|double: 10
|publish_dir: integerAsDouble
|""".stripMargin
Files.write(paramsPath, paramsStr.getBytes(StandardCharsets.UTF_8))

val (exitCode, stdOut, stdErr) = NextflowTestHelper.run(
mainScript = "target/nextflow/integer_as_double/main.nf",
args = Nil,
paramsFile = Some(paramsPath.toString()),
cwd = tempFolFile
)

assert(exitCode == 0, s"\nexit code was $exitCode\nStd output:\n$stdOut\nStd error:\n$stdErr")

val expectedFiles =
Map(
"state" -> "state.yaml",
"output" -> "output.txt",
).map{ case (id, suffix) =>
val path = temporaryFolder.resolve("integerAsDouble/foo.integer_as_double." + suffix)
(id, path)
}

// check if files exist

val src = Source.fromFile(tempFolStr + "/integerAsDouble/foo.integer_as_double.output.txt")
try {
val moduleOut = src.getLines().mkString(",")
assert(moduleOut.equals("one,two,three,Double: 10.0"), s"Expected output 'one,two,three,10.0' but got '$moduleOut'")
} finally {
src.close()
}
}

override def afterAll(): Unit = {
IO.deleteRecursively(temporaryFolder)
}
Expand Down
Loading