much more recent version
This commit is contained in:
parent
0f74918ea7
commit
1180ccdbe3
1 changed files with 236 additions and 19 deletions
|
|
@ -3,22 +3,6 @@
|
||||||
# $Id$
|
# $Id$
|
||||||
# $URL$
|
# $URL$
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2007, 2008 Ward Wouts <ward@wouts.nl>
|
|
||||||
#
|
|
||||||
# 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 'net/https'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
require 'rexml/document'
|
require 'rexml/document'
|
||||||
|
|
@ -120,12 +104,109 @@ class DSParse
|
||||||
end
|
end
|
||||||
end # class DSParse
|
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
|
def usage
|
||||||
puts <<EOT
|
puts <<EOT
|
||||||
Usage: #{$0.sub(/.*\//, "")} [options] -u <baseurl>
|
Usage: #{$0.sub(/.*\//, "")} [options] -u <baseurl>
|
||||||
|
|
||||||
-h, --help show this message
|
-h, --help show this message
|
||||||
-m <svn|cvs|ds> check for one of subversion, CVS or .DS_Store (default: all)
|
-H harvest subversion repositories. Tip: svn revert $(svn st|sed 's/^!//')
|
||||||
|
-m <svn|cvs|git|ds> check for one of subversion, CVS, git or .DS_Store (default: all)
|
||||||
-u <baseurl> set baseurl
|
-u <baseurl> set baseurl
|
||||||
-s use ssl
|
-s use ssl
|
||||||
EOT
|
EOT
|
||||||
|
|
@ -137,6 +218,7 @@ def cmdline
|
||||||
begin
|
begin
|
||||||
opts = GetoptLong.new(
|
opts = GetoptLong.new(
|
||||||
[ "-h", "--help", GetoptLong::NO_ARGUMENT ],
|
[ "-h", "--help", GetoptLong::NO_ARGUMENT ],
|
||||||
|
[ "-H", GetoptLong::NO_ARGUMENT ],
|
||||||
[ "-m", GetoptLong::REQUIRED_ARGUMENT ],
|
[ "-m", GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
[ "-u", GetoptLong::REQUIRED_ARGUMENT ],
|
[ "-u", GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
[ "-s", GetoptLong::NO_ARGUMENT ]
|
[ "-s", GetoptLong::NO_ARGUMENT ]
|
||||||
|
|
@ -154,6 +236,7 @@ def cmdline
|
||||||
if options["-h"]
|
if options["-h"]
|
||||||
usage
|
usage
|
||||||
end
|
end
|
||||||
|
@harvest = options["-H"]
|
||||||
return options
|
return options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -198,6 +281,68 @@ def fetch(uri_str, limit = 10)
|
||||||
end
|
end
|
||||||
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)
|
def svnparse(url)
|
||||||
puts "\n#{url}"
|
puts "\n#{url}"
|
||||||
begin
|
begin
|
||||||
|
|
@ -219,13 +364,15 @@ def svnparse(url)
|
||||||
end
|
end
|
||||||
puts "#{item.attribute("name")}/"
|
puts "#{item.attribute("name")}/"
|
||||||
dirs.push(item.attribute("name").to_s)
|
dirs.push(item.attribute("name").to_s)
|
||||||
|
svnharvestdir(url, item.attribute("name").to_s) if @harvest
|
||||||
when "file" then
|
when "file" then
|
||||||
puts "#{item.attribute("name")} #{item.attribute("last-author")} #{item.attribute("committed-date")}"
|
puts "#{item.attribute("name")} #{item.attribute("last-author")} #{item.attribute("committed-date")}"
|
||||||
|
svnharvestfile(url, item.attribute("name").to_s) if @harvest
|
||||||
else
|
else
|
||||||
puts " Strange kind #{item.attribute("kind")}"
|
puts " Strange kind #{item.attribute("kind")}"
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
when '8'
|
when '8', '9'
|
||||||
lastline = ""
|
lastline = ""
|
||||||
commitdate = ""
|
commitdate = ""
|
||||||
author = ""
|
author = ""
|
||||||
|
|
@ -247,8 +394,10 @@ def svnparse(url)
|
||||||
end
|
end
|
||||||
puts "#{lastline}/"
|
puts "#{lastline}/"
|
||||||
dirs.push lastline
|
dirs.push lastline
|
||||||
|
svnharvestdir(url, lastline) if @harvest
|
||||||
when 'file'
|
when 'file'
|
||||||
puts "#{lastline} #{author} #{commitdate}"
|
puts "#{lastline} #{author} #{commitdate}"
|
||||||
|
svnharvestfile(url, lastline) if @harvest
|
||||||
else
|
else
|
||||||
lastline = line
|
lastline = line
|
||||||
end
|
end
|
||||||
|
|
@ -258,7 +407,14 @@ def svnparse(url)
|
||||||
end
|
end
|
||||||
dirs.each{|dir|
|
dirs.each{|dir|
|
||||||
#p "#{url}/#{dir}"
|
#p "#{url}/#{dir}"
|
||||||
|
if @harvest
|
||||||
|
curdir = Dir.getwd
|
||||||
|
Dir.chdir(dir)
|
||||||
svnparse("#{url}/#{dir}")
|
svnparse("#{url}/#{dir}")
|
||||||
|
Dir.chdir(curdir)
|
||||||
|
else
|
||||||
|
svnparse("#{url}/#{dir}")
|
||||||
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -325,13 +481,45 @@ def dsparse(url)
|
||||||
}
|
}
|
||||||
end
|
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)
|
def checksvn(url)
|
||||||
begin
|
begin
|
||||||
puts "==================================================="
|
puts "==================================================="
|
||||||
body = fetch("#{url}/.svn/entries")
|
body = fetch("#{url}/.svn/entries")
|
||||||
puts "Subversion info found:"
|
puts "Subversion info found:"
|
||||||
|
svnharvestdir(url, ".") if @harvest
|
||||||
svnparse(url)
|
svnparse(url)
|
||||||
rescue
|
rescue
|
||||||
|
puts "No subversion info found"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -342,6 +530,7 @@ def checkcvs(url)
|
||||||
puts "CVS info found:"
|
puts "CVS info found:"
|
||||||
cvsparse(url)
|
cvsparse(url)
|
||||||
rescue
|
rescue
|
||||||
|
puts "No CVS info found"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -352,6 +541,18 @@ def checkds(url)
|
||||||
puts ".DS_Store file found:"
|
puts ".DS_Store file found:"
|
||||||
dsparse(url)
|
dsparse(url)
|
||||||
rescue
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -370,10 +571,24 @@ else
|
||||||
@use_ssl = false
|
@use_ssl = false
|
||||||
end
|
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?
|
if options["-m"].nil?
|
||||||
checksvn(options["-u"])
|
checksvn(options["-u"])
|
||||||
checkcvs(options["-u"])
|
checkcvs(options["-u"])
|
||||||
checkds(options["-u"])
|
checkds(options["-u"])
|
||||||
|
checkgit(options["-u"])
|
||||||
else
|
else
|
||||||
case options["-m"]
|
case options["-m"]
|
||||||
when "svn"
|
when "svn"
|
||||||
|
|
@ -382,5 +597,7 @@ else
|
||||||
checkcvs(options["-u"])
|
checkcvs(options["-u"])
|
||||||
when "ds"
|
when "ds"
|
||||||
checkds(options["-u"])
|
checkds(options["-u"])
|
||||||
|
when "git"
|
||||||
|
checkgit(options["-u"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue