diff --git a/CI/linters/sqlfluff.yml b/CI/linters/sqlfluff.yml new file mode 100644 index 0000000..f26427d --- /dev/null +++ b/CI/linters/sqlfluff.yml @@ -0,0 +1,48 @@ +sqlfluff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install SQLFluff + run: pip install sqlfluff==3.4.1 + + - name: Run SQLFluff on SQL files + run: | + set -euo pipefail + + # Config detection: .sqlfluff, pyproject.toml with [tool.sqlfluff], or setup.cfg with sqlfluff section + CONFIG_FOUND=0 + + if [[ -f ".sqlfluff" ]]; then + CONFIG_FOUND=1 + elif [[ -f "pyproject.toml" ]] && grep -q '\[tool\.sqlfluff\]' pyproject.toml; then + CONFIG_FOUND=1 + elif [[ -f "setup.cfg" ]] && grep -q '\[sqlfluff\]' setup.cfg; then + CONFIG_FOUND=1 + fi + + if [[ $CONFIG_FOUND -eq 0 ]]; then + echo "::error::No SQLFluff config found (.sqlfluff, pyproject.toml [tool.sqlfluff], or setup.cfg [sqlfluff])" + exit 1 + fi + + SQL_COUNT=$(find . -type f -name "*.sql" \ + -not -path "./node_modules/*" \ + -not -path "./.git/*" \ + -not -path "./_site/*" | wc -l | tr -d ' ') + + if [[ "$SQL_COUNT" -eq 0 ]]; then + echo "⚠️ No SQL files found. Skipping." + exit 0 + fi + + if sqlfluff lint .; then + echo "✅ SQLFluff passed" + else + echo "❌ SQLFluff found issues" + exit 1 + fi diff --git a/README.md b/README.md index 4332c87..850ad7f 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ that projects compose into their own workflows. | RuboCop | linters | [CI/linters/rubocop.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/rubocop.yml) | | Ruff | linters | [CI/linters/ruff.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/ruff.yml) | | ShellCheck | linters | [CI/linters/shellcheck.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/shellcheck.yml) | +| SQLFluff | linters | [CI/linters/sqlfluff.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/sqlfluff.yml) | | Stylelint | linters | [CI/linters/stylelint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/stylelint.yml) | | SwiftLint | linters | [CI/linters/swiftlint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/swiftlint.yml) | | yamllint | linters | [CI/linters/yamllint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/yamllint.yml) | @@ -83,6 +84,7 @@ Workflows/ │ │ │ ├── rubocop.yml │ │ │ ├── ruff.yml │ │ │ ├── shellcheck.yml +│ │ │ ├── sqlfluff.yml │ │ │ ├── stylelint.yml │ │ │ ├── swiftlint.yml │ │ │ └── yamllint.yml @@ -115,6 +117,7 @@ Workflows/ │ │ ├── rubocop.sh │ │ ├── ruff.sh │ │ ├── shellcheck.sh +│ │ ├── sqlfluff.sh │ │ ├── stylelint.sh │ │ ├── swiftlint.sh │ │ └── yamllint.sh @@ -140,6 +143,7 @@ Workflows/ │ │ ├── markdownlint.bats │ │ ├── phpcs.bats │ │ ├── shellcheck.bats +│ │ ├── sqlfluff.bats │ │ ├── stylelint.bats │ │ └── yamllint.bats │ ├── security/ @@ -240,6 +244,7 @@ shellcheck: | `CI/linters/rubocop.yml` | [rubocop](https://rubocop.org) | Ruby | | `CI/linters/ruff.yml` | [ruff](https://docs.astral.sh/ruff) | Python | | `CI/linters/shellcheck.yml` | [shellcheck](https://www.shellcheck.net) | Shell scripts | +| `CI/linters/sqlfluff.yml` | [sqlfluff](https://sqlfluff.com) | SQL files | | `CI/linters/stylelint.yml` | [stylelint](https://stylelint.io) | CSS / SCSS / LESS | | `CI/linters/swiftlint.yml` | [swiftlint](https://realm.github.io/SwiftLint) | Swift | | `CI/linters/yamllint.yml` | [yamllint](https://yamllint.readthedocs.io) | YAML files | diff --git a/scripts/CI/linters/sqlfluff.yml b/scripts/CI/linters/sqlfluff.yml new file mode 100644 index 0000000..7dcc52c --- /dev/null +++ b/scripts/CI/linters/sqlfluff.yml @@ -0,0 +1,14 @@ +sqlfluff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install SQLFluff + run: pip install sqlfluff==3.4.1 + + - name: Run SQLFluff on SQL files + run: bash scripts/shell/linters/sqlfluff.sh diff --git a/scripts/shell/linters/sqlfluff.sh b/scripts/shell/linters/sqlfluff.sh new file mode 100644 index 0000000..bb616d2 --- /dev/null +++ b/scripts/shell/linters/sqlfluff.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Config detection: .sqlfluff, pyproject.toml with [tool.sqlfluff], or setup.cfg with sqlfluff section +CONFIG_FOUND=0 + +if [[ -f ".sqlfluff" ]]; then + CONFIG_FOUND=1 +elif [[ -f "pyproject.toml" ]] && grep -q '\[tool\.sqlfluff\]' pyproject.toml; then + CONFIG_FOUND=1 +elif [[ -f "setup.cfg" ]] && grep -q '\[sqlfluff\]' setup.cfg; then + CONFIG_FOUND=1 +fi + +if [[ $CONFIG_FOUND -eq 0 ]]; then + echo "::error::No SQLFluff config found (.sqlfluff, pyproject.toml [tool.sqlfluff], or setup.cfg [sqlfluff])" + exit 1 +fi + +SQL_COUNT=$(find . -type f -name "*.sql" \ + -not -path "./node_modules/*" \ + -not -path "./.git/*" \ + -not -path "./_site/*" | wc -l | tr -d ' ') + +if [[ "$SQL_COUNT" -eq 0 ]]; then + echo "⚠️ No SQL files found. Skipping." + exit 0 +fi + +if sqlfluff lint .; then + echo "✅ SQLFluff passed" +else + echo "❌ SQLFluff found issues" + exit 1 +fi diff --git a/tests/linters/sqlfluff.bats b/tests/linters/sqlfluff.bats new file mode 100644 index 0000000..3aacd8d --- /dev/null +++ b/tests/linters/sqlfluff.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats + +load "../helpers/common" + +SCRIPT="$BATS_TEST_DIRNAME/../../scripts/shell/linters/sqlfluff.sh" + +setup() { + setup_test_dir + mkdir -p "$TEST_DIR/bin" + export PATH="$TEST_DIR/bin:$PATH" +} + +teardown() { + teardown_test_dir +} + +make_sqlfluff_stub() { + local exit_code="$1" + cat > "$TEST_DIR/bin/sqlfluff" <