Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WX-964 suffix() #7363

Merged
merged 7 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
15 changes: 15 additions & 0 deletions centaur/src/main/resources/standardTestCases/suffix.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: suffix
testFormat: workflowsuccess

files {
workflow: suffix/suffix.wdl
# https://github.com/broadinstitute/cromwell/issues/4590
options: suffix/suffix.options
}

metadata {
workflowName: suffix
status: Succeeded
"outputs.suffix.out": "logs.txt cmd.txt output.txt"
"calls.suffix.sfx.commandLine": "echo \"logs.txt cmd.txt output.txt\""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"read_from_cache": false
}
18 changes: 18 additions & 0 deletions centaur/src/main/resources/standardTestCases/suffix/suffix.wdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
task sfx {
Array[String] filenames = ["logs", "cmd", "output"]
Array[String] suffixed = suffix(".txt", filenames)
command {
echo "${sep=' ' suffixed}"
}
output {
String out = read_string(stdout())
}
runtime { docker: "ubuntu:latest" }
}

workflow suffix {
call sfx
output {
String out = sfx.out
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@
override def arg1: ExpressionElement = prefix
override def arg2: ExpressionElement = array
}

final case class Suffix(suffix: ExpressionElement, array: ExpressionElement) extends TwoParamFunctionCallElement {
override def arg1: ExpressionElement = suffix
override def arg2: ExpressionElement = array

Check warning on line 170 in wdl/model/draft3/src/main/scala/wdl/model/draft3/elements/ExpressionElement.scala

View check run for this annotation

Codecov / codecov/patch

wdl/model/draft3/src/main/scala/wdl/model/draft3/elements/ExpressionElement.scala#L169-L170

Added lines #L169 - L170 were not covered by tests
}
Comment on lines +168 to +171
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

draft-3 is not supposed to support suffix, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but all the other post-1.0 engine functions (ex. min, max, sep) have their case classes in here so I followed that convention. There aren't equivalent files in the other language version packages, though I can make that change if desirable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like those functions may have been put in there before a next language version was declared and/or before we had our current organization scheme. I do think that separating them out (both current and the new addition) would be optimal, though maybe that's a separate ticket.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed off-github and decided to leave this as-is.


final case class Min(arg1: ExpressionElement, arg2: ExpressionElement) extends TwoParamFunctionCallElement
final case class Max(arg1: ExpressionElement, arg2: ExpressionElement) extends TwoParamFunctionCallElement
final case class Sep(arg1: ExpressionElement, arg2: ExpressionElement) extends TwoParamFunctionCallElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import cats.syntax.validated._
import common.validation.ErrorOr.ErrorOr
import wdl.model.draft3.elements.ExpressionElement
import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep}
import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep, Suffix}
import wdl.transforms.base.ast2wdlom.AstNodeToExpressionElement

object AstToNewExpressionElements {
Expand All @@ -15,6 +15,7 @@
"min" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Min, "min"),
"max" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Max, "max"),
"sep" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Sep, "sep"),
"suffix" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Suffix, "suffix"),

Check warning on line 18 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/ast2wdlom/AstToNewExpressionElements.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/ast2wdlom/AstToNewExpressionElements.scala#L18

Added line #L18 was not covered by tests
"read_object" -> (_ =>
"read_object is no longer available in this WDL version. Consider using read_json instead".invalidNel
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@
expressionValueConsumer.expressionConsumedValueHooks(a.arg2)(expressionValueConsumer)
}

implicit val suffixExpressionValueConsumer: ExpressionValueConsumer[Suffix] = new ExpressionValueConsumer[Suffix] {

Check warning on line 61 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/consumed/BiscayneExpressionValueConsumers.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/consumed/BiscayneExpressionValueConsumers.scala#L61

Added line #L61 was not covered by tests
override def expressionConsumedValueHooks(a: Suffix)(implicit
expressionValueConsumer: ExpressionValueConsumer[ExpressionElement]
): Set[UnlinkedConsumedValueHook] =
expressionValueConsumer.expressionConsumedValueHooks(a.arg1)(expressionValueConsumer) ++
expressionValueConsumer.expressionConsumedValueHooks(a.arg2)(expressionValueConsumer)

Check warning on line 66 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/consumed/BiscayneExpressionValueConsumers.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/consumed/BiscayneExpressionValueConsumers.scala#L65-L66

Added lines #L65 - L66 were not covered by tests
}

