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.

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