From 6d72003446c9e879866963a2f429a5fef7d67466 Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Sat, 7 Feb 2026 19:01:02 +0200 Subject: [PATCH] fix(lint): fix all sonarcloud detected issues (#279) * fix(ci): replace broad permissions with specific scopes in workflows Replace read-all/write-all with minimum required permission scopes across all GitHub Actions workflows to follow the principle of least privilege (SonarCloud rule githubactions:S8234). * fix(shell): use [[ instead of [ for conditional tests Replace single brackets with double brackets in bash conditional expressions across 14 files (28 changes). All scripts use bash shebangs so [[ is safe everywhere (SonarCloud rule shelldre:S7688). * fix(shell): add explicit return statements to functions Add return 0 as the last statement in ~46 shell functions across 17 files that previously relied on implicit return codes (SonarCloud rule shelldre:S7682). * fix(shell): assign positional parameters to local variables Replace direct $1/$2/$3 usage with named local variables in _log(), msg(), msg_err(), msg_done(), msg_run(), msg_ok(), and array_diff() (SonarCloud rule shelldre:S7679). * fix(python): replace dict() constructor with literal Use {} instead of dict() for empty dictionary initialization (SonarCloud rule python:S7498). * fix(shell): fix husky shebang and tolerate npm outdated exit code * docs(shell): add function docstring comments * fix(shell): fix heredoc indentation in x-sonarcloud * feat(python): add ruff linter and formatter configuration * fix(ci): align megalinter config with biome, ruff, and shfmt settings * fix(ci): disable black and yaml-prettier in megalinter config * chore(ci): update ruff-pre-commit to v0.15.0 and fix hook name * fix(scripts): check for .git dir before skipping clone in install-fonts * fix(shell): address code review issues in scripts and shared.sh - Guard wezterm show-keys failure in create-wezterm-keymaps.sh - Stop masking git failures with return 0 in install-cheat-purebashbible.sh - Add missing shared.sh source in install-xcode-cli-tools.sh - Replace exit 1 with return 1 in sourced shared.sh * fix(scripts): address code review and security findings - Guard wezterm show-keys failure in create-wezterm-keymaps.sh - Stop masking git failures with return 0 in install-cheat-purebashbible.sh - Add missing shared.sh source in install-xcode-cli-tools.sh - Replace exit 1 with return 1 in sourced shared.sh - Remove shell=True subprocess calls in x-git-largest-files.py * style(shell): apply shfmt formatting and add args to pre-commit hook * fix(python): suppress bandit false positives in x-git-largest-files * fix(python): add nosemgrep suppression for check_output call * feat(format): add prettier for YAML formatting Install prettier, add .prettierrc.json config (200-char width, 2-space indent, LF endings), .prettierignore, yarn scripts (lint:prettier, fix:prettier, format:yaml), and pre-commit hook scoped to YAML files. * style(yaml): apply prettier formatting * fix(scripts): address remaining code review findings - Python: use list comprehension to filter empty strings instead of slicing off the last element - create-wezterm-keymaps: write to temp file and mv for atomic updates - install-xcode-cli-tools: fix shellcheck source directive path * fix(python): sort imports alphabetically in x-git-largest-files * fix(lint): disable PYTHON_ISORT in MegaLinter, ruff handles it * chore(git): add __pycache__ to gitignore * fix(python): rename ambiguous variable l to line (E741) * style: remove trailing whitespace and blank lines * style(fzf): apply shfmt formatting * style(shell): apply shfmt formatting * docs(plans): add design documents * style(docs): add language specifier to fenced code block * feat(lint): add markdown-table-formatter to dev tooling Add markdown-table-formatter as a dev dependency with yarn scripts (lint:md-table, fix:md-table) and a local pre-commit hook to automatically format markdown tables on commit. --- .editorconfig | 4 + .github/README.md | 6 +- .github/workflows/changelog.yml | 8 +- .github/workflows/linters.yml | 3 +- .github/workflows/new-release.yml | 8 +- .github/workflows/pre-commit-autoupdate.yml | 9 +- .github/workflows/semantic-pr.yml | 3 +- .github/workflows/sync-labels.yml | 5 +- .github/workflows/update-submodules.yml | 8 +- .gitignore | 1 + .mega-linter.yml | 9 +- .pre-commit-config.yaml | 21 ++ .prettierignore | 18 ++ .prettierrc.json | 9 + .serena/project.yml | 14 +- CLAUDE.md | 123 +++++++++ add-submodules.sh | 20 +- base/bashrc | 1 - base/zshrc | 1 - config/amethyst/amethyst.yml | 4 +- config/exports | 1 + config/fish/functions/__bass.py | 92 +++---- config/fish/functions/fisher.fish | 6 +- config/fish/themes/Catppuccin Frappe.theme | 1 - config/fish/themes/Catppuccin Macchiato.theme | 1 - config/fish/themes/Catppuccin Mocha.theme | 1 - config/fzf/completion.bash | 131 ++++++---- config/fzf/fzf.bash | 2 +- config/fzf/key-bindings.bash | 31 ++- config/gh-dash/config.yml | 2 +- config/gh/config.yml | 2 +- config/husky/init.sh | 6 +- config/shared.sh | 37 ++- config/tmux/rename-session.sh | 4 +- config/tmux/sesh.sh | 27 +- .../2026-02-04-cargo-skip-installed-design.md | 40 +++ docs/plans/2026-02-05-dfm-cleanup-design.md | 55 ++++ .../2026-02-05-x-scripts-cleanup-design.md | 46 ++++ hosts/air/install.conf.yaml | 4 +- hosts/lakka/install.conf.yaml | 4 +- hosts/s/install.conf.yaml | 4 +- hosts/tunkki/install.conf.yaml | 4 +- install | 6 +- install.conf.yaml | 4 +- local/bin/README.md | 2 +- local/bin/dfm | 10 + local/bin/git-attributes | 7 +- local/bin/git-dirty | 5 +- local/bin/msgr | 27 ++ local/bin/php-switcher | 14 +- local/bin/pushover | 3 + local/bin/x-codeql | 10 + local/bin/x-compare-versions.py | 4 +- local/bin/x-env-list | 1 + local/bin/x-git-largest-files.py | 246 ++++++++++-------- local/bin/x-multi-ping | 1 + local/bin/x-pr-comments | 3 + local/bin/x-sonarcloud | 27 +- local/bin/x-ssh-audit | 17 ++ local/bin/x-term-colors | 2 + local/bin/x-thumbgen | 4 + local/bin/x-when-down | 2 + local/bin/x-when-up | 3 + package.json | 11 +- pyproject.toml | 9 + scripts/create-nvim-keymaps.sh | 2 + scripts/create-wezterm-keymaps.sh | 16 +- scripts/install-apt-packages.sh | 46 ++-- scripts/install-cargo-packages.sh | 28 +- scripts/install-cheat-purebashbible.sh | 23 +- scripts/install-composer.sh | 4 +- scripts/install-dnf-packages.sh | 46 ++-- scripts/install-fonts.sh | 15 +- scripts/install-gh-extensions.sh | 3 + scripts/install-git-crypt.sh | 12 +- scripts/install-go-packages.sh | 19 +- scripts/install-macos-defaults.sh | 2 +- scripts/install-npm-packages.sh | 15 +- scripts/install-ntfy.sh | 5 +- scripts/install-python-packages.sh | 14 +- scripts/install-xcode-cli-tools.sh | 13 +- scripts/install-z.sh | 4 +- scripts/shared.sh | 2 +- test-all.sh | 2 +- tests/dfm.bats | 3 +- yarn.lock | 221 ++++++++++++++++ 86 files changed, 1264 insertions(+), 425 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 CLAUDE.md create mode 100644 docs/plans/2026-02-04-cargo-skip-installed-design.md create mode 100644 docs/plans/2026-02-05-dfm-cleanup-design.md create mode 100644 docs/plans/2026-02-05-x-scripts-cleanup-design.md create mode 100644 pyproject.toml diff --git a/.editorconfig b/.editorconfig index 713e73f..1ee2520 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,10 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true +[*.py] +indent_size = 4 +max_line_length = 120 + [*.fish] max_line_length = 120 diff --git a/.github/README.md b/.github/README.md index 4e0510d..0c8fff7 100644 --- a/.github/README.md +++ b/.github/README.md @@ -37,7 +37,7 @@ see what interesting stuff you've done with it. Sharing is caring. ### Interesting folders | Path | Description | -| ------------------- | -------------------------------------------- | +|---------------------|----------------------------------------------| | `.github` | GitHub Repository configuration files, meta. | | `hosts/{hostname}/` | Configs that should apply to that host only. | | `local/bin` | Helper scripts that I've collected or wrote. | @@ -52,7 +52,7 @@ is processed by Dotbot during installation. ### dotfile folders | Repo | Destination | Description | -| --------- | ----------- | ------------------------------------------- | +|-----------|-------------|---------------------------------------------| | `base/` | `.*` | `$HOME` level files. | | `config/` | `.config/` | Configurations for applications. | | `local/` | `.local/` | XDG Base folder: `bin`, `share` and `state` | @@ -86,7 +86,7 @@ The folder structure follows [XDG Base Directory Specification][xdg] where possi ### XDG Variables | Env | Default | Short description | -| ------------------ | -------------------- | ---------------------------------------------- | +|--------------------|----------------------|------------------------------------------------| | `$XDG_BIN_HOME` | `$HOME/.local/bin` | Local binaries | | `$XDG_CONFIG_HOME` | `$HOME/.config` | User-specific configs | | `$XDG_DATA_HOME` | `$HOME/.local/share` | User-specific data files | diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 1eb2b65..b5a2093 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -9,13 +9,15 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + contents: read jobs: debug-changelog: runs-on: ubuntu-latest - permissions: write-all + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -27,7 +29,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} config_file: .github/tag-changelog-config.js - - name: 'Echo results' + - name: "Echo results" id: output-changelog run: | echo "${{ steps.changelog.outputs.changes }}" diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index a5ff5d6..9499c82 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -11,7 +11,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + contents: read jobs: Linter: diff --git a/.github/workflows/new-release.yml b/.github/workflows/new-release.yml index 5cad4b6..09e36d5 100644 --- a/.github/workflows/new-release.yml +++ b/.github/workflows/new-release.yml @@ -5,19 +5,21 @@ name: Release Daily State on: workflow_dispatch: schedule: - - cron: '0 21 * * *' # 00:00 at Europe/Helsinki + - cron: "0 21 * * *" # 00:00 at Europe/Helsinki concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + contents: read jobs: new-daily-release: runs-on: ubuntu-latest - permissions: write-all + permissions: + contents: write outputs: created: ${{ steps.daily-version.outputs.created }} diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 55247ee..e17355d 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -5,14 +5,15 @@ name: Pre-commit autoupdate on: schedule: # At 04:00 on Monday and Thursday. - - cron: '0 4 * * 1,4' + - cron: "0 4 * * 1,4" workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + contents: read jobs: auto-update: @@ -33,6 +34,6 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} branch: update/pre-commit-hooks - title: 'chore: update pre-commit hooks' - commit-message: 'chore: update pre-commit hooks' + title: "chore: update pre-commit hooks" + commit-message: "chore: update pre-commit hooks" body: Update versions of pre-commit hooks to latest version. diff --git a/.github/workflows/semantic-pr.yml b/.github/workflows/semantic-pr.yml index f882012..a4e7ab8 100644 --- a/.github/workflows/semantic-pr.yml +++ b/.github/workflows/semantic-pr.yml @@ -14,7 +14,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + pull-requests: read jobs: semantic-pr: diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index aab4089..f06f615 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -11,7 +11,7 @@ on: - .github/workflows/sync-labels.yml - .github/labels.yml schedule: - - cron: '34 5 * * *' + - cron: "34 5 * * *" workflow_call: workflow_dispatch: @@ -19,7 +19,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + contents: read jobs: SyncLabels: diff --git a/.github/workflows/update-submodules.yml b/.github/workflows/update-submodules.yml index 9b304c1..8c05e85 100644 --- a/.github/workflows/update-submodules.yml +++ b/.github/workflows/update-submodules.yml @@ -5,20 +5,22 @@ name: Update submodules on: schedule: # At 04:00 on Monday and Thursday. - - cron: '0 4 * * 1' + - cron: "0 4 * * 1" workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -permissions: read-all +permissions: + contents: read jobs: update-submodules: runs-on: ubuntu-latest - permissions: write-all + permissions: + contents: write steps: - name: Checkout repository diff --git a/.gitignore b/.gitignore index 03523cf..49c8e93 100644 --- a/.gitignore +++ b/.gitignore @@ -56,5 +56,6 @@ local/man/yabai.1 local/share/fonts/* lock node_modules +__pycache__ ssh/local.d/* config/fish/fish_variables* diff --git a/.mega-linter.yml b/.mega-linter.yml index 44c5dbf..12d4f86 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -9,16 +9,21 @@ VALIDATE_ALL_CODEBASE: true FILEIO_REPORTER: false # Generate file.io report GITHUB_STATUS_REPORTER: true # Generate GitHub status report IGNORE_GENERATED_FILES: true # Ignore generated files -JAVASCRIPT_DEFAULT_STYLE: prettier # Default style for JavaScript PRINT_ALPACA: false # Print Alpaca logo in console SARIF_REPORTER: true # Generate SARIF report SHOW_SKIPPED_LINTERS: false # Show skipped linters in MegaLinter log -TYPESCRIPT_DEFAULT_STYLE: prettier # Default style for TypeScript DISABLE_LINTERS: - REPOSITORY_DEVSKIM - JAVASCRIPT_ES # using biome - JAVASCRIPT_PRETTIER # using biome + - TYPESCRIPT_PRETTIER # using biome + - JSON_PRETTIER # using biome + - PYTHON_BLACK # using ruff + - PYTHON_FLAKE8 # using ruff + - PYTHON_PYLINT # using ruff + - PYTHON_ISORT # using ruff (I rules) YAML_YAMLLINT_CONFIG_FILE: .yamllint.yml REPOSITORY_GIT_DIFF_DISABLE_ERRORS: true +BASH_SHFMT_ARGUMENTS: -i 2 -bn -ci -sr -fn FILTER_REGEX_EXCLUDE: > (node_modules|tools|config/cheat/cheatsheets/community|config/cheat/cheatsheets/tldr|config/fzf|config/zsh|config/tmux/plugins) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b9f085f..5328865 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,12 +28,25 @@ repos: entry: yarn biome check --write --files-ignore-unknown=true --no-errors-on-unmatched language: system files: \.(js|ts|jsx|tsx|json|md)$ + - id: markdown-table-formatter + name: Markdown Table Formatter + entry: yarn markdown-table-formatter + language: system + types: [markdown] - repo: https://github.com/adrienverge/yamllint rev: v1.38.0 hooks: - id: yamllint + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 + hooks: + - id: prettier + types_or: [yaml] + additional_dependencies: + - prettier@3.8.1 + - repo: https://github.com/shellcheck-py/shellcheck-py rev: v0.11.0.1 hooks: @@ -43,6 +56,7 @@ repos: rev: v3.12.0-2 hooks: - id: shfmt + args: [-i, "2", -bn, -ci, -sr, -fn, -w] - repo: https://github.com/rhysd/actionlint rev: v1.7.10 @@ -60,3 +74,10 @@ repos: hooks: - id: fish_syntax - id: fish_indent + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.0 + hooks: + - id: ruff-check + args: [--fix] + - id: ruff-format diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..0311b10 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,18 @@ +node_modules +.yarn +.pnp.* +.mypy_cache +Brewfile.lock.json +lazy-lock.json +config/cheat/cheatsheets/community +config/cheat/cheatsheets/tldr +config/fzf +config/nvim +config/op/plugins/used_plugins +config/tmux/plugins +config/vim/plugged +config/zsh +local/bin/antigen.zsh +local/bin/asdf +tools +docs/plans diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..62739f8 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "printWidth": 200, + "tabWidth": 2, + "useTabs": false, + "endOfLine": "lf", + "singleQuote": false, + "proseWrap": "preserve" +} diff --git a/.serena/project.yml b/.serena/project.yml index a0ff204..82b8167 100644 --- a/.serena/project.yml +++ b/.serena/project.yml @@ -13,11 +13,11 @@ ignore_all_files_in_gitignore: true # Was previously called `ignored_dirs`, please update your config if you are using that. # Added (renamed) on 2025-04-07 ignored_paths: - - '*.swp' - - '*.tmp' - - '*.tmp.*' - - '.DS_Store' - - '.git/**' + - "*.swp" + - "*.tmp" + - "*.tmp.*" + - ".DS_Store" + - ".git/**" - /config/cheat/cheatsheets/community/** - /config/cheat/cheatsheets/pure-bash-bible/** - /config/cheat/cheatsheets/tldr/** @@ -85,6 +85,6 @@ excluded_tools: [] # initial prompt for the project. It will always be given to the LLM upon activating the project # (contrary to the memories, which are loaded on demand). -initial_prompt: '' +initial_prompt: "" -project_name: '.dotfiles' +project_name: ".dotfiles" diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..4d88144 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,123 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) +when working with code in this repository. + +## Repository Overview + +Personal dotfiles repository for Ismo Vuorinen. +Uses **Dotbot** (not GNU Stow) to symlink configuration files into place. +The directory layout follows the XDG Base Directory Specification. + +## Directory Layout and Linking + +| Source | Destination | Notes | +|---------------------|-------------------|-------------------------------------------| +| `base/*` | `~/.*` | Home-level dotfiles (`.` added by Dotbot) | +| `config/*` | `~/.config/` | Application configurations | +| `local/bin/*` | `~/.local/bin/` | Helper scripts and utilities | +| `local/share/*` | `~/.local/share/` | Data files | +| `local/man/**` | `~/.local/man/` | Manual pages | +| `ssh/*` | `~/.ssh/` | SSH configuration (mode 0600) | +| `hosts//` | Overlays | Host-specific overrides | + +Installation: `./install` runs Dotbot with `install.conf.yaml`, +then applies `hosts//install.conf.yaml` if it exists. + +## Commands + +```bash +# Install dependencies (required before lint/test) +yarn install + +# Linting +yarn lint # Run biome + prettier + editorconfig-checker +yarn lint:biome # Biome only +yarn lint:ec # EditorConfig checker only + +# Formatting +yarn fix:biome # Autofix with biome (JS/TS/JSON/MD) +yarn fix:prettier # Autofix with prettier (YAML) +yarn format # Format with biome +yarn format:yaml # Format YAML files with prettier + +# Testing (Bats - Bash Automated Testing System) +yarn test # Run all tests in tests/ +# Run a single test file: +./node_modules/.bin/bats tests/dfm.bats + +# Shell linting +shellcheck