Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Markdown diff linter #879

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config:
line-length: false # Allow lines longer than 80 characters.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ ifndef LATEST_VERSION
else
./scripts/update_release_version.sh "$(LATEST_VERSION)"
endif

.PHONY: markdown-diff-lint
markdown-diff-lint:
./scripts/markdown_diff_lint.sh
98 changes: 98 additions & 0 deletions scripts/markdown_diff_lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# This script runs markdownlint-cli2 on changed files.
# Usage: ./markdown_lint.sh

set -eo pipefail

if ! command markdownlint-cli2 dummy.md &>/dev/null; then
echo "markdownlint-cli2 needs to be installed."
echo "Please refer to https://github.com/DavidAnson/markdownlint-cli2?tab=readme-ov-file#install for installation instructions."
exit 1
fi

COLOR_RED='\033[0;31m'
COLOR_BOLD='\033[1m'
COLOR_ORANGE='\033[0;33m'
COLOR_NONE='\033[0m' # No Color

function log_error {
echo -n -e "${COLOR_BOLD}${COLOR_RED}$*${COLOR_NONE}\n"
}

function log_warning {
echo -n -e "${COLOR_ORANGE}$*${COLOR_NONE}\n"
}

if [ -z "${PULL_BASE_SHA}" ]; then
echo "Empty base reference (\$PULL_BASE_SHA), assuming: main"
PULL_BASE_SHA=main
fi

if [ -z "${PULL_PULL_SHA}" ]; then
PULL_PULL_SHA="$(git rev-parse HEAD)"
echo "Empty pull reference (\$PULL_PULL_SHA), assuming: ${PULL_PULL_SHA}"
fi

MD_LINT_URL_PREFIX="https://github.com/DavidAnson/markdownlint/blob/main/doc/"

mapfile -t changed_files < <(git diff "${PULL_BASE_SHA}" --name-only)
declare -A files_with_failures start_ranges end_ranges

for file in "${changed_files[@]}"; do
if ! [[ "$file" =~ .md$ ]]; then
continue
fi

# Find start and end ranges from changed files.
start_ranges=()
end_ranges=()
# From https://github.com/paleite/eslint-plugin-diff/blob/46c5bcf296e9928db19333288457bf2805aad3b9/src/git.ts#L8-L27
ranges=$(git diff "${PULL_BASE_SHA}" \
--diff-algorithm=histogram \
--diff-filter=ACM \
--find-renames=100% \
--no-ext-diff \
--relative \
--unified=0 -- "${file}" | \
awk 'match($0, /^@@\s-[0-9,]+\s\+([0-9]+)(,([0-9]+))?/, m) { \
print m[1] ":" m[1] + ((m[3] == "") ? "0" : m[3]) }')
i=0
for range in ${ranges}; do
start_ranges["${i}"]=$(echo "${range}" | awk -F: '{print $1}')
end_ranges["${i}"]=$(echo "${range}" | awk -F: '{print $2}')
i=$((1 + i))
done
if [ -z "${ranges}" ]; then
start_ranges[0]=0
end_ranges[0]=0
fi

i=0
markdownlint-cli2 "${file}" 2>/dev/null || true
while IFS= read -r line; do
line_number=$(echo "${line}" | awk -F: '{print $2}' | awk '{print $1}')
while [ "${i}" -lt "${#end_ranges[@]}" ] && [ "${line_number}" -gt "${end_ranges["${i}"]}" ]; do
i=$((1 + i))
done
rule=$(echo "${line}" | awk 'match($2, /([^\/]+)/, m) {print tolower(m[1])}')
lint_error="${line} (${MD_LINT_URL_PREFIX}${rule}.md)"

if [ "${i}" -lt "${#start_ranges[@]}" ] && [ "${line_number}" -ge "${start_ranges["${i}"]}" ] && [ "${line_number}" -le "${end_ranges["${i}"]}" ]; then
# Inside range with changes, raise an error.
log_error "${lint_error}"
files_with_failures["${file}"]=1
else
# Outside of range, raise a warning.
log_warning "${lint_error}"
fi
done < <(markdownlint-cli2 "${file}" 2>&1 >/dev/null || true)
done

echo "Finished linting"

for file in "${!files_with_failures[@]}"; do
log_error "${file} has linting issues"
done
if [ "${#files_with_failures[@]}" -gt "0" ]; then
exit 1
fi