#!/usr/bin/perl -w #Justus Stadler, Juni2009 #Dieses Program soll die Änderungen an einem Archiv bei jedem Übertragen in die Datei "exports.txt" speichern. #Weiterhin werden die veränderten Dateien exportiert(bei hinzugefügt oder geändert) oder gelöscht(bei gelöscht). #Es wird durch die "post-commit.bat" mit folgendem Inhalt ausglöst: #The problem this script has to take care of is the following: #Users who do not have SVN installed (lets call them the "MAN")need to have the chance to look at the projectstatus. #Up until now the Engineers worked all together on a networkdrive(projektfolder=projectverzeichnis) so the MAN #only had to open the folder in the networkdrive to look at it. #Now with SVN this projectfolder has become unused because the engineers check out a workingcopy from the repo to #their local harddrive. But the MAN still wants to look at the status. So I thought about a way to make it happen... #My first idea was using WEBDAV. We are using svnserve, so forget it! #Second idea was putting a working copy in the projectfolder. But because we have hughe projects(some GB each) this #was too expensive. #So why not exporting the trunk? Well, same answer. Some GB take "some" time! Additionaly exporting does not delete:-( #That's why I wrote this. Please have mercy with my programming, but I know "Perl" for about a week now! #It is pretty ugly but it works! #Please feel free to change anything to your liking! #This script was written to get a list of changed, added or deleted files in the trunk for every commit and #to export these to a projektfolder(=$projektverzeichnis). It is designed to work on a svnserve Server run as a service on a Windows XP machine. #The Repos are located on a networkdrive($archivpfad) and therefore have to be adressed via UNC-path. #Please note that it works for a rep with several projects(=projektname). Stamm=trunk, Zweig=branches, Musterstand=tags #print FILE and die with english output are commented out below the german version. #If you plan to use this script please comment out all the "system $somecommand" commands. First check in info.txt what #your command would look like. The commands executed by system are always printed in info.txt first! #Before running this script for the first time, you will have to export the hole trunk. But only this one time. In future #this script will do that work for you! #It is triggered by the following "post-commit.bat" #@echo off #Set PATH=%PATH%;C:\Spezial\Perl\bin; #echo "%1" > C:\Spezial\perltest\temp\URL_temp.txt #C: #cd \Spezial\perltest #perl export_EAMi.txt 1>&2 ######Definitionen###### $i = 0; $j = 0; $url = "svn://c02l14ws0166/"; #Die URL des CAD-Rechners #our URL #$EAMi = "\\\\Europe.kspag.de\\europe\\Pierburg\\_P-CE\\Electronic\\30000_projects\\7.03206.00 EAMi GME M&H\\"; $EAMi = "\\\\Europe.kspag.de\\europe\\Pierburg\\_P-CE\\Electronic\\50000_external\\Arbeitskopie\\CA44000\\7.03206.00 EAMi GME M&H\\"; #Das Projektverzeichnis von EAMi_GME wird später als $projektverzeichnis gesetzt! $temp = "C:\\Spezial\\perltest\\temp"; #a folder where the script gets its information from and where you get your debugging info.txt open(INFO, ">$temp\\info.txt"); #zur Ablage von Zwischenergebnissen zum debuggen #for debugging &url_beziehen; #gibt den Pfad zu dem Archiv in $zeileurl aus #returns the root of the repo in $zeileurl but like "ROOT"; #ließt den archivnamen aus #gets the reponame in $archivname $start = rindex($zeileurl,"\\")+1; $stop = rindex($zeileurl,"\""); $stop = $stop-$start; $archivname = substr($zeileurl,$start,$stop); #liest den archivpfad aus #gets the root like ROOT $stop = rindex($zeileurl,"\""); $stop = $stop-1; $archivpfad[$j] = substr($zeileurl,1,$stop); print INFO "Der Archivpfad lautet: \"$archivpfad[$j]\"\nDer Name des Archivs lautet: \"$archivname\"\n"; #print INFO "The Path to the repo is: \"$archivpfad[$j]\"\nThe name of the repo is: \"$archivname\"\n"; &look; #erstellt die Basis-Datei "exports.txt" und liest diese in den String "$zeile[$i]" #creates the file "exports.txt" in whitch all changes in this commit are recorded and saves them in $zeile[$i] &info; #einige Zusatzinformatinen die im späteren programm benötigt werden! #a lot of information that is needed for the export. see sub &info for further details ######Exportieren##### #Das eigentliche Exportieren. Es wird eine Liste mit exportierten Dateien angefertigt! #The export and deleting. It generates a file called "exportiert.txt" so you have a record of all changes for more than one commit! open(EXPORTIERT, ">>$temp\\exportiert.txt") || die "keine Datei zum festhalten der Exportergebnisse gefunden.\n"; #die "No file found for recording the exported files\n"; $j = 0; while($j<$i) { if($stamm[$j] eq 'Stamm') # Nur Falls der Stamm geändert wurde # Only in case of changes made to trunk. Changes to branches and tags are ignored in this script { if($aktion[$j] eq 'D ') # falls gelöscht wurd # if a file ore folder has been deleted { print INFO "\nEs wurde etwas gelöscht!\n"; #print INFO "\nSomething has been deleted!\n"; if($dateiname[$j] eq "") # falls es sich um einen Ordner handelt # if it is a folder { print INFO "Ein Ordner!\n\n"; #print INFO "A Folder!\n\n"; $loesch[$j] = "rd \"$exportpfad[$j]\" /s /q"; print INFO "\n\n$loesch[$j]!\n\n"; system "$loesch[$j]"; # löscht ganze Verzeichnisse # deletes the hole path with subfolders and files } else # falls es sich um eine Datei handelt # if it is a file { print INFO "Eine Datei!\n\n"; #print INFO "A file!\n\n"; unlink $exportpfad[$j]; # löscht nur die einzelne Datei # deletes the single file } print EXPORTIERT "$URL[$j]\n und\n$exportpfad[$j]\n wurden gelöscht!\n"; #print EXPORTIERT "$URL[$j]\n and\n$exportpfad[$j]\n have been deleted!\n"; } else # falls hinzugefügt, verändert, verschoben oder umbenannt # if added, changed, renamed or moved { $befehl[$j] = "svn export --force \"$URL[$j]\" \"$exportpfad[$j]\""; print INFO "EXPORT-Befehl: $befehl[$j]\n"; #print INFO "EXPORT-command: $befehl[$j]\n"; !system $befehl[$j] or die "Der EXPORT-Befehl ist nicht korrekt!"; #or die "The EXPORT-command is incorrect!"; print EXPORTIERT "Dies wurde exportiert:\n$URL[$j]!\n\n"; #print EXPORTIERT "This has been exported:\n$URL[$j]!\n\n"; } $j += 1; } } close(EXPORTIERT); close(INFO); ####################################URL################################### #Hier wird der Pfad des Archivs aus einer temporären Datei gelesen. sub url_beziehen { @zeilen = (""); open(URL, "<$temp\\URL_temp.txt") || die "Datei mit der URL nicht gefunden\n"; #die "file containing the URL not found\n"; while() { push(@zeilen,$_); } close(URL); for(@zeilen) { chomp($zeileurl = $_); } } #####################################look#################################### sub look { $befehl = "svnlook changed \"$archivpfad[$j]\" > $temp\\exports.txt"; print INFO "Der LOOK-Befehl lautet: \"$befehl\"!\n"; #print INFO "The LOOK-command is: \"$befehl\"!\n"; !system "$befehl" or die "Der LOOK-Befehl ist nicht korrekt!"; #or die "The LOOK-command is incorrect!"; #Die Änderungen werden in "exports.txt festgehalten. #The changes are recorded in "exports.txt" #Speichert die Inhalte der Datei in den String $zeile[$i] #saves the changes in $zeile[$i] open(EXP, "<$temp\\exports.txt") || die "Exportdatei nicht gefunden!\n"; #die "Exportfile not found!\n; while() { $zeile[$i] = $_; $i += 1; } close(EXP); } #####################################info#################################### sub info { while ($j<$i) { $stop = rindex($zeile[$j],"\""); $stop = $stop; chomp($datei[$j] = substr($zeile[$j],4,$stop)); $aktion[$j] = substr($zeile[$j],0,4); $stop = rindex($zeile[$j],"/"); $stop = $stop-4; chomp($verz[$j] = substr($zeile[$j],4,$stop)); print INFO "$datei[$j] wurde $aktion[$j]!\n$verz[$j]\n"; #print INFO "$datei[$j] has been $aktion[$j]!\n$verz[$j]\n"; #hol den Projektnamen #get the projectname $stop = index($datei[$j],"/"); $projektname[$j] = substr($datei[$j],0,$stop); print INFO "Der Projektname lautet: \"$projektname[$j]\"!\n"; #print INFO "the projectname is: \"$projektname[$j]\"!\n"; if ($projektname[$j] eq "EAMi_GME") { $projektverzeichnis = $EAMi; } #hol den Stamm #gets the first Folder after the projectname(Stamm, Zweig oder Musterstand/trunk, branch or tag) $start = index($datei[$j],"/")+1; $stamm[$j] = substr($datei[$j],$start); $verzeichnis[$j] = $stamm[$j]; $stop = index($stamm[$j],"/"); $stamm[$j] = substr($stamm[$j],0,$stop); print INFO "Der Stamm lautet: $stamm[$j]\n"; #print INFO "the tunk equals: $stamm[$j]\n"; #hol den "Rest" dazwischen #get the "stuff" between trunk and the filename $start = index($verzeichnis[$j],"/")+1; $verzeichnis[$j] = substr($verzeichnis[$j],$start); $stop = rindex($verzeichnis[$j],"/"); $rest[$j] = substr($verzeichnis[$j],0,$stop); #mach einen pfad daraus #convert it to a Windows-path with backslashes @felder = split /\//, $rest[$j]; $restpfad[$j] = join "\\", @felder; #hol den Dateinamen #gets the filename $start = rindex($verzeichnis[$j],"/")+1; $dateiname[$j] = substr($verzeichnis[$j],$start); #Test auf Ordner oder Datei #Tests if it is a folder or a file if($dateiname[$j] eq "") #falls es ein Ordner ist #if it is a folder { $URL[$j] = "$url$archivname/$projektname[$j]/$stamm[$j]/$rest[$j]"; $exportpfad[$j] = "$projektverzeichnis$restpfad[$j]"; if($rest[$j] eq "") #Falls der gesammte Stamm geändert wurde #in case the hole trunk has been changed { $URL[$j] = "$url$archivname/$projektname[$j]/$stamm[$j]"; $exportpfad[$j] = "$projektverzeichnis"; print INFO "!!!!!!!Der komplette Stamm wurde geändert.\n"; #print INFO "!!!!!!!The hole trunk has been changed.\n"; } print INFO "Der Rest lautet: $rest[$j]\n"; #print INFO "the path between trunk and foldername is: $rest[$j]\n"; print INFO "der Rest als Pfad lautet: $restpfad[$j]\n"; #print INFO "the path between trunk and foldername in windows is: $restpfad[$j]\n"; print INFO "Es handelt sich hierbei um einen Ordner!\n"; #print INFO "This is a folder!\n"; print INFO "Seine URL lautet:$URL[$j]\nSein Export wird lauten:$exportpfad[$j]\n"; #print INFO "Its URL is:$URL[$j]\nits Exportpath will be:$exportpfad[$j]\n"; } else #falls die Änderung direkt unterhalb von Stamm war #if th change has been made below of trunk { $rest[$j] = "$rest[$j]/"; if ($rest[$j] =~ /\./) #Damit nicht so etwast geschieht "....Stamm\Releasedokumentation.doc\Releasedokumentation.doc" #So something like this does not happen "....trunk\text.doc\text.doc" { print INFO "\nDie Datei befindet sich direkt unterhalb von Stamm.\n"; #print INFO "\nThe file is right below of trunk.\n"; $rest[$j] = ""; } $restpfad[$j] = "$restpfad[$j]\\"; #Das Selbe mit dem Pfad #Same with the path if ($restpfad[$j] =~ /\./) { $restpfad[$j] = ""; } $URL[$j] = "$url$archivname/$projektname[$j]/$stamm[$j]/$rest[$j]$dateiname[$j]"; $exportpfad[$j] = "$projektverzeichnis$restpfad[$j]$dateiname[$j]"; print INFO "Der Rest lautet: $rest[$j]\n"; #print INFO "the path between trunk and foldername is: $rest[$j]\n"; print INFO "der Rest als Pfad lautet: $restpfad[$j]\n"; #print INFO "the path between trunk and foldername in windows is: $restpfad[$j]\n"; print INFO "der Dateiname lautet: $dateiname[$j]!\n"; #print INFO "The filename is: $dateiname[$j]!\n"; print INFO "Ihre URL lautet:$URL[$j]\nIhr Export wird lauten:$exportpfad[$j]\n"; #print INFO "Its URL is:$URL[$j]\nits exportpath will be:$exportpfad[$j]\n"; } $j += 1; } }