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 utils.shell 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))
else:
return False
def wc(self, args):
"word count, args have optional checks"
dbg('.wc({})'.format(args))
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(
fname
))
else:
raise Exception("Unknown wc check constraint {}".format(chk))
return all(result)
def contains(self, args):
"list of file: [words] to check for"
dbg('.contains({})'.format(args))
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:
finally:
os.chdir(incwd)
@click.command(short_help="Check LAB_NUMBER (e.g. \"lt check lab01\")")
@click.argument('lab_number')
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)
else:
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!")
return
if not labname:
error("Could not detect LAB. Run this command from your lab folder or specify the LAB on the command line (--lab #)")
return
#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
))
return
for part, info in rubric['parts'].items():
for partstr, info in rubric['parts'].items():
if info['check']:
if part and part != info['index']:
continue
c = Checker(info, os.path.join(coursepath, rubric['path']))
echo("-"*40)
echo(info['name'], info['prompt'])
echo("---[{:25}({})]{}[{} points]{}".format(
info['name'],
info['index'],
"-"*30,
info['points'],
"-"*30))
echo(info['prompt'])
if c.do_check():
if 'on_pass' in info:
success(info['on_pass'])
......@@ -108,5 +163,7 @@ def check(lab_number):
error(info['on_error'])
else:
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.")
#pprint(rubric)
......@@ -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).
"""
#https://stackoverflow.com/questions/25836175/python-how-to-discern-if-a-path-is-within-another-path
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):
os.chdir(coursepath)
return coursename, coursepath
return None, None
found = True
break
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):
continue
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 = subprocess.run(
shlex.split("git diff-index --quiet HEAD"),
env=os.environ.copy(),
cwd=cwd
)
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 = subprocess.run(
shlex.split(cmd),
env=os.environ.copy(),
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
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