mixster
2009-10-07 02:13:40
Um, title kind of says it all.
Could be improved, but it works. I have tested for compiling and aside from a TBooleanArray and T2DStringArray, it seems like everything was fine (Scar 3.15b does not want them :().
It is somewhat intelligent in that it stores the version number when it installs, however it doesn't check for pre-existing files, so having the ini file without SRL would mean it would assume you have an up to date SRL until the next rev. Likewise, if you have an up to date SRL, but haven't got an ini file it will assume it is out of date.
I have made it parse and store the rev number separate from the includes, but you can change where it is stored. I've tried to use as little absolute paths to ensure it is somewhat flexible.
Edit: Pretty much complete rewrite. Has OO style, which has kind of made it a lot less readable, but it has allowed me to combine both a SRL and Scar SVN downloader. In case you didn't just twig, this time it can also download latest pre-release Scar. Just like with SRL, it will keep a little tab of the current version of Scar as well as SRL. Only extra info is that it stores the INI file of SVN rev details where you set the Scar directory, so if you use it for downloading Scar, SRL and moving plugins then it will all be good, else just switch it to '' if installing SRL to the Scar you will run the script with. It should also work better as I make it parse the local and remote paths better where as I kind of just made it work before by applying a couple of replaces. Overall it should be nicer, but I can't guarantee that :)
Could be improved, but it works. I have tested for compiling and aside from a TBooleanArray and T2DStringArray, it seems like everything was fine (Scar 3.15b does not want them :().
It is somewhat intelligent in that it stores the version number when it installs, however it doesn't check for pre-existing files, so having the ini file without SRL would mean it would assume you have an up to date SRL until the next rev. Likewise, if you have an up to date SRL, but haven't got an ini file it will assume it is out of date.
I have made it parse and store the rev number separate from the includes, but you can change where it is stored. I've tried to use as little absolute paths to ensure it is somewhat flexible.
const
CheckVersion = True;
DownloadSCAR = False;
DownloadSRL = True;
MoveSRLPlugins = True;
//SCARDirectory = 'C:\Program Files\SCAR 3.22 pre\';
RootDirectory = '';
SRLDirectory = 'Includes\SRL\';
var
SCARDirectory: string;
type
TFile = record
path, filename: string;
end;
TSVNFile = record
local, remote: TFile;
end;
TMatch = record
start, finish: string;
end;
TFilter = record
exp, dir, fil: string;
local, remote: TMatch;
end;
TSVN = record
name: string;
skip: TStringArray;
baseloc: TSVNFile;
files: array of TSVNFile;
filter: TFilter;
rev: TMatch;
col: Boolean;
end;
function srl_Explode(str, del: string): TStringArray;
{$IFNDEF SCAR320_UP}
var
i, l, dL: Integer;
begin
i := 0;
l := -1;
SetLength(Result, 0);
if (str = '') then
Exit;
dL := Length(del) - 1;
repeat
Inc(l);
SetLength(Result, l + 1);
i := Pos(del, str);
if i <= 0 then
Break;
Result[l] := Copy(str, 1, i - 1);
Delete(str, 1, i + dL);
until false
Result[l] := Copy(str, 1, Length(str));
{$ELSE}
begin
Result := Explode(del, str);
{$ENDIF}
end;
function ReturnPage(svn: TSVN; dir: TSVNFile): string;
var
url: string;
begin
url := svn.baseloc.remote.path + dir.remote.path;
try
Result := GetPage(url);
except
Writeln('Downloading url "' + url + '" failed');
Result := '';
end;
end;
procedure RawCollectSVN(var svn: TSVN; cur_dir: TSVNFile);
var
input, tmpLoc, tmpRem: string;
split: TStringArray;
h, i, t: Integer;
new_dir: TSVNFile;
sk: Boolean;
begin
input := ReturnPage(svn, cur_dir);
split := srl_Explode(input, svn.filter.exp);
for i := 0 to High(split) do
begin
for h := 0 to High(svn.skip) do
begin
sk := Pos(svn.skip[h], split[i]) > 0;
if sk then
Break;
end;
if sk then
Continue;
tmpLoc := Between(svn.filter.local.start, svn.filter.local.finish, split[i]);
tmpRem := Between(svn.filter.remote.start, svn.filter.remote.finish, split[i]);
if (tmpLoc = '') or (tmpRem = '') then
Continue;
if Pos(svn.filter.dir, split[i]) > 0 then // Handle directory
begin
new_dir.local.path := cur_dir.local.path + tmpLoc + '\';
new_dir.remote.path := cur_dir.remote.path + tmpRem;
Writeln('Discovered directory "' + tmpLoc + '"');
t := GetDebugLineCount - 1;
RawCollectSVN(svn, new_dir);
ReplaceDebugLine(t, 'Finished collecting from "' + tmpLoc + '"');
end
else if Pos(svn.filter.fil, split[i]) > 0 then // Handle file
begin;
h := Length(svn.files);
SetLength(svn.files, h + 1);
svn.files[h].local.path := cur_dir.local.path;
svn.files[h].local.filename := tmpLoc;
svn.files[h].remote.path := cur_dir.remote.path;
svn.files[h].remote.filename := tmpRem;
end;
end;
end;
procedure CollectSVN(var svn: TSVN);
var
start: TSVNFile;
t: Integer;
begin
Writeln('Now starting to collect "' + svn.name + '"');
t := GetSystemTime;
RawCollectSVN(svn, start);
svn.col := True;
t := GetSystemTime - t;
Writeln('Finished collecting "' + svn.name + '" in ' + IntToStr(t) + ' ms');
Writeln('A total of ' + IntToStr(Length(svn.files)) + ' files were collected');
end;
procedure DownloadSVN(svn: TSVN);
var
i, f, c, l, t, line: Integer;
begin
Writeln('Now starting to download "' + svn.name + '"');
Writeln('');
line := GetDebugLineCount - 1;
t := GetSystemTime;
c := 0;
l := Length(svn.files);
for i := 0 to l - 1 do
try
c := c + 1;
if c mod 10 = 0 then
ReplaceDebugLine(line, 'Downloading file ' + IntToStr(c) + ' of ' + IntToStr(l));
f := RewriteFile(svn.baseloc.local.path + svn.files[i].local.path + svn.files[i].local.filename, False);
WriteFileString(f, GetPage(svn.baseloc.remote.path + svn.files[i].remote.path + svn.files[i].remote.filename));
CloseFile(f);
except
Writeln('Failed to download file.');
end;
t := GetSystemTime - t;
Writeln('Finished downloading "' + svn.name + '" in ' + IntToStr(t) + ' ms');
end;
function ReturnSRLSVN: TSVN;
begin
Result.name := 'SRL';
Result.baseloc.remote.path := 'http://www.villavu.com/repositories/srl-opendev/';
Result.baseloc.local.path := SCARDirectory + SRLDirectory;
Result.filter.exp := '<';
Result.filter.dir := 'dir';
Result.filter.fil := 'file';
Result.filter.local.start := 'name="';
Result.filter.local.finish := '"';
Result.filter.remote.start := 'href="';
Result.filter.remote.finish := '"';
Result.rev.start := 'rev="';
Result.rev.finish := '"';
Result.skip := [];
end;
function ReturnSCARSVN: TSVN;
begin
Result.name := 'SCAR';
Result.baseloc.remote.path := 'http://freddy1990.com/svn/scarprerelease/';
Result.baseloc.local.path := SCARDirectory
Result.filter.exp := '<a';
Result.filter.dir := '/"';
Result.filter.fil := '.';
Result.filter.local.start := '">';
Result.filter.local.finish := '<';
Result.filter.remote.start := 'href="';
Result.filter.remote.finish := '"';
Result.rev.start := 'Revision ';
Result.rev.finish := ':';
Result.skip := ['http', '..'];
end;
function GetSVNVersion(svn: TSVN): Integer;
var
input: string;
begin
input := GetPage(svn.baseloc.remote.path);
Result := StrToIntDef(Between(svn.rev.start, svn.rev.finish, input), 0);
end;
procedure WriteSVNVersion(svn: TSVN);
var
rev: Integer;
begin
rev := GetSVNVersion(svn);
if rev = 0 then
begin
Writeln('Collecting rev number failed');
Writeln('You can manually set svn_settings.ini if this results in a problem');
exit;
end;
WriteINI(svn.name, 'REVISION', IntToStr(rev), SCARDirectory + 'svn_settings.ini');
end;
function IsSVNOld(svn: TSVN): Boolean;
var
curRev, locRev: Integer;
begin
locRev := StrToIntDef(ReadINI(svn.name, 'REVISION', AppPath + 'svn_settings.ini'), 0);
curRev := GetSVNVersion(svn);
if curRev = 0 then
begin
Writeln('Collecting current rev number failed');
Writeln('Assuming newer SVN is on local system to avoid problems');
Result := False;
exit;
end;
Result := locRev < curRev;
if Result then
Writeln(svn.name + ' has the latest rev downloaded')
else
Writeln(svn.name + ' is rev ' + IntToStr(locRev) + ' and latest is ' + IntToStr(curRev));
end;
procedure MovePlugins(svn: TSVN; dest: string);
var
i, f: Integer;
s: string;
o: Boolean;
begin
for i := 0 to High(svn.files) do
if ExtractFileExt(svn.files[i].local.filename) = '.dll' then
try
Writeln('Found plugin "' + svn.files[i].local.filename);
o := False;
f := OpenFile(svn.baseloc.local.path + svn.files[i].local.path + svn.files[i].local.filename, False);
ReadFileString(f, s, FileSize(f));
CloseFile(f);
o := True;
f := RewriteFile(dest + svn.files[i].local.filename, False);
WriteFileString(f, s);
CloseFile(f);
except
Writeln('Failed to save plugin.');
if o then
Writeln('Problem involved rewriting the file at target folder')
else
Writeln('Problem involved opening the sauce file to read');
end;
end;
var
scar, srl: TSVN;
begin
Writeln('Begin');
SCARDirectory := RootDirectory;
if SCARDirectory = '' then
SCARDirectory := AppPath;
scar := ReturnSCARSVN;
srl := ReturnSRLSVN;
if DownloadSCAR then
begin
if (not CheckVersion) or (CheckVersion and IsSVNOld(scar)) then
begin
CollectSVN(scar);
DownloadSVN(scar);
end;
end;
if DownloadSRL then
begin
if (not CheckVersion) or (CheckVersion and IsSVNOld(srl)) then
begin
CollectSVN(srl);
DownloadSVN(srl);
if MoveSRLPlugins then
MovePlugins(srl, scar.baseloc.local.path + 'Plugins\');
end;
end else if MoveSRLPlugins then
begin
CollectSVN(srl);
MovePlugins(srl, scar.baseloc.local.path + 'Plugins\');
end;
Writeln('End');
end.Edit: Pretty much complete rewrite. Has OO style, which has kind of made it a lot less readable, but it has allowed me to combine both a SRL and Scar SVN downloader. In case you didn't just twig, this time it can also download latest pre-release Scar. Just like with SRL, it will keep a little tab of the current version of Scar as well as SRL. Only extra info is that it stores the INI file of SVN rev details where you set the Scar directory, so if you use it for downloading Scar, SRL and moving plugins then it will all be good, else just switch it to '' if installing SRL to the Scar you will run the script with. It should also work better as I make it parse the local and remote paths better where as I kind of just made it work before by applying a couple of replaces. Overall it should be nicer, but I can't guarantee that :)