A code autograder for student homework submissions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.0 KiB

  1. module KGrader
  2. class Assignment
  3. attr_reader :name, :manifest
  4. def initialize(filesystem, course, name)
  5. @fs = filesystem
  6. @course = course
  7. @name = name
  8. @root = @fs.assignment @course.name, @name
  9. @config = @fs.load @fs.assignment_config(@course.name, @name)
  10. verify_config
  11. @manifest = get_manifest
  12. rescue FilesystemError
  13. raise AssignmentError, "unknown assignment: #{name}"
  14. end
  15. def id
  16. @config['id'] || @name
  17. end
  18. def title
  19. @config['title'] || @name
  20. end
  21. def build_steps
  22. @config['build']
  23. end
  24. def tests
  25. @tests ||= @config['grade'].map do |it|
  26. name = it.keys.first
  27. opts = it.values.first
  28. script = File.join @root, name + '.rb'
  29. depends = *opts['depends'] || []
  30. depfail = opts['depfail'] || "depends on #{name}"
  31. { :name => name, :script => script, :max => opts['points'],
  32. :depends => depends, :depfail => depfail }
  33. end
  34. end
  35. def report
  36. @config['commit']['report'] || "report.txt"
  37. end
  38. def commit_message(student)
  39. default = "Adding grade report for #{title}: {student}"
  40. template = (@config['commit']['message'] || default).clone
  41. template['{student}'] = student
  42. template
  43. end
  44. def extra_comments
  45. conf = @config['commit']
  46. return *conf['comments'] || conf['comment'] || []
  47. end
  48. private
  49. def verify_config
  50. %w(stage build grade).each do |key|
  51. unless @config.include? key
  52. raise AssignmentError, "missing #{key} section in config: #{@name}"
  53. end
  54. end
  55. end
  56. def get_manifest
  57. stage = @config['stage']
  58. raise AssignmentError, "chroot is not supported yet" if stage['chroot']
  59. provided = stage['provided'].map do |fn|
  60. { :name => fn, :path => File.join(@root, 'provided', fn) }
  61. end
  62. graded = stage['graded'].map { |fn| { :name => fn } }
  63. { :provided => provided, :graded => graded }
  64. end
  65. end
  66. end