From fa0bdd7cd97c01bb61872eff0589147ec774ec2e Mon Sep 17 00:00:00 2001
From: Sanjit Bhat <sanjit.bhat@gmail.com>
Date: Tue, 19 Sep 2023 14:22:44 -0400
Subject: update grading and zipball rule

---
 .gitignore  |  5 ++---
 Makefile    |  5 +++--
 gradelib.py | 21 +++++++++++++++++++--
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3d25221..5c33438 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,12 +15,11 @@ mkfs
 kernel/kernel
 user/usys.S
 .gdbinit
-myapi.key
-*-handin.tar.gz
+*.zip
 xv6.out*
 .vagrant/
 submissions/
 ph
 barrier
 /lab-*.json
-.DS_Store
\ No newline at end of file
+.DS_Store
diff --git a/Makefile b/Makefile
index 5844ba3..c60ea76 100644
--- a/Makefile
+++ b/Makefile
@@ -272,6 +272,7 @@ clean:
 	mkfs/mkfs .gdbinit \
         $U/usys.S \
 	$(UPROGS) \
+	lab.zip \
 	ph barrier
 
 # try to generate a unique GDB port
@@ -363,7 +364,7 @@ submit-check:
 		test "$$r" = y; \
 	fi
 
-zipball: submit-check
-	git archive --format=zip --output lab.zip HEAD
+zipball: clean submit-check
+	git archive --verbose --format zip --output lab.zip HEAD
 
 .PHONY: zipball clean grade submit-check
diff --git a/gradelib.py b/gradelib.py
index e8d7814..f0d4934 100644
--- a/gradelib.py
+++ b/gradelib.py
@@ -1,6 +1,6 @@
 from __future__ import print_function
 
-import sys, os, re, time, socket, select, subprocess, errno, shutil, random, string
+import sys, os, re, time, socket, select, subprocess, errno, shutil, random, string, json
 from subprocess import check_call, Popen
 from optparse import OptionParser
 
@@ -16,6 +16,7 @@ TESTS = []
 TOTAL = POSSIBLE = 0
 PART_TOTAL = PART_POSSIBLE = 0
 CURRENT_TEST = None
+GRADES = {}
 
 def test(points, title=None, parent=None):
     """Decorator for declaring test functions.  If title is None, the
@@ -31,7 +32,7 @@ def test(points, title=None, parent=None):
             title = "  " + title
 
         def run_test():
-            global TOTAL, POSSIBLE, CURRENT_TEST
+            global TOTAL, POSSIBLE, CURRENT_TEST, GRADES
 
             # Handle test dependencies
             if run_test.complete:
@@ -68,6 +69,9 @@ def test(points, title=None, parent=None):
                 print("    %s" % fail.replace("\n", "\n    "))
             else:
                 TOTAL += points
+            if points:
+                GRADES[title] = 0 if fail else points
+
             for callback in run_test.on_finish:
                 callback(fail)
             CURRENT_TEST = None
@@ -95,6 +99,16 @@ def end_part(name):
     show_part.title = ""
     TESTS.append(show_part)
 
+def write_results():
+    global options
+    if not options.results:
+        return
+    try:
+        with open(options.results, "w") as f:
+            f.write(json.dumps(GRADES))
+    except OSError as e:
+        print("Provided a bad results path. Error:", e)
+
 def run_tests():
     """Set up for testing and run the registered test functions."""
 
@@ -105,6 +119,7 @@ def run_tests():
                       help="print commands")
     parser.add_option("--color", choices=["never", "always", "auto"],
                       default="auto", help="never, always, or auto")
+    parser.add_option("--results", help="results file path")
     (options, args) = parser.parse_args()
 
     # Start with a full build to catch build errors
@@ -120,6 +135,7 @@ def run_tests():
             if not limit or any(l in test.title.lower() for l in limit):
                 test()
         if not limit:
+            write_results()
             print("Score: %d/%d" % (TOTAL, POSSIBLE))
     except KeyboardInterrupt:
         pass
@@ -260,6 +276,7 @@ def check_time():
 
 def check_answers(file, n=10):
     try:
+        print("")
         with open(file) as f:
             d = f.read().strip()
             if len(d) < n:
-- 
cgit v1.2.3