Wednesday, March 28, 2007

Recursion

It has been a long long time (>10 years) since I have written any recursive code. Today, for the first time in my life I was in need of a practical one.

In one of our projects we use Subversion as our source control tool (the other one is Visual Source Safe). Subversion has an annoying habit of creating hidden .svn directories in all the directories you checkout. These .svn directories contain a lot of pesky little files which take a lot of time when you try to copy or delete directories of large projects.

So, I wanted a tool that would automatically remove .svn from all the subdirectories. Since I have a few programming tricks up my sleeve, I could do it myself. Recursion was the way to go. I toyed with the idea of using Phyton, Perl and Ruby. But then I went back to our good old Matlab (yeah, lazy here) and wrote the following recursive script (update: Code re-designed and refactored):

%--- This is the main Matlab script ---
%Remove all .svn direcotries in and under current directory
clc; clear all;
global svnCount
tic
disp('Checking for .svn directories...')
svnCount = 0;
fileList = dir; %get list of files and dir's in current dir
deleteSVNDir('.',fileList) %delete .svn directories
disp(' ')
disp(['# of .svn directories removed = ',int2str(svnCount)])
disp('Finished.')
toc

%Delete all .svn directories
function f=deleteSVNDir(currentPath,fileList)
global svnCount

for i=3:length(fileList),
if fileList(i).isdir, %if it is a directory
aDir = fileList(i).name;
subPath = [currentPath,'\',aDir];
disp(subPath)
if strcmp((aDir),'.svn') %if it is .svn directory
rmdir(subPath,'s')
disp(['...deleted'])
disp(' ')
svnCount = svnCount+1;
end
%directory is not .svn and contains subdirectories
if ~strcmp((aDir),'.svn') && (containsSubDir(subPath))
newFileList = dir(subPath);
deleteSVNDir(subPath,newFileList); %recursive call
end %contains subdir
end %if dir
end %for

%checks if current path has subdirectories
function f = containsSubDir(currentPath)
result = false;
fileList = dir(currentPath);
for i=3:length(fileList)
if fileList(i).isdir, %if it is a directory
result=true;
break;
end
end
f=result;

2 comments:

Nart Bedin Atalay said...

Recursion'un hayırlı olsun.

.svn lerin icinde baska .svn lerde bulunuyorsa, once eldekileri silip sonra kalan alt dizinlere girmek daha hayirli olur gibi.

az da ukelalik edelim, bu recursion tek bir fonksiyonla da yazilabilirmis. oturup yaziyim dedim ama usendim.

tic/toc fonksiyonlarini sayende ogrenmis oldum. boyle seyler basit yarayisli ama ogrenmesi zor seyler nedense.

bol bol matlab kodu istirham edecegim ki benim de matlabim gelissin. perit'te matlab ogrenmek istiyormus. o da faydalanir.

Samil Korkmaz said...

Kıymetli görüşlerinizi dikkate alarak kodu güncelledim. Ayrıca ufak da bir bug vardı. Şöyle ki: Eski hali sadece deleteSVNDir fonskiyonu Matlab'ın tanıdığı bir path içindeyse (misal c:\MATLAB6p5\work\) çalışıyordu. Matlab'da "path" dersek Matlab'ın tanıdığı path'leri görebiliriz. Yeni kodda "cd" komutundan vazgeçerek ve "dir" komutunu daha efektif kullanarak Matlab'ın path'inde olma zorunluluğunu kaldırdım.

Nefis günler dilerim...