Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

by Chris Nelson -
Number of replies: 5

Apologies for what might be a very silly question, but we have installed Ruff on our instance of CodeRunner (we know it's installed), but we cannot work out how to use get it running. Unless it's just incompatible(?).

Can anyone help, please?

In reply to Chris Nelson

Re: Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

by Richard Lobb -
You have installed it on Jobe, not on Moodle, I assume?

To use it, you need to modify the template to run the student answer with ruff before executing it. You should create a new question type, e.g. python3_ruff - check out the documentation if you're unfamiliar with how to do that.

The simplest possible modification to the standard python3 template would be something like the following:

import subprocess
SEPARATOR = "#<ab@17943918#@>#"

# Write the student answer to a file, check it with ruff
__student_answer__ = """{{ STUDENT_ANSWER | e('py') }}"""
with open("__student_answer__.py", "w") as outfile:
    outfile.write(__student_answer__)
subprocess.run("ruff check -q __student_answer__.py".split())

# Now run the student code, followed by all the tests
{{ STUDENT_ANSWER }}
{% for TEST in TESTCASES %}
{{ TEST.testcode }}
{% if not loop.last %}
print(SEPARATOR)
{% endif %}
{% endfor %}
However, I'd advise aborting the execution of the student answer if the ruff check fails or if it's a precheck run. [We always provide students with a Precheck button when using linters, as students don't usually have the ability to run the linter themselves so are likely to be penalised for style errors they're unaware of.]
In reply to Richard Lobb

Re: Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

by Oli Howson -
Hi Richard

I'm the academic trying to write the question(s) Chris is supporting. Your code is quite similar to mine; while trialling I've included this in the template:

def ruff_it():
    print(__file__)
    try:
        result = subprocess.run(["ruff", __file__], capture_output=True, text=True)
    
        # Print the output from Ruff
        print("Ruff Output:\n", result.stdout)
        
        # Check if Ruff found any issues
        if result.returncode == 0:
            print("No issues found by Ruff.")
        else:
            print("Ruff found issues.")
    except Exception as e:
        print(f"An error occurred: {e}") 
(obviously will tidy up once it's running). 

When ruff_it() is called in the test case, I'm getting this error:
__tester__.python3
An error occurred: [Errno 2] No such file or directory: 'ruff'
Which from my local machine experience suggests ruff isn't installed, or isn't installed correctly to be found on the path.
In reply to Oli Howson

Re: Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

by Richard Lobb -

Yes, it seems that ruff isn't installed in any of the directories in the PATH variable.

Chris's first message referred to ruff being installed in "our instance of CodeRunner (we know it's installed)". That raised a doubt in my mind as to whether ruff was installed on the Moodle server (which wouldn't work) or the Jobe server (which is what's required).

If ruff is definitely installed on the Jobe server, then I would assume it's not in a directory on the PATH.

When I was testing ruff, I first installed it with the command given on the ruff web page: "curl -LsSf https://astral.sh/ruff/install.sh | sh". But that installs in a a directory <home>/.cargo/bin, which won't be searched by Jobe as it has cleaned the PATH variable for security. I instead installed it using pip (as root) with the --break-system-packages command line option. I'd be a bit hesitant to do on a production server, but it worked fine on my development server, putting ruff at /usr/local/bin/ruff. It was then usable from CodeRunner.

Perhaps the first thing to try is to change your script to try executing /root/.cargo/bin/ruff rather than just ruff. It that doesn't work, talk to whoever installed ruff on jobe to find out where it landed up! You may be able to execute it by giving its full path to the subprocess run command, or you could ask the sysadmin to link to it from one of the standard executable directories, like /usr/local/bin. 

In reply to Richard Lobb

Re: Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

by Chris Nelson -
Hi,

Apologies, I meant that IT team installed it on to the JOBE server, with the files being confirmed as installed to /usr/local/bin/ruff

Having told Oli the directory, he seems to be having some joy running Python with Ruff when specifying the location in his question - hopefully he'll be able to better explain once he's had some time exploring. As this is outside of our usual area, the IT Servers colleague and I are unsure if there's a misconfiguration, we've failed to find some needed documentation, or if there's a bug somewhere.
In reply to Chris Nelson

Re: Installed Ruff in CodeRunner: but uh, a bit stuck how to use it!

by Oli Howson -
Yes as suspected it was a path issue - calling by /path/to/ruff it works fine.

worth noting for future issues:
1) You can drop a ruff.toml cofig file in the support files no problem - very useful
2) Using Richard's method is better than mine:

with open("__student_answer__.py", "w") as outfile:
outfile.write(__student_answer__)
subprocess.run("ruff check -q __student_answer__.py".split())

Otherwise it picks up on all our naughty code in the tester as well :)

so a win!