Skip to content

Instantly share code, notes, and snippets.

@mdeweerd
Last active January 22, 2024 10:45
Show Gist options
  • Save mdeweerd/edecd82d542b150859f65e6b73bdef79 to your computer and use it in GitHub Desktop.
Save mdeweerd/edecd82d542b150859f65e6b73bdef79 to your computer and use it in GitHub Desktop.
Script to add ignored lines to codespell configuration
#!/bin/bash
#
# Script to add codespell exceptions to the ignores lines file.
#
# The file is named '...-lines-ignore' to make TAB expansion on the cli easier.
#
# The line in the ignore file must match the line in the source
# exactly.
#
# To clean up or create the ignored lines file, just do
# ```shell
# echo > .codespell-lines-ignore.txt
# ```
# and then execute this script
#
# By default this will look for .codespell-lines-ignore.txt, best placed
# at the root of you project.
# You must then reference it in your codespell configuration:
#
# - pyproject.toml:
# exclude-file = ".codespell-lines-ignore.txt"
# - CLI:
# codespell -x .codespell-lines-ignore.txt OTHER_ARGUMENTS
#
# author: https://github.com/mdeweerd
# gist : https://gist.github.com/mdeweerd/edecd82d542b150859f65e6b73bdef79
#
#
# :warning:
#
# This script only works properly if codespell is installed for your CLI.
# If the configuration is in pyproject.toml, you also need tomli.
#
# ```shell
# python -m pip install codespell tomli
# # or
# pip install codespell tomli
# ```
codespell_ignore_file=${CODESPELL_IGNORE_FILE:=.codespell-lines-ignore.txt}
if [ -z "${0##*.sh}" ] ; then
# Suppose running from inside script
# Get real path
script=$(realpath "$(test -L "$0" && readlink "$0" || echo "$0")")
PROJECT_ROOT=$(realpath "${script}")
while [ "${PROJECT_ROOT}" != "/" ] ; do
[ -r "${PROJECT_ROOT}/${codespell_ignore_file}" ] && break
PROJECT_ROOT=$(dirname "${PROJECT_ROOT}")
done
if [ "${PROJECT_ROOT}" == "/" ] ; then
echo "Project root not found from '${script}'"
exit 1
fi
codespell_ignore_file=${PROJECT_ROOT}/${codespell_ignore_file}
fi
# Make sure we are at the root of the project
[ -r "${codespell_ignore_file}" ] || { echo "${codespell_ignore_file} not found" ; exit 1 ; }
# Then:
# - Run codespell;
# - Identify files that have fixes;
# - Limit to files under git control;
# - Run codespell on selected files;
# - For each line, create a grep command to find the lines;
# - Execute that command by evaluation
codespell . \
| sed -n -E 's@^([^:]+):.*@\1@p' \
| xargs -r git ls-files -- \
| xargs -r codespell -- \
| sed -n -E 's@^([^:]+):[[:digit:]]+:[[:space:]](\S+)[[:space:]].*@grep -P '\''\\b\2\\b'\'' -- "\1" >> '"${codespell_ignore_file}"'@p' \
| while read -r line ; do eval "$line" ; done
# Finally, sort and remove duplicates to make merges easier.
sort -u -o "${codespell_ignore_file}"{,}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment