chore(ci): Improve pre-commit hook, test harness, and linter

- Pre-commit hook:
       - Redo test harness so commands can run in parallel
       - Cleanup Vale command args
       - Replace lint-staged and husky with Lefthook.
    - Pre-push hook:
       - Scan for package vulnerabilities
    - Tests
      - Run tests on demand, in parallel, or debugged using docker compose up, run, exec, etc.
      - Each test container (service) runs the prepare-content script before running tests.
      - Return to using Python instead of Docker to provide environment variables so they don't get exposed in Docker inspect.
      - Bind mount influxctl config.toml and .env.test files
      - Bind mount scripts for faster builds while iterating on test scripts.
    - Vale:
      - Override Acronyms style def--ignore acronym if it's linked.
pull/5530/head
Jason Stirnaman 2024-07-23 15:08:28 -05:00
parent 3a4235c27d
commit 37a7a7c6e7
34 changed files with 1002 additions and 510 deletions

View File

@ -0,0 +1,65 @@
extends: conditional
message: "Spell out '%s', if it's unfamiliar to the audience."
link: 'https://developers.google.com/style/abbreviations'
level: suggestion
ignorecase: false
# Ensures that the existence of 'first' implies the existence of 'second'.
first: '\b([A-Z]{3,5})\b'
second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)'
# ... with the exception of these:
exceptions:
- \b(\[[A-Z]{3,5})\]\(.*\)\b
- API
- ASP
- CLI
- CPU
- CSS
- CSV
- DEBUG
- DOM
- DPI
- FAQ
- GCC
- GDB
- GET
- GPU
- GTK
- GUI
- HTML
- HTTP
- HTTPS
- IDE
- JAR
- JSON
- JSX
- LESS
- LLDB
- NET
- NOTE
- NVDA
- OSS
- PATH
- PDF
- PHP
- POST
- RAM
- REPL
- RSA
- SCM
- SCSS
- SDK
- SQL
- SSH
- SSL
- SVG
- TBD
- TCP
- TODO
- URI
- URL
- USB
- UTF
- XML
- XSS
- YAML
- ZIP

View File

@ -376,4 +376,8 @@ exceptions:
- kaufmans_adaptive_moving_average
- triple_exponential_moving_average
- triple_exponential_derivative
- relative_strength_index
- relative_strength_index
# Telegraf config
- agent
- token
- urls

View File

@ -12,3 +12,4 @@ ignore:
filters:
# Allow product-specific Branding.yml configurations to handle [Ss]erverless while also allowing serverless as a valid dictionary word.
- '[Ss]erverless'

View File

@ -23,7 +23,6 @@ datasource
deduplicate
deserialize
dotenv
downsample
enum
file_groups
fullscreen

View File

@ -11,12 +11,13 @@ CLI|\/cli\/
CSV
Data Explorer
Dedup
[Dd]ownsampl(e|ed|es|ing)
Execd
ExecutionPlan
Flight SQL
FlightQuery
GBs?
Grafana
Grafana|\{\{.*grafana.*\}\}
HostURL
InfluxDB Cloud
InfluxDB OSS
@ -25,6 +26,9 @@ Influxer
JavaScript
KBs?
LogicalPlan
[Mm]axim(ize|um)
[Mm]inim(ize|um)
[Mm]onitor
MBs?
PBs?
Parquet
@ -35,7 +39,7 @@ Splunk
[Ss]uperset
TBs?
UI
URLs
URL
US (East|West|Central|North|South|Northeast|Northwest|Southeast|Southwest)
Unix
WALs?
@ -43,6 +47,8 @@ Webpack
[pP]y.*\b
\b\w+_\w+\b
\b_\w+\b
airSensors
api-endpoint
batchBucket
batchInterval
commentPrefix
@ -51,8 +57,10 @@ destinationHost
destinationOrg
destinationToken
docs-v2
exampleTag
fieldKey
fieldType
gotType
groupId
hostURL
hostUrl
@ -61,6 +69,7 @@ influxctl
influxd
influxdata.com
iox
keep-url
lat
locf
logicalplan
@ -72,8 +81,8 @@ quoteChar
retentionRules
sourceBucket
tagKey
`url[s]?`
URL
url[s]?
v2
v3
venv
wantType

2
.gitignore vendored
View File

@ -12,6 +12,6 @@ node_modules
/api-docs/redoc-static.html*
.vscode/*
.idea
config.toml
**/config.toml
package-lock.json
tmp

1
.husky/.gitignore vendored
View File

@ -1 +0,0 @@
_

60
.husky/_/build Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "build" "$@"

60
.husky/_/pre-commit Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "pre-commit" "$@"

60
.husky/_/pre-push Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "pre-push" "$@"

60
.husky/_/prepare-commit-msg Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "prepare-commit-msg" "$@"

60
.husky/_/scripts Executable file
View File

@ -0,0 +1,60 @@
#!/bin/sh
if [ "$LEFTHOOK_VERBOSE" = "1" -o "$LEFTHOOK_VERBOSE" = "true" ]; then
set -x
fi
if [ "$LEFTHOOK" = "0" ]; then
exit 0
fi
call_lefthook()
{
if test -n "$LEFTHOOK_BIN"
then
"$LEFTHOOK_BIN" "$@"
elif lefthook -h >/dev/null 2>&1
then
lefthook "$@"
else
dir="$(git rev-parse --show-toplevel)"
osArch=$(uname | tr '[:upper:]' '[:lower:]')
cpuArch=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
if test -f "$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook"
then
"$dir/node_modules/lefthook-${osArch}-${cpuArch}/bin/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook/bin/lefthook-${osArch}-${cpuArch}/lefthook" "$@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook"
then
"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook" "$@"
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
"$dir/node_modules/lefthook/bin/index.js" "$@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook "$@"
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook "$@"
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook "$@"
elif swift package plugin lefthook >/dev/null 2>&1
then
swift package --disable-sandbox plugin lefthook "$@"
elif command -v mint >/dev/null 2>&1
then
mint run csjones/lefthook-plugin "$@"
elif command -v npx >/dev/null 2>&1
then
npx lefthook "$@"
else
echo "Can't find lefthook in PATH"
fi
fi
}
call_lefthook run "scripts" "$@"

View File

