From 1180ccdbe3a828c442428400616ac6cc034b5d41 Mon Sep 17 00:00:00 2001 From: Ward Wouts Date: Wed, 19 May 2010 11:07:11 +0000 Subject: [PATCH] much more recent version --- listversioned/listversioned.rb | 255 ++++++++++++++++++++++++++++++--- 1 file changed, 236 insertions(+), 19 deletions(-) diff --git a/listversioned/listversioned.rb b/listversioned/listversioned.rb index fb09721..e5db772 100755 --- a/listversioned/listversioned.rb +++ b/listversioned/listversioned.rb @@ -3,22 +3,6 @@ # $Id$ # $URL$ -# -# Copyright (c) 2007, 2008 Ward Wouts -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - require 'net/https' require 'uri' require 'rexml/document' @@ -120,12 +104,109 @@ class DSParse end end # class DSParse +class GitParse + # info over Git index files is te vinden op http://git.rsbx.net/Documents/Git_Data_Formats.txt + def initialize + @store = Array.new + end + + def arr2long(arr) + return (arr[0]<<24) + (arr[1]<<16) + (arr[2]<<8) + arr[3] + end + + def arr2string(arr) + string = "" + (0...arr.length).step{|i| + string += (arr[i]).chr + } + return string + end + + def readfile(filename) + @store = Array.new + File.open(filename).each_byte{|byte| + @store.push byte + } + end + + def readstring(string) + @store = Array.new + string.each_byte{|byte| + @store.push byte + } + end + + def isgit? + # 00 00 00 01 42 75 64 31 + # kan vast netter, don't care + @store[0] == 0x44 && @store[1] == 0x49 && @store[2] == 0x52 && @store[3] == 0x43 + end + + def gitversion + version = arr2long(@store[4, 4]) + end + + def entrycount + count = arr2long(@store[8, 4]) + end + + def entries + filenames= Array.new + # eerste heeft altijd een offset van 12 + offset = 12 + (0..entrycount).each{ + name, offset = statinfo(offset) + filenames.push name + } + filenames + end + + def statinfo(offset) +# ctime = arr2long(@store[offset, 8]) +# mtime = arr2long(@store[offset+8, 8]) +# dev = arr2long(@store[offset+16, 4]) +# inode = arr2long(@store[offset+20, 4]) +# mode = arr2long(@store[offset+24, 4]) +# uid = arr2long(@store[offset+28, 4]) +# gid = arr2long(@store[offset+32, 4]) +# size = arr2long(@store[offset+36, 4]) +#p uid +#p gid +#p size + +# entryid = arr2long(@store[offset+40, 4]) # hoe groot is zo'n object ID? +# entryflags = arr2long(@store[offset+44, 2]) + i = offset+62 + name = "" + while true + if @store[i] == 0x00 + i += 1 + break + else + name += @store[i].chr + end + i += 1 + end + cl = i-offset + plus = cl + if cl.modulo(8) != 0 + plus += 8 - cl.modulo(8) + end + nextoffset = offset + plus + + return name, nextoffset + end + +end # class GitParse + + def usage puts < -h, --help show this message --m check for one of subversion, CVS or .DS_Store (default: all) +-H harvest subversion repositories. Tip: svn revert $(svn st|sed 's/^!//') +-m check for one of subversion, CVS, git or .DS_Store (default: all) -u set baseurl -s use ssl EOT @@ -137,6 +218,7 @@ def cmdline begin opts = GetoptLong.new( [ "-h", "--help", GetoptLong::NO_ARGUMENT ], + [ "-H", GetoptLong::NO_ARGUMENT ], [ "-m", GetoptLong::REQUIRED_ARGUMENT ], [ "-u", GetoptLong::REQUIRED_ARGUMENT ], [ "-s", GetoptLong::NO_ARGUMENT ] @@ -154,6 +236,7 @@ def cmdline if options["-h"] usage end + @harvest = options["-H"] return options end @@ -198,6 +281,68 @@ def fetch(uri_str, limit = 10) end end +def svnharvestdir(url, name) + [ "#{name}", + "#{name}/.svn", + "#{name}/.svn/prop-base", + "#{name}/.svn/props", + "#{name}/.svn/text-base", + "#{name}/.svn/tmp", + "#{name}/.svn/tmp/prop-base", + "#{name}/.svn/tmp/props", + "#{name}/.svn/tmp/text-base", + "#{name}/.svn/tmp/wcprops", + "#{name}/.svn/wcprops" ].each{|dir| + begin + Dir.mkdir(dir) + rescue Errno::EEXIST + end + } + [ "README.txt", "all-wcprops", "empty-file", "entries", "format" ].each{|file| + begin + body = fetch("#{url}/#{name}/.svn/#{file}") + rescue Net::HTTPServerException + next + end + if body.nil? + next + end + begin + File.open("#{name}/.svn/#{file}", "w"){|f| + f.print body + } + rescue + p $! + end + } +end + +def svnharvestfile(url, lastline) + [ "prop-base", "props", "text-base", "tmp/prop-base", "tmp/props", "tmp/text-base", "tmp/wcprops", "wcprops" ].each{|subdir| + ext = ".svn-base" + if subdir.match(/s$/) + ext = ".svn-work" + end + begin + body = fetch("#{url}/.svn/#{subdir}/#{lastline}#{ext}") + rescue Net::HTTPServerException + next + end + if body.nil? + next + else + begin + File.open("#{Dir.getwd}/.svn/#{subdir}/#{lastline}#{ext}", "w"){|f| + f.print body + } + rescue + p "rescue File.open() in svnharvestfile(url, lastline)" + p $! + end + end + } +end + def svnparse(url) puts "\n#{url}" begin @@ -219,13 +364,15 @@ def svnparse(url) end puts "#{item.attribute("name")}/" dirs.push(item.attribute("name").to_s) + svnharvestdir(url, item.attribute("name").to_s) if @harvest when "file" then puts "#{item.attribute("name")} #{item.attribute("last-author")} #{item.attribute("committed-date")}" + svnharvestfile(url, item.attribute("name").to_s) if @harvest else puts " Strange kind #{item.attribute("kind")}" end } - when '8' + when '8', '9' lastline = "" commitdate = "" author = "" @@ -247,8 +394,10 @@ def svnparse(url) end puts "#{lastline}/" dirs.push lastline + svnharvestdir(url, lastline) if @harvest when 'file' puts "#{lastline} #{author} #{commitdate}" + svnharvestfile(url, lastline) if @harvest else lastline = line end @@ -258,7 +407,14 @@ def svnparse(url) end dirs.each{|dir| #p "#{url}/#{dir}" - svnparse("#{url}/#{dir}") + if @harvest + curdir = Dir.getwd + Dir.chdir(dir) + svnparse("#{url}/#{dir}") + Dir.chdir(curdir) + else + svnparse("#{url}/#{dir}") + end } end @@ -325,13 +481,45 @@ def dsparse(url) } end +def gitparse(url) + puts "\n#{url}" + git = GitParse.new + begin + body = fetch("#{url}/.git/index") + rescue + end + if body.nil? + return + end + git.readstring(body) + if ! git.isgit? + $stderr.puts "Not a git index format file" + return + end + if git.gitversion != 2 + p "Weird git version detected, this'll probably end up in tears" + end + git.gitversion + puts + git.entries.each{|name| + puts name + } + # begint met 'DIRC' + if ! body[0..3].to_s == 'DIRC' + $stderr.puts "Unknown Git index format found." + return + end +end + def checksvn(url) begin puts "===================================================" body = fetch("#{url}/.svn/entries") puts "Subversion info found:" + svnharvestdir(url, ".") if @harvest svnparse(url) rescue + puts "No subversion info found" end end @@ -342,6 +530,7 @@ def checkcvs(url) puts "CVS info found:" cvsparse(url) rescue + puts "No CVS info found" end end @@ -352,6 +541,18 @@ def checkds(url) puts ".DS_Store file found:" dsparse(url) rescue + puts "No .DS_store file found" + end +end + +def checkgit(url) + begin + puts "===================================================" + body = fetch("#{url}/.git/index") + puts "Git info found:" + gitparse(url) + rescue + puts "No Git info found" end end @@ -370,10 +571,24 @@ else @use_ssl = false end +# lelijke hack, wanneer andere formaten ook geharvest gaan kunnen worden moet dit +# anders. Nu, ach, dit werkt. +if options["-H"] + # even controleren of er al een .svn dir staat op deze locatie + # entries en andere bestanden zijn read-only, dus de rest loopt er op + # stuk. Bovendien wil je het zeer waarschijnlijk niet. Echt niet. + if FileTest.exists?(".svn") + STDERR.puts ".svn dir found at current location" + STDERR.puts "please use a different location" + exit + end +end + if options["-m"].nil? checksvn(options["-u"]) checkcvs(options["-u"]) checkds(options["-u"]) + checkgit(options["-u"]) else case options["-m"] when "svn" @@ -382,5 +597,7 @@ else checkcvs(options["-u"]) when "ds" checkds(options["-u"]) + when "git" + checkgit(options["-u"]) end end