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

Switch to arrays #762

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function ViashParseArgumentValue {
local flag="$1"
local env_name="$2"
local multiple="$3"
local value="$4"

if [ $# -lt 4 ]; then
ViashError "Not enough arguments passed to ${flag}. Use '--help' to get more information on the parameters."
exit 1
fi

if [ "$multiple" == "false" ]; then
# check whether the variable is already set
if [ ! -z ${!env_name+x} ]; then
local -n prev_value="$env_name"
ViashError "Pass only one argument to argument '${flag}'. Found: ${prev_value@Q} & ${value@Q}"
exit 1
fi

# set the variable
declare -g "$env_name=${value}"
else
local new_values

local -n prev_values="$env_name"

# todo: allow escaping the delimiter
readarray -d ';' -t new_values < <(printf '%s' "$value")

combined_values=( "${prev_values[@]}" "${new_values[@]}" )

declare -g -a "$env_name=(\"\${combined_values[@]}\")"
fi
}
75 changes: 75 additions & 0 deletions src/main/resources/io/viash/helpers/bashutils/ViashRenderYaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
function ViashRenderYamlQuotedValue {
local key="$1"
local value="$2"
# escape quotes, backslashes and newlines, and then surround by quotes
echo "$value" | \
sed 's#\\#\\\\#g' | \
sed 's#"#\\"#g' | \
sed ':a;N;$!ba;s/\n/\\n/g' | \
sed 's#^#"#g;s#$#"#g'
}

function ViashRenderYamlBooleanValue {
local key="$1"
local value="$2"
# convert to lowercase
value=$(echo "$value" | tr '[:upper:]' '[:lower:]')
if [[ "$value" == "true" || "$value" == "yes" ]]; then
echo "true"
elif [[ "$value" == "false" || "$value" == "no" ]]; then
echo "false"
else
echo "Argument '$key' has to be a boolean, but got '$value'. Use '--help' to get more information on the parameters."
fi
}

# can be infinite too
function ViashRenderYamlUnquotedValue {
local key="$1"
local value="$2"
echo "$value"
}

function ViashRenderYamlKeyValue {
local key="$1"
local type="$2"
local multiple="$3"
shift 3

local out=" ${key}: "

if [ "$1" == "UNDEFINED" ]; then
out+="null"
echo "$out"
return
fi

if [ "$multiple" == "true" ]; then
out+="["
fi

first_elem=1

for value in "$@"; do
if [ $first_elem -eq 1 ]; then
first_elem=0
else
out+=", "
fi
if [ "$value" == "UNDEFINED_ITEM" ]; then
out+="null"
elif [[ "$type" == "string" || "$type" == "file" ]]; then
out+="$(ViashRenderYamlQuotedValue "$key" "$value")"
elif [[ "$type" == "boolean" || "$type" == "boolean_true" || "$type" == "boolean_false" ]]; then
out+="$(ViashRenderYamlBooleanValue "$key" "$value")"
else
out+="$(ViashRenderYamlUnquotedValue "$key" "$value")"
fi
done

if [ "$multiple" == "true" ]; then
out+="]"
fi

echo "$out"
}
33 changes: 2 additions & 31 deletions src/main/scala/io/viash/helpers/Bash.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,12 @@ object Bash {
lazy val ViashRemoveFlags: String = readUtils("ViashRemoveFlags")
lazy val ViashAbsolutePath: String = readUtils("ViashAbsolutePath")
lazy val ViashDockerAutodetectMount: String = readUtils("ViashDockerAutodetectMount")
// backwards compatibility, for now
lazy val ViashAutodetectMount: String = ViashDockerAutodetectMount.replace("ViashDocker", "Viash")
lazy val ViashSourceDir: String = readUtils("ViashSourceDir")
lazy val ViashFindTargetDir: String = readUtils("ViashFindTargetDir")
lazy val ViashDockerFuns: String = readUtils("ViashDockerFuns")
lazy val ViashLogging: String = readUtils("ViashLogging")

def save(saveVariable: String, args: Seq[String]): String = {
saveVariable + "=\"$" + saveVariable + " " + args.mkString(" ") + "\""
}

// generate strings in the form of:
// SAVEVARIABLE="$SAVEVARIABLE $(Quote arg1) $(Quote arg2)"
def quoteSave(saveVariable: String, args: Seq[String]): String = {
saveVariable + "=\"$" + saveVariable +
args.map(" $(ViashQuote \"" + _ + "\")").mkString +
"\""
}

def argStore(name: String, plainName: String, store: String, argsConsumed: Int, storeUnparsed: Option[String]): String = {
val passStr =
if (storeUnparsed.isDefined) {
"\n " + quoteSave(storeUnparsed.get, (1 to argsConsumed).map("$" + _))
} else {
""
}
s""" $name)
| $plainName=$store$passStr
| shift $argsConsumed
| ;;""".stripMargin
}

def argStoreSed(name: String, plainName: String, storeUnparsed: Option[String]): String = {
argStore(name + "=*", plainName, "$(ViashRemoveFlags \"$1\")", 1, storeUnparsed)
}
lazy val ViashRenderYaml: String = readUtils("ViashRenderYaml")
lazy val ViashParseArgumentValue: String = readUtils("ViashParseArgumentValue")

/**
* Access the parameters contents in a bash script,
Expand Down
21 changes: 5 additions & 16 deletions src/main/scala/io/viash/runners/ExecutableRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -395,20 +395,14 @@ final case class ExecutableRunner(
val detectMounts = args.flatMap {
case arg: FileArgument if arg.multiple =>
// resolve arguments with multiplicity different from singular args
val viash_temp = "VIASH_TEST_" + arg.plainName.toUpperCase()
val chownIfOutput = if (arg.direction == Output) "\n VIASH_CHOWN_VARS+=( \"$var\" )" else ""
Some(
s"""
|if [ ! -z "$$${arg.VIASH_PAR}" ]; then
| $viash_temp=()
| IFS='${Bash.escapeString(arg.multiple_sep, quote = true)}'
| for var in $$${arg.VIASH_PAR}; do
| unset IFS
| VIASH_DIRECTORY_MOUNTS+=( "$$(ViashDockerAutodetectMountArg "$$var")" )
| var=$$(ViashDockerAutodetectMount "$$var")
| $viash_temp+=( "$$var" )$chownIfOutput
| for i in "$${!${arg.VIASH_PAR}[@]}"; do
| VIASH_DIRECTORY_MOUNTS+=( "$$(ViashDockerAutodetectMountArg $${${arg.VIASH_PAR}[$$i]})" )
| ${arg.VIASH_PAR}[$$i]=$$(ViashDockerAutodetectMount $${${arg.VIASH_PAR}[$$i]})
| done
| ${arg.VIASH_PAR}=$$(IFS='${Bash.escapeString(arg.multiple_sep, quote = true)}' ; echo "$${$viash_temp[*]}")
|fi""".stripMargin
)
case arg: FileArgument =>
Expand Down Expand Up @@ -455,17 +449,12 @@ final case class ExecutableRunner(
val stripAutomounts = args.flatMap {
case arg: FileArgument if arg.multiple && arg.direction == Input =>
// resolve arguments with multiplicity different from singular args
val viash_temp = "VIASH_TEST_" + arg.plainName.toUpperCase()
Some(
s"""
| if [ ! -z "$$${arg.VIASH_PAR}" ]; then
| unset $viash_temp
| IFS='${Bash.escapeString(arg.multiple_sep, quote = true)}'
| for var in $$${arg.VIASH_PAR}; do
| unset IFS
| ${BashWrapper.store("ViashDockerStripAutomount", viash_temp, "\"$(ViashDockerStripAutomount \"$var\")\"", Some(arg.multiple_sep)).mkString("\n ")}
| for i in "$${!${arg.VIASH_PAR}[@]}"; do
| ${arg.VIASH_PAR}[i]=$$(ViashDockerStripAutomount "$${${arg.VIASH_PAR}[i]}")
| done
| ${arg.VIASH_PAR}="$$$viash_temp"
| fi""".stripMargin
)
case arg: FileArgument =>
Expand Down
Loading
Loading