viash-io / viash

script + metadata = standalone component
https://viash.io
GNU General Public License v3.0
36 stars 2 forks source link

[BUG] Improper escape of curly bracketed variable when used as a default value for a file argument. #698

Open DriesSchaumont opened 2 months ago

DriesSchaumont commented 2 months ago

What happened?

Using curly brackets as a value for the default: field of a argument that is of type file leads to unboud variable error in bash.

Steps to reproduce

mkdir -p /tmp/test_bug
cd /tmp/test_bug
cat > _viash.yaml << 'HERE'
viash_version: 0.8.6

source: src
target: target
HERE

mkdir -p src/dummycomponent

cat > src/dummycomponent/config.vsh.yaml << 'HERE'
functionality:
  name: myscript
  namespace: "dummycomponent"
  arguments:
    - name: "--output"
      type: file
      direction: output
      default: "${id}"
  resources:
    - type: python_script
      path: script.py
      text: |
        print("OK!", flush=True)
platforms:
  - type: nextflow
HERE

mkdir -p src/dummyworkflow
cat > src/dummyworkflow/config.vsh.yaml << 'HERE'
functionality:
  name: myyworkflow
  namespace: "dummyworkflow"
  arguments:
    - name: "--output"
      type: file
      direction: output
      default: "${id}"
  resources:
    - type: nextflow_script
      path: main.nf
      text: |
        workflow run_wf {
          take:
            input_ch

          main:
            output_ch = input_ch
              | myscript

          emit:
            output_ch
        }
      entrypoint: run_wf
  dependencies:
    - name: dummycomponent/myscript
platforms:
  - type: nextflow
HERE

viash ns build
nextflow run . -main-script ./target/nextflow/dummyworkflow/myyworkflow/main.nf --publish_dir .

Expected behavior

Both ${id} and $id are correct syntax for groovy variables. Sometimes, using the ${} form is preferred because it clearly delineates where the variable name ends and the rest of the string begins when doing string interpolation: $id_foo vs ${id}_foo.

I would expect to use ${id} without it being interpreted a s a bash variable, but still being to use it as a proper default value for type: file

Relevant log output

ERROR ~ Error executing process > 'myyworkflow:run_wf:myscript:processWf:myscript_process (run)'

Caused by:
  Process `myyworkflow:run_wf:myscript:processWf:myscript_process (run)` terminated with an error exit status (1)

Command executed:

  # meta exports
  export VIASH_META_RESOURCES_DIR=".viash_meta_resources"
  export VIASH_META_TEMP_DIR="/var/folders/fv/p0mc5zps48v15zw2q667t6gw0000gn/T"
  export VIASH_META_FUNCTIONALITY_NAME="myscript"
  # export VIASH_META_EXECUTABLE="$VIASH_META_RESOURCES_DIR/$VIASH_META_FUNCTIONALITY_NAME"
  export VIASH_META_CONFIG="$VIASH_META_RESOURCES_DIR/.config.vsh.yaml"
  export VIASH_META_CPUS=1

  if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then
    export VIASH_META_MEMORY_KB=$(( ($VIASH_META_MEMORY_B+1023) / 1024 ))
    export VIASH_META_MEMORY_MB=$(( ($VIASH_META_MEMORY_KB+1023) / 1024 ))
    export VIASH_META_MEMORY_GB=$(( ($VIASH_META_MEMORY_MB+1023) / 1024 ))
    export VIASH_META_MEMORY_TB=$(( ($VIASH_META_MEMORY_GB+1023) / 1024 ))
    export VIASH_META_MEMORY_PB=$(( ($VIASH_META_MEMORY_TB+1023) / 1024 ))
  fi

  # meta synonyms
  export VIASH_TEMP="$VIASH_META_TEMP_DIR"
  export TEMP_DIR="$VIASH_META_TEMP_DIR"

  # create output dirs if need be
  function mkdir_parent {
    for file in "$@"; do
      mkdir -p "$(dirname "$file")"
    done
  }
  mkdir_parent "${id}"

  # argument exports
  export VIASH_PAR_OUTPUT="${id}"

  # process script
  set -e
  tempscript=".viash_script.sh"
  cat > "$tempscript" << VIASHMAIN
  ## VIASH START
  # The following code has been auto-generated by Viash.
  par = {
    'output': $( if [ ! -z ${VIASH_PAR_OUTPUT+x} ]; then echo "r'${VIASH_PAR_OUTPUT//\'/\'\"\'\"r\'}'"; else echo None; fi )
  }
  meta = {
    'functionality_name': $( if [ ! -z ${VIASH_META_FUNCTIONALITY_NAME+x} ]; then echo "r'${VIASH_META_FUNCTIONALITY_NAME//\'/\'\"\'\"r\'}'"; else echo None; fi ),
    'resources_dir': $( if [ ! -z ${VIASH_META_RESOURCES_DIR+x} ]; then echo "r'${VIASH_META_RESOURCES_DIR//\'/\'\"\'\"r\'}'"; else echo None; fi ),
    'executable': $( if [ ! -z ${VIASH_META_EXECUTABLE+x} ]; then echo "r'${VIASH_META_EXECUTABLE//\'/\'\"\'\"r\'}'"; else echo None; fi ),
    'config': $( if [ ! -z ${VIASH_META_CONFIG+x} ]; then echo "r'${VIASH_META_CONFIG//\'/\'\"\'\"r\'}'"; else echo None; fi ),
    'temp_dir': $( if [ ! -z ${VIASH_META_TEMP_DIR+x} ]; then echo "r'${VIASH_META_TEMP_DIR//\'/\'\"\'\"r\'}'"; else echo None; fi ),
    'cpus': $( if [ ! -z ${VIASH_META_CPUS+x} ]; then echo "int(r'${VIASH_META_CPUS//\'/\'\"\'\"r\'}')"; else echo None; fi ),
    'memory_b': $( if [ ! -z ${VIASH_META_MEMORY_B+x} ]; then echo "int(r'${VIASH_META_MEMORY_B//\'/\'\"\'\"r\'}')"; else echo None; fi ),
    'memory_kb': $( if [ ! -z ${VIASH_META_MEMORY_KB+x} ]; then echo "int(r'${VIASH_META_MEMORY_KB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
    'memory_mb': $( if [ ! -z ${VIASH_META_MEMORY_MB+x} ]; then echo "int(r'${VIASH_META_MEMORY_MB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
    'memory_gb': $( if [ ! -z ${VIASH_META_MEMORY_GB+x} ]; then echo "int(r'${VIASH_META_MEMORY_GB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
    'memory_tb': $( if [ ! -z ${VIASH_META_MEMORY_TB+x} ]; then echo "int(r'${VIASH_META_MEMORY_TB//\'/\'\"\'\"r\'}')"; else echo None; fi ),
    'memory_pb': $( if [ ! -z ${VIASH_META_MEMORY_PB+x} ]; then echo "int(r'${VIASH_META_MEMORY_PB//\'/\'\"\'\"r\'}')"; else echo None; fi )
  }
  dep = {

  }

  ## VIASH END
  print("OK!", flush=True)
  VIASHMAIN
  python -B "$tempscript"

Command exit status:
  1

Command output:
  (empty)

Command error:
  .command.sh: line 28: id: unbound variable

Work dir:
  /private/tmp/test_bug/work/f4/ae306dde928adacf0665e3cab1c7c6

Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out`

 -- Check '.nextflow.log' file for details

Version

Possible solution

No response

Confirmation

Additional context

No response