Commit c8eb0227 authored by Alan Marchiori's avatar Alan Marchiori
Browse files

lab1 finished

parent c14fa558
......@@ -5,9 +5,12 @@ from config.echo import *
import courses
from config import UserConfig
from import run
from pprint import pprint
import os
from pathlib import Path
from utils.git import Git
def dbg(x):
debug(__name__ + x)
......@@ -29,6 +32,40 @@ class Checker:
return all(map(lambda x: os.stat(x).st_size == 0, args))
return False
def wc(self, args):
"word count, args have optional checks"
result = []
for test in args:
for fname, check in test.items():
t = run('wc {}'.format(fname)).split()
#t = newlines, words, bytes, filename
for chk, value in check.items():
if chk == 'min_lines':
a = int(t[0]) >= int(value)
result += [a]
if not a:
warn("The file {} is too short.".format(
raise Exception("Unknown wc check constraint {}".format(chk))
return all(result)
def contains(self, args):
"list of file: [words] to check for"
result = []
for test in args:
for fname, check in test.items():
text = Path(fname).read_text()
for c in check:
a = c in text
result += [a]
if not a:
warn("The file {} does not contain \"{}\"".format(
fname, c
return all(result)
def cd_labroot(self):
if os.path.exists(self.cwd):
......@@ -70,34 +107,52 @@ class Checker:
@click.command(short_help="Check LAB_NUMBER (e.g. \"lt check lab01\")")
def check(lab_number):
"""check LAB_NUMBER without submitting, format as the string
"lab" plus a number (no spaces!), like "lab01" or "lab10".
@click.command(short_help="Check LAB")
@click.option('--lab', type=int, default=None)
@click.option('--part', type=int, default=None)
def check(lab, part):
"""check LAB and PART without submitting. If LAB is
omitted, we will attempt to auto detect from the working directory. If PART
is omitted, ALL parts are checked.
coursename, coursepath = courses.detect_course()
# convert lab number to filename magic.
if lab:
labstr = "lab{:02}".format(lab)
labstr = None
coursename, coursepath, labname = courses.detect_course(lab=labstr)
if not coursename:
error("The current directory is not an initialized course! You must first cd into an initialized course to check!")
if not labname:
error("Could not detect LAB. Run this command from your lab folder or specify the LAB on the command line (--lab #)")
#courseobj = courses.all[coursename]
success("Checking {} of {}".format(lab_number, coursename))
echo("Checking {} of {}".format(labname, coursename))
rubric = courses.load_rubric(coursename, lab_number)
rubric = courses.load_rubric(coursename, labname)
if not rubric:
error("{} is not defined for the course {}. Check the case and any leading zeros in the lab name (i.e., Lab1 --> lab01)".format(
lab_number, coursename
error("{} is not defined for the course {}.)".format(
labname, coursename
for part, info in rubric['parts'].items():
for partstr, info in rubric['parts'].items():
if info['check']:
if part and part != info['index']:
c = Checker(info, os.path.join(coursepath, rubric['path']))
echo(info['name'], info['prompt'])
echo("---[{:25}({})]{}[{} points]{}".format(
if c.do_check():
if 'on_pass' in info:
......@@ -108,5 +163,7 @@ def check(lab_number):
error('This part failed!')
g = Git()
if not g.clean(cwd=os.path.join(coursepath, rubric['path'])):
error("The remote git server is not consistent with your local path. Be sure to add/commit/push all local changes! Use 'git status' to see differences.")
......@@ -7,19 +7,41 @@ import collections
from config.echo import *
from config.user import UserConfig
def detect_course():
"detect, chdir into root, and return the course based on CWD (or None)."
def detect_course(lab = None):
"""detect and return the course and lab based on CWD (or None).
If you pass in lab, that will not be detected (faster).
def is_subpath(path, of_path):
abs_of_path = os.path.abspath(of_path)
return os.path.abspath(path).startswith(abs_of_path)
found = False
for coursename, coursepath in UserConfig.getConfig()['courses'].items():
if is_subpath(os.getcwd(), coursepath):
return coursename, coursepath
return None, None
found = True
cwd = os.getcwd()
if found:
if lab:
return coursename, coursepath, lab
# is cwd a Lab?
for pathname in all[coursename]['rubric_paths']:
if not os.path.exists(pathname):
for filename in os.listdir(pathname):
fnoext = os.path.splitext(filename)[0]
r = load_rubric(coursename, fnoext)
if r:
labpath = os.path.join(coursepath, r['path'])
if os.path.exists(labpath) and \
os.path.samefile(cwd, labpath):
# found a lab with matching path! this must be it!
return coursename, coursepath, fnoext
# no luck
return coursename, coursepath, None
return None, None, lab
def load_json(filepath):
"loads a json document from filepath"
......@@ -7,7 +7,14 @@ import shutil
from config.echo import *
class Git:
def clean(self, cwd):
"returns True if the there are no diffs to remote (aka clean)"
result =
shlex.split("git diff-index --quiet HEAD"),
return result.returncode == 0
def do_clone(self, giturl, localpath = None, cwd = '.', branch = None):
if localpath:
# localpath is where you want it like /home/amm042/CSCI206-S20-61
import subprocess
import os
import shlex
def run(cmd, cwd=None):
result =
return result.stdout.decode("utf-8", "replace").strip()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment