| @@ -9,7 +9,9 @@ module KGrader | |||
| @root = @fs.assignment @course.name, @name | |||
| @config = @fs.load @fs.assignment_config(@course.name, @name) | |||
| @manifest = build_manifest | |||
| verify_config | |||
| @manifest = get_manifest | |||
| rescue FilesystemError | |||
| raise AssignmentError, "unknown assignment: #{name}" | |||
| end | |||
| @@ -18,22 +20,44 @@ module KGrader | |||
| @config['id'] || @name | |||
| end | |||
| def build_manifest | |||
| unless @config.include? 'manifest' | |||
| raise AssignmentError, "missing manifest: #{@name}" | |||
| def build_steps | |||
| @config['build'] | |||
| end | |||
| def tests | |||
| @config['grade'] | |||
| end | |||
| def report | |||
| @config['commit']['report'] || "report.txt" | |||
| end | |||
| def commit_message(student) | |||
| default = "adding grade report for #{name}: {student}" | |||
| template = @config['commit']['message'].clone || default | |||
| template['{student}'] = student | |||
| template | |||
| end | |||
| private | |||
| def verify_config | |||
| %w(stage build grade).each do |key| | |||
| unless @config.include? key | |||
| raise AssignmentError, "missing #{key} section in config: #{@name}" | |||
| end | |||
| end | |||
| end | |||
| def get_manifest | |||
| stage = @config['stage'] | |||
| raise AssignmentError, "chroot is not supported yet" if stage['chroot'] | |||
| manifest = @config['manifest'] | |||
| provided = manifest['provided'].map do |fn| | |||
| provided = stage['provided'].map do |fn| | |||
| { :name => fn, :path => File.join(@root, 'provided', fn) } | |||
| end | |||
| graded = manifest['graded'].map { |fn| { :name => fn } } | |||
| graded = stage['graded'].map { |fn| { :name => fn } } | |||
| { | |||
| :provided => provided, | |||
| :graded => graded, | |||
| :report => manifest['report'] | |||
| } | |||
| { :provided => provided, :graded => graded } | |||
| end | |||
| end | |||
| end | |||
| @@ -5,16 +5,25 @@ module KGrader | |||
| @root = root | |||
| end | |||
| def reset | |||
| FileUtils.rm_rf @root | |||
| end | |||
| def init | |||
| FileUtils.mkdir_p @root | |||
| end | |||
| def reset | |||
| FileUtils.rm_rf @root | |||
| def stage(source, target) | |||
| FileUtils.cp source, File.join(@root, target) | |||
| end | |||
| def stage(source, target) | |||
| puts "[chroot::stage] #{source} -> (jail)/#{target}" | |||
| def exec(command) | |||
| pid = Process.fork do | |||
| Dir.chdir @root | |||
| # TODO: rlimit in exec, umask? | |||
| Process.exec command | |||
| end | |||
| Process.waitpid pid, 0 | |||
| end | |||
| end | |||
| end | |||
| @@ -48,30 +48,24 @@ module KGrader | |||
| end | |||
| def grade | |||
| # TODO: | |||
| # self.status = :ungraded | |||
| self.status = :ungraded | |||
| stage | |||
| # [grade the stuff] | |||
| # [save report to gradefile] | |||
| # @fs.jail.reset | |||
| # FileUtils.touch pendingfile | |||
| # self.status = :graded | |||
| # return grade summary string | |||
| sleep rand / 2 | |||
| '100%' | |||
| build | |||
| test | |||
| save | |||
| # self.status = :graded # UNCOMMENT | |||
| # @fs.jail.reset # UNCOMMENT | |||
| # TODO: return grade summary string | |||
| end | |||
| def commit | |||
| # TODO: | |||
| # if status == :graded && File.exists? pendingfile | |||
| # [copy gradefile to repo] | |||
| # @course.backend.commit repo, <message>, <gradefile path> | |||
| # FileUtils.rm pendingfile | |||
| # end | |||
| sleep rand / 2 | |||
| nil | |||
| if status == :graded && File.exists?(pendingfile) | |||
| target = File.join(repo, @assignment.report) | |||
| message = @assignment.commit_message @student | |||
| FileUtils.cp gradefile, target | |||
| @course.backend.commit repo, message, target | |||
| FileUtils.rm pendingfile | |||
| end | |||
| end | |||
| private | |||
| @@ -118,5 +112,22 @@ module KGrader | |||
| @fs.jail.stage File.join(repo, entry[:name]), entry[:name] | |||
| end | |||
| end | |||
| def build | |||
| @assignment.build_steps.each do |command| | |||
| @fs.jail.exec command | |||
| end | |||
| end | |||
| def test | |||
| @assignment.tests.each do |script| | |||
| # TODO: execute script in jail | |||
| end | |||
| end | |||
| def save | |||
| # TODO: save gradefile | |||
| FileUtils.touch pendingfile | |||
| end | |||
| end | |||
| end | |||
| @@ -1 +1 @@ | |||
| Subproject commit 438e509e4c9097894f275dd66a5ae37bbcb62c24 | |||
| Subproject commit f9cb0aabbe48368ef7a8db6c43e7d81e71d2c4fa | |||