This commit is contained in:
Norayr Chilingarian 2026-04-09 04:42:25 +04:00
parent be57b069f8
commit be6d26d7f0
7 changed files with 555 additions and 18 deletions

View file

@ -1,4 +1,4 @@
DEPEND = github.com/norayr/unixFileSystem github.com/norayr/strutils github.com/norayr/base64 github.com/norayr/dbg github.com/norayr/Internet github.com/norayr/http github.com/norayr/mbedtls github.com/norayr/lists github.com/norayr/opts github.com/norayr/skprLogger codeberg.org/sts-q/vishaps-ssqJson DEPEND = github.com/norayr/unixFileSystem github.com/norayr/strutils github.com/norayr/base64 github.com/norayr/dbg github.com/norayr/Internet github.com/norayr/http github.com/norayr/mbedtls github.com/norayr/lists github.com/norayr/opts github.com/norayr/skprLogger codeberg.org/sts-q/vishaps-ssqJson github.com/norayr/toml
VOC = voc VOC = voc
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
@ -66,6 +66,8 @@ buildThis:
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkDot.Mod cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkDot.Mod
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkResolver.Mod cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkResolver.Mod
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkJsonDepRetriever.Mod cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkJsonDepRetriever.Mod
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkTOMLDepRetriever.Mod
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkMetaRetriever.Mod
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkInstaller.Mod cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkInstaller.Mod
cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkLocalBuilder.Mod cd $(BUILD) && $(VOC) -s $(mkfile_dir_path)/src/vpkLocalBuilder.Mod
cd $(BUILD) && $(VOC) $(mkfile_dir_path)/src/vipak.Mod -cm cd $(BUILD) && $(VOC) $(mkfile_dir_path)/src/vipak.Mod -cm

View file

@ -1,7 +1,7 @@
MODULE vipak; MODULE vipak;
IMPORT Texts, Strings, Oberon, Out, IMPORT Texts, Strings, Oberon, Out,
vpkConf, vpkLogger, vpkSyncer, vpkInstaller, vpkdepTree, opts, StringList, vpkConf, vpkLogger, vpkSyncer, vpkInstaller, vpkdepTree, opts, StringList,
vpkLocalBuilder; vpkLocalBuilder, vpkMetaRetriever;
PROCEDURE msgnopkg(VAR options: opts.Options); PROCEDURE msgnopkg(VAR options: opts.Options);
BEGIN BEGIN
@ -11,7 +11,7 @@ END msgnopkg;
PROCEDURE main; PROCEDURE main;
VAR VAR
deps, sync, fetch, ask, local, init: BOOLEAN; deps, sync, fetch, ask, local, init, toml: BOOLEAN;
package, prefix, pkgTree, localFile: ARRAY 128 OF CHAR; package, prefix, pkgTree, localFile: ARRAY 128 OF CHAR;
options: opts.Options; options: opts.Options;
@ -81,6 +81,14 @@ BEGIN
opts.setOptRequired(opt, FALSE); opts.setOptRequired(opt, FALSE);
options.add(options, opt); options.add(options, opt);
opt := opts.createOpt();
opts.setOptName(opt, "--toml");
opts.setOptLName(opt, "--toml");
opts.setOptHasVal(opt, FALSE);
opts.setOptDesc(opt, "use .vipak file format instead of JSON");
opts.setOptRequired(opt, FALSE);
options.add(options, opt);
(* New local build options *) (* New local build options *)
opt := opts.createOpt(); opt := opts.createOpt();
opts.setOptName(opt, "-l"); opts.setOptName(opt, "-l");
@ -110,7 +118,7 @@ BEGIN
COPY("", package); COPY("", prefix); COPY("", pkgTree); COPY("vipak.json", localFile); COPY("", package); COPY("", prefix); COPY("", pkgTree); COPY("vipak.json", localFile);
deps := FALSE; sync := FALSE; fetch := FALSE; ask := FALSE; deps := FALSE; sync := FALSE; fetch := FALSE; ask := FALSE;
local := FALSE; init := FALSE; local := FALSE; init := FALSE; toml := FALSE;
fopt := opts.createOpt(); fopt := opts.createOpt();
fopt := opts.findOpt("-d", foptions); fopt := opts.findOpt("-d", foptions);
@ -136,6 +144,15 @@ BEGIN
fopt := opts.findOpt("-i", foptions); fopt := opts.findOpt("-i", foptions);
IF fopt # NIL THEN init := TRUE END; IF fopt # NIL THEN init := TRUE END;
fopt := opts.createOpt();
fopt := opts.findOpt("--toml", foptions);
IF fopt # NIL THEN toml := TRUE END;
IF toml THEN
vpkMetaRetriever.SetPreferredFormat(vpkMetaRetriever.fmtToml);
COPY("vipak.vipak", localFile)
END;
opts.valOfOpt("-p", foptions, package); opts.valOfOpt("-p", foptions, package);
opts.valOfOpt("-P", foptions, prefix); opts.valOfOpt("-P", foptions, prefix);
IF prefix = "" THEN IF prefix = "" THEN

