201 lines
4.8 KiB
ObjectPascal

// SPDX-License-Identifier: LGPL-3.0-linking-exception
unit ProjectFile;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, ReleaserTypes, laz2_XMLRead, laz2_XMLWrite, Laz2_DOM;
type
{ TProjectFile }
TProjectFile = class(TReleaserObject)
private
FFilename: 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;
implementation
{ TProjectFile }
function TProjectFile.GetName: string;
var
config, projectNode, titleNode, generalNode: TDOMNode;
begin
config := FXml.FindNode('CONFIG');
if Assigned(config) then
begin
projectNode := config.FindNode('ProjectOptions');
if Assigned(projectNode) then
begin
generalNode := projectNode.FindNode('General');
if Assigned(generalNode) then
begin
titleNode := generalNode.FindNode('Title');
if Assigned(titleNode) then
begin
with (titleNode as TDOMElement) do
begin
result := GetAttribute('Value');
exit;
end;
end;
end;
end;
end;
result := ChangeFileExt(ExtractFileName(FFilename),'');
end;
constructor TProjectFile.Create(AParameters: TStringList; ALogicDir: string);
var
stream: TFileStream;
begin
inherited Create(AParameters, ALogicDir);
ExpectParamCount(1);
FFilename:= ExpandFileName(ReplaceVariables(Param[0]));
stream := TFileStream.Create(FFilename, fmOpenRead);
try
ReadXMLFile(FXml,stream);
finally
stream.Free;
end;
writeln('Project ',Name,' version ',VersionToStr(GetVersion));
end;
destructor TProjectFile.Destroy;
begin
FXml.Free;
inherited Destroy;
end;
function TProjectFile.GetVersion: TVersion;
var
config, projectNode, versionNode: TDOMNode;
function GetSubNode(ATag: string): integer;
var
subNode: TDOMNode;
begin
subNode := versionNode.FindNode(ATag);
if Assigned(subNode) then with (subNode as TDOMElement) do
result:= StrToIntDef(GetAttribute('Value'),0)
else
result:= 0;
end;
begin
config := FXml.FindNode('CONFIG');
if Assigned(config) then
begin
projectNode := config.FindNode('ProjectOptions');
if Assigned(projectNode) then
begin
versionNode := projectNode.FindNode('VersionInfo');
if Assigned(versionNode) then
begin
result.Major:= GetSubNode('MajorVersionNr');
result.Minor:= GetSubNode('MinorVersionNr');
result.Release:= GetSubNode('RevisionNr');
result.Build:= GetSubNode('BuildNr');
exit;
end;
end;
end;
raise exception.Create('Version node not found');
end;
procedure TProjectFile.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 TProjectFile.CheckVersion(AVersion: TVersion);
begin
inherited CheckVersion(AVersion);
if AVersion<>GetVersion then raise exception.Create('Inconsistent version of project '+Name);
end;
procedure TProjectFile.Save;
begin
if FChanged then
begin
writeln('Updating project ', Name,'...');
WriteXMLFile(FXml, FFilename);
end else
writeln('Project file unchanged');
end;
procedure TProjectFile.UpdateVersion(AVersion: TVersion);
var
config, projectNode, versionNode: TDOMNode;
procedure UpdateSubNode(ATag: string; AValue: integer);
var
subNode: TDOMElement;
begin
subNode := versionNode.FindNode(ATag) as TDOMElement;
if AValue<>0 then
begin
if subNode=nil then
begin
subNode := FXml.CreateElement(ATag);
versionNode.AppendChild(subNode);
end;
subNode.SetAttribute('Value', inttostr(AValue));
end else
begin
if Assigned(subNode) then
begin
versionNode.RemoveChild(subNode);
subNode.Free;
end;
end;
end;
begin
config := FXml.FindNode('CONFIG');
if Assigned(config) then
begin
projectNode := config.FindNode('ProjectOptions');
if Assigned(projectNode) then
begin
versionNode := projectNode.FindNode('VersionInfo');
if Assigned(versionNode) then
begin
FChanged := true;
UpdateSubNode('MajorVersionNr', AVersion.Major);
UpdateSubNode('MinorVersionNr', AVersion.Minor);
UpdateSubNode('RevisionNr', AVersion.Release);
UpdateSubNode('BuildNr', AVersion.Build);
exit;
end;
end;
end;
raise exception.Create('Version node not found');
end;
end.