| @@ -1,2 +1,6 @@ | |||||
| require_relative 'kgrader/cli' | require_relative 'kgrader/cli' | ||||
| require_relative 'kgrader/course' | |||||
| require_relative 'kgrader/filesystem' | |||||
| require_relative 'kgrader/roster' | |||||
| require_relative 'kgrader/task' | |||||
| require_relative 'kgrader/util' | require_relative 'kgrader/util' | ||||
| @@ -1,8 +1,11 @@ | |||||
| require_relative 'course' | |||||
| require_relative 'filesystem' | |||||
| module KGrader | module KGrader | ||||
| class CLI | class CLI | ||||
| def initialize(dir) | def initialize(dir) | ||||
| @dir = dir | |||||
| @fs = Filesystem.new dir | |||||
| end | end | ||||
| def list | def list | ||||
| @@ -11,23 +14,22 @@ module KGrader | |||||
| end | end | ||||
| def roster(course, semester, rosterfile) | def roster(course, semester, rosterfile) | ||||
| # TODO | |||||
| puts "[installing roster: c=#{course} s=#{semester} rf=#{rosterfile}]" | |||||
| Course.new(@fs, course).roster(semester).load rosterfile | |||||
| end | end | ||||
| def grade(course, semester, assignment, options = {}) | def grade(course, semester, assignment, options = {}) | ||||
| # TODO | # TODO | ||||
| puts "[grading c=#{course} s=#{semester} a=#{assignment}]" | |||||
| puts " - [students=#{options[:students].inspect}]" | |||||
| puts " - [due=#{options[:due].inspect}]" | |||||
| puts " - [fetch=#{options.fetch(:fetch, true).inspect}]" | |||||
| puts " - [regrade=#{options.fetch(:regrade, false).inspect}]" | |||||
| # need to get default semester... | |||||
| semester ||= 'DEFAULT' | |||||
| task = Course.new(@fs, course).task semester, assignment | |||||
| task.grade options | |||||
| end | end | ||||
| def commit(course, semester, assignment, options = {}) | def commit(course, semester, assignment, options = {}) | ||||
| # TODO | # TODO | ||||
| puts "[committing c=#{course} s=#{semester} a=#{assignment}]" | |||||
| puts " - [students=#{options[:students].inspect}]" | |||||
| semester ||= 'DEFAULT' | |||||
| task = Course.new(@fs, course).task semester, assignment | |||||
| task.commit options | |||||
| end | end | ||||
| def clean | def clean | ||||
| @@ -43,15 +45,13 @@ module KGrader | |||||
| private | private | ||||
| def reset_jail | def reset_jail | ||||
| jail_dir = File.join(@dir, 'jail') | |||||
| FileUtils.rm_rf jail_dir | |||||
| FileUtils.mkdir jail_dir | |||||
| FileUtils.touch File.join(jail_dir, '.gitkeep') | |||||
| FileUtils.rm_rf @fs.jail | |||||
| FileUtils.mkdir @fs.jail | |||||
| FileUtils.touch File.join(@fs.jail, '.gitkeep') | |||||
| end | end | ||||
| def reset_desk | def reset_desk | ||||
| desk_dir = File.join(@dir, 'desk') | |||||
| FileUtils.rm_rf Dir.glob(File.join(desk_dir, '*', '')) | |||||
| FileUtils.rm_rf Dir[File.join @fs.desk, '*', ''] | |||||
| end | end | ||||
| end | end | ||||
| end | end | ||||
| @@ -0,0 +1,24 @@ | |||||
| require_relative 'roster' | |||||
| require_relative 'task' | |||||
| module KGrader | |||||
| class Course | |||||
| attr_reader :name | |||||
| def initialize(filesystem, name) | |||||
| @fs = filesystem | |||||
| @name = name | |||||
| @config = @fs.load @fs.course_config(@name) | |||||
| end | |||||
| def roster(semester) | |||||
| # TODO: cache | |||||
| Roster.new @fs, self, semester | |||||
| end | |||||
| def task(semester, assignment) | |||||
| # TODO: cache | |||||
| Task.new @fs, self, semester, assignment | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,39 @@ | |||||
| require 'yaml' | |||||
| module KGrader | |||||
| class Filesystem | |||||
| def initialize(root) | |||||
| @root = root | |||||
| end | |||||
| def course(name) | |||||
| File.join @root, 'spec', name | |||||
| end | |||||
| def course_config(name) | |||||
| File.join course(name), '_config.yml' | |||||
| end | |||||
| def courses | |||||
| Dir[File.join @root, 'spec', '*', ''].each { |fn| File.basename fn } | |||||
| end | |||||
| def desk | |||||
| File.join @root, 'desk' | |||||
| end | |||||
| def jail | |||||
| File.join @root, 'jail' | |||||
| end | |||||
| def load(path) | |||||
| case File.extname path | |||||
| when '.yml', '.yaml' | |||||
| YAML.load File.read(path) | |||||
| when '.csv' | |||||
| # TODO | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,15 @@ | |||||
| module KGrader | |||||
| class Roster | |||||
| def initialize(filesystem, course, semester) | |||||
| @fs = filesystem | |||||
| @course = course | |||||
| @semester = semester | |||||
| end | |||||
| def load(filename) | |||||
| # TODO | |||||
| puts "Loading roster for #{@course.name}:#{@semester} from [#{filename}]..." | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -0,0 +1,23 @@ | |||||
| module KGrader | |||||
| class Task | |||||
| def initialize(filesystem, course, semester, assignment) | |||||
| @fs = filesystem | |||||
| @course = course | |||||
| @semester = semester | |||||
| @assignment = assignment | |||||
| end | |||||
| def grade(options = {}) | |||||
| # TODO | |||||
| puts "Grading #{@course.name}:#{@semester} assignment #{@assignment}..." | |||||
| puts "- options: #{options}" | |||||
| end | |||||
| def commit(options = {}) | |||||
| # TODO | |||||
| puts "Committing #{@course.name}:#{@semester} assignment #{@assignment}..." | |||||
| puts "- options: #{options}" | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -1,6 +1,10 @@ | |||||
| require 'date' | require 'date' | ||||
| module KGrader | module KGrader | ||||
| def self.abort(error) | |||||
| Kernel::abort "fatal: #{error}" | |||||
| end | |||||
| def self.parse_args(raw, num, keywords) | def self.parse_args(raw, num, keywords) | ||||
| args = [] | args = [] | ||||
| options = {} | options = {} | ||||
| @@ -9,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 | ||||
| yield "unknown keyword #{key}" unless keywords.include? key | |||||
| abort "unknown keyword #{key}" unless keywords.include? key | |||||
| options[key] = case keywords[key] | options[key] = case keywords[key] | ||||
| when :string | when :string | ||||
| val | val | ||||
| @@ -25,8 +29,8 @@ module KGrader | |||||
| end | end | ||||
| end | end | ||||
| yield "too few arguments" if args.size < num | |||||
| yield "too many arguments" if args.size > num | |||||
| abort "too few arguments" if args.size < num | |||||
| abort "too many arguments" if args.size > num | |||||
| return args, options | return args, options | ||||
| end | end | ||||
| end | end | ||||
| @@ -4,10 +4,8 @@ def cli | |||||
| KGrader::CLI.new Rake.application.original_dir | KGrader::CLI.new Rake.application.original_dir | ||||
| end | end | ||||
| def parse_args(num, keywords) | |||||
| args, options = KGrader::parse_args ARGV.drop(1), num, keywords do |err| | |||||
| abort err | |||||
| end | |||||
| def parse_args(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] | ||||
| end | end | ||||