A code autograder for student homework submissions
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

84 lignes
2.1 KiB

  1. require 'io/console'
  2. require 'nokogiri'
  3. require 'open3'
  4. module KGrader::Backend
  5. class SVN
  6. def initialize(filesystem, course, config)
  7. @fs = filesystem
  8. @course = course
  9. @config = config
  10. @password = nil
  11. end
  12. def prepare(semester, assignment)
  13. return unless @config['verify']
  14. unless test_okay
  15. print "svn: password: "
  16. @password = STDIN.noecho(&:gets).chomp
  17. print "svn: bad password or other network issues" unless test_okay
  18. end
  19. end
  20. def revision(repo)
  21. xml = Nokogiri::XML run('log', '--xml', '-l', '1', repo).first
  22. xml.css('logentry').attr('revision').value.to_i
  23. end
  24. def clone(repo, semester, assignment, student)
  25. url = get_url semester, assignment, student
  26. run 'checkout', '--ignore-externals', url, repo
  27. end
  28. def update(repo, revision = nil)
  29. args = 'update', '--ignore-externals', '--accept', 'tf'
  30. args.push "-r#{revision}" unless revision.nil?
  31. run *args, repo
  32. end
  33. def log(repo)
  34. xml = Nokogiri::XML run('log', '--xml', repo).first
  35. xml.css('logentry').map do |elem|
  36. { :rev => elem.attr('revision').to_i,
  37. :date => Time.parse(elem.css('date').text) }
  38. end
  39. end
  40. def commit(repo, message, paths = nil)
  41. run 'commit', '-m', message, *paths.map { |fn| File.join repo, fn }
  42. end
  43. def commit_date(repo)
  44. xml = Nokogiri::XML run('log', '--xml', '-l', '1', repo).first
  45. Time.parse xml.css('logentry date').text
  46. end
  47. private
  48. def run(*cmd)
  49. if @password
  50. cmd.unshift @password
  51. cmd.unshift '--password'
  52. end
  53. Open3.capture2e('svn', *cmd)
  54. end
  55. def get_url(semester, assignment, student)
  56. @config['url'] % {
  57. :semester => semester,
  58. :assignment => assignment,
  59. :student => student
  60. }
  61. end
  62. def test_okay
  63. url = @config['verify'] % {
  64. :semester => semester,
  65. :assignment => assignment
  66. }
  67. status = run('list', '--non-interactive', url)[1]
  68. status.exited? && status.exitstatus == 0
  69. end
  70. end
  71. end