View file

@ -1,7 +1,7 @@
MODULE vpkInstaller; MODULE vpkInstaller;
IMPORT In, Out, Platform, Strings, IMPORT In, Out, Platform, Strings,
List, StringList, List, StringList,
vpkResolver, vpkdepTree, vpkDot, vpkEnv, vpkJsonDepRetriever,vpkSyncer, vpkResolver, vpkdepTree, vpkDot, vpkEnv, vpkMetaRetriever, vpkSyncer,
vpkTools, vpkSettings; vpkTools, vpkSettings;
PROCEDURE resolve*(VAR unit: ARRAY OF CHAR): vpkdepTree.TdepTree; PROCEDURE resolve*(VAR unit: ARRAY OF CHAR): vpkdepTree.TdepTree;
@ -14,7 +14,7 @@ VAR
BEGIN BEGIN
vpkEnv.getGraphName(graphName); vpkEnv.getGraphName(graphName);
Out.Ln; Out.String("resolving dependencies..."); Out.Ln; Out.Ln; Out.String("resolving dependencies..."); Out.Ln;
tree := vpkResolver.resolve(unit, vpkJsonDepRetriever.getDeps); tree := vpkResolver.resolve(unit, vpkMetaRetriever.getDeps);
Out.String(" done! (:"); Out.Ln; Out.Ln; Out.String(" done! (:"); Out.Ln; Out.Ln;
lst := vpkDot.tree2dot(tree); lst := vpkDot.tree2dot(tree);
Out.String("dependency graph:"); Out.Ln; Out.String("dependency graph:"); Out.Ln;
@ -61,7 +61,7 @@ BEGIN
i := 0; i := 0;
REPEAT REPEAT
dep := vpkdepTree.Get(depTree, i); dep := vpkdepTree.Get(depTree, i);
vpkJsonDepRetriever.getURIandType(dep); vpkMetaRetriever.getURIandType(dep);
(* Pass build directory instead of prefix *) (* Pass build directory instead of prefix *)
vpkSyncer.fetch(dep, builddir^); vpkSyncer.fetch(dep, builddir^);
INC(i) INC(i)
@ -91,11 +91,11 @@ BEGIN
i := 0; i := 0;
REPEAT REPEAT
dep := vpkdepTree.Get(depTree, i); dep := vpkdepTree.Get(depTree, i);
vpkJsonDepRetriever.getURIandType(dep); vpkMetaRetriever.getURIandType(dep);
(* Pass build directory instead of prefix *) (* Pass build directory instead of prefix *)
vpkSyncer.fetch(dep, builddir^); vpkSyncer.fetch(dep, builddir^);
b := FALSE; b := FALSE;
b := vpkJsonDepRetriever.getBuildInfo(dep, keys, values); b := vpkMetaRetriever.getBuildInfo(dep, keys, values);
IF b THEN IF b THEN
Out.String("Build info found for the package: "); Out.String(dep.name^); Out.Ln; Out.String("Build info found for the package: "); Out.String(dep.name^); Out.Ln;

View file

