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

bdocs: script for auto-generating redirects + general improvements #8364

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
Draft
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
101 changes: 56 additions & 45 deletions bdocs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
#!/bin/bash

# This is a bash script for interacting with the various files in './scripts/'.
# This is a wrapper script for interacting with the files in './scripts/'.
#
# Usage: ./bdocs [option]

set -e

# The project's root directory.
export PROJECT_ROOT
PROJECT_ROOT="$(dirname "$(realpath "$0")")"
# The project's root directory and redirect file.
export PROJECT_ROOT="$(dirname "$(realpath "$0")")"
export REDIRECT_FILE="./assets/js/broken_redirect_list.js"

# All scripts exported so they can source bdocs and call each other if needed.
export DEPLOY="$PROJECT_ROOT/scripts/create_deploy_text.sh"
export RELEASE="$PROJECT_ROOT/scripts/create_release_text.sh"
export TLINKS="$PROJECT_ROOT/scripts/transform_reference_links.py"
export RLINKS="$PROJECT_ROOT/scripts/remove_unused_reference_links.rb"
export CREDIRECTS="$PROJECT_ROOT/scripts/create_redirects.py"
export LREDIRECTS="$PROJECT_ROOT/scripts/list_redirect_urls.sh"

# Displays usage for bdocs
display_help() {
Expand All @@ -19,72 +27,75 @@ USAGE:
./bdocs [option]

OPTIONS:
deploy Create the deploy body text for weekly deployments
release Create the release body text for monthly releases
tlinks Transform reference links to inline links on 1 or more pages
rlinks Remove reference links that are not being used on 1 or more pages
redirects List the old URLs for all new redirects in this branch
help Display this help message and exit
deploy Create the deploy body text for weekly deployments
release Create the release body text for monthly releases
tlinks Transform reference links to inline links on 1 or more pages
rlinks Remove unused reference links on 1 or more pages
credirects Create redirects for all changed files in _docs
lredirects List the old URLs for all new redirects in this branch
help Display this help message and exit

EOF
}

# If a file or directory is required, pass or fail.
require_path_or_file() {
if [[ -z "$1" ]]; then
echo "Error: A file or directory path is required."
exit 1
fi
}

# If new merges into 'develop' are required, pass or fail.
require_new_merges() {
LATEST_COMMIT_HASH=$(git log --max-count=1 --format="%H" origin/master ^origin/develop)
COMMIT_LOGS=$(git log --first-parent "$LATEST_COMMIT_HASH"..origin/develop)
if [ -z "$COMMIT_LOGS" ]; then
echo "Error: No new merges into 'develop' since the last deployment."
exit 1
fi
}

# Check if no arguments were provided
if [[ $# -eq 0 ]]; then
display_help
exit 1
fi

# Fetch the latest changes from the remote quietly.
git fetch origin develop --quiet

# Argument parsing
case $1 in
deploy)
require_new_merges
if [[ $# -eq 3 ]]; then
"$PROJECT_ROOT/scripts/create_deploy_text.sh" "$2" "$3"
"$DEPLOY" "$2" "$3"
else
"$PROJECT_ROOT/scripts/create_deploy_text.sh"
"$DEPLOY"
fi
;;
release)
"$PROJECT_ROOT/scripts/create_release_text.sh"
require_new_merges
"$RELEASE"
;;
tlinks)
if [[ -z "$2" ]]; then
echo "Error: A file or directory path is required."
exit 1
fi
python3 "$PROJECT_ROOT/scripts/transform_reference_links.py" "$2"
echo "Success!"
while true; do
echo "Do you want to remove the unused reference links? [Y/n]."
read -r opt
case $opt in
y*|Y*)
ruby "$PROJECT_ROOT/scripts/remove_unused_reference_links.rb" "$2"
echo "Success!"
break
;;
n*|N*)
echo "The unused reference links were left untouched."
break
;;
*) echo "Error: Invalid choice."
echo ""
;;
esac
done
require_path_or_file "$2"
"$TLINKS" "$2"
"$RLINKS" "$2" # Run rlinks next, to clean up unused reference links.
;;
rlinks)
if [[ -z "$2" ]]; then
echo "Error: The path to file or directory is required."
exit 1
fi
ruby "$PROJECT_ROOT/scripts/remove_unused_reference_links.rb" "$2"
require_path_or_file "$2"
"$RLINKS" "$2"
;;
credirects)
"$CREDIRECTS"
;;
redirects)
lredirects)
if [[ $# -eq 2 ]]; then
"$PROJECT_ROOT/scripts/list_redirect_urls.sh" "$2"
"$LREDIRECTS" "$2"
else
"$PROJECT_ROOT/scripts/list_redirect_urls.sh"
"$LREDIRECTS"
fi
;;
help)
Expand Down
70 changes: 70 additions & 0 deletions scripts/create_redirects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3

# DESCRIPTION
#
# Usage: ./bdocs credirects

import re
import subprocess

# Paths (assuming these are sourced or set elsewhere in your environment)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the global vars!

redirect_file = "./assets/js/broken_redirect_list.js"
project_root = "./" # Adjust to your actual root if needed

# Using Git, get the list of files that have been renamed.
def get_changed_files():
cmd = f"git diff -M --summary develop HEAD -- {project_root}_docs"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
# Filter lines that start with "rename" or " rename"
return [line.strip() for line in result.stdout.splitlines() if line.startswith("rename") or line.startswith(" rename")]

def create_redirect(line):
# Remove everything up to and including the first space, but keep the initial underscore
line = line.split(" ", 1)[1]

# Remove any trailing `(NUM%)` from the line
line = re.sub(r"\s\(\d+%\)$", "", line)

# Get the relative paths for the old and new filenames
line_separator = line.split("{")[0].strip()

# Check if this is a directory rename (no `.md` in `{old => }/new.md` portion)
if re.search(r"{([^{}]+) => }/[^\s]+\.md", line):
# Directory-only rename handling
old_path_part, new_filename = re.search(r"{([^{}]+) => }/(.+)", line).groups()

# Construct the paths for old and new locations
old_path = f"/{line_separator}{old_path_part}/{new_filename}"
new_path = f"/{line_separator}{new_filename}"
elif re.search(r"{(.+?) => (.+?)}", line):
# Standard file rename handling with `{old => new}` pattern
unformatted_old_path, unformatted_new_path = re.search(r"{(.+?) => (.+?)}", line).groups()
old_path = f"/{line_separator}{unformatted_old_path}"
new_path = f"/{line_separator}{unformatted_new_path}"
else:
return None

# Remove leading underscores and .md extensions, and format paths
old_path = old_path.replace("/_", "/").replace(".md", "")
new_path = new_path.replace("/_", "/").replace(".md", "")

# Convert paths to the redirect syntax: validurls['OLD'] = 'NEW';
redirect = f"validurls['{old_path}'] = '{new_path}';"

return redirect

def main():
# Fetch changed files
changed_files = get_changed_files()

# Process each line and write to redirect file
with open(redirect_file, 'a') as f:
for line in changed_files:
formatted_redirect = create_redirect(line)
if formatted_redirect:
f.write(formatted_redirect + "\n")

print("Redirects added successfully!")

if __name__ == "__main__":
main()
4 changes: 2 additions & 2 deletions scripts/create_release_text.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ main() {
COMMIT_TITLE=$(echo "$commit" | jq -r '.title')
COMMIT_BODY=$(echo "$commit" | jq -r '.body')

# Print the deploy text for each deployment.
# Print the deploy text for each deployment using the sourced DEPLOY.
echo "## $COMMIT_BODY"
./scripts/create_deploy_text.sh "$PREV_COMMIT_DATE" "$COMMIT_DATE"
"$DEPLOY" "$PREV_COMMIT_DATE" "$COMMIT_DATE"
echo ""

# Get the next range of commits by increasing 'PREV_COMMIT_DATE'.
Expand Down
5 changes: 1 addition & 4 deletions scripts/list_redirect_urls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
# base URL to list all old URLs so the user can open old links directly from
# the terminal to test redirects.
#
# Usage: ./bdocs redirects

# Fetch the latest changes from the remote.
git fetch origin develop --quiet
# Usage: ./bdocs lredirects

# Check new redirects by comparing the current branch to develop.
NEW_REDIRECTS=$(git diff develop -- $PROJECT_ROOT/assets/js/broken_redirect_list.js)
Expand Down
2 changes: 2 additions & 0 deletions scripts/remove_unused_reference_links.rb
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env ruby

# Removes unused reference-style links from the bottom of a file, such as:
# [1]: {{site.baseurl}}/contributing/your_first_contribution/
#
Expand Down
2 changes: 2 additions & 0 deletions scripts/transform_reference_links.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env python3

# Converts Markdown reference links to in-line links. Created because
# reference links cannot be placed inside Liquid {% tab %} tags.
#
Expand Down