implicit val noneLiteralExpressionValueConsumer: ExpressionValueConsumer[NoneLiteralElement.type] =
new ExpressionValueConsumer[NoneLiteralElement.type] {
override def expressionConsumedValueHooks(a: NoneLiteralElement.type)(implicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
case a: Length => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Flatten => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Prefix => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Suffix => a.expressionConsumedValueHooks(expressionValueConsumer)

Check warning on line 84 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/consumed/consumed.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/consumed/consumed.scala#L84

Added line #L84 was not covered by tests
case a: SelectFirst => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: SelectAll => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Defined => a.expressionConsumedValueHooks(expressionValueConsumer)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package wdl.transforms.biscayne.linking.expression.files

import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep}
import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep, Suffix}
import wdl.model.draft3.graph.expression.FileEvaluator
import wdl.transforms.base.linking.expression.files.EngineFunctionEvaluators
import wdl.transforms.base.linking.expression.files.EngineFunctionEvaluators.twoParameterFunctionPassthroughFileEvaluator
Expand All @@ -16,6 +16,7 @@
EngineFunctionEvaluators.singleParameterPassthroughFileEvaluator

implicit val sepFunctionEvaluator: FileEvaluator[Sep] = twoParameterFunctionPassthroughFileEvaluator[Sep]
implicit val suffixFunctionEvaluator: FileEvaluator[Suffix] = twoParameterFunctionPassthroughFileEvaluator[Suffix]

Check warning on line 19 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/files/BiscayneFileEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/files/BiscayneFileEvaluators.scala#L19

Added line #L19 was not covered by tests

implicit val minFunctionEvaluator: FileEvaluator[Min] = twoParameterFunctionPassthroughFileEvaluator[Min]
implicit val maxFunctionEvaluator: FileEvaluator[Max] = twoParameterFunctionPassthroughFileEvaluator[Max]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
case a: Flatten =>
a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)
case a: Prefix => a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)
case a: Suffix => a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)

Check warning on line 138 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/files/files.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/files/files.scala#L138

Added line #L138 was not covered by tests
case a: SelectFirst =>
a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)
case a: SelectAll =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package wdl.transforms.biscayne.linking.expression.types

import cats.implicits.catsSyntaxTuple2Semigroupal
import cats.syntax.validated._
import common.validation.ErrorOr._
import wdl.model.draft3.elements.ExpressionElement
Expand Down Expand Up @@ -100,4 +101,13 @@

}
}

implicit val suffixFunctionEvaluator: TypeEvaluator[Suffix] = new TypeEvaluator[Suffix] {

Check warning on line 105 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/BiscayneTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/BiscayneTypeEvaluators.scala#L105

Added line #L105 was not covered by tests
override def evaluateType(a: Suffix, linkedValues: Map[UnlinkedConsumedValueHook, GeneratedValueHandle])(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
(validateParamType(a.suffix, linkedValues, WomStringType),
validateParamType(a.array, linkedValues, WomArrayType(WomStringType))
) mapN { (_, _) => WomArrayType(WomStringType) }

Check warning on line 111 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/BiscayneTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/BiscayneTypeEvaluators.scala#L109-L111

Added lines #L109 - L111 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
case a: Length => a.evaluateType(linkedValues)(typeEvaluator)
case a: Flatten => a.evaluateType(linkedValues)(typeEvaluator)
case a: Prefix => a.evaluateType(linkedValues)(typeEvaluator)
case a: Suffix => a.evaluateType(linkedValues)(typeEvaluator)

Check warning on line 86 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/types.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/types/types.scala#L86

Added line #L86 was not covered by tests
case a: SelectFirst => a.evaluateType(linkedValues)(typeEvaluator)
case a: SelectAll => a.evaluateType(linkedValues)(typeEvaluator)
case a: Defined => a.evaluateType(linkedValues)(typeEvaluator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,22 @@
EvaluatedValue(WomString(arr.value.map(v => v.valueString).mkString(sepvalue.value)), Seq.empty).validNel
}
}

implicit val suffixFunctionEvaluator: ValueEvaluator[Suffix] = new ValueEvaluator[Suffix] {

Check warning on line 221 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala#L221

Added line #L221 was not covered by tests
override def evaluateValue(a: Suffix,
inputs: Map[String, WomValue],
ioFunctionSet: IoFunctionSet,
forCommandInstantiationOptions: Option[ForCommandInstantiationOptions]
)(implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomArray]] =
processTwoValidatedValues[WomString, WomArray, WomArray](
expressionValueEvaluator.evaluateValue(a.arg1, inputs, ioFunctionSet, forCommandInstantiationOptions)(

Check warning on line 228 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala#L228

Added line #L228 was not covered by tests
expressionValueEvaluator
),
expressionValueEvaluator.evaluateValue(a.arg2, inputs, ioFunctionSet, forCommandInstantiationOptions)(

Check warning on line 231 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala#L231

Added line #L231 was not covered by tests
expressionValueEvaluator
)
) { (suffix, arr) =>
EvaluatedValue(WomArray(arr.value.map(v => WomString(v.valueString + suffix.value))), Seq.empty).validNel

Check warning on line 235 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/BiscayneValueEvaluators.scala#L234-L235

Added lines #L234 - L235 were not covered by tests
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the part that actually does the suffix-ing

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)
case a: Prefix =>
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)
case a: Suffix =>
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)

