From 16e75b9b49453e3d728122f8d3b62deb6c4cde5f Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Wed, 23 Mar 2016 00:55:39 -0400 Subject: [PATCH] More command-line parsing code --- README.md | 10 ++++----- lib/kgrader.rb | 1 + lib/kgrader/cli.rb | 37 +++++++++++++++++++++++++++++++ lib/kgrader/util.rb | 32 +++++++++++++++++++++++++++ rakefile | 64 +++++++++++++++++++++++++++++------------------------ spec/cs241h | 2 +- 6 files changed, 111 insertions(+), 35 deletions(-) create mode 100644 lib/kgrader/util.rb diff --git a/README.md b/README.md index c18d584..bbb4eca 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ kgrader uses rake as its command-line interface. ### Setup +To show all known classes, semesters, and assignments: + + rake list + To load a roster for a course semester: rake roster cs123 sp2016 myroster.csv @@ -43,10 +47,6 @@ After verifying that everything looks good, push the grade reports with: ### Housekeeping -To show all known classes, semesters, and assignments: - - rake list - To do some basic cleanup (i.e., trash uncommitted grading attempts, or reset messy internal state after a bad run): @@ -63,7 +63,7 @@ but also delete checked-out student repos and roster files -- dangerous!): To specify the semester, instead of the inferred current one: - rake grade cs123 mp1 semester=sp2016 + rake grade cs123 mp1 semester=sp16 To set a cutoff date after which commits will be ignored: diff --git a/lib/kgrader.rb b/lib/kgrader.rb index 863abfc..723a311 100644 --- a/lib/kgrader.rb +++ b/lib/kgrader.rb @@ -1 +1,2 @@ require_relative 'kgrader/cli' +require_relative 'kgrader/util' diff --git a/lib/kgrader/cli.rb b/lib/kgrader/cli.rb index 0bfd6ea..078972a 100644 --- a/lib/kgrader/cli.rb +++ b/lib/kgrader/cli.rb @@ -5,6 +5,43 @@ module KGrader @dir = dir end + def list + # TODO + puts "[list]" + end + + def roster(course, semester, rosterfile) + # TODO + puts "[installing roster: c=#{course} s=#{semester} rf=#{rosterfile}]" + end + + def grade(course, semester, assignment, options = {}) + # 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}]" + end + + def commit(course, semester, assignment, options = {}) + # TODO + puts "[committing c=#{course} s=#{semester} a=#{assignment}]" + puts " - [students=#{options[:students].inspect}]" + end + + def clean + # TODO: also purge uncommitted grades + reset_jail + end + + def clobber + # TODO: confirm + reset_jail + reset_desk + end + + private def reset_jail jail_dir = File.join(@dir, 'jail') FileUtils.rm_rf jail_dir diff --git a/lib/kgrader/util.rb b/lib/kgrader/util.rb new file mode 100644 index 0000000..467e5b5 --- /dev/null +++ b/lib/kgrader/util.rb @@ -0,0 +1,32 @@ +require 'date' + +module KGrader + def self.parse_args(raw, num, keywords) + args = [] + options = {} + + raw.each do |arg| + if arg.include? '=' + key, val = arg.split('=', 2) + key = key.to_sym + yield "unknown keyword #{key}" unless keywords.include? key + options[key] = case keywords[key] + when :string + val + when :bool + %w(true yes 1 t y).include? val.downcase + when :array + val.split(",").map! { |x| x.strip.downcase } + when :datetime + DateTime.parse(val) + end + else + args << arg + end + end + + yield "too few arguments" if args.size < num + yield "too many arguments" if args.size > num + return args, options + end +end diff --git a/rakefile b/rakefile index 4b94890..8bf7987 100644 --- a/rakefile +++ b/rakefile @@ -1,50 +1,56 @@ require_relative 'lib/kgrader' -def get_cli +def cli KGrader::CLI.new Rake.application.original_dir end -task :clean do - cli = get_cli - # TODO: also purge uncommitted grades - cli.reset_jail +def parse_args(num, keywords) + args, options = KGrader::parse_args ARGV.drop(1), num, keywords do |err| + abort err + end + args.each { |arg| task arg.to_sym {} } + args + [options] end -task :clobber do - cli = get_cli - # TODO: confirm - cli.reset_jail - cli.reset_desk +task :default => :help do ; end + +task :help do + puts %{usage: +- rake list +- rake roster +- rake grade [semester=<...>] [students=<...>] + [due=<...>] [fetch=] [regrade=] +- rake commit [semester=<...>] [students=<...>] +- rake clean +- rake clobber} end task :list do - # TODO - puts '[list!]' + cli.list end task :roster do - # TODO: [course, assignment, rosterfile] - puts '[installing roster!]' + course, semester, rosterfile = parse_args 3 + cli.roster course, semester, rosterfile end task :grade do - puts ARGV.inspect - course = ARGV[1] - assignment = ARGV[2] + course, assignment, options = parse_args 2, + { :semester => :string, :students => :array, :due => :datetime, + :fetch => :bool, :regrade => :bool } + cli.grade course, options[:semester], assignment, options +end - task course.to_sym {} - task assignment.to_sym {} +task :commit do + course, assignment, options = parse_args 2, + { :semester => :string, :students => :array } + cli.commit course, options[:semester], assignment, options +end - # TODO - puts "Grading #{assignment} for #{course}..." - puts " - semester:" - puts " - due:" - puts " - fetch:" - puts " - students:" - puts " - regrade:" +task :clean do + cli.clean end -task :commit do - # TODO: [course, assignment], semester=, students= - puts '[committing!]' +task :clobber do + cli.clobber end diff --git a/spec/cs241h b/spec/cs241h index a0a432c..54398ad 160000 --- a/spec/cs241h +++ b/spec/cs241h @@ -1 +1 @@ -Subproject commit a0a432cb96f38c230355e3e5b12bbf131beb04bd +Subproject commit 54398ad4a16ac3d9f7344ecf680f4dd167e05818