// 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; 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.