Browse Source

Refactor exception handling; cleanup

master
Ben Kurtovic 8 years ago
parent
commit
88629001d4
9 changed files with 74 additions and 43 deletions
  1. +2
    -1
      README.md
  2. +3
    -9
      lib/kgrader/cli.rb
  3. +3
    -6
      lib/kgrader/course.rb
  4. +12
    -0
      lib/kgrader/errors.rb
  5. +2
    -2
      lib/kgrader/filesystem.rb
  6. +4
    -0
      lib/kgrader/roster.rb
  7. +13
    -4
      lib/kgrader/task.rb
  8. +18
    -12
      lib/kgrader/util.rb
  9. +17
    -9
      rakefile

+ 2
- 1
README.md View File

@@ -31,7 +31,8 @@ To show all known classes, semesters, and assignments:


rake list rake list


To load a roster for a specific semester:
To load a roster (a newline-delimited list of student identifiers) for a
specific semester:


rake roster cs123 myroster.csv semester=sp16 rake roster cs123 myroster.csv semester=sp16




+ 3
- 9
lib/kgrader/cli.rb View File

@@ -26,19 +26,19 @@ module KGrader
end end


def roster(course, semester, rosterfile) def roster(course, semester, rosterfile)
course = fetch_course course
course = Course.new(@fs, course)
semester ||= course.current_semester semester ||= course.current_semester
course.roster(semester).load rosterfile course.roster(semester).load rosterfile
end end