@ -1,6 +0,0 @@
# If you're running tests in a container that doesn't support TTY (docker run -t), you can use monitor-tests.sh to open URLs in the host's browser.
# Your test needs to redirect the URL to the test/urls.txt file--for example:
# influxctl database update /dev/null > test/urls.txt
sh ./test/src/monitor-tests.sh start
npx lint-staged --relative
sh ./test/src/monitor-tests.sh stop

View File

@ -1,118 +0,0 @@
// Lint-staged configuration. This file must export a lint-staged configuration object.
function pytestStagedContent(paths, productPath) {
const productName = productPath.replace(/\//g, '-');
const CONTENT = `staged-${productName}`;
const TEST = `pytest-${productName}`;
return [
// Remove existing containers
`sh -c "docker rm -f ${CONTENT} || true"`,
`sh -c "docker rm -f ${TEST} || true"`,
`docker build . -f Dockerfile.tests -t influxdata-docs/tests:latest`,
// Remove any existing Docker volume for staged content
`sh -c "docker volume rm -f ${CONTENT} || true"`,
// Create a Docker volume for product staged content
`sh -c "docker volume create \
--label tag=influxdata-docs \
--label stage=test \
--name ${CONTENT} || true"`,
// Copy staged content to a volume and run the prepare script
// to remove the existing
`docker run --name ${CONTENT}
--label tag=influxdata-docs
--label stage=test
--mount type=volume,source=${CONTENT},target=/app/content
--mount type=bind,src=./content,dst=/src/content
--mount type=bind,src=./static/downloads,dst=/app/data
influxdata-docs/tests --files "${paths.join(' ')}"`,
`docker build .
-f Dockerfile.pytest
-t influxdata-docs/pytest:latest`,
// Create a Docker volume for temporary files generated during testing
`sh -c "docker volume create \
--label tag=influxdata-docs \
--label stage=test \
--name test-tmp || true"`,
// Run test runners.
// Uses a pytest plugin to suppress exit code 5 (if no tests are found),
// This avoids needing to "pre-run" test collection in a subshell to check the exit code.
// Instead of the plugin, we could use a placeholder test that always or conditionally passes.
// Whether tests pass or fail, the container is removed,
// but the CONTENT container and associated volume will remain until the next run.
// Run pytest with:
// -s to make pytest output log info during the test (instead of after).
// --suppress-no-test-exit-code to suppress exit code 5 (no tests collected).
// --exitfirst to stop after the first failure.
// --codeblocks to test code blocks in markdown files.
// Run
`docker run --tty=true --label tag=influxdata-docs --label stage=test \
--name ${TEST} \
--env-file ${productPath}/.env.test \
--volumes-from ${CONTENT} \
--mount type=bind,src=./test/shared,dst=/shared \
--mount type=volume,source=test-tmp,target=/app/iot-starter \
influxdata-docs/pytest -s --codeblocks --suppress-no-test-exit-code --exitfirst ${productPath}/`,
];
}
// Export a lint-staged configuration object.
// Run tests and linters on staged files.
export default {
"*.{js,css}": paths => `prettier --write ${paths.join(' ')}`,
"*.md": paths => `.ci/vale/vale.sh --config .vale.ini ${paths} --min|| true`,
"content/influxdb/api-docs/": paths =>
`.ci/vale/vale.sh --config .vale.ini --minAlertLevel error ${paths}`,
"content/influxdb/cloud/**/*.md":
paths => [
`.ci/vale/vale.sh --config .vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/influxdb/cloud'),
],
"content/influxdb/cloud-dedicated/**/*.md":
paths => [
`.ci/vale/vale.sh --config content/influxdb/cloud-dedicated/.vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/influxdb/cloud-dedicated'),
],
"content/influxdb/cloud-serverless/**/*.md":
paths => [
`.ci/vale/vale.sh --config content/influxdb/cloud-serverless/.vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/influxdb/cloud-serverless'),
],
"content/influxdb/clustered/**/*.md":
paths => [
`.ci/vale/vale.sh --config content/influxdb/clustered/.vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/influxdb/clustered'),
],
"content/influxdb/v1/**/*.md":
paths => [
`.ci/vale/vale.sh --config .vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/influxdb/v1'),
],
"content/influxdb/v2/**/*.md":
paths => [
`.ci/vale/vale.sh --config .vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/influxdb/v2'),
],
"content/telegraf/**/*.md":
paths => [
`.ci/vale/vale.sh --config .vale.ini --minAlertLevel error ${paths}`,
...pytestStagedContent(paths, 'content/telegraf'),
],
}

View File

@ -9,6 +9,7 @@ Packages = Google, write-good, Hugo
[*.md]
BasedOnStyles = Vale, InfluxDataDocs, Google, write-good
Google.Acronyms = NO
Google.DateFormat = NO
Google.Ellipses = NO
Google.Headings = NO

View File

@ -1,9 +1,22 @@
FROM golang:latest
### Install InfluxDB clients for testing
# Install InfluxDB keys to verify client installs.
# Follow the install instructions (https://docs.influxdata.com/telegraf/v1/install/?t=curl), except for sudo (which isn't available in Docker).
# influxdata-archive_compat.key GPG fingerprint:
# 9D53 9D90 D332 8DC7 D6C8 D3B9 D8FF 8E1F 7DF8 B07E
ADD https://repos.influxdata.com/influxdata-archive_compat.key ./influxdata-archive_compat.key
RUN echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
RUN echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | tee /etc/apt/sources.list.d/influxdata.list
# Install InfluxDB clients to use in tests.
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
curl \
git \
gpg \
influxdb2-cli \
influxctl \
jq \
maven \
nodejs \
@ -11,6 +24,8 @@ RUN apt-get update && apt-get upgrade -y && apt-get install -y \
python3 \
python3-pip \
python3-venv \
rsync \
telegraf \
wget
RUN ln -s /usr/bin/python3 /usr/bin/python
@ -26,38 +41,33 @@ ENV PYTHONUNBUFFERED=1
WORKDIR /app
# Some Python test dependencies (pytest-dotenv and pytest-codeblocks) aren't
# available as packages in apt-cache, so use pip to download dependencies in a # separate step and use Docker's caching.
# Pytest configuration file.
COPY ./test/pytest/pytest.ini pytest.ini
# Python and Pytest dependencies.
COPY ./test/pytest/requirements.txt requirements.txt
# Pytest fixtures.
COPY ./test/pytest/conftest.py conftest.py
RUN pip install -Ur requirements.txt
# Activate the Python virtual environment configured in the Dockerfile.
RUN . /opt/venv/bin/activate
ARG CONTENT_PATH
ENV CONTENT_PATH="${CONTENT_PATH}"
# Create a mock xdg-open script` to prevent the test suite from attempting to open a browser (for example, during influxctl OAuth2 authentication).
RUN echo '#!/bin/bash' > /usr/local/bin/xdg-open \
&& echo 'echo "$1" > /shared/urls.txt' >> /usr/local/bin/xdg-open \
&& chmod +x /usr/local/bin/xdg-open
# Some Python test dependencies (pytest-dotenv and pytest-codeblocks) aren't
# available as packages in apt-cache, so use pip to download dependencies in a # separate step and use Docker's caching.
# Pytest configuration file.
COPY ./test/src/pytest.ini pytest.ini
# Python and Pytest dependencies.
COPY ./test/src/requirements.txt requirements.txt
# Pytest fixtures.
COPY ./test/src/conftest.py conftest.py
RUN pip install -Ur requirements.txt
# Activate the Python virtual environment configured in the Dockerfile.
RUN . /opt/venv/bin/activate
### Install InfluxDB clients for testing
# Install InfluxDB keys to verify client installs.
# Follow the install instructions (https://docs.influxdata.com/telegraf/v1/install/?t=curl), except for sudo (which isn't available in Docker).
# influxdata-archive_compat.key GPG fingerprint:
# 9D53 9D90 D332 8DC7 D6C8 D3B9 D8FF 8E1F 7DF8 B07E
ADD https://repos.influxdata.com/influxdata-archive_compat.key ./influxdata-archive_compat.key
RUN echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
RUN echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | tee /etc/apt/sources.list.d/influxdata.list
# Install InfluxDB clients to use in tests.
RUN apt-get update && apt-get -y install telegraf influxdb2-cli influxctl
COPY --chmod=755 ./test/config.toml /root/.config/influxctl/config.toml
### End InfluxDB client installs
# Copy test scripts and make them executable.
COPY --chmod=755 ./test/scripts/parse_yaml.sh /usr/local/bin/parse_yaml
ENTRYPOINT [ "pytest" ]
CMD [ "" ]
# Specify command arguments:
# --env-file to pass environment variables to the test suite.
# the test directory to run the test suite.
CMD [ "--codeblocks", "" ]

View File

@ -12,6 +12,7 @@ COPY --chmod=755 ./test/src/prepare-content.sh /usr/local/bin/prepare-content
COPY ./data/products.yml /app/appdata/products.yml
WORKDIR /src
# In your docker run or exec command, you can set the prepare-content script as your entrypoint or command.
ENTRYPOINT [ "prepare-content" ]
# The default command is an empty string to pass all command line arguments to the entrypoint and allow the entrypoint to run.
CMD [ "" ]

View File

@ -2,12 +2,20 @@
## Run documentation tests for code samples.
name: influxdata-docs
services:
## Run InfluxData documentation with the hugo development server on port 1313.
## For more information about the hugomods/hugo image, see
## https://docker.hugomods.com/docs/development/docker-compose/
local-dev:
image: hugomods/hugo:exts-0.123.8
build:
context: .
dockerfile_inline: |
FROM hugomods/hugo:exts-0.123.8
RUN apk add --no-cache curl openssl
command: hugo server --bind 0.0.0.0
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:1313/influxdb/cloud-dedicated/"]
interval: 1m
timeout: 10s
retries: 2
start_period: 40s
start_interval: 5s
ports:
- 1313:1313
volumes:
@ -17,3 +25,317 @@ services:
- type: bind
source: $HOME/hugo_cache
target: /tmp/hugo_cache
profiles:
- local
- lint
cloud-pytest:
image: influxdata/docs-pytest
build:
args:
- CONTENT_PATH=content/influxdb/cloud
context: .
dockerfile: Dockerfile.pytest
entrypoint:
- /bin/bash
- /src/test/scripts/run-tests.sh
- pytest
command:
# In the command, pass file paths to test.
# The container preprocesses the files for testing and runs the tests.
- content/influxdb/cloud/**/*.md
profiles:
- test
- v2
stdin_open: true
tty: true
volumes:
# Site configuration files.
- type: bind
source: .
target: /src
read_only: true
# Files shared between host and container and writeable by both.
- type: bind
source: ./test/shared
target: /shared
- type: bind
source: ./content/influxdb/cloud/.env.test
target: /app/.env.test
read_only: true
# In your code samples, use `/app/data/<FILE.lp>` or `data/<FILE.lp>` to access sample data files from the `static/downloads` directory.
- type: bind
source: ./static/downloads
target: /app/data
read_only: true
# In your code samples, use `/app/iot-starter` to store example modules or project files.
- type: volume
source: cloud-tmp
target: /app/iot-starter
# Target directory for the content under test.
# Files are copied from /src/content/<productpath> to /app/content/<productpath> before running tests.
- type: volume
source: test-content
target: /app/content
working_dir: /app
cloud-dedicated-pytest:
image: influxdata/docs-pytest
build:
args:
- CONTENT_PATH=content/influxdb/cloud-dedicated
context: .
dockerfile: Dockerfile.pytest
entrypoint:
- /bin/bash
- /src/test/scripts/run-tests.sh
- pytest
command:
# In the command, pass file paths to test.
# The container preprocesses the files for testing and runs the tests.
- content/influxdb/cloud-dedicated/**/*.md
profiles:
- test
- v3
stdin_open: true
tty: true
volumes:
# Site configuration files.
- type: bind
source: .
target: /src
read_only: true
# Files shared between host and container and writeable by both.
- type: bind
source: ./test/shared
target: /shared
- type: bind
source: ./content/influxdb/cloud-dedicated/.env.test
target: /app/.env.test
read_only: true
# The following mount assumes your influxctl configuration file is located at ./content/influxdb/cloud-dedicated/config.toml.
- type: bind
source: ./content/influxdb/cloud-dedicated/config.toml
target: /root/.config/influxctl/config.toml
read_only: true
# In your code samples, use `/app/data/<FILE.lp>` or `data/<FILE.lp>` to access sample data files from the `static/downloads` directory.
- type: bind
source: ./static/downloads
target: /app/data
read_only: true
# In your code samples, use `/app/iot-starter` to store example modules or project files.
- type: volume
source: cloud-dedicated-tmp
target: /app/iot-starter
# Target directory for the content under test.
# Files are copied from /src/content/<productpath> to /app/content/<productpath> before running tests.
- type: volume
source: test-content
target: /app/content
working_dir: /app
cloud-serverless-pytest:
image: influxdata/docs-pytest
build:
args:
- CONTENT_PATH=content/influxdb/cloud-serverless
context: .
dockerfile: Dockerfile.pytest
entrypoint:
- /bin/bash
- /src/test/scripts/run-tests.sh
- pytest
command:
# In the command, pass file paths to test.
# The container preprocesses the files for testing and runs the tests.
- content/influxdb/cloud-serverless/**/*.md
profiles:
- test
- v3
stdin_open: true
tty: true
volumes:
# Site configuration files.
- type: bind
source: .
target: /src
read_only: true
# Files shared between host and container and writeable by both.
- type: bind
source: ./test/shared
target: /shared
- type: bind
source: ./content/influxdb/cloud-serverless/.env.test
target: /app/.env.test
read_only: true
# In your code samples, use `/app/data/<FILE.lp>` or `data/<FILE.lp>` to access sample data files from the `static/downloads` directory.
- type: bind
source: ./static/downloads
target: /app/data
read_only: true
# In your code samples, use `/app/iot-starter` to store example modules or project files.
- type: volume
source: cloud-serverless-tmp
target: /app/iot-starter
# Target directory for the content under test.
# Files are copied from /src/content/<productpath> to /app/content/<productpath> before running tests.
- type: volume
source: test-content
target: /app/content
working_dir: /app
clustered-pytest:
image: influxdata/docs-pytest
build:
args:
- CONTENT_PATH=content/influxdb/clustered
context: .
dockerfile: Dockerfile.pytest
entrypoint:
- /bin/bash
- /src/test/scripts/run-tests.sh
- pytest
command:
# In the command, pass file paths to test.
# The container preprocesses the files for testing and runs the tests.
- content/influxdb/clustered/**/*.md
profiles:
- test
- v3
stdin_open: true
tty: true
volumes:
# Site configuration files.
- type: bind
source: .
target: /src
read_only: true
# Files shared between host and container and writeable by both.
- type: bind
source: ./test/shared
target: /shared
- type: bind
source: ./content/influxdb/clustered/.env.test
target: /app/.env.test
read_only: true
# The following mount assumes your influxctl configuration file is located at ./content/influxdb/clustered/config.toml.
- type: bind
source: ./content/influxdb/clustered/config.toml
target: /root/.config/influxctl/config.toml
read_only: true
# In your code samples, use `/app/data/<FILE.lp>` or `data/<FILE.lp>` to access sample data files from the `static/downloads` directory.
- type: bind
source: ./static/downloads
target: /app/data
read_only: true
# In your code samples, use `/app/iot-starter` to store example modules or project files.
- type: volume
source: clustered-tmp
target: /app/iot-starter
# Target directory for the content under test.
# Files are copied from /src/content/<productpath> to /app/content/<productpath> before running tests.
- type: volume
source: test-content
target: /app/content
working_dir: /app
telegraf-pytest:
image: influxdata/docs-pytest
build:
args:
- CONTENT_PATH=content/telegraf
context: .
dockerfile: Dockerfile.pytest
entrypoint:
- /bin/bash
- /src/test/scripts/run-tests.sh
- pytest
command:
# In the command, pass file paths to test.
# The container preprocesses the files for testing and runs the tests.
- content/telegraf/**/*.md
profiles:
- test
stdin_open: true
tty: true
volumes:
# Site configuration files.
- type: bind
source: .
target: /src
read_only: true
# Files shared between host and container and writeable by both.
- type: bind
source: ./test/shared
target: /shared
- type: bind
source: ./content/telegraf/.env.test
target: /app/.env.test
read_only: true
# In your code samples, use `/app/data/<FILE.lp>` or `data/<FILE.lp>` to access sample data files from the `static/downloads` directory.
- type: bind
source: ./static/downloads
target: /app/data
read_only: true
# In your code samples, use `/app/iot-starter` to store example modules or project files.
- type: volume
source: telegraf-tmp
target: /app/iot-starter
# Target directory for the content under test.
# Files are copied from /src/content/<productpath> to /app/content/<productpath> before running tests.
- type: volume
source: test-content
target: /app/content
working_dir: /app
v2-pytest:
image: influxdata/docs-pytest
build:
args:
- CONTENT_PATH=content/influxdb/v2
context: .
dockerfile: Dockerfile.pytest
entrypoint:
- /bin/bash
- /src/test/scripts/run-tests.sh
- pytest
command:
# In the command, pass file paths to test.
# The container preprocesses the files for testing and runs the tests.
- content/influxdb/v2/**/*.md
profiles:
- test
- v2
stdin_open: true
tty: true
volumes:
# Site configuration files.
- type: bind
source: .
target: /src
read_only: true
# Files shared between host and container and writeable by both.
- type: bind
source: ./test/shared
target: /shared
- type: bind
source: ./content/influxdb/v2/.env.test
target: /app/.env.test
read_only: true
# In your code samples, use `/app/data/<FILE.lp>` or `data/<FILE.lp>` to access sample data files from the `static/downloads` directory.
- type: bind
source: ./static/downloads
target: /app/data
read_only: true
# In your code samples, use `/app/iot-starter` to store example modules or project files.
- type: volume
source: v2-tmp
target: /app/iot-starter
# Target directory for the content under test.
# Files are copied from /src/content/<productpath> to /app/content/<productpath> before running tests.
- type: volume
source: test-content
target: /app/content
working_dir: /app
volumes:
test-content:
cloud-tmp:
cloud-dedicated-tmp:
cloud-serverless-tmp:
clustered-tmp:
telegraf-tmp:
v2-tmp:

View File

@ -9,6 +9,7 @@ Packages = Google, write-good, Hugo
[*.md]
BasedOnStyles = Vale, InfluxDataDocs, Cloud-Dedicated, Google, write-good
Google.Acronyms = NO
Google.DateFormat = NO
Google.Ellipses = NO
Google.Headings = NO

View File

@ -9,6 +9,7 @@ Packages = Google, write-good, Hugo
[*.md]
BasedOnStyles = Vale, InfluxDataDocs, Cloud-Serverless, Google, write-good
Google.Acronyms = NO
Google.DateFormat = NO
Google.Ellipses = NO
Google.Headings = NO

View File

@ -9,6 +9,7 @@ Packages = Google, write-good, Hugo
[*.md]
BasedOnStyles = Vale, InfluxDataDocs, Clustered, Google, write-good
Google.Acronyms = NO
Google.DateFormat = NO
Google.Ellipses = NO
Google.Headings = NO

106
lefthook.yml Normal file
View File

@ -0,0 +1,106 @@
# Refer for explanation to following link:
# https://github.com/evilmartians/lefthook/blob/master/docs/configuration.md
#
pre-push:
commands:
packages-audit:
tags: frontend security
run: yarn audit
pre-commit:
parallel: true
commands:
cloud-lint:
tags: lint v2
glob: "content/influxdb/cloud/**/*.md"
run: '.ci/vale/vale.sh
-config=.vale.ini
--minAlertLevel=error {staged_files}'
cloud-dedicated-lint:
tags: lint v3
glob: "content/influxdb/cloud-dedicated/**/*.md"
run: '.ci/vale/vale.sh
--config=content/influxdb/cloud-dedicated/.vale.ini
--minAlertLevel=error {staged_files}'
cloud-serverless-lint:
tags: lint v3
glob: "content/influxdb/cloud-serverless/**/*.md"
run: '.ci/vale/vale.sh
--config=content/influxdb/cloud-serverless/.vale.ini
--minAlertLevel=error {staged_files}'
clustered-lint:
tags: lint v3
glob: "content/influxdb/clustered/**/*.md"
run: '.ci/vale/vale.sh
--config=content/influxdb/cloud-serverless/.vale.ini
--minAlertLevel=error {staged_files}'
telegraf-lint:
tags: lint clients
glob: "content/telegraf/**/*.md"
run: '.ci/vale/vale.sh
--config=.vale.ini
--minAlertLevel=error {staged_files}'
v2-lint:
tags: lint v2
glob: "content/influxdb/v2/**/*.md"
run: '.ci/vale/vale.sh
--config=.vale.ini
--minAlertLevel=error {staged_files}'
cloud-pytest:
glob: content/influxdb/cloud/**/*.md
tags: test codeblocks v2
env:
- SERVICE: cloud-pytest
run: docker compose run $SERVICE '{staged_files}'
cloud-dedicated-pytest:
tags: test codeblocks v3
glob: content/influxdb/cloud-dedicated/**/*.md
env:
- SERVICE: cloud-dedicated-pytest
run: |
./test/scripts/monitor-tests.sh start $SERVICE ;
docker compose run $SERVICE {staged_files} ;
./test/scripts/monitor-tests.sh stop $SERVICE
cloud-serverless-pytest:
tags: test codeblocks v3
glob: content/influxdb/cloud-serverless/**/*.md
env:
- SERVICE: cloud-serverless-pytest
run: docker compose run $SERVICE '{staged_files}'
clustered-pytest:
tags: test codeblocks v3
glob: content/influxdb/clustered/**/*.md
env:
- SERVICE: clustered-pytest
run: |
./test/scripts/monitor-tests.sh start $SERVICE ;
docker compose run $SERVICE {staged_files} ;
./test/scripts/monitor-tests.sh stop $SERVICE
telegraf-pytest:
tags: test codeblocks
glob: content/telegraf/**/*.md
env:
- SERVICE: telegraf-pytest
run: docker compose run $SERVICE '{staged_files}'
v2-pytest:
tags: test codeblocks v2
glob: content/influxdb/v2/**/*.md
env:
- SERVICE: v2-pytest
run: docker compose run $SERVICE '{staged_files}'
prettier:
tags: frontend style
glob: "*.{css,js,ts,jsx,tsx}"
run: yarn prettier {staged_files}
build:
commands:
prune-legacy-containers:
priority: 1
tags: test
run: '(docker container ls --format "{{.ID}}"
--filter label=tag=influxdata-docs
--filter status=exited | xargs docker rm)
|| true'
rebuild-test-images:
tags: test
run: docker compose build pytest-codeblocks

