261 lines
6.5 KiB
ObjectPascal
261 lines
6.5 KiB
ObjectPascal
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
|
unit ManagerFile;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, ReleaserTypes,
|
|
fpjson, jsonparser, ArchiveUrl, PackageFile;
|
|
|
|
type
|
|
|
|
{ TManagerFile }
|
|
|
|
TManagerFile = class(TReleaserObject)
|
|
private
|
|
FArchive: TArchiveUrl;
|
|
FFilename: string;
|
|
FPackages: TPackageFileList;
|
|
FRoot: TJSONObject;
|
|
FNew, FChanged: boolean;
|
|
FLineEnding: string;
|
|
procedure SetArchive(AValue: TArchiveUrl);
|
|
function GetPackageUpdateList: TJSONArray;
|
|
function GetDataNode: TJSONObject;
|
|
function GetDownloadUrl: string;
|
|
public
|
|
constructor Create(AParameters: TStringList; ALogicDir: string); override;
|
|
destructor Destroy; override;
|
|
class function IsUnique: boolean; override;
|
|
procedure LinkWith(AOtherObject: TReleaserObject); override;
|
|
property Archive: TArchiveUrl read FArchive write SetArchive;
|
|
procedure GetVersions({%H-}AVersionList: TStringList); override;
|
|
procedure CheckVersion(AVersion: TVersion); override;
|
|
procedure UpdateVersion(AVersion: TVersion); override;
|
|
procedure Save; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TManagerFile }
|
|
|
|
procedure TManagerFile.SetArchive(AValue: TArchiveUrl);
|
|
begin
|
|
if FArchive=AValue then Exit;
|
|
FArchive:=AValue;
|
|
end;
|
|
|
|
function TManagerFile.GetPackageUpdateList: TJSONArray;
|
|
const packagePath1 = 'UpdateLazPackages';
|
|
packagePath2 = 'UpdatePackageFiles';
|
|
var
|
|
node: TJSONData;
|
|
begin
|
|
node := FRoot.FindPath(packagePath1);
|
|
if node = nil then node := FRoot.FindPath(packagePath2);
|
|
if node <> nil then result := node as TJSONArray
|
|
else
|
|
begin
|
|
result := TJSONArray.Create;
|
|
FRoot.Add(packagePath1, result);
|
|
end;
|
|
end;
|
|
|
|
function TManagerFile.GetDataNode: TJSONObject;
|
|
const dataPath = 'UpdatePackageData';
|
|
var
|
|
node: TJSONData;
|
|
begin
|
|
node := FRoot.FindPath(dataPath);
|
|
if node <> nil then result := node as TJSONObject
|
|
else
|
|
begin
|
|
result := TJSONObject.Create;
|
|
FRoot.Add(dataPath, result);
|
|
end;
|
|
end;
|
|
|
|
function TManagerFile.GetDownloadUrl: string;
|
|
var
|
|
url: string;
|
|
data: TJSONObject;
|
|
begin
|
|
if Archive <> nil then
|
|
begin
|
|
data := GetDataNode;
|
|
url := '';
|
|
url := data.Get('DownloadZipURL', url);
|
|
result := url;
|
|
end
|
|
else result := '';
|
|
end;
|
|
|
|
constructor TManagerFile.Create(AParameters: TStringList; ALogicDir: string);
|
|
var
|
|
stream: TFileStream;
|
|
begin
|
|
inherited Create(AParameters, ALogicDir);
|
|
ExpectParamCount(1);
|
|
FFilename:= ExpandFileName(ReplaceVariables(Param[0]));
|
|
if FileExists(FFilename) then
|
|
begin
|
|
FLineEnding:= DetectLineEnding(FFilename);
|
|
FNew := false;
|
|
stream := TFileStream.Create(FFilename, fmOpenRead);
|
|
try
|
|
FRoot := GetJSON(stream) as TJSONObject;
|
|
finally
|
|
stream.Free;
|
|
end;
|
|
end else
|
|
begin
|
|
FNew := true;
|
|
FRoot := TJSONObject.Create;
|
|
end;
|
|
FPackages := TPackageFileList.Create;
|
|
end;
|
|
|
|
destructor TManagerFile.Destroy;
|
|
begin
|
|
FPackages.Free;
|
|
FRoot.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
class function TManagerFile.IsUnique: boolean;
|
|
begin
|
|
Result:= true;
|
|
end;
|
|
|
|
procedure TManagerFile.LinkWith(AOtherObject: TReleaserObject);
|
|
var
|
|
updateList: TJSONArray;
|
|
packageEntry: TJSONObject;
|
|
name: String;
|
|
i: Integer;
|
|
updateName: string;
|
|
package: TPackageFile;
|
|
updateVer: TVersion;
|
|
begin
|
|
inherited LinkWith(AOtherObject);
|
|
if AOtherObject is TArchiveUrl then
|
|
Archive := TArchiveUrl(AOtherObject)
|
|
else if AOtherObject is TPackageFile then
|
|
begin
|
|
package := TPackageFile(AOtherObject);
|
|
name := ExtractFileName(package.Filename);
|
|
updateList := GetPackageUpdateList;
|
|
if FNew then
|
|
begin
|
|
packageEntry := TJSONObject.Create;
|
|
packageEntry.Booleans['ForceNotify'] := false;
|
|
packageEntry.Integers['InternalVersion'] := 1;
|
|
packageEntry.Strings['Name'] := name;
|
|
packageEntry.Strings['Version'] := VersionToStr(package.GetVersion, true);
|
|
updateList.Add(packageEntry);
|
|
FPackages.Add(package);
|
|
end else
|
|
for i := 0 to updateList.Count-1 do
|
|
begin
|
|
packageEntry := updateList.Items[i] as TJSONObject;
|
|
updateName := packageEntry.Strings['Name'];
|
|
updateVer := StrToVersion(packageEntry.Strings['Version']);
|
|
if updateName = name then
|
|
begin
|
|
FPackages.Add(package);
|
|
writeln('Package ', package.name,' is used in manager');
|
|
if updateVer <> package.GetVersion then
|
|
raise exception.Create('Package version specified in manager is inconsistent');
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TManagerFile.GetVersions(AVersionList: TStringList);
|
|
begin
|
|
//version will be provided by packages
|
|
end;
|
|
|
|
procedure TManagerFile.CheckVersion(AVersion: TVersion);
|
|
var
|
|
url: string;
|
|
begin
|
|
inherited CheckVersion(AVersion);
|
|
if Archive <> nil then
|
|
begin
|
|
url := GetDownloadUrl;
|
|
if (url <> '') and (url <> Archive.GetUrlForVersion(AVersion)) then
|
|
raise exception.Create('Archive version is not consistent (DownloadZipURL field of JSON)');
|
|
end;
|
|
end;
|
|
|
|
procedure TManagerFile.UpdateVersion(AVersion: TVersion);
|
|
var
|
|
name, updateName, url: String;
|
|
i, j: Integer;
|
|
updateList: TJSONArray;
|
|
packageEntry, data: TJSONObject;
|
|
begin
|
|
for i := 0 to FPackages.Count-1 do
|
|
begin
|
|
name := ExtractFileName(FPackages[i].Filename);
|
|
updateList := GetPackageUpdateList;
|
|
for j := 0 to updateList.Count-1 do
|
|
begin
|
|
packageEntry := updateList.Items[j] as TJSONObject;
|
|
updateName := packageEntry.Strings['Name'];
|
|
if updateName = name then
|
|
begin
|
|
packageEntry.Strings['Version'] := VersionToStr(AVersion, true);
|
|
FChanged := true;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
data := GetDataNode;
|
|
url := Archive.GetUrlForVersion(AVersion);
|
|
data.Strings['DownloadZipURL'] := url;
|
|
end;
|
|
|
|
procedure TManagerFile.Save;
|
|
var t: textfile;
|
|
data: TJSONObject;
|
|
url: String;
|
|
begin
|
|
if (FPackages.Count = 0) then raise exception.Create('Manager does not have an associated package');
|
|
|
|
data := GetDataNode;
|
|
if FNew then
|
|
begin
|
|
data.Booleans['DisableInOPM'] := false;
|
|
data.Strings['Name'] := FPackages[0].Name;
|
|
end;
|
|
if Assigned(Archive) then
|
|
begin
|
|
if GetDownloadUrl = '' then
|
|
begin
|
|
url := Archive.GetUrlForVersion(FPackages[0].GetVersion);
|
|
data.Strings['DownloadZipURL'] := url;
|
|
FChanged := true;
|
|
end;
|
|
end;
|
|
|
|
if FNew or FChanged then
|
|
begin
|
|
if FNew then
|
|
writeln('Creating manager file...')
|
|
else
|
|
writeln('Updating manager file...');
|
|
assignfile(t, FFilename);
|
|
rewrite(t);
|
|
write(t, StringReplace(FRoot.FormatJSON, LineEnding, FLineEnding, [rfReplaceAll]));
|
|
closefile(t);
|
|
end else
|
|
writeln('Manager file unchanged');
|
|
end;
|
|
|
|
end.
|
|
|