Rakefile 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. # FreeBSD Ports
  2. #
  3. # Douglas Thrift
  4. #
  5. # Rakefile
  6. require 'date'
  7. require 'ostruct'
  8. require 'pathname'
  9. require 'pry'
  10. require 'set'
  11. Color = Pry::Helpers::Text
  12. def in_portdir(&block)
  13. Dir.chdir(Rake.original_dir) do |portdir|
  14. block.call(Pathname.new(portdir))
  15. end
  16. end
  17. def in_portstree(portstree, &block)
  18. portstree_zfs = `zfs get -H -o name mountpoint #{portstree.path}`.chomp
  19. sh "sudo zfs snapshot #{portstree_zfs}@clean"
  20. Dir.chdir(portstree.path) do
  21. block.call(portstree.path)
  22. end
  23. ensure
  24. sh "sudo zfs rollback #{portstree_zfs}@clean"
  25. sh "sudo zfs destroy #{portstree_zfs}@clean"
  26. end
  27. def update_portstree_map(map = {})
  28. `poudriere ports -l -q`.each_line do |line|
  29. line.chomp!
  30. if line =~ /^([^ ]+) +([^ ]+) +([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}) +([^ ]+)$/
  31. map[$1.to_sym] = OpenStruct.new(method: $2, timestamp: DateTime.parse($3), path: Pathname.new($4))
  32. else
  33. raise "unexpected line: #{line}"
  34. end
  35. end
  36. map
  37. end
  38. portstree_map = update_portstree_map
  39. portsdir = Pathname.pwd
  40. distdir = portsdir.join('distfiles')
  41. task default: %i(update_githead update_svnhead)
  42. desc 'Create or update the port checksum file (distinfo)'
  43. task :makesum do
  44. in_portdir do
  45. sh "make makesum DEV_WARNING_WAIT=0 DISTDIR=#{distdir}"
  46. end
  47. end
  48. %w(md5 sha1 sha256).each do |sum|
  49. desc "Show the #{sum.upcase} sums of the distfiles"
  50. task sum do
  51. sh "mkdir -p #{distdir}" unless distdir.exist?
  52. sh "#{sum} #{distdir.join('*')}"
  53. end
  54. end
  55. desc 'Remove the ports distfiles'
  56. task :distclean do
  57. in_portdir do
  58. sh "make distclean DISTDIR=#{distdir}"
  59. end
  60. end
  61. desc 'Verify the port using portlint'
  62. task portlint: :update_githead do
  63. in_portdir do |portdir|
  64. if githead_portstree.path.join(portdir.relative_path_from(portsdir), 'Makefile').exist?
  65. sh "portlint -C"
  66. else
  67. sh "portlint -A"
  68. end
  69. end
  70. end
  71. desc 'Show the port differences'
  72. task diff: :update_svnhead do |_, args|
  73. patch = args.extras.find {|arg| arg == 'patch'}
  74. in_portdir do |portdir|
  75. new_files = Set.new(`git ls-files`.each_line.map{|line| Pathname.new(line.chomp)})
  76. in_portstree(svnhead_portstree) do |path|
  77. rel_portdir = portdir.relative_path_from(portsdir)
  78. svnhead_portdir = path.join(rel_portdir)
  79. if svnhead_portdir.exist?
  80. old_files = Set.new(`svn ls -R #{svnhead_portdir}`.each_line.reject {|line| line =~ %r{/$}}.map {|line| Pathname.new(line.chomp)})
  81. else
  82. old_files = Set.new
  83. end
  84. sh "sudo mkdir -p #{svnhead_portdir}"
  85. Dir.chdir(svnhead_portdir) do
  86. new_files.each do |file|
  87. portdir_file = portdir.join(file)
  88. sh "sudo mkdir -p #{file.dirname}" unless file.dirname.exist?
  89. sh "sudo cp #{portdir_file} #{file}"
  90. end
  91. (old_files - new_files).each do |file|
  92. sh "sudo svn add --parents #{file}"
  93. end
  94. (new_files - old_files).each do |file|
  95. sh "sudo svn remove #{file}"
  96. end
  97. unless old_files.empty?
  98. if patch
  99. sh "svn diff > #{portdir.dirname.join("#{`make -V PKGNAME`.chomp}.diff")}"
  100. else
  101. sh "svn diff"
  102. end
  103. end
  104. end
  105. if old_files.empty?
  106. if patch
  107. sh "svn diff #{rel_portdir} > #{portsdir.join("#{portdir.basename}.diff")}"
  108. else
  109. sh "svn diff #{rel_portdir}"
  110. end
  111. end
  112. end
  113. end
  114. end
  115. {githead: 'git+https', svnhead: 'svn+https'}.each do |name, method|
  116. define_method("#{name}_portstree") do
  117. portstree_map[name]
  118. end
  119. desc "Create or update the #{name} portstree"
  120. task "update_#{name}" do |_, args|
  121. force = args.extras.find {|arg| arg == 'force'}
  122. portstree = portstree_map[name]
  123. if portstree
  124. raise "unexpected portstree method for #{name}: #{portstree[:method]} (expected: #{method})" if portstree[:method] != method
  125. if force || portstree.timestamp < Date.today
  126. sh "sudo poudriere ports -u -p #{name}"
  127. end
  128. else
  129. sh "sudo poudriere ports -c -m #{method} -p #{name}"
  130. update_portstree_map(portstree_map)
  131. end
  132. end
  133. end