View File

@ -5,11 +5,10 @@
"description": "InfluxDB documentation",
"license": "MIT",
"devDependencies": {
"@evilmartians/lefthook": "^1.7.1",
"@vvago/vale": "^3.4.2",
"autoprefixer": ">=10.2.5",
"hugo-extended": ">=0.101.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.5",
"postcss": ">=8.4.31",
"postcss-cli": ">=9.1.0",
"prettier": "^3.2.5",
@ -20,15 +19,9 @@
"js-yaml": "^4.1.0"
},
"scripts": {
"lint-cloud": "git diff --name-only --diff-filter=d HEAD | grep \"content/influxdb/cloud\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=.vale.ini",
"lint-clustered": "git diff --name-only --diff-filter=d HEAD | grep \"content/influxdb/clustered\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=content/influxdb/clustered/.vale.ini",
"lint-dedicated": "git diff --name-only --diff-filter=d HEAD | grep \"content/influxdb/cloud-dedicated\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=content/influxdb/cloud-dedicated/.vale.ini",
"lint-serverless": "git diff --name-only --diff-filter=d HEAD | grep \"content/influxdb/cloud-serverless\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=content/influxdb/cloud-serverless/.vale.ini",
"lint-telegraf": "git diff --name-only --diff-filter=d HEAD | grep \"content/telegraf\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=.vale.ini",
"lint-v1": "git diff --name-only --diff-filter=d HEAD | grep \"content/influxdb/v1\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=.vale.ini",
"lint-v2": "git diff --name-only --diff-filter=d HEAD | grep \"content/influxdb/v2\" | xargs .ci/vale/vale.sh --minAlertLevel=suggestion --config=.vale.ini",
"prepare": "husky",
"test": "lint-staged --relative"
"lint": "LEFTHOOK_EXCLUDE=test lefthook run pre-commit && lefthook run pre-push",
"pre-commit": "lefthook run pre-commit",
"test-content": "docker compose --profile test up"
},
"main": "index.js",
"module": "main.js",

