Skip to content
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
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,44 @@ find . -name "*.sh" -exec sed -i 's/\r$//' {} +
```
Or by installing and using `dos2unix`.

### Windows: Git Bash and MSYS2

The scripts are written for Bash and run unchanged on Linux, macOS and WSL.
They also run on Windows from Git Bash or from an MSYS2 shell (for example MINGW64 or UCRT64), provided you first turn off the automatic path conversion of these shells and make them drop the carriage returns Windows programs print:

```bash
export MSYS_NO_PATHCONV=1
set -o igncr
export SHELLOPTS
```

When Git Bash or an MSYS2 shell starts a Windows program such as the Azure CLI, it rewrites every argument that looks like an absolute POSIX path into a Windows path.
Azure values that only look like paths are rewritten too, and the commands that receive them fail:

- `--partition-key-path /username` reaches `az` as `C:/Program Files/Git/username`, so creating the Cosmos DB container fails with an invalid partition key path error.
- Resource IDs such as `/subscriptions/<subscription-id>/resourceGroups/...`, passed to `--scope`, `--ids` and similar options, become paths under the shell's installation folder, for example `C:/Program Files/Git/subscriptions/...`.
- Paths such as the Front Door `--origin-path /api` are rewritten the same way.

With `MSYS_NO_PATHCONV=1` set, these values reach the Azure CLI exactly as written.
The scripts convert the paths of the local files they hand to Windows programs, such as the temporary files read by `curl` and `jq`, with `cygpath` when it is available, so they keep working with the variable set.
Comment thread
paolosalvatori marked this conversation as resolved.
They also hand `curl` the Windows `NUL` device instead of `/dev/null` for the responses they discard, because the variable stops these shells from making that conversion too.
On Linux and macOS `cygpath` does not exist, and the paths are left unchanged.

Windows programs such as the Azure CLI and `jq` also end every line they print with a carriage return, which Bash keeps when a script captures their output with `$(...)` or `read`.
A name or an ID read from `az ... --output tsv` then carries an invisible `\r`, and the next command that receives it fails, for example with `ResourceNotFound` for a resource that exists.
`set -o igncr` makes these shells drop carriage returns from `$(...)` and `read`, and `export SHELLOPTS` passes the option on to the scripts you start.
`mapfile` keeps them even then, so the scripts that fill an array from the Azure CLI strip them with `tr -d '\r'`.

Tips:

- To apply these settings in every new Git Bash window, add the three lines to `~/.bash_profile`, or to `~/.bashrc` if your `.bash_profile` sources it.
- `echo $MSYSTEM` prints a value such as `MINGW64` only in these shells.
- Any value turns the conversion off, `0` included; run `unset MSYS_NO_PATHCONV` to turn it back on, and `set +o igncr` to keep carriage returns again.
- WSL runs Linux and needs none of these settings.
- When you write a script that passes a local file to `az`, `curl`, `jq`, `python`, `docker` or `zip`, convert its path with the `native_path` helper the existing scripts define; Git Bash ships no `zip`, and a `zip.exe` built for Windows needs the converted path too.
- To discard what a Windows program writes to a file, such as `curl -o`, pass it `"$(null_device)"` rather than `/dev/null`, as the existing scripts do. Shell redirections such as `> /dev/null` need no change.
- A launcher written as a shell script that hands its own paths to a Windows program, such as Maven's `mvn`, needs the conversion: run it as `(unset MSYS_NO_PATHCONV; mvn ...)`, as the Service Bus sample does. Setting the variable to an empty value is not enough, because any value turns the conversion off.

## Configuration

Follow the comprehensive setup guide in [LocalStack for Azure Quick Start](./docs/LOCALSTACK.md) to configure your LocalStack for Azure development environment.
Expand Down
1 change: 1 addition & 0 deletions run-samples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ SAMPLES=(
"samples/function-app-storage-http/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-http-triggers.sh"
"samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-cosmosdb-mongodb-api/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-cosmosdb-nosql-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-cosmosdb-nosql-api/dotnet|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-managed-identity/dotnet|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
Expand Down
16 changes: 14 additions & 2 deletions samples/api-management-function-app/python/scripts/call-api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,21 @@ APIM_NAME="${PREFIX}-inventory-apim-${SUFFIX}"
APIM_API_VERSION='2022-08-01'
API_PATH='inventory'
APIM_SUBSCRIPTION_ID='partner-subscription'

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

# mktemp rather than fixed paths, as in validate.sh: parallel-safe, and cleaned up on exit.
BODY_FILE="$(mktemp "${TMPDIR:-/tmp}/inventory_call.XXXXXX.json")"
HEADERS_FILE="$(mktemp "${TMPDIR:-/tmp}/inventory_call_headers.XXXXXX.txt")"
BODY_FILE="$(native_path "$(mktemp "${TMPDIR:-/tmp}/inventory_call.XXXXXX.json")")"
HEADERS_FILE="$(native_path "$(mktemp "${TMPDIR:-/tmp}/inventory_call_headers.XXXXXX.txt")")"
trap 'rm -f "$BODY_FILE" "$HEADERS_FILE"' EXIT

# Retrieve the API Management service
Expand Down
14 changes: 13 additions & 1 deletion samples/api-management-function-app/python/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,19 @@ APIM_SUBSCRIPTION_ID='partner-subscription'
NAMED_VALUE_ID='backend-secret'
FUNCTION_ZIPFILE='inventory_function.zip'
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
APIM_DIR="$CURRENT_DIR/../apim"

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

APIM_DIR="$(native_path "$CURRENT_DIR/../apim")"

# Get the current subscription
SUBSCRIPTION_NAME=$(az account show --query name --output tsv)
Expand Down
31 changes: 27 additions & 4 deletions samples/api-management-function-app/python/scripts/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,33 @@ API_ID='inventory-api'
API_PATH='inventory'
APIM_SUBSCRIPTION_ID='partner-subscription'
RATE_LIMIT_CALLS=10

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

# Where curl discards a response body. Git Bash and MSYS2 shells hand a Windows curl /dev/null
# unchanged when MSYS_NO_PATHCONV=1 is set, as the README asks, and it cannot open that path, so it
# gets the NUL device instead; MSYS2's own curl, under /usr/bin, opens /dev/null as on Linux and macOS.
null_device() {
if command -v cygpath >/dev/null 2>&1 && [[ "$(command -v curl)" != /usr/bin/* ]]; then
echo NUL
else
echo /dev/null
fi
}

# mktemp rather than fixed paths: two runs of this script must not write the same file, and
# `curl -o` would follow a symlink a third party had left at a predictable name.
BODY_FILE="$(mktemp "${TMPDIR:-/tmp}/inventory_body.XXXXXX.json")"
HEADERS_FILE="$(mktemp "${TMPDIR:-/tmp}/inventory_headers.XXXXXX.txt")"
BODY_FILE="$(native_path "$(mktemp "${TMPDIR:-/tmp}/inventory_body.XXXXXX.json")")"
HEADERS_FILE="$(native_path "$(mktemp "${TMPDIR:-/tmp}/inventory_headers.XXXXXX.txt")")"
trap 'rm -f "$BODY_FILE" "$HEADERS_FILE"' EXIT

FAILED=0
Expand Down Expand Up @@ -54,7 +77,7 @@ echo "Gateway URL: $API_URL"
echo "Waiting for the [$FUNCTION_APP_NAME] function app to answer..."
BACKEND_STATUS=""
for i in $(seq 1 60); do
BACKEND_STATUS=$(curl -s -m 10 -o /dev/null -w "%{http_code}" "$BACKEND_URL/items")
BACKEND_STATUS=$(curl -s -m 10 -o "$(null_device)" -w "%{http_code}" "$BACKEND_URL/items")
[[ "$BACKEND_STATUS" == "401" ]] && break
sleep 5
done
Expand Down Expand Up @@ -211,7 +234,7 @@ fi
# so the preflight never reaches the API's cors policy. Asserted against Azure only.
# TODO: assert this unconditionally once the emulator lets the gateway's cors policy answer.
echo "Sending a CORS preflight to [$API_URL/items]..."
PREFLIGHT_STATUS=$(curl -s -m 10 -o /dev/null -D "$HEADERS_FILE" -w "%{http_code}" \
PREFLIGHT_STATUS=$(curl -s -m 10 -o "$(null_device)" -D "$HEADERS_FILE" -w "%{http_code}" \
-X OPTIONS \
-H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: GET" \
Expand Down
13 changes: 12 additions & 1 deletion samples/container-apps-blob-storage/python/scripts/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
# replicas, the live HTTP ingress, and a revision update.
# =============================================================================

# Where curl discards a response body. Git Bash and MSYS2 shells hand a Windows curl /dev/null
# unchanged when MSYS_NO_PATHCONV=1 is set, as the README asks, and it cannot open that path, so it
# gets the NUL device instead; MSYS2's own curl, under /usr/bin, opens /dev/null as on Linux and macOS.
null_device() {
if command -v cygpath >/dev/null 2>&1 && [[ "$(command -v curl)" != /usr/bin/* ]]; then
echo NUL
else
echo /dev/null
fi
}

# Variables (must match deploy.sh)
PREFIX='local'
LOCATION='eastus'
Expand Down Expand Up @@ -232,7 +243,7 @@ echo "[12] Guestbook Round Trip"
ENTRY_AUTHOR="validate-sh"
ENTRY_MESSAGE="Hello from validate.sh at $(date +%s)"
echo -n " Posting a guestbook entry... "
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 \
HTTP_CODE=$(curl -s -o "$(null_device)" -w "%{http_code}" --max-time 10 \
-X POST "$APP_URL/" \
--data-urlencode "author=$ENTRY_AUTHOR" \
--data-urlencode "message=$ENTRY_MESSAGE" 2>/dev/null)
Expand Down
13 changes: 12 additions & 1 deletion samples/eventhubs-eventgrid/python/bicep/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ FUNCTION_ZIP='capture_processor.zip'

CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$(cd "$CURRENT_DIR/../src" && pwd)"
# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

cd "$CURRENT_DIR" || exit 1

fail() {
Expand Down Expand Up @@ -120,7 +131,7 @@ echo "=== Publishing the application code ==="
# -----------------------------------------------------------------------------
cd "$SRC_DIR/functions" || fail "missing src/functions"
rm -f "$CURRENT_DIR/$FUNCTION_ZIP"
zip -r "$CURRENT_DIR/$FUNCTION_ZIP" function_app.py host.json requirements.txt 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$FUNCTION_ZIP")" function_app.py host.json requirements.txt 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the capture processor (the first run can take several minutes)..."
Expand Down
13 changes: 12 additions & 1 deletion samples/eventhubs-eventgrid/python/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ FUNCTION_ZIP='capture_processor.zip'

CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$(cd "$CURRENT_DIR/../src" && pwd)"
# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

cd "$CURRENT_DIR" || exit 1

fail() {
Expand Down Expand Up @@ -314,7 +325,7 @@ echo "Configured function app settings."

cd "$SRC_DIR/functions" || fail "missing src/functions"
rm -f "$CURRENT_DIR/$FUNCTION_ZIP"
zip -r "$CURRENT_DIR/$FUNCTION_ZIP" function_app.py host.json requirements.txt 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$FUNCTION_ZIP")" function_app.py host.json requirements.txt 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the processor (the first run pulls the build image and can take a few minutes)..."
Expand Down
15 changes: 13 additions & 2 deletions samples/eventhubs-eventgrid/python/scripts/run-pipeline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$(cd "$CURRENT_DIR/../src" && pwd)"
PYTHON_BIN="${PYTHON_BIN:-python3}"

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

READING_COUNT="${READING_COUNT:-120}"
DEVICE_COUNT="${DEVICE_COUNT:-6}"
EXCURSION_DEVICE="${EXCURSION_DEVICE:-DEV-0003}"
Expand Down Expand Up @@ -123,7 +134,7 @@ step "Step 3/5 - Event Hubs raises CaptureFileCreated, Event Grid delivers it"
echo "Reading '$NOTIFICATION_HUB_NAME', where the subscription's EventHub destination delivers..."
NOTIFICATIONS=$(EVENTHUB_LISTEN_CONNECTION_STRING="$EVENTHUB_LISTEN_CONNECTION_STRING" \
EVENT_HUB_NAME="$NOTIFICATION_HUB_NAME" \
"$PYTHON_BIN" "$CURRENT_DIR/roundtrip_check.py" --partitions 2>/dev/null | tail -1)
"$PYTHON_BIN" "$(native_path "$CURRENT_DIR/roundtrip_check.py")" --partitions 2>/dev/null | tail -1)
echo " $NOTIFICATIONS"
echo ""
echo "Nothing polled Blob Storage and no webhook was exposed: the notification arrived as a"
Expand All @@ -138,7 +149,7 @@ SUMMARY_OUTPUT=""
while [ $SECONDS -lt $DEADLINE ]; do
SUMMARY_OUTPUT=$(EVENTHUB_LISTEN_CONNECTION_STRING="$EVENTHUB_LISTEN_CONNECTION_STRING" \
CURATED_HUB_NAME="$CURATED_HUB_NAME" \
"$PYTHON_BIN" "$CURRENT_DIR/read_curated.py" 2>/dev/null)
"$PYTHON_BIN" "$(native_path "$CURRENT_DIR/read_curated.py")" 2>/dev/null)
if [[ "$SUMMARY_OUTPUT" == SUMMARIES_OK* ]]; then
break
fi
Expand Down
13 changes: 12 additions & 1 deletion samples/eventhubs-eventgrid/python/scripts/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ TELEMETRY_PARTITION_COUNT=4
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
PYTHON_BIN="${PYTHON_BIN:-python3}"

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

PASS_COUNT=0
FAIL_COUNT=0

Expand Down Expand Up @@ -158,7 +169,7 @@ ROUNDTRIP=$(EVENTHUB_SEND_CONNECTION_STRING=$(az eventhubs eventhub authorizatio
--resource-group "$RESOURCE_GROUP_NAME" \
--query primaryConnectionString -o tsv --only-show-errors) \
EVENT_HUB_NAME="$TELEMETRY_HUB_NAME" \
"$PYTHON_BIN" "$CURRENT_DIR/roundtrip_check.py" 2>&1 | tail -1)
"$PYTHON_BIN" "$(native_path "$CURRENT_DIR/roundtrip_check.py")" 2>&1 | tail -1)
if [[ "$ROUNDTRIP" == ROUNDTRIP_OK* ]]; then
echo "OK (${ROUNDTRIP#ROUNDTRIP_OK })"
PASS_COUNT=$((PASS_COUNT + 1))
Expand Down
13 changes: 12 additions & 1 deletion samples/eventhubs-eventgrid/python/terraform/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$(cd "$CURRENT_DIR/../src" && pwd)"
FUNCTION_ZIP='capture_processor.zip'

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

cd "$CURRENT_DIR" || exit 1

fail() {
Expand Down Expand Up @@ -60,7 +71,7 @@ FUNCTION_APP_NAME=$(terraform output -raw function_app_name)

cd "$SRC_DIR/functions" || fail "missing src/functions"
rm -f "$CURRENT_DIR/$FUNCTION_ZIP"
zip -r "$CURRENT_DIR/$FUNCTION_ZIP" function_app.py host.json requirements.txt 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$FUNCTION_ZIP")" function_app.py host.json requirements.txt 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the capture processor (the first run can take several minutes)..."
Expand Down
15 changes: 13 additions & 2 deletions samples/eventhubs/python/bicep/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ WEB_APP_ZIP="dashboard.zip"
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$(cd "$CURRENT_DIR/../src" && pwd)"

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

cd "$CURRENT_DIR" || exit 1

fail() {
Expand Down Expand Up @@ -142,7 +153,7 @@ echo "=== Publishing the application code ==="
# -----------------------------------------------------------------------------
cd "$SRC_DIR/functions" || fail "missing src/functions"
rm -f "$CURRENT_DIR/$FUNCTION_ZIP"
zip -r "$CURRENT_DIR/$FUNCTION_ZIP" function_app.py host.json requirements.txt 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$FUNCTION_ZIP")" function_app.py host.json requirements.txt 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the fraud detection function (the first run can take several minutes)..."
Expand All @@ -155,7 +166,7 @@ rm -f "$FUNCTION_ZIP"

cd "$SRC_DIR/dashboard" || fail "missing src/dashboard"
rm -f "$CURRENT_DIR/$WEB_APP_ZIP"
zip -r "$CURRENT_DIR/$WEB_APP_ZIP" app.py gunicorn.conf.py requirements.txt templates static 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$WEB_APP_ZIP")" app.py gunicorn.conf.py requirements.txt templates static 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the dashboard..."
Expand Down
15 changes: 13 additions & 2 deletions samples/eventhubs/python/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ FRAUD_VELOCITY_WINDOW_SECONDS=60
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$(cd "$CURRENT_DIR/../src" && pwd)"

# On Windows, Git Bash and MSYS2 shells pass a path such as /tmp/... unconverted to Windows programs
# (az, curl, jq, python, docker) when MSYS_NO_PATHCONV=1 is set, as the README asks. cygpath, which
# those shells provide, returns the C:/... form those programs can open; elsewhere the path is unchanged.
native_path() {
if command -v cygpath >/dev/null 2>&1; then
cygpath -m "$1"
else
echo "$1"
fi
}

cd "$CURRENT_DIR" || exit 1

fail() {
Expand Down Expand Up @@ -455,7 +466,7 @@ echo "Configured function app settings."

cd "$SRC_DIR/functions" || fail "missing src/functions"
rm -f "$CURRENT_DIR/$FUNCTION_ZIP"
zip -r "$CURRENT_DIR/$FUNCTION_ZIP" function_app.py host.json requirements.txt 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$FUNCTION_ZIP")" function_app.py host.json requirements.txt 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the function package (first run pulls the build image and can take a few minutes)..."
Expand Down Expand Up @@ -517,7 +528,7 @@ az webapp config set \

cd "$SRC_DIR/dashboard" || fail "missing src/dashboard"
rm -f "$CURRENT_DIR/$WEB_APP_ZIP"
zip -r "$CURRENT_DIR/$WEB_APP_ZIP" app.py gunicorn.conf.py requirements.txt templates static 1>/dev/null
zip -r "$(native_path "$CURRENT_DIR/$WEB_APP_ZIP")" app.py gunicorn.conf.py requirements.txt templates static 1>/dev/null
cd "$CURRENT_DIR" || exit 1

echo "Deploying the dashboard package..."
Expand Down
Loading
Loading