Check warning on line 146 in wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/values.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/biscayne/src/main/scala/wdl/transforms/biscayne/linking/expression/values/values.scala#L146

Added line #L146 was not covered by tests
case a: SelectFirst =>
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)
case a: SelectAll =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,10 @@ class Ast2WdlomSpec extends AnyFlatSpec with CromwellTimeoutSpec with Matchers {
val expr = fromString[ExpressionElement](str, parser.parse_e)
expr shouldBeValid NoneLiteralElement
}

it should "parse the new suffix function" in {
val str = "suffix(some_str, some_arr)"
val expr = fromString[ExpressionElement](str, parser.parse_e)
expr shouldBeValid (Suffix(IdentifierLookup("some_str"), IdentifierLookup("some_arr")))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,22 @@ class BiscayneExpressionValueConsumersSpec extends AnyFlatSpec with CromwellTime
e.expressionConsumedValueHooks should be(Set(UnlinkedIdentifierHook("my_separator"), UnlinkedIdentifierHook("c")))
}
}

it should "discover the variable lookups within a suffix() call" in {
val str = """ suffix(my_suffix, ["a", "b", c]) """
val expr = fromString[ExpressionElement](str, parser.parse_e)

expr.shouldBeValidPF { case e =>
e.expressionConsumedValueHooks should be(Set(UnlinkedIdentifierHook("my_suffix"), UnlinkedIdentifierHook("c")))
}
}

it should "discover an array variable lookup within a suffix() call" in {
val str = """ suffix("SFX", my_array) """
val expr = fromString[ExpressionElement](str, parser.parse_e)

expr.shouldBeValidPF { case e =>
e.expressionConsumedValueHooks should be(Set(UnlinkedIdentifierHook("my_array")))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,15 @@ class BiscayneFileEvaluatorSpec extends AnyFlatSpec with CromwellTimeoutSpec wit
)
}
}

it should "discover the file which would be required to evaluate a suffix() function" in {
val str = """ suffix(' # what a line', read_lines("foo.txt")) """
val expr = fromString[ExpressionElement](str, parser.parse_e)

expr.shouldBeValidPF { case e =>
e.predictFilesNeededToEvaluate(Map.empty, NoIoFunctionSet, WomStringType) shouldBeValid Set(
WomSingleFile("foo.txt")
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,12 @@ class BiscayneTypeEvaluatorSpec extends AnyFlatSpec with CromwellTimeoutSpec wit
}
}

it should "evaluate the type of a suffix() function as Array[String]" in {
val str = """ suffix('S', ["a", "b", "c"]) """
val expr = fromString[ExpressionElement](str, parser.parse_e)

expr.shouldBeValidPF { case e =>
e.evaluateType(Map.empty) shouldBeValid WomArrayType(WomStringType)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,21 @@ class BiscayneValueEvaluatorSpec extends AnyFlatSpec with CromwellTimeoutSpec wi
e.evaluateValue(Map.empty, NoIoFunctionSet, None) shouldBeValid EvaluatedValue(expectedString, Seq.empty)
}
}

it should "evaluate a suffix expression correctly" in {
val str = """ suffix("S", ["a", "b", "c"]) """
val expr = fromString[ExpressionElement](str, parser.parse_e)

val expectedArray: WomArray = WomArray(
Seq(
WomString("aS"),
WomString("bS"),
WomString("cS")
)
)

expr.shouldBeValidPF { case e =>
e.evaluateValue(Map.empty, NoIoFunctionSet, None) shouldBeValid EvaluatedValue(expectedArray, Seq.empty)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import cats.syntax.validated._
import common.validation.ErrorOr.ErrorOr
import wdl.model.draft3.elements.ExpressionElement
import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep}
import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep, Suffix}
import wdl.transforms.base.ast2wdlom.AstNodeToExpressionElement

object AstToNewExpressionElements {
Expand All @@ -15,6 +15,7 @@
"min" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Min, "min"),
"max" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Max, "max"),
"sep" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Sep, "sep"),
"suffix" -> AstNodeToExpressionElement.validateTwoParamEngineFunction(Suffix, "suffix"),

