deps dir moved to build. git builds work.

This commit is contained in:
Norayr Chilingarian 2025-07-19 19:06:11 +04:00
parent 49d24a5afe
commit ee137b10df
9 changed files with 452 additions and 129 deletions

View file

@ -19,31 +19,111 @@ BEGIN
END getGraphName;
PROCEDURE createIfNotThere*(VAR fileName: ARRAY OF CHAR);
VAR
workName: ARRAY 512 OF CHAR;
len: INTEGER;
BEGIN
IF ~UnixFS.ExistsByName(fileName) THEN
IF ~UnixFS.mkDir(fileName) THEN
Out.String("failed to create directory "); Out.String(fileName); Out.Ln; HALT(1);
END;
END;
COPY(fileName, workName);
(* Remove trailing slash for directory creation *)
len := Strings.Length(workName);
IF (len > 1) & (workName[len - 1] = '/') THEN
workName[len - 1] := 0X;
END;
IF ~UnixFS.ExistsByName(workName) THEN
IF ~UnixFS.mkDir(workName) THEN
Out.String("failed to create directory "); Out.String(workName); Out.Ln; HALT(1);
END;
END;
END createIfNotThere;
PROCEDURE getSrcRelPath*(VAR depName, domain, path0: ARRAY OF CHAR): strTypes.pstring;
(* Create directories recursively like mkdir -p *)
PROCEDURE mkDirRecursive*(VAR fullPath: ARRAY OF CHAR);
VAR
currentPath: ARRAY 512 OF CHAR;
component: ARRAY 128 OF CHAR;
pos, nextPos: INTEGER;
i: INTEGER;
BEGIN
(*
Out.String(">>> mkDirRecursive called with: '"); Out.String(fullPath); Out.String("'"); Out.Ln;
*)
COPY("", currentPath);
pos := 0;
(* Handle absolute paths starting with / *)
IF (Strings.Length(fullPath) > 0) & (fullPath[0] = '/') THEN
COPY("/", currentPath);
pos := 1;
END;
WHILE pos < Strings.Length(fullPath) DO
(* Find next '/' or end of string *)
nextPos := pos;
WHILE (nextPos < Strings.Length(fullPath)) & (fullPath[nextPos] # '/') DO
INC(nextPos);
END;
(* Extract component *)
IF nextPos > pos THEN
i := 0;
WHILE (pos < nextPos) & (i < LEN(component) - 1) DO
component[i] := fullPath[pos];
INC(i); INC(pos);
END;
component[i] := 0X;
(* Append component to current path *)
IF Strings.Length(currentPath) > 0 THEN
IF currentPath[Strings.Length(currentPath) - 1] # '/' THEN
Strings.Append("/", currentPath);
END;
END;
Strings.Append(component, currentPath);
(*
Out.String(">>> Creating directory: '"); Out.String(currentPath); Out.String("'"); Out.Ln;
*)
(* Create directory if it doesn't exist - createIfNotThere handles trailing slashes *)
createIfNotThere(currentPath);
END;
(* Skip the '/' *)
IF (pos < Strings.Length(fullPath)) & (fullPath[pos] = '/') THEN
INC(pos);
END;
END;
(*
Out.String(">>> mkDirRecursive completed"); Out.Ln;
*)
END mkDirRecursive;
PROCEDURE getSrcRelPath*(VAR depName, repoPath, path0: ARRAY OF CHAR): strTypes.pstring;
VAR
p: strTypes.pstring;
len: INTEGER;
BEGIN
len := 12 + Strings.Length(depName) + Strings.Length(path0) + Strings.Length(domain);
(* 5 chars are ../, /, /, plus a couple of chars *)
(*
Out.String("@@@ getSrcRelPath called with:"); Out.Ln;
Out.String("@@@ depName: '"); Out.String(depName); Out.String("'"); Out.Ln;
Out.String("@@@ repoPath: '"); Out.String(repoPath); Out.String("'"); Out.Ln;
Out.String("@@@ path0: '"); Out.String(path0); Out.String("'"); Out.Ln;
*)
len := 16 + Strings.Length(path0) + Strings.Length(repoPath);
NEW(p, len);
COPY("../", p^);
COPY("", p^); (* Start with empty string instead of "../" *)
Strings.Append(vpkSettings.vpkDepDir, p^);
Strings.Append("/", p^);
Strings.Append(domain, p^);
Strings.Append("/", p^);
Strings.Append(depName, p^);
Strings.Append(repoPath, p^);
Strings.Append("/", p^);
Strings.Append(path0, p^);
(*
Out.String("@@@ result: '"); Out.String(p^); Out.String("'"); Out.Ln;
*)
RETURN p;
END getSrcRelPath;
@ -89,42 +169,82 @@ BEGIN
RETURN builddir
END mkdefBldDir;
PROCEDURE mkdefPkgDirPath*(VAR domain, name, path: ARRAY OF CHAR);
PROCEDURE mkdefPkgDirPath*(VAR repoPath, name, path: ARRAY OF CHAR);
VAR
home: ARRAY 128 OF CHAR;
finalPath: ARRAY 512 OF CHAR;
BEGIN
getHome(home);
COPY(home, path);
Strings.Append("/", path);
Strings.Append(vpkSettings.vpkPkgDir, path);
createIfNotThere(path);
Strings.Append("/", path);
Strings.Append(vpkSettings.vpkDepDir, path);
createIfNotThere(path);
Strings.Append("/", path);
Strings.Append(domain, path);
createIfNotThere(path);
Strings.Append("/", path);
Strings.Append(name, path);
createIfNotThere(path);
(* Build: <home>/<vpkPkgDir>/deps/<repoPath>/<name>/ *)
COPY(home, finalPath);
Strings.Append("/", finalPath);
Strings.Append(vpkSettings.vpkPkgDir, finalPath);
Strings.Append("/", finalPath);
Strings.Append(vpkSettings.vpkDepDir, finalPath);
Strings.Append("/", finalPath);
Strings.Append(repoPath, finalPath);
Strings.Append("/", finalPath);
Strings.Append(name, finalPath);
(* Create all directories recursively *)
mkDirRecursive(finalPath);
(* Return the path with trailing slash *)
COPY(finalPath, path);
Strings.Append("/", path);
END mkdefPkgDirPath;
PROCEDURE mkPkgDirPath*(VAR domain, name, path: ARRAY OF CHAR);
PROCEDURE mkPkgDirPath*(VAR repoPath, name, path: ARRAY OF CHAR);
VAR
finalPath: ARRAY 512 OF CHAR;
len: INTEGER;
BEGIN
Strings.Append("/", path);
createIfNotThere(path);
Strings.Append(vpkSettings.vpkDepDir, path);
Strings.Append("/", path);
createIfNotThere(path);
Strings.Append(domain, path);
createIfNotThere(path);
Strings.Append("/", path);
Strings.Append(name, path);
createIfNotThere(path);
Strings.Append("/", path);
END mkPkgDirPath;
(*
Out.String("=== DEBUG mkPkgDirPath START ==="); Out.Ln;
Out.String("Input path: '"); Out.String(path); Out.String("'"); Out.Ln;
Out.String("Input repoPath: '"); Out.String(repoPath); Out.String("'"); Out.Ln;
Out.String("Input name: '"); Out.String(name); Out.String("'"); Out.Ln;
*)
(* Start with clean path *)
COPY(path, finalPath);
(* Remove trailing slashes *)
len := Strings.Length(finalPath);
WHILE (len > 1) & (finalPath[len - 1] = '/') DO
finalPath[len - 1] := 0X;
DEC(len);
END;
(*
Out.String("After removing trailing slashes: '"); Out.String(finalPath); Out.String("'"); Out.Ln;
*)
(* Add /deps *)
Strings.Append("/", finalPath);
Strings.Append(vpkSettings.vpkDepDir, finalPath);
(*
Out.String("After adding deps: '"); Out.String(finalPath); Out.String("'"); Out.Ln;
*)
(* Add /<repoPath> - this already contains the package name! *)
Strings.Append("/", finalPath);
Strings.Append(repoPath, finalPath);
(*
Out.String("After adding repoPath: '"); Out.String(finalPath); Out.String("'"); Out.Ln;
*)
(* Create directories *)
mkDirRecursive(finalPath);
(* Return with trailing slash *)
COPY(finalPath, path);
Strings.Append("/", path);
(*
Out.String("Final output path: '"); Out.String(path); Out.String("'"); Out.Ln;
Out.String("=== DEBUG mkPkgDirPath END ==="); Out.Ln;
*)
END mkPkgDirPath;
PROCEDURE mkCmd*(VAR p0, p1: ARRAY OF CHAR): strTypes.pstring;
VAR

View file

@ -4,28 +4,38 @@ IMPORT Out, Strings, Platform, vpkEnv;
PROCEDURE pull*(VAR url : ARRAY OF CHAR; VAR dst : ARRAY OF CHAR; VAR branch: ARRAY OF CHAR);
VAR i : INTEGER;
cmd : ARRAY 2048 OF CHAR;
cleanDst: ARRAY 512 OF CHAR;
BEGIN
cmd := "git init ";
Strings.Append(dst, cmd);
i:=Platform.System(cmd);
(*cmd := "git -C ";
Strings.Append(dst, cmd);
Strings.Append(" remote add origin ", cmd);
(* Clean destination path - remove trailing slash *)
COPY(dst, cleanDst);
IF (Strings.Length(cleanDst) > 1) & (cleanDst[Strings.Length(cleanDst) - 1] = '/') THEN
cleanDst[Strings.Length(cleanDst) - 1] := 0X;
END;
Out.String("*** GIT: Cloning to: '"); Out.String(cleanDst); Out.String("'"); Out.Ln;
(* Remove directory if it exists to avoid conflicts *)
cmd := "rm -rf ";
Strings.Append(cleanDst, cmd);
i := Platform.System(cmd);
(* Use git clone directly - much simpler *)
cmd := "git clone ";
Strings.Append(url, cmd);
i:=Platform.System(cmd);*)
cmd := "";
cmd := "git -C ";
Strings.Append(dst, cmd);
Strings.Append(" pull ", cmd);
Strings.Append(url, cmd);
Out.String("branch: '"); Out.String(branch); Out.String("'."); Out.Ln;
IF branch # "" THEN
Out.String("adding branch to commandline"); Out.Ln;
Strings.Append(" ", cmd);
Strings.Append(" --branch ", cmd);
Strings.Append(branch, cmd);
END;
Out.String("fetch command: '"); Out.String(cmd); Out.Char("'"); Out.Ln;
Strings.Append(" ", cmd);
Strings.Append(cleanDst, cmd);
Out.String("*** GIT: Executing: '"); Out.String(cmd); Out.String("'"); Out.Ln;
i := Platform.System(cmd);
IF i # 0 THEN
Out.String("*** GIT: Command failed with exit code: "); Out.Int(i, 0); Out.Ln;
ELSE
Out.String("*** GIT: Clone successful"); Out.Ln;
END;
END pull;
PROCEDURE syncTree*(url, branch: ARRAY OF CHAR);

View file

@ -11,7 +11,7 @@ END msgnopkg;
PROCEDURE main;
VAR
deps, sync, fetch, ask, local, init, withDeps: BOOLEAN;
deps, sync, fetch, ask, local, init: BOOLEAN;
package, prefix, pkgTree, localFile: ARRAY 128 OF CHAR;
options: opts.Options;
@ -86,7 +86,7 @@ BEGIN
opts.setOptName(opt, "-l");
opts.setOptLName(opt, "--local");
opts.setOptHasVal(opt, FALSE);
opts.setOptDesc(opt, "build local project from vipak.json file");
opts.setOptDesc(opt, "build local project from vipak.json file (includes dependencies)");
opts.setOptRequired(opt, FALSE);
options.add(options, opt);
@ -98,14 +98,6 @@ BEGIN
opts.setOptRequired(opt, FALSE);
options.add(options, opt);
opt := opts.createOpt();
opts.setOptName(opt, "-w");
opts.setOptLName(opt, "--with-deps");
opts.setOptHasVal(opt, FALSE);
opts.setOptDesc(opt, "also build dependencies when building local project");
opts.setOptRequired(opt, FALSE);
options.add(options, opt);
foptions := opts.populateOptions(options);
IF opts.reqsSatisfied(options, foptions) THEN
Out.String("required options provided"); Out.Ln;
@ -118,7 +110,7 @@ BEGIN
COPY("", package); COPY("", prefix); COPY("", pkgTree); COPY("vipak.json", localFile);
deps := FALSE; sync := FALSE; fetch := FALSE; ask := FALSE;
local := FALSE; init := FALSE; withDeps := FALSE;
local := FALSE; init := FALSE;
fopt := opts.createOpt();
fopt := opts.findOpt("-d", foptions);
@ -144,10 +136,6 @@ BEGIN
fopt := opts.findOpt("-i", foptions);
IF fopt # NIL THEN init := TRUE END;
fopt := opts.createOpt();
fopt := opts.findOpt("-w", foptions);
IF fopt # NIL THEN withDeps := TRUE END;
opts.valOfOpt("-p", foptions, package);
opts.valOfOpt("-P", foptions, prefix);
IF prefix = "" THEN
@ -166,7 +154,7 @@ BEGIN
vpkLocalBuilder.init
ELSIF local THEN
Out.String("Building local project from: "); Out.String(localFile); Out.Ln;
vpkLocalBuilder.buildLocal(localFile, withDeps)
vpkLocalBuilder.buildLocal(localFile)
ELSIF sync THEN
vpkSyncer.sync
ELSE
@ -187,4 +175,4 @@ END main;
BEGIN
main
END vipak.
END vipak.

View file

@ -8,6 +8,7 @@ VAR
h: http.Client;
answer: strTypes.pstring;
domain, path: ARRAY 128 OF CHAR; port: ARRAY 8 OF CHAR;
repoPath: ARRAY 256 OF CHAR; (* Added for full repository path *)
filename: ARRAY 64 OF CHAR;
i, j: LONGINT;
node: List.Node;
@ -25,12 +26,19 @@ BEGIN
IF node^.obj(vpkdepTree.File) # NIL THEN
Out.String("getting "); Out.String(node^.obj(vpkdepTree.File)^.URI); Out.Ln;
(* Extract domain for connection *)
vpkTools.extractDomainFromUrl(node^.obj(vpkdepTree.File)^.URI, domain);
Out.String("connecting to "); Out.String(domain); Out.Ln;
(* Extract full repository path for directory structure *)
vpkTools.extractRepoPathFromUrl(node^.obj(vpkdepTree.File)^.URI, repoPath);
Out.String("repo path: "); Out.String(repoPath); Out.Ln;
vpkTools.extractPathFromUrl(node^.obj(vpkdepTree.File)^.URI, path);
vpkTools.extractFilenameFromUrl(node^.obj(vpkdepTree.File)^.URI, filename);
vpkEnv.mkPkgDirPath(domain, dep^.name^, dst);
(* Use full repository path instead of just domain *)
vpkEnv.mkPkgDirPath(repoPath, dep^.name^, dst);
j := Platform.Chdir(dst);
@ -65,4 +73,4 @@ BEGIN
END fetchFiles;
END vpkHttp.
END vpkHttp.

View file

@ -8,12 +8,14 @@ VAR
h: https.TLSClient;
answer: strTypes.pstring;
domain, path: ARRAY 128 OF CHAR; port: ARRAY 8 OF CHAR;
repoPath: ARRAY 256 OF CHAR; (* Added for full repository path *)
filename: ARRAY 64 OF CHAR;
i, j: LONGINT;
node: List.Node;
bool, continueFetching: BOOLEAN;
initialDst: ARRAY 512 OF CHAR;
BEGIN
Out.String("*** HTTPS: fetchFiles called"); Out.Ln;
COPY(dst, initialDst);
COPY("443", port);
i := 0;
@ -25,12 +27,19 @@ BEGIN
IF node^.obj(vpkdepTree.File) # NIL THEN
Out.String("getting "); Out.String(node^.obj(vpkdepTree.File)^.URI); Out.Ln;
(* Extract domain for connection *)
vpkTools.extractDomainFromUrl(node^.obj(vpkdepTree.File)^.URI, domain);
Out.String("connecting to "); Out.String(domain); Out.Ln;
(* Extract full repository path for directory structure *)
vpkTools.extractRepoPathFromUrl(node^.obj(vpkdepTree.File)^.URI, repoPath);
Out.String("repo path: "); Out.String(repoPath); Out.Ln;
vpkTools.extractPathFromUrl(node^.obj(vpkdepTree.File)^.URI, path);
vpkTools.extractFilenameFromUrl(node^.obj(vpkdepTree.File)^.URI, filename);
vpkEnv.mkPkgDirPath(domain, dep^.name^, dst);
(* Use full repository path - DO NOT add package name again *)
vpkEnv.mkPkgDirPath(repoPath, dep^.name^, dst);
j := Platform.Chdir(dst);

View file

@ -47,14 +47,23 @@ VAR
depTree: vpkdepTree.TdepTree;
dep: vpkdepTree.Tdep;
i: LONGINT;
builddir: StringList.pstring;
BEGIN
(* Create build directory path *)
IF prefix # "" THEN
builddir := vpkEnv.mkBldDir(prefix)
ELSE
builddir := vpkEnv.mkdefBldDir();
END;
depTree := resolve(package);
IF a THEN ask END;
i := 0;
REPEAT
dep := vpkdepTree.Get(depTree, i);
vpkJsonDepRetriever.getURIandType(dep);
vpkSyncer.fetch(dep, prefix);
(* Pass build directory instead of prefix *)
vpkSyncer.fetch(dep, builddir^);
INC(i)
UNTIL i = depTree.Count;
END fetch;
@ -69,7 +78,7 @@ VAR
b: BOOLEAN;
builddir, cmd, srcPath: StringList.pstring;
res: INTEGER;
domain: ARRAY 256 OF CHAR;
repoPath: ARRAY 256 OF CHAR; (* Changed from domain to repoPath *)
node: List.Node;
BEGIN
IF prefix # "" THEN
@ -83,12 +92,13 @@ BEGIN
REPEAT
dep := vpkdepTree.Get(depTree, i);
vpkJsonDepRetriever.getURIandType(dep);
vpkSyncer.fetch(dep, prefix);
(* Pass build directory instead of prefix *)
vpkSyncer.fetch(dep, builddir^);
b := FALSE;
b := vpkJsonDepRetriever.getBuildInfo(dep, keys, values);
IF b THEN
Out.String("Build info found for the package: "); Out.String(dep.name^); Out.Ln;
(* Ensure keys and values are not NIL *)
IF keys = NIL THEN
Out.String("Error: keys list is NIL."); Out.Ln;
@ -98,17 +108,18 @@ BEGIN
Out.String("Error: values list is NIL."); Out.Ln;
HALT(10);
END;
Out.String("keys.Count = "); Out.Int(keys.Count, 0); Out.Ln;
Out.String("values.Count = "); Out.Int(values.Count, 0); Out.Ln;
j := 0;
REPEAT
Out.String("Processing build step "); Out.Int(j, 0); Out.Ln;
IF dep^.rmt IS vpkdepTree.RemoteGit THEN
vpkTools.extractDomainFromUrl(dep^.rmt.URI, domain);
(* Use extractRepoPathFromUrl instead of extractDomainFromUrl *)
vpkTools.extractRepoPathFromUrl(dep^.rmt.URI, repoPath);
ELSIF dep^.rmt IS vpkdepTree.RemoteHttps THEN
node := dep^.rmt(vpkdepTree.RemoteHttps)^.Files.Get(dep^.rmt(vpkdepTree.RemoteHttps)^.Files, j);
vpkTools.extractDomainFromUrl(node^.obj(vpkdepTree.File)^.URI, domain)
vpkTools.extractRepoPathFromUrl(node^.obj(vpkdepTree.File)^.URI, repoPath)
ELSE
Out.String("WARNING: building for neither git nor https sources not supported yet"); Out.Ln;
END;
@ -120,7 +131,8 @@ BEGIN
v := values.GetString(values, j);
Out.String("Got key: "); Out.String(k^); Out.Ln;
Out.String("Got value: "); Out.String(v^); Out.Ln;
srcPath := vpkEnv.getSrcRelPath(dep.name^, domain, v^);
(* Use repoPath instead of domain, and deps/ prefix to reflect new structure *)
srcPath := vpkEnv.getSrcRelPath(dep.name^, repoPath, v^);
cmd := vpkEnv.mkCmd(k^, srcPath^);
Out.String("Command: "); Out.String(cmd^); Out.Ln;
Out.String("Building in "); Out.String(builddir^); Out.Ln;

View file

@ -2,7 +2,7 @@ MODULE vpkLocalBuilder;
IMPORT Files, Out, Strings, Platform, In,
Json, StringList, strUtils,
vpkStorage, vpkSettings, vpkdepTree, vpkInstaller, vpkEnv, vpkJsonDepRetriever,
UnixFS;
vpkResolver, vpkSyncer, vpkDot, vpkTools, UnixFS;
CONST
DefaultProjectFile = "vipak.json";
@ -45,7 +45,7 @@ BEGIN
COPY("src/", filename);
Strings.Append(projectName, filename);
Strings.Append(".Mod", filename);
(* Create template module content *)
COPY("MODULE ", content);
Strings.Append(projectName, content);
@ -96,7 +96,7 @@ VAR
BEGIN
(* Use a simple default project name *)
COPY("myproject", projectName);
(* Create default JSON content *)
COPY('{', content);
Strings.Append(eol, content);
@ -265,12 +265,117 @@ BEGIN
RETURN TRUE;
END createBuildDir;
PROCEDURE buildDependencies(VAR projectFile: ARRAY OF CHAR);
PROCEDURE resolveLocal(VAR projectFile: ARRAY OF CHAR): vpkdepTree.TdepTree;
VAR
localDep: vpkdepTree.Tdep;
depsList: StringList.TStringList;
depName: StringList.pstring;
combinedTree, subTree: vpkdepTree.TdepTree;
currentDep: vpkdepTree.Tdep;
i, j: LONGINT;
found: BOOLEAN;
graphName: ARRAY 32 OF CHAR;
lst: StringList.TStringList;
localName: ARRAY 16 OF CHAR;
BEGIN
(* For now, skip dependency building in local mode *)
(* This can be implemented later when the infrastructure is ready *)
Out.String("Dependency building for local projects not yet implemented."); Out.Ln;
Out.String("Please build dependencies manually using 'vipak -p <package>'"); Out.Ln;
Out.Ln; Out.String("resolving dependencies for local project..."); Out.Ln;
(* Set the local project file for dependency reading *)
vpkJsonDepRetriever.setLocalProjectFile(projectFile);
(* Create a dummy dependency object to read dependencies from local file *)
COPY("local-project", localName);
localDep := vpkdepTree.CreateDep(localName);
(* Create combined dependency tree *)
combinedTree := vpkdepTree.Create();
(* Get direct dependencies from the local project file *)
IF vpkJsonDepRetriever.getDepsFromFile(localDep, depsList) > 0 THEN
Out.String("Found "); Out.Int(depsList.Count, 0); Out.String(" direct dependencies"); Out.Ln;
(* Resolve each dependency using normal tree-based resolution *)
i := 0;
REPEAT
depName := depsList.GetString(depsList, i);
IF depName # NIL THEN
Out.String("Resolving: "); Out.String(depName^); Out.Ln;
(* Use normal vpkResolver.resolve for this dependency (it's in the tree) *)
subTree := vpkResolver.resolve(depName^, vpkJsonDepRetriever.getDeps);
(* Merge this subtree into combined tree (avoiding duplicates) *)
j := 0;
REPEAT
currentDep := vpkdepTree.Get(subTree, j);
IF currentDep # NIL THEN
(* Check if this dependency is already in combined tree *)
found := (combinedTree.GetByName(combinedTree, currentDep.name^) # NIL);
IF ~found THEN
vpkdepTree.AddCopy(combinedTree, currentDep);
END;
END;
INC(j);
UNTIL j = subTree.Count;
END;
INC(i);
UNTIL i = depsList.Count;
Out.String(" done! (:"); Out.Ln; Out.Ln;
(* Show dependency graph like normal vipak *)
vpkEnv.getGraphName(graphName);
lst := vpkDot.tree2dot(combinedTree);
Out.String("dependency graph:"); Out.Ln;
Out.String("-----------------"); Out.Ln;
StringList.DumpOut(lst);
lst.Dump(lst, graphName);
Out.String("-----------------"); Out.Ln;
Out.String("(use 'dot -Tpng deps.dot > deps.png' to get the graph image)"); Out.Ln; Out.Ln;
Out.String("dependencies will be installed in the following order:"); Out.Ln;
i := 0;
REPEAT
currentDep := vpkdepTree.Get(combinedTree, i);
IF currentDep # NIL THEN
Out.String(currentDep.name^); Out.Ln;
END;
INC(i);
UNTIL i = combinedTree.Count;
ELSE
Out.String("No dependencies found in project file."); Out.Ln;
END;
RETURN combinedTree;
END resolveLocal;
PROCEDURE buildDependencies(VAR projectFile: ARRAY OF CHAR);
VAR
depTree: vpkdepTree.TdepTree;
currentDep: vpkdepTree.Tdep;
i: LONGINT;
buildDir: ARRAY 128 OF CHAR;
BEGIN
(* Resolve all dependencies for local project *)
depTree := resolveLocal(projectFile);
IF depTree.Count > 0 THEN
(* Fetch all resolved dependencies *)
COPY("./", buildDir);
Strings.Append(DefaultBuildDir, buildDir);
i := 0;
REPEAT
currentDep := vpkdepTree.Get(depTree, i);
IF currentDep # NIL THEN
Out.String("Fetching: "); Out.String(currentDep.name^); Out.Ln;
vpkJsonDepRetriever.getURIandType(currentDep);
vpkSyncer.fetch(currentDep, buildDir);
END;
INC(i);
UNTIL i = depTree.Count;
Out.String("All dependencies fetched successfully!"); Out.Ln;
END;
END buildDependencies;
PROCEDURE buildProject(VAR projectFile: ARRAY OF CHAR; info: ProjectInfo): BOOLEAN;
@ -285,13 +390,13 @@ VAR
BEGIN
(* Create a dummy dependency object for build info extraction *)
dep := vpkdepTree.CreateDep(info.name);
(* Get build information using the procedure from vpkJsonDepRetriever *)
b := vpkJsonDepRetriever.getBuildInfoFromFile(dep, keys, values, projectFile);
IF b & (keys # NIL) & (values # NIL) THEN
Out.String("Building project: "); Out.String(info.name); Out.Ln;
(* Change to build directory *)
COPY(DefaultBuildDir, buildDirVar);
res := Platform.Chdir(buildDirVar);
@ -299,18 +404,18 @@ BEGIN
Out.String("Failed to change to build directory"); Out.Ln;
RETURN FALSE;
END;
(* Execute build commands *)
i := 0;
REPEAT
k := keys.GetString(keys, i);
v := values.GetString(values, i);
(* Create command: copy from parent directory if needed *)
COPY(k^, cmd);
Strings.Append(" ../", cmd);
Strings.Append(v^, cmd);
Out.String("Executing: "); Out.String(cmd); Out.Ln;
res := Platform.System(cmd);
IF res # 0 THEN
@ -321,7 +426,7 @@ BEGIN
END;
INC(i);
UNTIL i = keys.Count;
(* Restore original directory *)
COPY("..", buildDirVar);
res := Platform.Chdir(buildDirVar);
@ -333,7 +438,7 @@ BEGIN
END;
END buildProject;
PROCEDURE buildLocal*(VAR projectFile: ARRAY OF CHAR; withDeps: BOOLEAN);
PROCEDURE buildLocal*(VAR projectFile: ARRAY OF CHAR);
VAR
info: ProjectInfo;
b: BOOLEAN;
@ -344,27 +449,27 @@ BEGIN
Out.String("Create one with 'vipak --init'"); Out.Ln;
HALT(1);
END;
(* Parse project file *)
b := parseProjectFile(projectFile, info);
IF ~b THEN
Out.String("Failed to parse project file: "); Out.String(projectFile); Out.Ln;
HALT(1);
END;
Out.String("Building project: "); Out.String(info.name);
Out.String("Building project: "); Out.String(info.name);
Out.String(" v"); Out.String(info.version); Out.Ln;
(* Create build directory *)
IF ~createBuildDir() THEN
HALT(1);
END;
(* Build dependencies if requested and available *)
IF withDeps & info.hasDeps THEN
(* Build dependencies if available - default behavior for local projects *)
IF info.hasDeps THEN
buildDependencies(projectFile);
END;
(* Build the project itself *)
IF info.hasBuild THEN
b := buildProject(projectFile, info);
@ -386,11 +491,11 @@ BEGIN
Out.String("Project file already exists: "); Out.String(projectFile); Out.Ln;
HALT(1);
END;
COPY("myproject", projectName);
createDefaultProject(projectFile);
createTemplateModule(projectName);
Out.Ln;
Out.String("Project initialized! You can now:"); Out.Ln;
Out.String(" 1. Edit src/"); Out.String(projectName); Out.String(".Mod with your code"); Out.Ln;
@ -400,4 +505,4 @@ END init;
BEGIN
eol[0] := 0AX; eol[1] := 0X; (* Unix line ending *)
END vpkLocalBuilder.
END vpkLocalBuilder.

View file

@ -24,10 +24,14 @@ BEGIN
END sync;
PROCEDURE fetch*(VAR dep: vpkdepTree.Tdep; dst: ARRAY OF CHAR);
VAR domain: ARRAY 64 OF CHAR;
VAR repoPath: ARRAY 256 OF CHAR;
workingDst: ARRAY 512 OF CHAR; (* Local copy to modify *)
BEGIN
Out.String("Starting fetch process..."); Out.Ln;
Out.String("Destination: "); Out.String(dst); Out.Ln;
Out.String("*** SYNCER: Starting fetch process..."); Out.Ln;
Out.String("*** SYNCER: Input destination: '"); Out.String(dst); Out.String("'"); Out.Ln;
COPY(dst, workingDst); (* Make a local copy to modify *)
Out.String("*** SYNCER: Working destination: '"); Out.String(workingDst); Out.String("'"); Out.Ln;
IF dep = NIL THEN
Out.String("Dependency is NIL"); Out.Ln;
HALT(1);
@ -37,33 +41,42 @@ BEGIN
HALT(5);
ELSE
IF dep^.rmt IS vpkdepTree.RemoteGit THEN
Out.String("Remote type is Git"); Out.Ln;
vpkTools.extractDomainFromUrl(dep^.rmt^.URI, domain);
Out.String("Extracted domain: "); Out.String(domain); Out.Ln;
(* dst is changed by mkdefPkgDirPath and mkPkgdirPath *)
IF dst = "" THEN
vpkEnv.mkdefPkgDirPath(domain, dep^.name^, dst);
Out.String("*** SYNCER: Remote type is Git"); Out.Ln;
Out.String("*** SYNCER: Package name is: '"); Out.String(dep^.name^); Out.String("'"); Out.Ln;
Out.String("*** SYNCER: Remote URI is: '"); Out.String(dep^.rmt^.URI); Out.String("'"); Out.Ln;
vpkTools.extractRepoPathFromUrl(dep^.rmt^.URI, repoPath);
Out.String("*** SYNCER: Extracted repo path: '"); Out.String(repoPath); Out.String("'"); Out.Ln;
Out.String("*** SYNCER: About to call mkPkgDirPath with:"); Out.Ln;
Out.String("*** repoPath = '"); Out.String(repoPath); Out.String("'"); Out.Ln;
Out.String("*** name = '"); Out.String(dep^.name^); Out.String("'"); Out.Ln;
Out.String("*** workingDst = '"); Out.String(workingDst); Out.String("'"); Out.Ln;
(* Build the proper destination path *)
IF Strings.Length(workingDst) = 0 THEN
vpkEnv.mkdefPkgDirPath(repoPath, dep^.name^, workingDst);
ELSE
vpkEnv.mkPkgDirPath(domain, dep^.name^, dst);
vpkEnv.mkPkgDirPath(repoPath, dep^.name^, workingDst);
END;
Out.String("Final destination path: "); Out.String(dst); Out.Ln;
Out.String("Fetching repository..."); Out.Ln;
vpkGit.fetchRepo(dep^.rmt^.URI, dst, dep^.rmt(vpkdepTree.RemoteGit).branch);
Out.String("*** SYNCER: After mkPkgDirPath, workingDst = '"); Out.String(workingDst); Out.String("'"); Out.Ln;
Out.String("*** SYNCER: About to call git with destination: '"); Out.String(workingDst); Out.String("'"); Out.Ln;
vpkGit.fetchRepo(dep^.rmt^.URI, workingDst, dep^.rmt(vpkdepTree.RemoteGit).branch);
ELSIF dep^.rmt IS vpkdepTree.RemoteHttps THEN
Out.String("Remote type is HTTPS"); Out.Ln;
(* full dst will be determined in vpkHttps.fetchFiles for each file *)
vpkHttps.fetchFiles(dep, dst);
vpkHttps.fetchFiles(dep, workingDst);
ELSIF dep^.rmt IS vpkdepTree.RemoteHttp THEN
Out.String("Remote type is HTTP"); Out.Ln;
(* full dst will be determined in vpkHttps.fetchFiles for each file *)
vpkHttp.fetchFiles(dep, dst);
vpkHttp.fetchFiles(dep, workingDst);
ELSE
Out.String("TODO: neither git nor https url"); Out.Ln;
Out.String("not handled");
Out.Ln;
END;
END;
Out.String("Fetch process completed."); Out.Ln;
Out.String("*** SYNCER: Fetch process completed."); Out.Ln;
END fetch;
END vpkSyncer.

View file

@ -1,5 +1,5 @@
MODULE vpkTools;
IMPORT Strings, strUtils;
IMPORT Strings, strUtils, Out;
PROCEDURE extractDomainFromUrl*(VAR url: ARRAY OF CHAR; VAR domain: ARRAY OF CHAR);
@ -78,5 +78,63 @@ BEGIN
END;
END extractFilenameFromUrl;
PROCEDURE extractRepoPathFromUrl*(VAR url: ARRAY OF CHAR; VAR repoPath: ARRAY OF CHAR);
(* Extracts full repository path from URL like:
https://github.com/norayr/strutils -> github.com/norayr/strutils
https://codeberg.org/user/project -> codeberg.org/user/project
*)
VAR
start, i, j: INTEGER;
found: BOOLEAN;
BEGIN
Out.String("@@@ extractRepoPathFromUrl input: '"); Out.String(url); Out.String("'"); Out.Ln;
start := 0;
found := FALSE;
repoPath[0] := 0X; (* Initialize to empty string *)
(* Find the "://" pattern to skip protocol *)
WHILE (start < LEN(url) - 2) & (url[start] # 0X) & ~found DO
IF (url[start] = ':') & (url[start+1] = '/') & (url[start+2] = '/') THEN
found := TRUE;
start := start + 3; (* Skip "://" *)
ELSE
INC(start);
END;
END;
Out.String("@@@ After skipping protocol, start="); Out.Int(start, 0); Out.Ln;
IF ~found THEN
(* No protocol found, assume the whole URL is the path *)
COPY(url, repoPath);
Out.String("@@@ No protocol found, using whole URL: '"); Out.String(repoPath); Out.String("'"); Out.Ln;
RETURN;
END;
(* Find end of URL (exclude .git suffix if present) *)
i := start;
WHILE (i < LEN(url)) & (url[i] # 0X) DO
INC(i);
END;
Out.String("@@@ End of URL at position: "); Out.Int(i, 0); Out.Ln;
(* Remove .git suffix if present *)
IF (i >= 4) & (url[i-4] = '.') & (url[i-3] = 'g') & (url[i-2] = 'i') & (url[i-1] = 't') THEN
i := i - 4;
Out.String("@@@ Removed .git suffix, new end: "); Out.Int(i, 0); Out.Ln;
END;
(* Copy domain + path *)
j := 0;
WHILE (start < i) & (j < LEN(repoPath) - 1) DO
repoPath[j] := url[start];
INC(j); INC(start);
END;
repoPath[j] := 0X;
Out.String("@@@ extractRepoPathFromUrl output: '"); Out.String(repoPath); Out.String("'"); Out.Ln;
END extractRepoPathFromUrl;
END vpkTools.