178 lines
4.6 KiB
ObjectPascal

// SPDX-License-Identifier: LGPL-3.0-linking-exception
unit PackageFile;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, ReleaserTypes, fgl, laz2_XMLRead, laz2_XMLWrite, Laz2_DOM;
type
{ TPackageFile }
TPackageFile = class(TReleaserObject)
private
FFilename: string;
FLineEnding: string;
FXml: TXmlDocument;
FChanged: boolean;
function GetName: string;
public
constructor Create(AParameters: TStringList; ALogicDir: string); override;
destructor Destroy; override;
property Filename: string read FFilename;
function GetVersion: TVersion;
procedure GetVersions(AVersionList: TStringList); override;
procedure CheckVersion(AVersion: TVersion); override;
property Name: string read GetName;
procedure Save; override;
procedure UpdateVersion(AVersion: TVersion); override;
end;
TPackageFileList = specialize TFPGList<TPackageFile>;
implementation
{ TPackageFile }
function TPackageFile.GetName: string;
var
config, packageNode, nameNode: TDOMNode;
begin
config := FXml.FindNode('CONFIG');
if Assigned(config) then
begin
packageNode := config.FindNode('Package');
if Assigned(packageNode) then
begin
nameNode := packageNode.FindNode('Name');
if Assigned(nameNode) then
begin
with (nameNode as TDOMElement) do
begin
result := GetAttribute('Value');
exit;
end;
end;
end;
end;
result := ChangeFileExt(ExtractFileName(FFilename),'');
end;
constructor TPackageFile.Create(AParameters: TStringList; ALogicDir: string);
var
stream: TFileStream;
begin
inherited Create(AParameters, ALogicDir);
ExpectParamCount(1);
FFilename:= ExpandFileName(ReplaceVariables(Param[0]));
FLineEnding:= DetectLineEnding(FFilename);
stream := TFileStream.Create(FFilename, fmOpenRead);
try
ReadXMLFile(FXml,stream);
finally
stream.Free;
end;
writeln('Package ',Name,' version ',VersionToStr(GetVersion));
end;
destructor TPackageFile.Destroy;
begin
FXml.Free;
inherited Destroy;
end;
function TPackageFile.GetVersion: TVersion;
var
config, packageNode, versionNode: TDOMNode;
begin
config := FXml.FindNode('CONFIG');
if Assigned(config) then
begin
packageNode := config.FindNode('Package');
if Assigned(packageNode) then
begin
versionNode := packageNode.FindNode('Version');
if Assigned(versionNode) then
begin
with (versionNode as TDOMElement) do
begin
result.Major:= StrToIntDef(GetAttribute('Major'),0);
result.Minor:= StrToIntDef(GetAttribute('Minor'),0);
result.Release:= StrToIntDef(GetAttribute('Release'),0);
result.Build:= StrToIntDef(GetAttribute('Build'),0);
exit;
end;
end;
end;
end;
raise exception.Create('Version node not found');
end;
procedure TPackageFile.GetVersions(AVersionList: TStringList);
var
ver: TVersion;
verStr: String;
begin
ver := GetVersion;
verStr := VersionToStr(ver);
if AVersionList.IndexOf(verStr)=-1 then
AVersionList.Add(verStr);
end;
procedure TPackageFile.CheckVersion(AVersion: TVersion);
begin
inherited CheckVersion(AVersion);
if AVersion<>GetVersion then raise exception.Create('Inconsistent version of package '+Name);
end;
procedure TPackageFile.Save;
var textStream: TStringStream;
t: TextFile;
begin
if FChanged then
begin
writeln('Updating package ', Name,'...');
textStream := TStringStream.Create;
WriteXMLFile(FXml, textStream);
AssignFile(t, FFilename);
Rewrite(t);
Write(t, StringReplace(textStream.DataString, LineEnding, FLineEnding, [rfReplaceAll]));
CloseFile(t);
textStream.Free;
end;
end;
procedure TPackageFile.UpdateVersion(AVersion: TVersion);
var
config, packageNode, versionNode: TDOMNode;
begin
config := FXml.FindNode('CONFIG');
if Assigned(config) then
begin
packageNode := config.FindNode('Package');
if Assigned(packageNode) then
begin
versionNode := packageNode.FindNode('Version');
if Assigned(versionNode) then
begin
with (versionNode as TDOMElement) do
begin
FChanged := true;
SetAttribute('Major', inttostr(AVersion.Major));
if AVersion.Minor <> 0 then SetAttribute('Minor', inttostr(AVersion.Minor)) else RemoveAttribute('Minor');
if AVersion.Release <> 0 then SetAttribute('Release', inttostr(AVersion.Release)) else RemoveAttribute('Release');
if AVersion.Build <> 0 then SetAttribute('Build', inttostr(AVersion.Build)) else RemoveAttribute('Build');
exit;
end;
end;
end;
end;
raise exception.Create('Version node not found');
end;
end.