Check warning on line 18 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/ast2wdlom/AstToNewExpressionElements.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/ast2wdlom/AstToNewExpressionElements.scala#L18

Added line #L18 was not covered by tests
"read_object" -> (_ =>
"read_object is no longer available in this WDL version. Consider using read_json instead".invalidNel
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@
expressionValueConsumer.expressionConsumedValueHooks(a.arg2)(expressionValueConsumer)
}

implicit val suffixExpressionValueConsumer: ExpressionValueConsumer[Suffix] = new ExpressionValueConsumer[Suffix] {

Check warning on line 61 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/consumed/CascadesExpressionValueConsumers.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/consumed/CascadesExpressionValueConsumers.scala#L61

Added line #L61 was not covered by tests
override def expressionConsumedValueHooks(a: Suffix)(implicit
expressionValueConsumer: ExpressionValueConsumer[ExpressionElement]
): Set[UnlinkedConsumedValueHook] =
expressionValueConsumer.expressionConsumedValueHooks(a.arg1)(expressionValueConsumer) ++
expressionValueConsumer.expressionConsumedValueHooks(a.arg2)(expressionValueConsumer)

Check warning on line 66 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/consumed/CascadesExpressionValueConsumers.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/consumed/CascadesExpressionValueConsumers.scala#L65-L66

Added lines #L65 - L66 were not covered by tests
}

implicit val noneLiteralExpressionValueConsumer: ExpressionValueConsumer[NoneLiteralElement.type] =
new ExpressionValueConsumer[NoneLiteralElement.type] {
override def expressionConsumedValueHooks(a: NoneLiteralElement.type)(implicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
case a: Length => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Flatten => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Prefix => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Suffix => a.expressionConsumedValueHooks(expressionValueConsumer)

Check warning on line 84 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/consumed/consumed.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/consumed/consumed.scala#L84

Added line #L84 was not covered by tests
case a: SelectFirst => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: SelectAll => a.expressionConsumedValueHooks(expressionValueConsumer)
case a: Defined => a.expressionConsumedValueHooks(expressionValueConsumer)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package wdl.transforms.cascades.linking.expression.files

import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep}
import wdl.model.draft3.elements.ExpressionElement.{AsMap, AsPairs, CollectByKey, Keys, Max, Min, Sep, Suffix}
import wdl.model.draft3.graph.expression.FileEvaluator
import wdl.transforms.base.linking.expression.files.EngineFunctionEvaluators
import wdl.transforms.base.linking.expression.files.EngineFunctionEvaluators.twoParameterFunctionPassthroughFileEvaluator
Expand All @@ -16,6 +16,7 @@
EngineFunctionEvaluators.singleParameterPassthroughFileEvaluator

implicit val sepFunctionEvaluator: FileEvaluator[Sep] = twoParameterFunctionPassthroughFileEvaluator[Sep]
implicit val suffixFunctionEvaluator: FileEvaluator[Suffix] = twoParameterFunctionPassthroughFileEvaluator[Suffix]

Check warning on line 19 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/files/CascadesFileEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/files/CascadesFileEvaluators.scala#L19

Added line #L19 was not covered by tests

implicit val minFunctionEvaluator: FileEvaluator[Min] = twoParameterFunctionPassthroughFileEvaluator[Min]
implicit val maxFunctionEvaluator: FileEvaluator[Max] = twoParameterFunctionPassthroughFileEvaluator[Max]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
case a: Flatten =>
a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)
case a: Prefix => a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)
case a: Suffix => a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)

Check warning on line 138 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/files/files.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/files/files.scala#L138

Added line #L138 was not covered by tests
case a: SelectFirst =>
a.predictFilesNeededToEvaluate(inputs, ioFunctionSet, coerceTo)(fileEvaluator, valueEvaluator)
case a: SelectAll =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package wdl.transforms.biscayne.linking.expression.types