def grade(course, semester, assignment, options = {}) def grade(course, semester, assignment, options = {})
course = fetch_course course
course = Course.new(@fs, 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 = fetch_course course
course = Course.new(@fs, course)
semester ||= course.current_semester semester ||= course.current_semester
course.task(semester, assignment).commit options course.task(semester, assignment).commit options
end end
@@ -58,12 +58,6 @@ 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


+ 3
- 6
lib/kgrader/course.rb View File

@@ -11,6 +11,8 @@ module KGrader


@config = @fs.load @fs.course_config(@name) @config = @fs.load @fs.course_config(@name)
@rosters = {} @rosters = {}
rescue FilesystemError
raise CourseError, "unknown or invalid course: #{name}"
end end


def roster(semester) def roster(semester)
@@ -30,12 +32,7 @@ module KGrader
end end


def current_semester def current_semester
case @config['semesters']
when 'faspYY'
KGrader::season + DateTime.now.strftime('%y')
when 'faspYYYY'
KGrader::season + DateTime.now.strftime('%Y')
end
KGrader::current_semester @config['semesters']
end end
end end
end end

+ 12
- 0
lib/kgrader/errors.rb View File

@@ -2,6 +2,18 @@ module KGrader
class KGraderError < StandardError class KGraderError < StandardError
end end


class ArgumentError < KGraderError
end

class FilesystemError < KGraderError class FilesystemError < KGraderError
end end

class ConfigError < KGraderError
end

class CourseError < KGraderError
end

class RosterError < KGraderError
end
end end

+ 2
- 2
lib/kgrader/filesystem.rb View File

@@ -52,10 +52,10 @@ module KGrader
when '.csv' when '.csv'
File.read(path).split("\n").map! { |line| line.split "," } File.read(path).split("\n").map! { |line| line.split "," }
else else
raise FilesystemError, "unknown file type"
raise FilesystemError, "unknown file type: #{path}"
end end
rescue SystemCallError # Errno::ENOENT, etc. rescue SystemCallError # Errno::ENOENT, etc.
raise FilesystemError, "can't read file"
raise FilesystemError, "can't read file: #{path}"
end end
end end
end end

+ 4
- 0
lib/kgrader/roster.rb View File

@@ -13,10 +13,14 @@ module KGrader
@students = @fs.load(filename).map! { |item| item.first } @students = @fs.load(filename).map! { |item| item.first }
FileUtils.mkdir_p File.dirname(rosterfile) FileUtils.mkdir_p File.dirname(rosterfile)
File.write rosterfile, @students.join("\n") File.write rosterfile, @students.join("\n")
rescue FilesystemError => err
raise RosterError, err
end end


def students def students
@students ||= @fs.load(rosterfile).map! { |item| item.first } @students ||= @fs.load(rosterfile).map! { |item| item.first }
rescue FilesystemError
raise RosterError, "unknown semester: #{semester}"
end end


private private


+ 13
- 4
lib/kgrader/task.rb View File

@@ -6,23 +6,32 @@ module KGrader
@course = course @course = course
@semester = semester @semester = semester
@assignment = assignment @assignment = assignment
@roster = @course.roster @semester
@students = @course.roster(@semester).students
end end


def grade(options = {}) def grade(options = {})
students = @roster.students
students = @students
students &= options[:students] unless options[:students].nil? students &= options[:students] unless options[:students].nil?


due = options.fetch(:due, Time.now)
fetch = options.fetch(:fetch, true)
regrade = options.fetch(:regrade, false)

# TODO # TODO
puts "Grading #{@course.name}:#{@semester} assignment #{@assignment}..." puts "Grading #{@course.name}:#{@semester} assignment #{@assignment}..."
puts "- options: #{options}"
puts "- students: #{students.inspect}" puts "- students: #{students.inspect}"
puts "- due: #{due}"
puts "- fetch: #{fetch}"
puts "- regrade: #{regrade}"
end end


def commit(options = {}) def commit(options = {})
students = @students
students &= options[:students] unless options[:students].nil?

# TODO # TODO
puts "Committing #{@course.name}:#{@semester} assignment #{@assignment}..." puts "Committing #{@course.name}:#{@semester} assignment #{@assignment}..."
puts "- options: #{options}"
puts "- students: #{students.inspect}"
end end
end end
end end

+ 18
- 12
lib/kgrader/util.rb View File

@@ -1,10 +1,6 @@
require 'date'
require 'time'


module KGrader module KGrader
def self.die(error)
Kernel::abort "fatal: #{error}"
end

def self.parse_args(raw, num, keywords) def self.parse_args(raw, num, keywords)
args = [] args = []
options = {} options = {}
@@ -13,7 +9,9 @@ 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
die "unknown keyword #{key}" unless keywords.include? key
unless keywords.include? key
raise ArgumentError, "unknown keyword: #{key}"
end
options[key] = case keywords[key] options[key] = case keywords[key]
when :string when :string
val val
@@ -21,20 +19,28 @@ module KGrader
%w(true yes 1 t y).include? val.downcase %w(true yes 1 t y).include? val.downcase
when :array when :array
val.split(",").map! { |x| x.strip.downcase } val.split(",").map! { |x| x.strip.downcase }
when :datetime
DateTime.parse(val)
when :time
Time.parse(val)
end end
else else
args << arg args << arg
end end
end end


die "too few arguments" if args.size < num
die "too many arguments" if args.size > num
raise ArgumentError, "too few arguments" if args.size < num
raise ArgumentError, "too many arguments" if args.size > num
return args, options return args, options
end end


def self.season
DateTime.now.strftime('%m').to_i <= 6 ? 'sp' : 'fa'
def self.current_semester(format)
season = Time.now.strftime('%m').to_i <= 6 ? 'sp' : 'fa'
case format
when 'faspYY'
season + Time.now.strftime('%y')
when 'faspYYYY'
season + Time.now.strftime('%Y')
else
raise ConfigError, "unknown semester format: #{format}"
end
end end
end end

+ 17
- 9
rakefile View File

@@ -1,13 +1,21 @@
require_relative 'lib/kgrader' require_relative 'lib/kgrader'


def cli
KGrader::CLI.new Rake.application.original_dir
def die(error)
abort "fatal: [#{error.class}] #{error}"
end

def run
yield KGrader::CLI.new Rake.application.original_dir
rescue KGrader::KGraderError => err
die err
end end


def parse_args(num, keywords = {}) def parse_args(num, keywords = {})
args, options = KGrader::parse_args ARGV.drop(1), num, keywords args, options = KGrader::parse_args ARGV.drop(1), num, keywords
args.each { |arg| task arg.to_sym {} } args.each { |arg| task arg.to_sym {} }
args + [options] args + [options]
rescue KGrader::KGraderError => err
die err
end end


task :default => :help do ; end task :default => :help do ; end
@@ -24,31 +32,31 @@ task :help do
end end


task :list do task :list do
cli.list
run { |cli| cli.list }
end end


task :roster do task :roster do
course, rosterfile, options = parse_args 2, { :semester => :string } course, rosterfile, options = parse_args 2, { :semester => :string }
cli.roster course, options[:semester], rosterfile
run { |cli| cli.roster course, options[:semester], rosterfile }
end end


task :grade do task :grade do
course, assignment, options = parse_args 2, course, assignment, options = parse_args 2,
{ :semester => :string, :students => :array, :due => :datetime,
{ :semester => :string, :students => :array, :due => :time,
:fetch => :bool, :regrade => :bool } :fetch => :bool, :regrade => :bool }
cli.grade course, options[:semester], assignment, options
run { |cli| cli.grade course, options[:semester], assignment, options }
end end


task :commit do task :commit do
course, assignment, options = parse_args 2, course, assignment, options = parse_args 2,
{ :semester => :string, :students => :array } { :semester => :string, :students => :array }
cli.commit course, options[:semester], assignment, options
run { |cli| cli.commit course, options[:semester], assignment, options }
end end


task :clean do task :clean do
cli.clean
run { |cli| cli.clean }
end end


task :clobber do task :clobber do
cli.clobber
run { |cli| cli.clobber }
end end

Loading…
Cancel
Save