Skip to content

Commit d174f6d

Browse files
committed
feat(prm): implement project-lock.pxcf, cache system and improve manifest detection
1 parent a3dea7a commit d174f6d

File tree

5 files changed

+94
-208
lines changed

5 files changed

+94
-208
lines changed

examples/demo_web/index.html

Lines changed: 0 additions & 138 deletions
This file was deleted.

src/main.c

Lines changed: 10 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -336,91 +336,32 @@ static int dispatchPRM(int argc, const char* argv[]) {
336336

337337
} else if (strcmp(sub, "run") == 0 || strcmp(sub, "build") == 0 ||
338338
strcmp(sub, "test") == 0 || strcmp(sub, "watch") == 0) {
339-
// Load project.pxcf
340-
FILE* mf = fopen("project.pxcf", "r");
341-
if (!mf) {
342-
fprintf(stderr, "Error: No project.pxcf found in the current directory.\n");
343-
fprintf(stderr, "Run 'prm init <name>' to create a new project.\n");
339+
// Unified manifest loading
340+
Manifest m;
341+
const char* hint = (argc >= 3 && strcmp(argv[2], "web") != 0) ? argv[2] : NULL;
342+
343+
if (!prm_load_manifest_auto(&m, hint)) {
344+
fprintf(stderr, "Error: No project.pxcf found in the current directory or specified path.\n");
345+
fprintf(stderr, "Run 'prm init <name>' to create a new project, or 'cd' into your project folder.\n");
344346
exit(1);
345347
}
346-
char pname[64] = "untitled";
347-
char pversion[32] = "0.1.0";
348-
char pentry[1024] = "src/main.prox";
349-
char mline[512];
350-
while (fgets(mline, sizeof(mline), mf)) {
351-
char key[64], val[256];
352-
char* nl = strchr(mline, '\n'); if (nl) *nl = '\0';
353-
if (mline[0] == '[' || mline[0] == '#' || mline[0] == '\0') continue;
354-
if (sscanf(mline, " %63[^ =] = \"%255[^\"]\"", key, val) == 2) {
355-
if (strcmp(key, "name") == 0) { strncpy(pname, val, 63); pname[63] = '\0'; }
356-
if (strcmp(key, "version") == 0) { strncpy(pversion, val, 31); pversion[31] = '\0'; }
357-
if (strcmp(key, "entry") == 0) { strncpy(pentry, val, 1023); pentry[1023] = '\0'; }
358-
}
359-
}
360-
fclose(mf);
361348

362349
if (strcmp(sub, "run") == 0) {
363-
printf("[PRM] Running project: %s v%s\n", pname, pversion);
364-
printf("[PRM] Executing: %s %s\n", argv[0], pentry);
365-
366-
int code = -1;
367-
#ifdef _WIN32
368-
code = _spawnl(_P_WAIT, argv[0], argv[0], pentry, NULL);
369-
#else
370-
pid_t pid = fork();
371-
if (pid == 0) {
372-
execl(argv[0], argv[0], pentry, (char*)NULL);
373-
exit(1);
374-
} else if (pid > 0) {
375-
int status;
376-
waitpid(pid, &status, 0);
377-
if (WIFEXITED(status)) code = WEXITSTATUS(status);
378-
}
379-
#endif
380-
381-
if (code != 0) printf("[PRM] Process exited with code %d\n", code);
350+
prm_run(&m);
382351

383352
} else if (strcmp(sub, "build") == 0) {
384353
if (argc >= 3 && strcmp(argv[2], "web") == 0) {
385-
Manifest m;
386-
// Try to load manifest, if fails, use defaults
387-
if (!prm_load_manifest(&m)) {
388-
strcpy(m.name, "untitled");
389-
strcpy(m.version, "0.1.0");
390-
strcpy(m.entryPoint, (argc >= 4 && argv[3][0] != '-') ? argv[3] : "src/main.prox");
391-
}
392-
393354
const char* outDir = NULL;
394355
for (int i = 2; i < argc; i++) {
395356
if (strcmp(argv[i], "--output") == 0 && i + 1 < argc) {
396357
outDir = argv[i+1];
397358
break;
398359
}
399360
}
400-
401361
prm_build_web(&m, outDir);
402362
} else {
403-
int releaseMode = (argc >= 3 && strcmp(argv[2], "--release") == 0);
404-
printf("[PRM] Building project: %s v%s%s\n", pname, pversion, releaseMode ? " (release)" : "");
405-
printf("Compile-only mode not fully supported yet, running instead...\n");
406-
printf("[PRM] Executing: %s %s\n", argv[0], pentry);
407-
408-
int res = -1;
409-
#ifdef _WIN32
410-
res = _spawnl(_P_WAIT, argv[0], argv[0], pentry, NULL);
411-
#else
412-
pid_t pid = fork();
413-
if (pid == 0) {
414-
execl(argv[0], argv[0], pentry, (char*)NULL);
415-
exit(1);
416-
} else if (pid > 0) {
417-
int status;
418-
waitpid(pid, &status, 0);
419-
if (WIFEXITED(status)) res = WEXITSTATUS(status);
420-
}
421-
#endif
422-
423-
(void)res;
363+
bool releaseMode = (argc >= 3 && strcmp(argv[2], "--release") == 0);
364+
prm_build(&m, releaseMode);
424365
}
425366

426367
} else if (strcmp(sub, "test") == 0) {

src/prm/builder.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,17 @@ static void invoke_compiler(const char* file, bool run) {
7979
void prm_build(const Manifest* manifest, bool releaseMode) {
8080
(void)releaseMode;
8181
printf("[PRM] Building project: %s v%s\n", manifest->name, manifest->version);
82+
83+
prm_init_cache();
84+
prm_save_lockfile(manifest);
85+
// In the future, check if build is needed
86+
8287
invoke_compiler(manifest->entryPoint, false);
8388
}
8489

8590
void prm_build_web(const Manifest* manifest, const char* outputDir) {
8691
printf("[PRM] Building Web App: %s v%s\n", manifest->name, manifest->version);
87-
92+
prm_init_cache();
8893
char* source = read_file_prm(manifest->entryPoint);
8994
if (!source) {
9095
fprintf(stderr, "[PRM] Error: Could not read entry point '%s'\n", manifest->entryPoint);
@@ -142,5 +147,6 @@ void prm_build_web(const Manifest* manifest, const char* outputDir) {
142147

143148
void prm_run(const Manifest* manifest) {
144149
printf("[PRM] Running project: %s v%s\n", manifest->name, manifest->version);
150+
prm_save_lockfile(manifest);
145151
invoke_compiler(manifest->entryPoint, true);
146152
}

src/prm/manifest.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,5 +128,76 @@ void prm_init(const char* name) {
128128
fclose(mainFile);
129129
}
130130

131+
// Initialize storage (lockfile and cache)
132+
prm_init_cache();
133+
Manifest dummy;
134+
strcpy(dummy.name, name);
135+
strcpy(dummy.version, "0.1.0");
136+
prm_save_lockfile(&dummy);
137+
131138
printf("Created new project: %s\n", name);
132139
}
140+
141+
void prm_save_lockfile(const Manifest* manifest) {
142+
FILE* file = fopen("project-lock.pxcf", "w");
143+
if (!file) return;
144+
145+
fprintf(file, "# ProXPL Project Lockfile - DO NOT EDIT MANUALLY\n");
146+
fprintf(file, "lock_version: \"1.0.0\"\n");
147+
fprintf(file, "project: \"%s\"\n", manifest->name);
148+
fprintf(file, "version: \"%s\"\n\n", manifest->version);
149+
150+
fprintf(file, "dependencies {\n");
151+
fprintf(file, " # Resolved hashes will go here\n");
152+
fprintf(file, "}\n");
153+
154+
fclose(file);
155+
}
156+
157+
void prm_init_cache() {
158+
#ifdef _WIN32
159+
_mkdir(".pxcache");
160+
#else
161+
mkdir(".pxcache", 0777);
162+
#endif
163+
164+
FILE* readme = fopen(".pxcache/README.txt", "w");
165+
if (readme) {
166+
fprintf(readme, "ProXPL Compiler Cache. Safe to delete.\n");
167+
fclose(readme);
168+
}
169+
}
170+
171+
bool prm_is_cached(const char* artifactName) {
172+
char path[256];
173+
snprintf(path, sizeof(path), ".pxcache/%s", artifactName);
174+
FILE* f = fopen(path, "r");
175+
if (f) {
176+
fclose(f);
177+
return true;
178+
}
179+
return false;
180+
}
181+
182+
bool prm_load_manifest_auto(Manifest* manifest, const char* hintName) {
183+
// 1. Try current directory
184+
if (prm_load_manifest(manifest)) return true;
185+
186+
// 2. Try hint directory (e.g. if user just did 'prm init project' and is still in parent)
187+
if (hintName) {
188+
char path[512];
189+
snprintf(path, sizeof(path), "%s/project.pxcf", hintName);
190+
FILE* f = fopen(path, "r");
191+
if (f) {
192+
fclose(f);
193+
if (CHDIR(hintName) == 0) {
194+
return prm_load_manifest(manifest);
195+
}
196+
}
197+
}
198+
199+
// 3. (Optional) Walk subdirectories to find exactly one project.pxcf
200+
// For now, let's keep it simple and just do the hint or current.
201+
202+
return false;
203+
}

src/prm/prm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,10 @@ void prm_doc();
7575
void prm_exec(const char* command);
7676
void prm_why(const char* packageName);
7777

78+
// --- Extended Storage & Manifest ---
79+
bool prm_load_manifest_auto(Manifest* manifest, const char* hintName);
80+
void prm_save_lockfile(const Manifest* manifest);
81+
void prm_init_cache();
82+
bool prm_is_cached(const char* artifactName);
83+
7884
#endif

0 commit comments

Comments
 (0)