import cats.implicits.catsSyntaxTuple2Semigroupal
import cats.syntax.validated._
import common.validation.ErrorOr._
import wdl.model.draft3.elements.ExpressionElement
Expand Down Expand Up @@ -100,4 +101,13 @@

}
}

implicit val suffixFunctionEvaluator: TypeEvaluator[Suffix] = new TypeEvaluator[Suffix] {

Check warning on line 105 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L105

Added line #L105 was not covered by tests
override def evaluateType(a: Suffix, linkedValues: Map[UnlinkedConsumedValueHook, GeneratedValueHandle])(implicit
expressionTypeEvaluator: TypeEvaluator[ExpressionElement]
): ErrorOr[WomType] =
(validateParamType(a.suffix, linkedValues, WomStringType),
validateParamType(a.array, linkedValues, WomArrayType(WomStringType))
) mapN { (_, _) => WomArrayType(WomStringType) }

Check warning on line 111 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/CascadesTypeEvaluators.scala#L109-L111

Added lines #L109 - L111 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
case a: Length => a.evaluateType(linkedValues)(typeEvaluator)
case a: Flatten => a.evaluateType(linkedValues)(typeEvaluator)
case a: Prefix => a.evaluateType(linkedValues)(typeEvaluator)
case a: Suffix => a.evaluateType(linkedValues)(typeEvaluator)

Check warning on line 86 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/types.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/types/types.scala#L86

Added line #L86 was not covered by tests
case a: SelectFirst => a.evaluateType(linkedValues)(typeEvaluator)
case a: SelectAll => a.evaluateType(linkedValues)(typeEvaluator)
case a: Defined => a.evaluateType(linkedValues)(typeEvaluator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,22 @@
EvaluatedValue(WomString(arr.value.map(v => v.valueString).mkString(sepvalue.value)), Seq.empty).validNel
}
}

implicit val suffixFunctionEvaluator: ValueEvaluator[Suffix] = new ValueEvaluator[Suffix] {

Check warning on line 221 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala#L221

Added line #L221 was not covered by tests
override def evaluateValue(a: Suffix,
inputs: Map[String, WomValue],
ioFunctionSet: IoFunctionSet,
forCommandInstantiationOptions: Option[ForCommandInstantiationOptions]
)(implicit expressionValueEvaluator: ValueEvaluator[ExpressionElement]): ErrorOr[EvaluatedValue[WomArray]] =
processTwoValidatedValues[WomString, WomArray, WomArray](
expressionValueEvaluator.evaluateValue(a.arg1, inputs, ioFunctionSet, forCommandInstantiationOptions)(

Check warning on line 228 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala#L228

Added line #L228 was not covered by tests
expressionValueEvaluator
),
expressionValueEvaluator.evaluateValue(a.arg2, inputs, ioFunctionSet, forCommandInstantiationOptions)(

Check warning on line 231 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala#L231

Added line #L231 was not covered by tests
expressionValueEvaluator
)
) { (suffix, arr) =>
EvaluatedValue(WomArray(arr.value.map(v => WomString(v.valueString + suffix.value))), Seq.empty).validNel

Check warning on line 235 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/CascadesValueEvaluators.scala#L234-L235

Added lines #L234 - L235 were not covered by tests
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)
case a: Prefix =>
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)
case a: Suffix =>
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)

Check warning on line 146 in wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/values.scala

View check run for this annotation

Codecov / codecov/patch

wdl/transforms/cascades/src/main/scala/wdl/transforms/cascades/linking/expression/values/values.scala#L146

Added line #L146 was not covered by tests
case a: SelectFirst =>
a.evaluateValue(inputs, ioFunctionSet, forCommandInstantiationOptions)(expressionValueEvaluator)
case a: SelectAll =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,10 @@ class Ast2WdlomSpec extends AnyFlatSpec with CromwellTimeoutSpec with Matchers {
val expr = fromString[ExpressionElement](str, parser.parse_e)
expr shouldBeValid NoneLiteralElement
}

it should "parse the new suffix function" in {
val str = "suffix(some_str, some_arr)"
val expr = fromString[ExpressionElement](str, parser.parse_e)
expr shouldBeValid (Suffix(IdentifierLookup("some_str"), IdentifierLookup("some_arr")))
}
}
Loading
Loading