robotpy / examples

Repository of RobotPy example projects
43 stars 52 forks source link

Standardize robot.py styling for copyright header #93

Closed fletch3555 closed 9 months ago

virtuald commented 9 months ago

I'm fine with doing this, but it feels that if we're going to do this that we should add a check to CI to make sure it doesn't happen differently in the future?

fletch3555 commented 9 months ago

Sounds good to me. I figured I'd start with getting things lined up first. Any recommendations on how to confirm this? Just check for presence of the header through grep or similar? All done in github actions of course. Does python have an established way to check files against a defined style guide?

virtuald commented 9 months ago

These days I tend to write short custom python scripts for this sort of thing instead of shell scripts, they tend to be more obviously correct and are easier to generate user friendly error messages. I would ... tell ChatGPT to do this.

Write a python script that checks every python file in the subdirectory that the script resides in and ensures it starts with a particular string. Parse all files first, then if any files do not comply, output the list of non-compliant files and exit with an error code. Use pathlib glob to find the files.

import pathlib

def check_file_start(files, start_string):
    non_compliant_files = []

    for file_path in files:
        with open(file_path, 'r', encoding='utf-8') as file:
            first_line = file.readline().strip()
            if not first_line.startswith(start_string):
                non_compliant_files.append(file_path)

    return non_compliant_files

def main():
    # Set the directory where the script resides
    script_directory = pathlib.Path(__file__).parent

    # Specify the desired starting string
    desired_start_string = "# Your desired starting string"

    # Use pathlib and glob to find all Python files in the script's subdirectory
    python_files = script_directory.glob('*.py')

    # Check each file for compliance
    non_compliant_files = check_file_start(python_files, desired_start_string)

    # If there are non-compliant files, print the list and exit with an error code
    if non_compliant_files:
        print("Non-compliant files:")
        for file_path in non_compliant_files:
            print(file_path)
        exit(1)
    else:
        print("All files comply with the specified starting string.")

if __name__ == "__main__":
    main()

I think it would be sufficient to only check for the copyright statement. Checking the docstring isn't needed and would be more effort than it's worth. Probably should only enforce robot.py to have the #!/usr/bin/env python3 start.

virtuald commented 9 months ago

Write a python script that checks every python file in the subdirectory that the script resides in and ensures it starts with a specified set of lines. Parse all files first, then if any files do not comply, output the list of non-compliant files and exit with an error code. Use pathlib glob to find the files.

Use a different set of lines if the filename is robot.py

from pathlib import Path

def check_file_content(file_path):
    with open(file_path, 'r') as file:
        lines = file.readlines()
        if file.name.endswith('robot.py'):
            expected_lines = ["# Robot file\n", "# Author: Your Name\n", "\n"]
        else:
            expected_lines = ["# Your custom set of lines\n", "\n"]

        if lines[:len(expected_lines)] != expected_lines:
            return False
    return True

def main():
    current_directory = Path(__file__).parent
    python_files = current_directory.glob('*.py')

    non_compliant_files = [file for file in python_files if not check_file_content(file)]

    if non_compliant_files:
        print("Non-compliant files:")
        for file in non_compliant_files:
            print(f"- {file}")
        exit(1)  # Exit with an error code
    else:
        print("All files are compliant.")

if __name__ == "__main__":
    main()
fletch3555 commented 9 months ago

Hm okay. Yeah that could work. I honestly don't use ChatGPT for much at all, so it's cool to see what it comes up with.

Check my understanding here.

Does that about cover it?

virtuald commented 9 months ago

Yeah, but I'd probably add it to the existing workflow file as a new job instead of creating a new workflow.

fletch3555 commented 9 months ago

Whoops... thought I was working in my own fork, but apparently blew up the github actions job queue here with some rapid iteration and I don't have access to cancel them... That should hopefully clear up quickly.

In any case, I have a check setup called "check-file-headers" that will trigger a script (modified from what was posted above from chatgpt) to enforce the shebang in robot.py and the copyright in all. Also needed to special-case the "init.py" files because black was complaining about extra blank lines at the end, while this was requiring it. If there's a better solution, I'm all ears.