2
test/.gitignore vendored
View File

@ -2,7 +2,7 @@
/Cargo.lock
config.toml
content
monitor_urls_pid
_*_pid
node_modules
shared
tmp

View File

@ -1,9 +1,9 @@
#!/bin/bash
## This script is meant to be run on the host and monitors a file for URLs written by a container.
DOCS_ROOT=$(git rev-parse --show-toplevel)
# The file to monitor for URLs written by the container.
URL_FILE="./test/shared/urls.txt"
URL_FILE=$DOCS_ROOT/test/shared/urls.txt
# Define the URL pattern for OAuth2 authorization.
OAUTH_PATTERN='https://auth\.influxdata\.com/activate\?user_code=[A-Z]{1,8}-[A-Z]{1,8}'

43
test/scripts/monitor-tests.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
CONTEXT=$(git rev-parse --show-toplevel)
function start() {
pid_file=$1
$CONTEXT/test/scripts/monitor-container-urls.sh & echo $! >> "$pid_file"
}
function kill_processes() {
pid_file=$1
# Kill all processes in the monitor_urls_pid file
echo "Cleaning up monitor-container-urls processes..."
while read -r PID; do
kill $PID 2>/dev/null; ps -p $PID > /dev/null
if [ $? -ne 0 ]; then
sed -i '' "/$PID/d" "$pid_file"
echo "Successfully stopped monitor-container-urls process $PID"
else
# Leave it in the file to try stopping it again next time
# and output the error message
echo "Failed to stop monitor-container-urls process $PID"
fi
done < "$pid_file"
}
function get_pid_path() {
TMP_DIR="${CONTEXT}/test/tmp"
mkdir -p $TMP_DIR
echo "${TMP_DIR}/_${1}_monitor_urls_pid"
}
case "$1" in
start)
test_name=$2
start "$(get_pid_path $test_name)"
;;
stop)
test_name=$2
kill_processes "$(get_pid_path $test_name)"
;;
*) echo "Usage: $0 {start TEST_NAME|stop TEST_NAME}" ;;
esac

View File

@ -2,9 +2,7 @@
# This script is used to run tests for the InfluxDB documentation.
# The script is designed to be run in a Docker container. It is used to substitute placeholder values in test files.
TEST_CONTENT="/app/content"
# Pattern to match a 10-digit Unix timestamp
TIMESTAMP_PATTERN='[0-9]{10}'
@ -17,7 +15,6 @@ function substitute_placeholders {
# echo "PRETEST: substituting values in $file"
# Replaces placeholder values with environment variable references.
# Date-specific replacements.
grep -oE "$TIMESTAMP_PATTERN" "$file" | while read -r timestamp; do
@ -62,7 +59,7 @@ function substitute_placeholders {
s/f"DATABASE_TOKEN"/os.getenv("INFLUX_TOKEN")/g;
s/f"get-started"/os.getenv("INFLUX_DATABASE")/g;
s|f"{{< influxdb/host >}}"|os.getenv("INFLUX_HOSTNAME")|g;
s/f"MANAGEMENT_TOKEN"/os.getenv("MANAGEMENT_TOKEN")/g;
s/f"MANAGEMENT_TOKEN"/os.getenv("INFLUX_MANAGEMENT_TOKEN")/g;
s|f"RETENTION_POLICY_NAME\|RETENTION_POLICY"|"autogen"|g;
' $file
@ -80,12 +77,13 @@ function substitute_placeholders {
/os.getenv("BUCKET_ID")/! s/--bucket-id BUCKET_ID/--bucket-id $INFLUX_BUCKET_ID/g;
/os.getenv("BUCKET_NAME")/! s/BUCKET_NAME/$INFLUX_DATABASE/g;
/os.getenv("CLUSTER_ID")/! s/CLUSTER_ID/$CLUSTER_ID/g;
s/0x000000-xy00-0xy-x00-0x00y0000000/$CLUSTER_ID/g;
/os.getenv("DATABASE_TOKEN")/! s/DATABASE_TOKEN/$INFLUX_TOKEN/g;
/os.getenv("DATABASE_NAME")/! s/DATABASE_NAME/$INFLUX_DATABASE/g;
s/--id DBRP_ID/--id $INFLUX_DBRP_ID/g;
s/example-db/$INFLUX_DATABASE/g;
s/get-started/$INFLUX_DATABASE/g;
/os.getenv("MANAGEMENT_TOKEN")/! s/MANAGEMENT_TOKEN/$MANAGEMENT_TOKEN/g;
/os.getenv("MANAGEMENT_TOKEN")/! s/INFLUX_MANAGEMENT_TOKEN/$MANAGEMENT_TOKEN/g;
/os.getenv("ORG_ID")/! s/ORG_ID/$INFLUX_ORG/g;
/os.getenv("RETENTION_POLICY")/! s/RETENTION_POLICY_NAME\|RETENTION_POLICY/$INFLUX_RETENTION_POLICY/g;
s/CONFIG_NAME/CONFIG_$(shuf -i 0-100 -n1)/g;
@ -111,8 +109,9 @@ function substitute_placeholders {
}
setup() {
# Set up the environment for the tests.
# Parse YAML config files into dotenv files to be used by tests.
parse_yaml /app/appdata/products.yml > /app/appdata/.env.products
mkdir -p /app/appdata && (parse_yaml /src/data/products.yml > /app/appdata/.env.products)
# Miscellaneous test setup.
# For macOS samples.
@ -120,30 +119,17 @@ setup() {
}
prepare_tests() {
TEST_FILES="$*"
echo "Preparing test files: $*"
SRC_FILES="$*"
# Copy the test files to the target directory while preserving the directory structure.
for FILE in $TEST_FILES; do
# Create the parent directories of the destination file
#mkdir -p "$(dirname "$TEST_TARGET/$FILE")"
# Copy the file
rsync -avz --relative --log-file=./test.log "$FILE" /app/
cd /src
for FILE in $SRC_FILES; do
rsync -az --relative "$FILE" /app/
done
cd /app
substitute_placeholders
setup
}
# If arguments were passed and the first argument is not --files, run the command. This is useful for running "/bin/bash" for debugging the container.
# If --files is passed, prepare all remaining arguments as test files.
# Otherwise (no arguments), run the setup function and return existing files to be tested.
if [ "$1" != "--files" ]; then
echo "Executing $0 without --files argument."
"$@"
fi
if [ "$1" == "--files" ]; then
shift
prepare_tests "$@"
fi
setup
# Return new or existing files to be tested.
find "$TEST_CONTENT" -type f -name '*.md'
prepare_tests "$*"

34
test/scripts/run-tests.sh Normal file
View File

@ -0,0 +1,34 @@
#!/bin/bash
# This script is used to run Pytest for the InfluxDB documentation.
# Required arguments:
# - A space-separated list of file paths--the files to test--as unnamed arguments.
src_path=""
if [[ $CONTENT_PATH =~ ^content/. ]]; then
# Find the source content path in the container.
src_path=$(find "/src/${CONTENT_PATH}" -type d)
fi
if [[ ! $src_path ]]; then
echo "The CONTENT_PATH variable must reference a directory inside content/."
exit 1
fi
runner="$1"
tests="${*:2}"
rm -rf /app/"${CONTENT_PATH}"/*
bash /src/test/scripts/prepare-content.sh $tests
if [[ $runner == "pytest" ]]; then
pytest \
-s \
--codeblocks \
--suppress-no-test-exit-code \
--exitfirst \
--envfile=/app/.env.test \
$tests
fi

View File

@ -1,26 +0,0 @@
pid_file=./test/monitor_urls_pid
function start {
./test/src/monitor-container-urls.sh & echo $! >> "$pid_file"
}
function kill_processes {
# Kill all processes in the monitor_urls_pid file
echo "Cleaning up monitor-container-urls processes..."
while read -r PID; do
kill $PID 2>/dev/null; ps -p $PID > /dev/null
if [ $? -ne 0 ]; then
sed -i '' "/$PID/d" "$pid_file"
echo "Successfully stopped monitor-container-urls process $PID"
else
# Leave it in the file to try stopping it again next time
# and output the error message
echo "Failed to stop monitor-container-urls process $PID"
fi
done < "$pid_file"
}
case "$1" in
start) start ;;
stop) kill_processes ;;
*) echo "Usage: $0 {start|stop}" ;;
esac

324
yarn.lock
View File

@ -25,6 +25,11 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@evilmartians/lefthook@^1.7.1":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@evilmartians/lefthook/-/lefthook-1.7.1.tgz#9278070fcfc0b03acaaa5d4fb1ccfd11527b7adf"
integrity sha512-Wp8DaTMHZM1tUV4Mow6nG+6zq+giruD5054zHmFIDLXlPQxqYxnZMqJg0aYxe16vYwqFmH6NIClEMRdtGucO0Q==
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz"
@ -45,7 +50,7 @@
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@ -100,11 +105,6 @@
tar "^6.1.15"
unzipper "^0.10.14"
ansi-escapes@^6.2.0:
version "6.2.1"
resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz"
integrity sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
@ -129,7 +129,7 @@ ansi-styles@^4.0.0:
dependencies:
color-convert "^2.0.1"
ansi-styles@^6.0.0, ansi-styles@^6.1.0, ansi-styles@^6.2.1:
ansi-styles@^6.1.0:
version "6.2.1"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
@ -236,7 +236,7 @@ braces@^3.0.3, braces@~3.0.2:
dependencies:
fill-range "^7.1.1"
browserslist@^4.23.0, "browserslist@>= 4.21.0":
browserslist@^4.23.0:
version "4.23.0"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz"
integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==
@ -338,7 +338,7 @@ chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^5.0.0, chalk@~5.3.0:
chalk@^5.0.0:
version "5.3.0"
resolved "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz"
integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==
@ -363,21 +363,6 @@ chownr@^2.0.0:
resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
cli-cursor@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz"
integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==
dependencies:
restore-cursor "^4.0.0"
cli-truncate@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz"
integrity sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==
dependencies:
slice-ansi "^5.0.0"
string-width "^7.0.0"
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz"
@ -401,21 +386,16 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
colorette@^2.0.20:
version "2.0.20"
resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz"
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
@ -428,11 +408,6 @@ commander@^2.19.0, commander@^2.8.1:
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@~12.1.0:
version "12.1.0"
resolved "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz"
integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
@ -443,7 +418,7 @@ core-util-is@~1.0.0:
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cross-spawn@^7.0.0, cross-spawn@^7.0.3:
cross-spawn@^7.0.0:
version "7.0.3"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@ -459,7 +434,7 @@ crypto-random-string@^4.0.0:
dependencies:
type-fest "^1.0.1"
debug@^4.3.4, debug@~4.3.4:
debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@ -563,11 +538,6 @@ electron-to-chromium@^1.4.668:
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.784.tgz"
integrity sha512-9CZwh+sDrhDAeOEFh8s3PqwduzTyYIeYwZolc1b9ENAUt3ePu7R1sJSCWr/820ISssRxCJUyHI9Wb7j+0Uo1AA==
emoji-regex@^10.3.0:
version "10.3.0"
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz"
integrity sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
@ -602,26 +572,6 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
eventemitter3@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz"
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
execa@~8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz"
integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==
dependencies:
cross-spawn "^7.0.3"
get-stream "^8.0.1"
human-signals "^5.0.0"
is-stream "^3.0.0"
merge-stream "^2.0.0"
npm-run-path "^5.1.0"
onetime "^6.0.0"
signal-exit "^4.1.0"
strip-final-newline "^3.0.0"
fast-glob@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz"
@ -760,21 +710,16 @@ get-caller-file@^2.0.5:
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-east-asian-width@^1.0.0:
version "1.2.0"
resolved "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz"
integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==
get-stdin@=8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz"
integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==
get-stdin@^9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz"
integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==
get-stdin@=8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz"
integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==
get-stream@^2.2.0:
version "2.3.1"
resolved "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz"
@ -788,11 +733,6 @@ get-stream@^6.0.1:
resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
get-stream@^8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz"
integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==
glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
@ -898,16 +838,6 @@ hugo-extended@>=0.101.0:
log-symbols "^5.1.0"
read-pkg-up "^9.1.0"
human-signals@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz"
integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==
husky@^9.0.11:
version "9.0.11"
resolved "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz"
integrity sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
@ -926,7 +856,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@~2.0.0, inherits@~2.0.3, inherits@2:
inherits@2, inherits@~2.0.0, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -960,18 +890,6 @@ is-fullwidth-code-point@^3.0.0:
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-fullwidth-code-point@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz"
integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==
is-fullwidth-code-point@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz"
integrity sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==
dependencies:
get-east-asian-width "^1.0.0"
is-glob@^4.0.1, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
@ -1071,7 +989,7 @@ keyv@^4.5.3:
dependencies:
json-buffer "3.0.1"
lilconfig@^3.1.1, lilconfig@~3.1.1:
lilconfig@^3.1.1:
version "3.1.1"
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz"
integrity sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==
@ -1081,39 +999,11 @@ lines-and-columns@^1.1.6:
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lint-staged@^15.2.5:
version "15.2.5"
resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.5.tgz"
integrity sha512-j+DfX7W9YUvdzEZl3Rk47FhDF6xwDBV5wwsCPw6BwWZVPYJemusQmvb9bRsW23Sqsaa+vRloAWogbK4BUuU2zA==
dependencies:
chalk "~5.3.0"
commander "~12.1.0"
debug "~4.3.4"
execa "~8.0.1"
lilconfig "~3.1.1"
listr2 "~8.2.1"
micromatch "~4.0.7"
pidtree "~0.6.0"
string-argv "~0.3.2"
yaml "~2.4.2"
listenercount@~1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz"
integrity sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==
listr2@~8.2.1:
version "8.2.1"
resolved "https://registry.npmjs.org/listr2/-/listr2-8.2.1.tgz"
integrity sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==
dependencies:
cli-truncate "^4.0.0"
colorette "^2.0.20"
eventemitter3 "^5.0.1"
log-update "^6.0.0"
rfdc "^1.3.1"
wrap-ansi "^9.0.0"
locate-path@^7.1.0:
version "7.2.0"
resolved "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz"
@ -1129,17 +1019,6 @@ log-symbols@^5.1.0:
chalk "^5.0.0"
is-unicode-supported "^1.1.0"
log-update@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz"
integrity sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==
dependencies:
ansi-escapes "^6.2.0"
cli-cursor "^4.0.0"
slice-ansi "^7.0.0"
strip-ansi "^7.1.0"
wrap-ansi "^9.0.0"
lowercase-keys@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz"
@ -1164,17 +1043,12 @@ make-dir@^1.0.0:
dependencies:
pify "^3.0.0"
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.4, micromatch@~4.0.7:
micromatch@^4.0.4:
version "4.0.7"
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz"
integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==
@ -1194,16 +1068,6 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.52.0"
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
mimic-fn@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz"
integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
mimic-response@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz"
@ -1240,17 +1104,12 @@ minipass@^3.0.0:
dependencies:
yallist "^4.0.0"
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0":
version "7.1.2"
resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz"
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
minipass@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
minipass@^7.1.2:
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
version "7.1.2"
resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz"
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
@ -1263,11 +1122,6 @@ minizlib@^2.1.1:
minipass "^3.0.0"
yallist "^4.0.0"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
"mkdirp@>=0.5 0":
version "0.5.6"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz"
@ -1275,6 +1129,11 @@ mkdirp@^1.0.3:
dependencies:
minimist "^1.2.6"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moo@^0.5.0:
version "0.5.2"
resolved "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz"
@ -1337,13 +1196,6 @@ normalize-url@^8.0.0:
resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz"
integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==
npm-run-path@^5.1.0:
version "5.3.0"
resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz"
integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==
dependencies:
path-key "^4.0.0"
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
@ -1356,20 +1208,6 @@ once@^1.3.0, once@^1.4.0:
dependencies:
wrappy "1"
onetime@^5.1.0:
version "5.1.2"
resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
dependencies:
mimic-fn "^2.1.0"
onetime@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz"
integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
dependencies:
mimic-fn "^4.0.0"
p-cancelable@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz"
@ -1414,11 +1252,6 @@ path-key@^3.1.0:
resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-key@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz"
integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
path-scurry@^1.11.1:
version "1.11.1"
resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz"
@ -1447,11 +1280,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pidtree@~0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz"
integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
@ -1513,7 +1341,7 @@ postcss-value-parser@^4.2.0:
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.0.0, postcss@^8.1.0, postcss@>=8.0.9, postcss@>=8.4.31:
postcss@>=8.4.31:
version "8.4.38"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz"
integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
@ -1532,7 +1360,7 @@ prettier-plugin-sql@^0.18.0:
sql-formatter "^15.0.2"
tslib "^2.6.2"
prettier@^3.0.3, prettier@^3.2.5:
prettier@^3.2.5:
version "3.2.5"
resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz"
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
@ -1638,14 +1466,6 @@ responselike@^3.0.0:
dependencies:
lowercase-keys "^3.0.0"
restore-cursor@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz"
integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==
dependencies:
onetime "^5.1.0"
signal-exit "^3.0.2"
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz"
@ -1656,10 +1476,12 @@ reusify@^1.0.4:
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rfdc@^1.3.1:
version "1.3.1"
resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz"
integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==
rimraf@2:
version "2.7.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
rimraf@^5.0.0:
version "5.0.7"
@ -1668,13 +1490,6 @@ rimraf@^5.0.0:
dependencies:
glob "^10.3.7"
rimraf@2:
version "2.7.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
@ -1721,12 +1536,7 @@ shebang-regex@^3.0.0:
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
signal-exit@^3.0.2:
version "3.0.7"
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
signal-exit@^4.0.1, signal-exit@^4.1.0:
signal-exit@^4.0.1:
version "4.1.0"
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
@ -1736,22 +1546,6 @@ slash@^5.0.0, slash@^5.1.0:
resolved "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz"
integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
slice-ansi@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz"
integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==
dependencies:
ansi-styles "^6.0.0"
is-fullwidth-code-point "^4.0.0"
slice-ansi@^7.0.0:
version "7.1.0"
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz"
integrity sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==
dependencies:
ansi-styles "^6.2.1"
is-fullwidth-code-point "^5.0.0"
source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz"
@ -1792,18 +1586,6 @@ sql-formatter@^15.0.2:
get-stdin "=8.0.0"
nearley "^2.20.1"
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
string-argv@~0.3.2:
version "0.3.2"
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
@ -1831,14 +1613,12 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
string-width@^7.0.0:
version "7.1.0"
resolved "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz"
integrity sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
emoji-regex "^10.3.0"
get-east-asian-width "^1.0.0"
strip-ansi "^7.1.0"
safe-buffer "~5.1.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
@ -1854,7 +1634,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^7.0.1, strip-ansi@^7.1.0:
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
@ -1868,11 +1648,6 @@ strip-dirs@^2.0.0:
dependencies:
is-natural-number "^4.0.1"
strip-final-newline@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz"
integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
@ -2058,15 +1833,6 @@ wrap-ansi@^8.1.0:
string-width "^5.0.1"
strip-ansi "^7.0.1"
wrap-ansi@^9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz"
integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==
dependencies:
ansi-styles "^6.2.1"
string-width "^7.0.0"
strip-ansi "^7.1.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
@ -2087,7 +1853,7 @@ yallist@^4.0.0:
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^2.4.2, yaml@~2.4.2:
yaml@^2.4.2:
version "2.4.2"
resolved "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz"
integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==