| @@ -31,9 +31,13 @@ To show all known classes, semesters, and assignments: | |||||
| rake list | rake list | ||||
| To load a roster for a course semester: | |||||
| To load a roster for a specific semester: | |||||
| rake roster cs123 sp2016 myroster.csv | |||||
| rake roster cs123 myroster.csv semester=sp16 | |||||
| To load a roster for the current semester: | |||||
| rake roster cs123 myroster.csv | |||||
| ### Grading | ### Grading | ||||
| @@ -83,4 +87,5 @@ repo has changed since the last run. To forcibly regrade: | |||||
| rake grade cs123 mp1 regrade=yes | rake grade cs123 mp1 regrade=yes | ||||
| You can combine these arguments in any meaningful way. | |||||
| You can combine these arguments in any meaningful way. `semester` is available | |||||
| for `roster` and `commit`, and and `students` is available for `commit`. | |||||
| @@ -1,5 +1,6 @@ | |||||
| require_relative 'kgrader/cli' | require_relative 'kgrader/cli' | ||||
| require_relative 'kgrader/course' | require_relative 'kgrader/course' | ||||
| require_relative 'kgrader/errors' | |||||
| require_relative 'kgrader/filesystem' | require_relative 'kgrader/filesystem' | ||||
| require_relative 'kgrader/roster' | require_relative 'kgrader/roster' | ||||
| require_relative 'kgrader/task' | require_relative 'kgrader/task' | ||||
| @@ -26,17 +26,19 @@ module KGrader | |||||
| end | end | ||||
| def roster(course, semester, rosterfile) | def roster(course, semester, rosterfile) | ||||
| Course.new(@fs, course).roster(semester).load rosterfile | |||||
| course = fetch_course course | |||||
| semester ||= course.current_semester | |||||
| course.roster(semester).load rosterfile | |||||
| end | end | ||||
| def grade(course, semester, assignment, options = {}) | def grade(course, semester, assignment, options = {}) | ||||
| course = Course.new @fs, course | |||||
| course = fetch_course course | |||||
| semester ||= course.current_semester | semester ||= course.current_semester | ||||
| course.task(semester, assignment).grade options | course.task(semester, assignment).grade options | ||||
| end | end | ||||
| def commit(course, semester, assignment, options = {}) | def commit(course, semester, assignment, options = {}) | ||||
| course = Course.new @fs, course | |||||
| course = fetch_course course | |||||
| semester ||= course.current_semester | semester ||= course.current_semester | ||||
| course.task(semester, assignment).commit options | course.task(semester, assignment).commit options | ||||
| end | end | ||||
| @@ -56,6 +58,12 @@ module KGrader | |||||
| end | end | ||||
| private | private | ||||
| def fetch_course(course) | |||||
| Course.new(@fs, course) | |||||
| rescue FilesystemError | |||||
| KGrader::die "unknown course" | |||||
| end | |||||
| def reset_jail | def reset_jail | ||||
| FileUtils.rm_rf @fs.jail | FileUtils.rm_rf @fs.jail | ||||
| FileUtils.mkdir @fs.jail | FileUtils.mkdir @fs.jail | ||||
| @@ -0,0 +1,7 @@ | |||||
| module KGrader | |||||
| class KGraderError < StandardError | |||||
| end | |||||
| class FilesystemError < KGraderError | |||||
| end | |||||
| end | |||||
| @@ -51,7 +51,11 @@ module KGrader | |||||
| YAML.load File.read(path) | YAML.load File.read(path) | ||||
| when '.csv' | when '.csv' | ||||
| File.read(path).split("\n").map! { |line| line.split "," } | File.read(path).split("\n").map! { |line| line.split "," } | ||||
| else | |||||
| raise FilesystemError, "unknown file type" | |||||
| end | end | ||||
| rescue SystemCallError # Errno::ENOENT, etc. | |||||
| raise FilesystemError, "can't read file" | |||||
| end | end | ||||
| end | end | ||||
| end | end | ||||
| @@ -1,7 +1,7 @@ | |||||
| require 'date' | require 'date' | ||||
| module KGrader | module KGrader | ||||
| def self.abort(error) | |||||
| def self.die(error) | |||||
| Kernel::abort "fatal: #{error}" | Kernel::abort "fatal: #{error}" | ||||
| end | end | ||||
| @@ -13,7 +13,7 @@ module KGrader | |||||
| if arg.include? '=' | if arg.include? '=' | ||||
| key, val = arg.split('=', 2) | key, val = arg.split('=', 2) | ||||
| key = key.to_sym | key = key.to_sym | ||||
| abort "unknown keyword #{key}" unless keywords.include? key | |||||
| die "unknown keyword #{key}" unless keywords.include? key | |||||
| options[key] = case keywords[key] | options[key] = case keywords[key] | ||||
| when :string | when :string | ||||
| val | val | ||||
| @@ -29,8 +29,8 @@ module KGrader | |||||
| end | end | ||||
| end | end | ||||
| abort "too few arguments" if args.size < num | |||||
| abort "too many arguments" if args.size > num | |||||
| die "too few arguments" if args.size < num | |||||
| die "too many arguments" if args.size > num | |||||
| return args, options | return args, options | ||||
| end | end | ||||
| @@ -15,7 +15,7 @@ task :default => :help do ; end | |||||
| task :help do | task :help do | ||||
| puts %{usage: | puts %{usage: | ||||
| - rake list | - rake list | ||||
| - rake roster <course> <semester> <rosterfile> | |||||
| - rake roster <course> <rosterfile> [semester=<...>] | |||||
| - rake grade <course> <assignment> [semester=<...>] [students=<...>] | - rake grade <course> <assignment> [semester=<...>] [students=<...>] | ||||
| [due=<...>] [fetch=<yes/no>] [regrade=<yes/no>] | [due=<...>] [fetch=<yes/no>] [regrade=<yes/no>] | ||||
| - rake commit <course> <assignment> [semester=<...>] [students=<...>] | - rake commit <course> <assignment> [semester=<...>] [students=<...>] | ||||
| @@ -28,8 +28,8 @@ task :list do | |||||
| end | end | ||||
| task :roster do | task :roster do | ||||
| course, semester, rosterfile = parse_args 3 | |||||
| cli.roster course, semester, rosterfile | |||||
| course, rosterfile, options = parse_args 2, { :semester => :string } | |||||
| cli.roster course, options[:semester], rosterfile | |||||
| end | end | ||||
| task :grade do | task :grade do | ||||