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

adding ta support

parent 1ebdc0f6
CYTHON=cython
CPYFLAGS=-3 --embed
CC=gcc
#CYTHON=cython
#CPYFLAGS=-3 --embed
#CC=gcc
#CFLAGS=`python3-config --cflags`
CFLAGS=-I/nfs/software/anaconda-3.6/include/python3.6m -I/nfs/software/anaconda-3.6/include/python3.6m -Wno-unused-result -Wsign-compare -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-lto -fno-plt -O3 -pipe -fdebug-prefix-map==/usr/local/src/conda/- -fdebug-prefix-map==/usr/local/src/conda-prefix -fuse-linker-plugin -DNDEBUG -fwrapv -O3 -Wall
#CFLAGS=-I/nfs/software/anaconda-3.6/include/python3.6m -I/nfs/software/anaconda-3.6/include/python3.6m -Wno-unused-result -Wsign-compare -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-lto -fno-plt -O3 -pipe -fdebug-prefix-map==/usr/local/src/conda/- -fdebug-prefix-map==/usr/local/src/conda-prefix -fuse-linker-plugin -DNDEBUG -fwrapv -O3 -Wall
# -ffat-lto-objects -flto-partition=none -flto
LDFLAGS=`python3-config --ldflags`
LIBS=
all: lt
#LDFLAGS=`python3-config --ldflags`
#LIBS=
all: dist
.PHONY: dist clean deploy
#lt.c: lt.py
#$(CYTHON) $(CPYFLAGS) lt.py
lt:
dist:
#$(CC) lt.c -o lt -fno-lto -fPIC $(CFLAGS) $(LDFLAGS) $(LIBS)
rm -rf dist
./rev.py lt.py
chmod go+rx lt.py
pyinstaller lt.py
chmod -R go+r dist
clean:
rm -f lt.c deploy lt
deploy: lt
rm -rf ~cs206/bin/lt
cp -R dist/lt ~cs206/bin
chmod -R go+r ~cs206/bin/lt
rm -fr lt.c deploy lt dist lt.spec
import click
import config
import subprocess
from config.echo import *
import courses
from config import UserConfig
......@@ -33,40 +34,67 @@ class Checker:
else:
# dicts can be used to specify tests to perform
for cmd, check in test.items():
if 'shell' in check and check['shell']:
sh = True
else:
sh = False
if 'stdin' in check:
c,t = run(cmd, shell=sh, input=check['stdin'])
else:
c,t = run(cmd, shell=sh)
if 'message' in check:
msg = check['message']
else:
msg = "$ {}".format(cmd)
sh = True if 'shell' in check and check['shell'] else False
instr = check['stdin'] if 'stdin' in check else None
to = check['timeout'] if 'timeout' in check else 2
# check for multiline inputs
if instr:
if type(instr) == list:
instr = "\n".join(instr)
if type(instr) != str:
warn("Rubric has non-string stdin ({})!".format(
type(instr)))
instr = str(instr)
if to > 2:
warn("Running {} with timeout {}s, please wait!".format(
cmd, to
))
try:
c,t = run(cmd, shell=sh, input=instr, timeout=to)
except subprocess.TimeoutExpired:
error("{}: Command timeout!".format(cmd))
c = -1
t = ""
msg = check['message'] if 'message' in check else "$ {}".format(cmd)
if 'returncode' in check:
results += [c == check['returncode']]
if results[-1]:
success("{}: Reported success.".format(msg))
success("{}: success.".format(msg))
else:
error("{}: Reported failure!".format(msg))
error("{}: failed!".format(msg))
error(t)
# stop on first error
return False
if 'stdout' in check:
results += [t == check['stdout']]
if type(check['stdout']) == list:
x = "\n".join(check['stdout'])
elif type(check['stdout']) == str:
x = check['stdout']
else:
warn("Rubric has non-string stdout!")
x = str(check['stdout'])
results += [t == x]
if results[-1]:
success("{}: Output passed.".format(msg))
else:
error("{}: Output not as expected (check formatting!)".format(msg))
for line in difflib.context_diff(
check['stdout'].split("\n"), t.split("\n"),
fromfile='Expected output',
tofile='Your output'):
echo(line.strip())
showdiff = True
if 'diff' in check:
showdiff = check['diff']
if showdiff:
error("{}: Output not as expected (check formatting!)".format(msg))
for line in difflib.context_diff(
x.split("\n"), t.split("\n"),
fromfile='Expected output',
tofile='Your output'):
echo(line.strip())
else:
error("{}: failed.".format(msg))
return False
return all(results)
......@@ -75,7 +103,7 @@ class Checker:
dbg('.exists({})'.format(args))
for fname, result in zip(args, map(os.path.exists, args)):
if not result:
error("The file {} does not exist!".format(fname))
error("The file '{}' does not exist!".format(fname))
return False
return True
......@@ -189,8 +217,11 @@ def check(lab, part):
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]
echo("Checking {} of {}".format(labname, coursename))
if part:
echo("Checking {} (part {}) of {}".format(labname, part, coursename))
else:
echo("Checking {} of {}".format(labname, coursename))
rubric = courses.load_rubric(coursename, labname)
......@@ -210,10 +241,10 @@ def check(lab, part):
os.path.join(coursepath, rubric['path']))
newline()
echo("{}[{:25}({:3}) ]{}[{:3} points]{}".format(
"-"*10,
info['name'][:max(10,width-55)].ljust(width-55),
xlen = 47 # length of everything without name
echo("Part {:3}: {}{}[{:3} points]{}".format(
info['index'],
info['name'][:max(10,width-xlen)].ljust(width-xlen),
"-"*10,
info['points'],
"-"*10))
......@@ -230,6 +261,8 @@ def check(lab, part):
error(info['on_error'])
else:
error('This part failed!')
# stop checking on first part failure
break
# only check gitlab if all tests pass
if all(presults):
......
......@@ -8,16 +8,40 @@ import shutil
from config.echo import *
from utils.gitlab import GitLab
from utils.git import Git
from utils.shell import run
import courses
def init_ta(coursename, localpath):
"called when init sees the ta flag set."
localpath += "-TA"
if confirm("Initialize {} into {} as a TA?".format(coursename, localpath)):
if os.path.exists(localpath):
# prompt to wipe it.
warn("The path already exists!")
if warn_confirm("Would you like me to WIPE {} and re-create (this will DELETE ALL files)".format(localpath)):
shutil.rmtree(localpath)
success("Deleted {}".format(localpath))
if os.path.exists(localpath):
error("ABORT: Cannot initialize since the path {} already exists!".format(
localpath))
return
with config.UserConfig() as uc:
uc.add_ta(
name=coursename,
path=localpath)
@click.command(short_help='Initialize a course.')
@click.argument('course', callback=validation.course)
@click.argument('section', callback=validation.section)
@click.argument('semester', callback=validation.semester)
@click.option('--prefix', default=None,
@click.option('--prefix', default="~/",
help="Override the default path prefix (~/)")
def init(course, semester, section, prefix):
@click.option("--ta", default=False,
help = "Set if you are a course TA or instructor.",
is_flag = True)
def init(course, semester, section, prefix, ta):
"""Initializes the lab tool structure on your local system
and on gitlab for a given COURSE, SECTION, and SEMESTER. Example: init CSCI206 S20 61.
"""
......@@ -46,7 +70,9 @@ def init(course, semester, section, prefix):
course=course,
semester=semester,
section=section)))
if ta:
init_ta(coursename, lp)
return
if confirm("Initialize {} into {}?".format(coursename, lp)):
if os.path.exists(lp):
......@@ -57,7 +83,7 @@ def init(course, semester, section, prefix):
success("Deleted {}".format(lp))
if os.path.exists(lp):
error("ABROT: Cannot initalize since the path {} already exists!".format(
error("ABORT: Cannot initialize since the path {} already exists!".format(
lp))
return
......@@ -154,7 +180,21 @@ def init(course, semester, section, prefix):
# finally clone the repo
git = Git()
if git.do_clone(repo['ssh_url_to_repo'], lp):
if git.do_clone(repo['ssh_url_to_repo'], localpath=lp):
# copy cs206 gitignore and add to repo
igf = os.path.join(lp, '.gitignore')
src = "curl {} -o {}".format(
"http://eg.bucknell.edu/~cs206/.gitignore", igf)
c,t = run(src)
if c == 0:
success(src)
git.do_push(addfiles=['.gitignore'],
cwd=lp, message='Added by labtool')
else:
warn("Failed to initialize gitignore file.")
warn(src)
warn(t)
success("Initialization complete!")
else:
error("Sorry, I was unable to clone the repo (did something go wrong earlier?)!")
......@@ -24,7 +24,11 @@ class UserConfig:
# self.cfg[x].append(val)
# else:
# self.cfg[x] = list(val)
def add_ta(self, name, path):
"add a course to the dict of ta courses: local_path"
if not 'ta' in self.cfg:
self.cfg['ta'] = {}
self.cfg['ta'][name] = path
def add_course(self, name, path):
"add a course to the dict of courses: local_path"
if not 'courses' in self.cfg:
......
......@@ -20,8 +20,10 @@ import config
# CLI commands
import commands
__version__ = '1.0.0'
__version__ = '1.0.1'
__date__ = '2020-01-08T15:12:16.309992'
__user__ = 'cs206'
__host__ = 'linuxremote3.bucknell.edu'
@click.group()
def main():
"""Bucknell University Computer Science lab tool [lt].
......@@ -36,7 +38,11 @@ def main():
@main.command()
def version():
"Display the version of labtool"
click.echo("labtool version {}.".format( __version__))
click.echo("labtool version {} built on {} by {}@{}.".format(
__version__,
__date__,
__user__,
__host__))
# attach all commands to the main cli entry group
for cmd in commands.__all__:
......
......@@ -23,7 +23,7 @@ class Git:
def status(self, cwd):
"runs git status and returns the result"
return shell.run("git status", cwd=cwd)[1]
def do_clone(self, giturl, localpath = None, cwd = '.', branch = None):
if localpath:
# localpath is where you want it like /home/amm042/CSCI206-S20-61
......@@ -38,25 +38,29 @@ class Git:
echo("Cloning {}... ".format(giturl))
c, r = shell.run(cmd, cwd=cwd)
if c != 0:
error('[{}]$ {}'.format(cwd, cmd))
error(r)
else:
success('[{}]$ {}'.format(cwd, cmd))
return c == 0
def do_push(self, login, cwd, addfiles=[],
def do_push(self, cwd, addfiles=[],
message='A commit message', branch='master',
addall=False):
#
# cmd = 'git branch {}'.format(branch)
# c,r = shell.run(cmd, cwd=cwd)
# if c != 0:
# error('[{}]$ {}'.format(cwd, cmd))
# error(r)
# else:
# success('[{}]$ {}'.format(cwd, cmd))
cmd = 'git branch {}'.format(branch)
c,r = shell.run(cmd, cwd=cwd)
if c != 0:
error(r)
else:
success('[{}]$ {}'.format(cwd, cmd))
cmd = 'git checkout {}'.format(branch)
# -B creates the branch if missing
cmd = 'git checkout -B {}'.format(branch)
c,r = shell.run(cmd, cwd=cwd)
if c != 0:
error('[{}]$ {}'.format(cwd, cmd))
error(r)
else:
success('[{}]$ {}'.format(cwd, cmd))
......@@ -66,6 +70,7 @@ class Git:
echo("Adding: ", cmd)
c,r = shell.run(cmd, cwd=cwd)
if c != 0:
error('[{}]$ {}'.format(cwd, cmd))
error(r)
else:
success('[{}]$ {}'.format(cwd, cmd))
......@@ -82,6 +87,7 @@ class Git:
cmd = 'git commit -m "{}"'.format(message)
c,r = shell.run(cmd, cwd=cwd)
if c != 0:
error('[{}]$ {}'.format(cwd, cmd))
error(r)
else:
success('[{}]$ {}'.format(cwd, cmd))
......@@ -89,6 +95,7 @@ class Git:
cmd = 'git push origin ' + branch
c,r = shell.run(cmd, cwd=cwd)
if c != 0:
error('[{}]$ {}'.format(cwd, cmd))
error(r)
return False
else:
......
......@@ -2,7 +2,7 @@ import subprocess
import os
import shlex
def run(cmd, cwd=None, input=None, shell=False, timeout=5):
def run(cmd, cwd=None, input=None, shell=False, timeout=3):
result = subprocess.run(
cmd if shell else shlex.split(cmd),
executable = '/bin/bash' if shell else None,
......
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