@ -1,7 +1,7 @@
MODULE vpkLocalBuilder; MODULE vpkLocalBuilder;
IMPORT Files, Out, Strings, Platform, IMPORT Files, Out, Strings, Platform,
Json, StringList, List, strUtils, Json, StringList, List, strUtils,
vpkStorage, vpkSettings, vpkdepTree, vpkEnv, vpkJsonDepRetriever, TOML, vpkStorage, vpkSettings, vpkdepTree, vpkEnv, vpkMetaRetriever,
vpkResolver, vpkSyncer, vpkDot, vpkTools, UnixFS; vpkResolver, vpkSyncer, vpkDot, vpkTools, UnixFS;
CONST CONST
@ -243,6 +243,62 @@ BEGIN
RETURN FALSE; RETURN FALSE;
END parseProjectFile; END parseProjectFile;
PROCEDURE FileEndsWith(s, suffix: ARRAY OF CHAR): BOOLEAN;
VAR ls, lf, i: INTEGER;
BEGIN
ls := Strings.Length(s);
lf := Strings.Length(suffix);
IF lf > ls THEN RETURN FALSE END;
i := 0;
WHILE i < lf DO
IF s[ls - lf + i] # suffix[i] THEN RETURN FALSE END;
INC(i)
END;
RETURN TRUE
END FileEndsWith;
PROCEDURE parseVipakProjectFile(VAR filename: ARRAY OF CHAR; VAR info: ProjectInfo): BOOLEAN;
VAR
content: strUtils.pstring;
doc: TOML.Doc;
sec: TOML.Section;
secName: ARRAY 16 OF CHAR;
keyName: ARRAY 16 OF CHAR;
val: ARRAY 64 OF CHAR;
BEGIN
info.hasDeps := FALSE;
info.hasBuild := FALSE;
COPY("", info.name);
COPY("", info.author);
COPY("", info.license);
COPY("", info.version);
vpkStorage.fileToString(filename, content);
IF content = NIL THEN RETURN FALSE END;
doc := TOML.Parse(content^);
COPY("package", secName);
sec := TOML.GetSection(doc, secName);
IF sec # NIL THEN
COPY("name", keyName); IF TOML.GetField(sec, keyName, val) THEN COPY(val, info.name) END;
COPY("author", keyName); IF TOML.GetField(sec, keyName, val) THEN COPY(val, info.author) END;
COPY("license", keyName); IF TOML.GetField(sec, keyName, val) THEN COPY(val, info.license) END;
COPY("version", keyName); IF TOML.GetField(sec, keyName, val) THEN COPY(val, info.version) END
END;
COPY("deps", secName);
sec := TOML.GetSection(doc, secName);
IF (sec # NIL) & (sec^.first # NIL) THEN info.hasDeps := TRUE END;
COPY("build", secName);
sec := TOML.GetSection(doc, secName);
IF sec # NIL THEN info.hasBuild := TRUE END;
IF info.name[0] = 0X THEN COPY("myproject", info.name) END;
RETURN TRUE
END parseVipakProjectFile;
PROCEDURE createBuildDir(): BOOLEAN; PROCEDURE createBuildDir(): BOOLEAN;
VAR VAR
fi: UnixFS.fileInfo; fi: UnixFS.fileInfo;
@ -276,14 +332,14 @@ VAR
BEGIN BEGIN
Out.Ln; Out.String("resolving dependencies for local project..."); Out.Ln; Out.Ln; Out.String("resolving dependencies for local project..."); Out.Ln;
vpkJsonDepRetriever.setLocalProjectFile(projectFile); vpkMetaRetriever.setLocalProjectFile(projectFile);
COPY("local-project", projectName); COPY("local-project", projectName);
localDep := vpkdepTree.CreateDep(projectName); localDep := vpkdepTree.CreateDep(projectName);
combinedTree := vpkdepTree.Create(); combinedTree := vpkdepTree.Create();
IF vpkJsonDepRetriever.getDepsFromFile(localDep, depsList) > 0 THEN IF vpkMetaRetriever.getDepsFromFile(localDep, depsList) > 0 THEN
Out.String("Found "); Out.Int(depsList.Count, 0); Out.String(" direct dependencies"); Out.Ln; Out.String("Found "); Out.Int(depsList.Count, 0); Out.String(" direct dependencies"); Out.Ln;
i := 0; i := 0;
@ -291,7 +347,7 @@ BEGIN
depName := depsList.GetString(depsList, i); depName := depsList.GetString(depsList, i);
IF depName # NIL THEN IF depName # NIL THEN
Out.String("Resolving: "); Out.String(depName^); Out.Ln; Out.String("Resolving: "); Out.String(depName^); Out.Ln;
subTree := vpkResolver.resolve(depName^, vpkJsonDepRetriever.getDeps); subTree := vpkResolver.resolve(depName^, vpkMetaRetriever.getDeps);
j := 0; j := 0;
REPEAT REPEAT
currentDep := vpkdepTree.Get(subTree, j); currentDep := vpkdepTree.Get(subTree, j);
@ -385,12 +441,12 @@ BEGIN
currentDep := vpkdepTree.Get(depTree, i); currentDep := vpkdepTree.Get(depTree, i);
IF currentDep # NIL THEN IF currentDep # NIL THEN
Out.String("Fetching: "); Out.String(currentDep.name^); Out.Ln; Out.String("Fetching: "); Out.String(currentDep.name^); Out.Ln;
vpkJsonDepRetriever.getURIandType(currentDep); vpkMetaRetriever.getURIandType(currentDep);
vpkSyncer.fetch(currentDep, buildDir); vpkSyncer.fetch(currentDep, buildDir);
(* Now build the dependency *) (* Now build the dependency *)
Out.String("Building dependency: "); Out.String(currentDep.name^); Out.Ln; Out.String("Building dependency: "); Out.String(currentDep.name^); Out.Ln;
b := vpkJsonDepRetriever.getBuildInfo(currentDep, keys, values); b := vpkMetaRetriever.getBuildInfo(currentDep, keys, values);
IF b & (keys # NIL) & (values # NIL) THEN IF b & (keys # NIL) & (values # NIL) THEN
Out.String("Build info found for dependency: "); Out.String(currentDep.name^); Out.Ln; Out.String("Build info found for dependency: "); Out.String(currentDep.name^); Out.Ln;
@ -480,7 +536,7 @@ VAR
res, i: INTEGER; res, i: INTEGER;
BEGIN BEGIN
dep := vpkdepTree.CreateDep(info.name); dep := vpkdepTree.CreateDep(info.name);
b := vpkJsonDepRetriever.getBuildInfoFromFile(dep, keys, values, projectFile); b := vpkMetaRetriever.getBuildInfoFromFile(dep, keys, values, projectFile);
IF b & (keys # NIL) & (values # NIL) THEN IF b & (keys # NIL) & (values # NIL) THEN
Out.String("Building project: "); Out.String(info.name); Out.Ln; Out.String("Building project: "); Out.String(info.name); Out.Ln;
@ -530,8 +586,12 @@ BEGIN
HALT(1); HALT(1);
END; END;
(* Parse project file *) (* Parse project file - detect format by extension *)
b := parseProjectFile(projectFile, info); IF FileEndsWith(projectFile, ".vipak") THEN
b := parseVipakProjectFile(projectFile, info)
ELSE
b := parseProjectFile(projectFile, info)
END;
IF ~b THEN IF ~b THEN
Out.String("Failed to parse project file: "); Out.String(projectFile); Out.Ln; Out.String("Failed to parse project file: "); Out.String(projectFile); Out.Ln;
HALT(1); HALT(1);

76
src/vpkMetaRetriever.Mod Normal file
View file

@ -0,0 +1,76 @@
MODULE vpkMetaRetriever;
IMPORT
StringList,
vpkdepTree,
vpkJsonDepRetriever,
vpkTOMLDepRetriever;
CONST
fmtAuto* = 0;
fmtJson* = 1;
fmtVipakfile* = 2;
fmtToml* = 3;
VAR
preferredFormat*: INTEGER;
PROCEDURE SetPreferredFormat*(fmt: INTEGER);
BEGIN
preferredFormat := fmt
END SetPreferredFormat;
PROCEDURE setLocalProjectFile*(VAR filename: ARRAY OF CHAR);
BEGIN
vpkJsonDepRetriever.setLocalProjectFile(filename);
vpkTOMLDepRetriever.setLocalProjectFile(filename)
END setLocalProjectFile;
PROCEDURE getDeps*(VAR d: vpkdepTree.Tdep; VAR depstrlist: StringList.TStringList): LONGINT;
BEGIN
IF preferredFormat = fmtToml THEN
RETURN vpkTOMLDepRetriever.getDeps(d, depstrlist)
ELSE (* fmtJson, fmtAuto, fmtVipakfile *)
RETURN vpkJsonDepRetriever.getDeps(d, depstrlist)
END
END getDeps;
PROCEDURE getURIandType*(VAR d: vpkdepTree.Tdep);
BEGIN
IF preferredFormat = fmtToml THEN
vpkTOMLDepRetriever.getURIandType(d)
ELSE
vpkJsonDepRetriever.getURIandType(d)
END
END getURIandType;
PROCEDURE getBuildInfo*(VAR d: vpkdepTree.Tdep; VAR k, v: StringList.TStringList): BOOLEAN;
BEGIN
IF preferredFormat = fmtToml THEN
RETURN vpkTOMLDepRetriever.getBuildInfo(d, k, v)
ELSE
RETURN vpkJsonDepRetriever.getBuildInfo(d, k, v)
END
END getBuildInfo;
PROCEDURE getDepsFromFile*(VAR d: vpkdepTree.Tdep; VAR depstrlist: StringList.TStringList): LONGINT;
BEGIN
IF preferredFormat = fmtToml THEN
RETURN vpkTOMLDepRetriever.getDepsFromFile(d, depstrlist)
ELSE
RETURN vpkJsonDepRetriever.getDepsFromFile(d, depstrlist)
END
END getDepsFromFile;
PROCEDURE getBuildInfoFromFile*(VAR d: vpkdepTree.Tdep; VAR k, v: StringList.TStringList; VAR filename: ARRAY OF CHAR): BOOLEAN;
BEGIN
IF preferredFormat = fmtToml THEN
RETURN vpkTOMLDepRetriever.getBuildInfoFromFile(d, k, v, filename)
ELSE
RETURN vpkJsonDepRetriever.getBuildInfoFromFile(d, k, v, filename)
END
END getBuildInfoFromFile;
BEGIN
preferredFormat := fmtJson
END vpkMetaRetriever.

View file

@ -268,4 +268,92 @@ BEGIN
END END
END json2pstring; END json2pstring;
PROCEDURE findPackageVipakPath*(pkgName, reqVersion: ARRAY OF CHAR; VAR path: ARRAY OF CHAR): BOOLEAN;
VAR
dirPath, fullPath, currentVersion, bestVersion: ARRAY 512 OF CHAR;
lst: UnixFS.list;
i: INTEGER;
found: BOOLEAN;
emptyVersion, vipakSuffix: ARRAY 16 OF CHAR;
stem, base: ARRAY 512 OF CHAR;
pkgPrefix: ARRAY 512 OF CHAR;
lp, ls, iv: INTEGER;
BEGIN
COPY("", path);
COPY("", bestVersion);
COPY("", emptyVersion);
COPY(".vipak", vipakSuffix);
found := FALSE;
vpkEnv.getTreeDir(dirPath);
Strings.Append("/", dirPath);
Strings.Append(pkgName, dirPath);
IF ~UnixFS.ExistsByName(dirPath) THEN RETURN FALSE END;
UnixFS.ListDir(dirPath, lst);
IF lst = NIL THEN RETURN FALSE END;
COPY(pkgName, pkgPrefix);
Strings.Append("-", pkgPrefix);
lp := Strings.Length(pkgPrefix);
i := 0;
WHILE i < LEN(lst^) DO
IF (lst^[i].name # ".") & (lst^[i].name # "..") THEN
IF EndsWith(lst^[i].name, vipakSuffix) THEN
COPY(dirPath, fullPath);
Strings.Append("/", fullPath);
Strings.Append(lst^[i].name, fullPath);
(* Extract version from filename: pkgname-version.vipak *)
BaseName(fullPath, base);
IF StripSuffix(base, vipakSuffix, stem) THEN
ls := Strings.Length(stem);
IF ls > lp THEN
iv := 0;
WHILE iv < lp DO
IF stem[iv] # pkgPrefix[iv] THEN iv := lp + 1 END; (* mismatch *)
INC(iv)
END;
IF iv = lp THEN
(* prefix matches, remainder is version - copy char by char *)
iv := 0;
WHILE stem[lp + iv] # 0X DO
currentVersion[iv] := stem[lp + iv]; INC(iv)
END;
currentVersion[iv] := 0X;
IF currentVersion # emptyVersion THEN
IF reqVersion # emptyVersion THEN
IF currentVersion = reqVersion THEN
COPY(fullPath, path);
RETURN TRUE
END
ELSE
IF ~found OR (CompareVersions(bestVersion, currentVersion) < 0) THEN
COPY(currentVersion, bestVersion);
COPY(fullPath, path);
found := TRUE
END
END
END
END
END
END
END
END;
INC(i)
END;
RETURN found
END findPackageVipakPath;
PROCEDURE vipak2pstring*(pkgName, reqVersion: ARRAY OF CHAR; VAR pstr: strUtils.pstring);
VAR
path: ARRAY 512 OF CHAR;
BEGIN
pstr := NIL;
IF findPackageVipakPath(pkgName, reqVersion, path) THEN
fileToString(path, pstr)
END
END vipak2pstring;
END vpkStorage. END vpkStorage.

294
src/vpkTOMLDepRetriever.Mod Normal file
View file

@ -0,0 +1,294 @@
MODULE vpkTOMLDepRetriever;
IMPORT
Out, Strings,
List, StringList, strUtils,
TOML, vpkStorage, vpkSettings, vpkdepTree;
VAR
currentLocalProjectFile: ARRAY 256 OF CHAR;
(* Split a build step on the last space: cmd = everything before, file = last token *)
PROCEDURE SplitLastSpace(VAR step: ARRAY OF CHAR; VAR cmd, file: ARRAY OF CHAR): BOOLEAN;
VAR i, l, lastSp: INTEGER;
BEGIN
l := Strings.Length(step);
lastSp := -1;
i := 0;
WHILE i < l DO
IF (step[i] = " ") OR (step[i] = 09X) THEN lastSp := i END;
INC(i)
END;
IF lastSp < 0 THEN RETURN FALSE END;
i := 0;
WHILE i < lastSp DO cmd[i] := step[i]; INC(i) END;
cmd[i] := 0X;
TOML.TrimRight(cmd);
i := lastSp + 1; l := 0;
WHILE step[i] # 0X DO file[l] := step[i]; INC(i); INC(l) END;
file[l] := 0X;
TOML.TrimLeft(file);
RETURN (cmd[0] # 0X) & (file[0] # 0X)
END SplitLastSpace;
(* Split run value on newlines and ; into (cmd, file) pairs *)
PROCEDURE ParseBuildRun(VAR run: ARRAY OF CHAR; VAR k, v: StringList.TStringList): BOOLEAN;
VAR
i, j, l: INTEGER;
ch: CHAR;
step, cmd, file: ARRAY 512 OF CHAR;
done: BOOLEAN;
BEGIN
k := NIL; v := NIL;
l := Strings.Length(run);
i := 0; j := 0;
step[0] := 0X;
done := FALSE;
WHILE ~done DO
IF i >= l THEN
ch := 0X; done := TRUE
ELSE
ch := run[i]; INC(i)
END;
IF (ch = 0AX) OR (ch = ";") OR (ch = 0X) THEN
step[j] := 0X;
TOML.Trim(step);
IF step[0] # 0X THEN
IF SplitLastSpace(step, cmd, file) THEN
IF k = NIL THEN k := StringList.Create() END;
IF v = NIL THEN v := StringList.Create() END;
k.AppendString(k, cmd);
v.AppendString(v, file)
END
END;
j := 0; step[0] := 0X
ELSE
IF j < 511 THEN step[j] := ch; INC(j) END
END
END;
RETURN (k # NIL) & (k.Count > 0)
END ParseBuildRun;
PROCEDURE getDepsFromContent(VAR content: ARRAY OF CHAR; VAR depstrlist: StringList.TStringList): LONGINT;
VAR
doc: TOML.Doc;
sec: TOML.Section;
fld: TOML.Field;
spec: ARRAY 256 OF CHAR;
secName: ARRAY 16 OF CHAR;
BEGIN
depstrlist := NIL;
doc := TOML.Parse(content);
COPY("deps", secName);
sec := TOML.GetSection(doc, secName);
IF sec = NIL THEN RETURN 0 END;
fld := sec^.first;
WHILE fld # NIL DO
IF fld^.key[0] # 0X THEN
IF fld^.value[0] # 0X THEN
COPY(fld^.key, spec);
Strings.Append(":", spec);
Strings.Append(fld^.value, spec)
ELSE
COPY(fld^.key, spec)
END;
IF depstrlist = NIL THEN depstrlist := StringList.Create() END;
depstrlist.AppendString(depstrlist, spec)
END;
fld := fld^.next
END;
IF depstrlist = NIL THEN RETURN 0 END;
RETURN depstrlist.Count
END getDepsFromContent;
PROCEDURE getURIandTypeFromContent(VAR content: ARRAY OF CHAR; VAR d: vpkdepTree.Tdep): BOOLEAN;
VAR
doc: TOML.Doc;
sec: TOML.Section;
typ: ARRAY 32 OF CHAR;
uri: ARRAY 512 OF CHAR;
tag: ARRAY 64 OF CHAR;
md5: ARRAY 34 OF CHAR;
authtype: ARRAY 32 OF CHAR;
user: ARRAY 32 OF CHAR;
pass: ARRAY 32 OF CHAR;
typLow: ARRAY 32 OF CHAR;
atLow: ARRAY 32 OF CHAR;
gitRemote: vpkdepTree.RemoteGit;
httpsRemote: vpkdepTree.RemoteHttps;
httpRemote: vpkdepTree.RemoteHttp;
httpsFile: vpkdepTree.File;
secName: ARRAY 16 OF CHAR;
keyName: ARRAY 16 OF CHAR;
BEGIN
doc := TOML.Parse(content);
COPY("remote", secName);
sec := TOML.GetSection(doc, secName);
IF sec = NIL THEN RETURN FALSE END;
COPY("", typ);
COPY("type", keyName); IF ~TOML.GetField(sec, keyName, typ) THEN END;
COPY(typ, typLow); TOML.ToLower(typLow);
IF typLow = "git" THEN
COPY("", uri); COPY("", tag);
COPY("uri", keyName);
IF ~TOML.GetField(sec, keyName, uri) THEN
COPY("path", keyName); IF ~TOML.GetField(sec, keyName, uri) THEN END
END;
COPY("tag", keyName); IF ~TOML.GetField(sec, keyName, tag) THEN END;
NEW(gitRemote);
d^.rmt := gitRemote;
d^.Type := vpkSettings.git;
COPY(uri, gitRemote^.URI);
COPY(tag, gitRemote^.tag);
gitRemote^.branch[0] := 0X;
RETURN TRUE
ELSIF typLow = "https" THEN
NEW(httpsRemote);
d^.rmt := httpsRemote;
d^.Type := vpkSettings.https;
httpsRemote^.Files := List.Create();
WHILE sec # NIL DO
COPY("", uri); COPY("", md5); COPY("", authtype); COPY("", user); COPY("", pass);
COPY("uri", keyName); IF ~TOML.GetField(sec, keyName, uri) THEN END;
COPY("md5", keyName); IF ~TOML.GetField(sec, keyName, md5) THEN END;
COPY("authtype", keyName); IF ~TOML.GetField(sec, keyName, authtype) THEN END;
COPY("user", keyName); IF ~TOML.GetField(sec, keyName, user) THEN END;
COPY("password", keyName); IF ~TOML.GetField(sec, keyName, pass) THEN END;
IF uri[0] # 0X THEN
NEW(httpsFile);
COPY(uri, httpsFile^.URI);
COPY(md5, httpsFile^.md5);
COPY(authtype, atLow); TOML.ToLower(atLow);
IF atLow = "basicauth" THEN
httpsFile^.auth := TRUE;
COPY(user, httpsFile^.username);
COPY(pass, httpsFile^.password)
ELSE
httpsFile^.auth := FALSE
END;
httpsRemote^.Files.Append(httpsRemote^.Files, httpsFile)
END;
sec := TOML.GetNextSection(sec, secName)
END;
RETURN TRUE
ELSIF typLow = "http" THEN
NEW(httpRemote);
d^.rmt := httpRemote;
d^.Type := vpkSettings.http;
httpRemote^.Files := List.Create();
WHILE sec # NIL DO
COPY("", uri); COPY("", md5); COPY("", authtype); COPY("", user); COPY("", pass);
COPY("uri", keyName); IF ~TOML.GetField(sec, keyName, uri) THEN END;
COPY("md5", keyName); IF ~TOML.GetField(sec, keyName, md5) THEN END;
COPY("authtype", keyName); IF ~TOML.GetField(sec, keyName, authtype) THEN END;
COPY("user", keyName); IF ~TOML.GetField(sec, keyName, user) THEN END;
COPY("password", keyName); IF ~TOML.GetField(sec, keyName, pass) THEN END;
IF uri[0] # 0X THEN
NEW(httpsFile);
COPY(uri, httpsFile^.URI);
COPY(md5, httpsFile^.md5);
COPY(authtype, atLow); TOML.ToLower(atLow);
IF atLow = "basicauth" THEN
httpsFile^.auth := TRUE;
COPY(user, httpsFile^.username);
COPY(pass, httpsFile^.password)
ELSE
httpsFile^.auth := FALSE
END;
httpRemote^.Files.Append(httpRemote^.Files, httpsFile)
END;
sec := TOML.GetNextSection(sec, secName)
END;
RETURN TRUE
END;
Out.String("vpkTOMLDepRetriever: unsupported remote type: "); Out.String(typ); Out.Ln;
RETURN FALSE
END getURIandTypeFromContent;
PROCEDURE getBuildInfoFromContent(VAR content: ARRAY OF CHAR; VAR k, v: StringList.TStringList): BOOLEAN;
VAR
doc: TOML.Doc;
sec: TOML.Section;
run: ARRAY 4096 OF CHAR;
secName, keyName: ARRAY 16 OF CHAR;
BEGIN
k := NIL; v := NIL;
doc := TOML.Parse(content);
COPY("build", secName);
sec := TOML.GetSection(doc, secName);
IF sec = NIL THEN RETURN FALSE END;
COPY("run", keyName);
IF ~TOML.GetField(sec, keyName, run) THEN RETURN FALSE END;
RETURN ParseBuildRun(run, k, v)
END getBuildInfoFromContent;
PROCEDURE getDeps*(VAR d: vpkdepTree.Tdep; VAR depstrlist: StringList.TStringList): LONGINT;
VAR content: strUtils.pstring;
BEGIN
depstrlist := NIL;
vpkStorage.vipak2pstring(d.name^, d.version, content);
IF content = NIL THEN
Out.String("No .vipak file found for: "); Out.String(d.name^); Out.Ln;
RETURN -1
END;
RETURN getDepsFromContent(content^, depstrlist)
END getDeps;
PROCEDURE getURIandType*(VAR d: vpkdepTree.Tdep);
VAR content: strUtils.pstring;
BEGIN
vpkStorage.vipak2pstring(d.name^, d.version, content);
IF content = NIL THEN
Out.String("No .vipak file found for: "); Out.String(d.name^); Out.Ln;
RETURN
END;
IF ~getURIandTypeFromContent(content^, d) THEN
Out.String("Failed to get remote info from .vipak for: "); Out.String(d.name^); Out.Ln
END
END getURIandType;
PROCEDURE getBuildInfo*(VAR d: vpkdepTree.Tdep; VAR k, v: StringList.TStringList): BOOLEAN;
VAR content: strUtils.pstring;
BEGIN
vpkStorage.vipak2pstring(d.name^, d.version, content);
IF content = NIL THEN k := NIL; v := NIL; RETURN FALSE END;
RETURN getBuildInfoFromContent(content^, k, v)
END getBuildInfo;
PROCEDURE setLocalProjectFile*(VAR filename: ARRAY OF CHAR);
BEGIN
COPY(filename, currentLocalProjectFile)
END setLocalProjectFile;
PROCEDURE getDepsFromFile*(VAR d: vpkdepTree.Tdep; VAR depstrlist: StringList.TStringList): LONGINT;
VAR
content: strUtils.pstring;
filename: ARRAY 256 OF CHAR;
BEGIN
depstrlist := NIL;
IF currentLocalProjectFile[0] = 0X THEN
COPY("vipak.vipak", filename)
ELSE
COPY(currentLocalProjectFile, filename)
END;
vpkStorage.fileToString(filename, content);
IF content = NIL THEN RETURN -1 END;
RETURN getDepsFromContent(content^, depstrlist)
END getDepsFromFile;
PROCEDURE getBuildInfoFromFile*(VAR d: vpkdepTree.Tdep; VAR k, v: StringList.TStringList; VAR filename: ARRAY OF CHAR): BOOLEAN;
VAR content: strUtils.pstring;
BEGIN
vpkStorage.fileToString(filename, content);
IF content = NIL THEN k := NIL; v := NIL; RETURN FALSE END;
RETURN getBuildInfoFromContent(content^, k, v)
END getBuildInfoFromFile;
BEGIN
currentLocalProjectFile[0] := 0X
END vpkTOMLDepRetriever.