-
Notifications
You must be signed in to change notification settings - Fork 825
pre-commit autocreate Markdown report of rake -T output
#6592
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @jbampton, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request implements an automated system to keep Rake task documentation up-to-date within the repository. By integrating a new pre-commit hook, any changes to Rakefiles will trigger the regeneration of a Markdown report of rake -T output, along with its checksum, ensuring that the documentation accurately reflects the current state of available Rake tasks before a commit is finalized. This significantly improves documentation consistency and reduces manual effort.
Highlights
- New Pre-commit Hook: I've introduced a new
localpre-commit hook namedgenerate-rake-docs. This hook is designed to automatically generate and update documentation for Rake tasks. - Automated Documentation Generation: The new hook executes a Python script (
scripts/generate_rake_docs.py) which runsrake -Tto capture all available Rake tasks. This output is then formatted into a Markdown file,doc/guides/rake-tasks.md. - Checksum Verification: To ensure the integrity and synchronization of the generated documentation, the hook also calculates and stores a SHA256 checksum of
rake-tasks.mdindoc/guides/checksums/rake-tasks.md.sha256. This checksum file is also managed by the pre-commit system. - Pre-commit Configuration Updates: The
.pre-commit-config.yamlhas been updated to include the new hook, configured to run only when.rakefiles are staged. Additionally, the.editorconfigand.pre-commit-config.yamlwere adjusted to prevent theend-of-file-fixerhook from modifying the checksum files, preserving their exact content.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a pre-commit hook to generate Rake task documentation. The review suggests using language: python in .pre-commit-config.yaml for environment consistency and specifying encoding="utf-8" in scripts/generate_rake_docs.py for cross-platform compatibility. A refactoring is recommended to improve efficiency by checking checksums before regenerating files.
| def generate_markdown_file(output): | ||
| """ | ||
| Creates or updates the RAKE_TASKS.md file with the captured Rake output. | ||
| The content includes a header and the raw output embedded in a Markdown code block. | ||
| """ | ||
| print(f"Generating Markdown file: {RAKE_MD_PATH}...") | ||
| # Ensure the directory structure exists. `exist_ok=True` prevents an error if it already exists. | ||
| os.makedirs(DOCS_DIR, exist_ok=True) | ||
|
|
||
| # Construct the full Markdown content. | ||
| markdown_content = f"""# Rake Tasks | ||
|
|
||
| This file is automatically generated by a pre-commit hook. Do not edit manually. | ||
|
|
||
| ``` | ||
| {output.strip()} | ||
| ``` | ||
| """ | ||
| # Write the content to the Markdown file. | ||
| with open(RAKE_MD_PATH, "w") as f: | ||
| f.write(markdown_content) | ||
| print(f"Successfully generated {RAKE_MD_PATH}") | ||
|
|
||
| def calculate_sha256(filepath): | ||
| """ | ||
| Calculates the SHA256 hash of a given file. | ||
| Reads the file in chunks to handle potentially large files efficiently. | ||
| """ | ||
| hasher = hashlib.sha256() | ||
| # Open the file in binary read mode. | ||
| with open(filepath, "rb") as f: | ||
| # Read the file in 8KB chunks until the end. | ||
| while chunk := f.read(8192): | ||
| hasher.update(chunk) # Update the hash with each chunk. | ||
| return hasher.hexdigest() # Return the hexadecimal representation of the hash. | ||
|
|
||
| def generate_checksum_file(): | ||
| """ | ||
| Generates a SHA256 checksum file for RAKE_TASKS.md. | ||
| The checksum is stored in a separate file in the 'checksums' subdirectory. | ||
| """ | ||
| print(f"Generating checksum file: {CHECKSUM_PATH}...") | ||
| # Ensure the checksums directory exists. | ||
| os.makedirs(CHECKSUMS_DIR, exist_ok=True) | ||
|
|
||
| # Calculate the checksum of the Markdown file. | ||
| checksum = calculate_sha256(RAKE_MD_PATH) | ||
|
|
||
| # Write the checksum to its dedicated file. | ||
| with open(CHECKSUM_PATH, "w") as f: | ||
| f.write(checksum) | ||
| print(f"Successfully generated {CHECKSUM_PATH}") | ||
|
|
||
| # --- Main Execution --- | ||
|
|
||
| def main(): | ||
| """ | ||
| Main function to orchestrate the Rake documentation generation process. | ||
| """ | ||
| # Step 1: Run 'rake -T' and get its output. | ||
| rake_output = run_rake_tasks() | ||
|
|
||
| # Step 2: Generate the Markdown file with the captured Rake output. | ||
| generate_markdown_file(rake_output) | ||
|
|
||
| # Step 3: Generate the checksum file for the newly created Markdown file. | ||
| generate_checksum_file() | ||
|
|
||
| # If the script reaches this point, it means all operations (running rake, | ||
| # generating markdown, and generating checksum) were successful. | ||
| # The pre-commit framework will automatically check if these newly generated | ||
| # files are unstaged. If they are, it will fail the commit and prompt the | ||
| # user to 'git add' them. This is the standard and recommended behavior. | ||
| print("\nRake documentation generation complete.") | ||
| sys.exit(0) # Exit with 0 to indicate success to the pre-commit hook. | ||
|
|
||
| if __name__ == "__main__": | ||
| main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script regenerates documentation and checksum files on every run, even if the rake -T output is unchanged. This can be inefficient. Refactor to compare checksums and only write files if content changes. Also, specify encoding="utf-8" for file I/O.
def get_current_checksum():
"""Reads the checksum from the existing file, if it exists."""
try:
with open(CHECKSUM_PATH, "r", encoding="utf-8") as f:
return f.read().strip()
except FileNotFoundError:
return None
def write_docs(content, checksum):
"""Writes the markdown and checksum files."""
print("Writing Rake documentation files...")
os.makedirs(CHECKSUMS_DIR, exist_ok=True)
with open(RAKE_MD_PATH, "w", encoding="utf-8") as f:
f.write(content)
print(f"Successfully generated {RAKE_MD_PATH}")
with open(CHECKSUM_PATH, "w", encoding="utf-8") as f:
f.write(checksum)
print(f"Successfully generated {CHECKSUM_PATH}")
def main():
"""
Main function to orchestrate the Rake documentation generation process.
It only updates files if the Rake task list has changed.
"""
rake_output = run_rake_tasks()
markdown_content = f"""# Rake Tasks
This file is automatically generated by a pre-commit hook. Do not edit manually.{rake_output.strip()}
"""
new_checksum = hashlib.sha256(markdown_content.encode("utf-8")).hexdigest()
old_checksum = get_current_checksum()
if new_checksum == old_checksum:
print("Rake documentation is already up-to-date.")
sys.exit(0)
print("Rake documentation is outdated. Regenerating files...")
write_docs(markdown_content, new_checksum)
print("\nRake documentation generation complete.")
sys.exit(0)
if __name__ == "__main__":
main()
| # 'language: system' means pre-commit will execute the 'entry' command | ||
| # directly in your system's environment. Ensure Python is in your PATH. | ||
| language: system |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| # capture_output=True redirects stdout and stderr. | ||
| # text=True decodes stdout/stderr as text using default encoding. | ||
| # check=True raises CalledProcessError if the command returns a non-zero exit code. | ||
| result = subprocess.run(["rake", "-T"], capture_output=True, text=True, check=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The subprocess.run call uses text=True without specifying an encoding. Explicitly specify encoding="utf-8" to ensure consistent behavior across systems.
| result = subprocess.run(["rake", "-T"], capture_output=True, text=True, check=True) | |
| result = subprocess.run(["rake", "-T"], capture_output=True, text=True, check=True, encoding="utf-8") |
How it Works:
When you attempt to git commit, pre-commit will execute the generate-rake-docs hook.
It will only run this specific hook if you have staged any files that end with .rake (e.g., Rakefile, lib/tasks/my_task.rake).
The Python script (generate_rake_docs.py) will then:
Execute rake -T to get the list of Rake tasks.
Create (or update) doc/guides/RAKE_TASKS.md with this output.
Calculate the SHA256 checksum of RAKE_TASKS.md and save it to doc/guides/checksums/RAKE_TASKS.md.sha256.
After the script finishes, pre-commit automatically checks if any files in your working directory were modified by the hook and are not currently staged.
If RAKE_TASKS.md or its checksum file were updated by the script (meaning they changed since the last commit or are new) and you haven't git added them, pre-commit will fail the commit. It will print a message telling you which files need to be staged.
You then simply git add doc/guides/RAKE_TASKS.md doc/guides/checksums/RAKE_TASKS.md.sha256 and commit again. The hook will run again, find the files are now staged and up-to-date, and allow the commit to proceed.This ensures that your Rake task documentation and its checksum are always in sync with your Rakefiles before a commit is finalized.
Example below for this hook when I changed a Rake file with dummy content the hook failed and the reports were regenerated: