pro-cpp-cli-core 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +85 -112
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,15 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ /**
4
+ * PRO C++ CLI Core (With C++20 Modules Topological Sorter)
5
+ * FIX: Kept .ifc files alive for IntelliSense!
6
+ */
7
+
3
8
  const { execSync, spawn } = require('child_process');
4
9
  const fs = require('fs');
5
10
  const path = require('path');
6
11
 
7
12
  const [,, command, ...args] = process.argv;
8
-
9
13
  let currentAppProcess = null;
10
14
  let watchTimeout = null;
11
15
 
12
- // Helper: Safely execute synchronous shell commands
13
16
  function runSyncCommand(cmd) {
14
17
  try {
15
18
  execSync(cmd, { stdio: 'inherit' });
@@ -19,44 +22,79 @@ function runSyncCommand(cmd) {
19
22
  }
20
23
  }
21
24
 
22
- // Helper: Clean up old build files to save disk space
23
25
  function cleanupOldBuilds() {
24
26
  const files = fs.readdirSync(process.cwd());
25
27
  files.forEach(file => {
26
- if ((file.startsWith('app_build_') && file.endsWith('.exe')) || file.endsWith('.obj') || file.endsWith('.pdb') || file.endsWith('.ilk')) {
27
- try {
28
- fs.unlinkSync(path.join(process.cwd(), file));
29
- } catch (err) {
30
- // Ignore errors: file might be locked by OS or Antivirus. We will try next time!
31
- }
28
+ // PRO FIX: Removed .ifc from deletion list. IntelliSense needs them to resolve imports!
29
+ const isArtifact = file.endsWith('.obj') || file.endsWith('.pdb') || file.endsWith('.ilk') || (file.startsWith('app_build_') && file.endsWith('.exe'));
30
+ if (isArtifact) {
31
+ try { fs.unlinkSync(path.join(process.cwd(), file)); } catch (err) {}
32
32
  }
33
33
  });
34
34
  }
35
35
 
36
- // Helper: Get all .cpp files in the directory
37
- function getCppFiles() {
38
- const files = fs.readdirSync(process.cwd());
39
- return files.filter(file => file.endsWith('.cpp')).join(' ');
36
+ function getSortedCppFiles() {
37
+ const fileList = [];
38
+
39
+ function scanDir(dir) {
40
+ const files = fs.readdirSync(dir);
41
+ for (const file of files) {
42
+ const filePath = path.join(dir, file);
43
+ if (fs.statSync(filePath).isDirectory()) {
44
+ if (file !== 'node_modules' && file !== '.vscode' && file !== 'build') {
45
+ scanDir(filePath);
46
+ }
47
+ } else if (filePath.endsWith('.cpp') || filePath.endsWith('.ixx')) {
48
+ fileList.push(filePath);
49
+ }
50
+ }
51
+ }
52
+ scanDir(process.cwd());
53
+
54
+ const fileData = fileList.map(file => {
55
+ const content = fs.readFileSync(file, 'utf8');
56
+ const exportsMatch = content.match(/export\s+module\s+([a-zA-Z0-9_]+)\s*;/);
57
+ const importsMatches = [...content.matchAll(/import\s+([a-zA-Z0-9_]+)\s*;/g)].map(m => m[1]);
58
+
59
+ return {
60
+ file,
61
+ exports: exportsMatch ? exportsMatch[1] : null,
62
+ imports: importsMatches
63
+ };
64
+ });
65
+
66
+ const sortedFiles = [];
67
+ const visited = new Set();
68
+ const processing = new Set();
69
+
70
+ function visit(node) {
71
+ if (visited.has(node.file)) return;
72
+ if (processing.has(node.file)) return;
73
+ processing.add(node.file);
74
+
75
+ node.imports.forEach(imp => {
76
+ const dep = fileData.find(f => f.exports === imp);
77
+ if (dep) visit(dep);
78
+ });
79
+
80
+ processing.delete(node.file);
81
+ visited.add(node.file);
82
+ sortedFiles.push(`"${node.file}"`);
83
+ }
84
+
85
+ fileData.forEach(visit);
86
+ return sortedFiles.join(' ');
40
87
  }
41
88
 
42
- // Command: procpp init
43
89
  function initProject() {
44
- console.log("šŸš€ Initializing PRO C++ Project with C++20....");
45
-
90
+ console.log("šŸš€ Initializing PRO C++ Project (C++20 Modules)...");
46
91
  const vscodeDir = path.join(process.cwd(), '.vscode');
47
- if (!fs.existsSync(vscodeDir)) {
48
- fs.mkdirSync(vscodeDir);
49
- }
92
+ if (!fs.existsSync(vscodeDir)) fs.mkdirSync(vscodeDir);
50
93
 
51
94
  const mainCppPath = path.join(process.cwd(), 'main.cpp');
52
- const mainCppContent = `#include <iostream>\n\n// The main entry point of the application\nint main() {\n std::cout << "PRO CLI works like magic!\\n";\n return 0;\n}\n`;
95
+ const mainCppContent = `import std.core;\n// C++20 Modules ready!\nint main() { return 0; }`;
96
+ if (!fs.existsSync(mainCppPath)) fs.writeFileSync(mainCppPath, mainCppContent);
53
97
 
54
- if (!fs.existsSync(mainCppPath)) {
55
- fs.writeFileSync(mainCppPath, mainCppContent);
56
- console.log("āœ… Created main.cpp");
57
- }
58
-
59
- // Generate tasks.json with C++20
60
98
  const tasksContent = {
61
99
  "version": "2.0.0",
62
100
  "tasks": [
@@ -64,126 +102,61 @@ function initProject() {
64
102
  "type": "cppbuild",
65
103
  "label": "DEBUG-BUILD-MSVC",
66
104
  "command": "cl.exe",
67
- "args": [
68
- "/std:c++20", "/Zi", "/EHsc", "/nologo",
69
- "/Fe${fileDirname}\\debug_build_999.exe",
70
- "${file}"
71
- ],
72
- "options": { "cwd": "${fileDirname}" },
105
+ "args": ["/std:c++20", "/Zi", "/EHsc", "/nologo", "/Fe${fileDirname}\\debug_build.exe", "${file}"],
73
106
  "problemMatcher": ["$msCompile"],
74
107
  "group": "build"
75
108
  }
76
109
  ]
77
110
  };
78
111
  fs.writeFileSync(path.join(vscodeDir, 'tasks.json'), JSON.stringify(tasksContent, null, 4));
79
-
80
- // Generate launch.json for bulletproof debugging
81
- const launchContent = {
82
- "version": "0.2.0",
83
- "configurations": [
84
- {
85
- "name": "āš™ļø PRO C++ Debug",
86
- "type": "cppvsdbg",
87
- "request": "launch",
88
- "program": "${fileDirname}\\debug_build_999.exe",
89
- "args": [],
90
- "stopAtEntry": false,
91
- "cwd": "${fileDirname}",
92
- "environment": [],
93
- "console": "integratedTerminal",
94
- "preLaunchTask": "DEBUG-BUILD-MSVC"
95
- }
96
- ]
97
- };
98
- fs.writeFileSync(path.join(vscodeDir, 'launch.json'), JSON.stringify(launchContent, null, 4));
99
-
100
- console.log("āœ… Created .vscode debugger configs (C++20 & F5 ready!)");
101
- console.log("šŸŽÆ Project initialized! Run 'procpp watch' to start developing.");
112
+ console.log("āœ… Ready! Standard set to C++20.");
102
113
  }
103
114
 
104
- // Core Build and Run Logic
105
- function buildAndRun(isWatchMode = false) {
106
- const cppFiles = getCppFiles();
107
-
115
+ function buildAndRun() {
116
+ const cppFiles = getSortedCppFiles();
108
117
  if (!cppFiles) {
109
- console.error("āŒ No .cpp files found in this directory!");
118
+ console.error("āŒ Error: No .cpp or .ixx files found!");
110
119
  return;
111
120
  }
112
121
 
113
- // 1. Kill previous running instance if it exists
114
- if (currentAppProcess) {
115
- currentAppProcess.kill();
116
- currentAppProcess = null;
117
- }
118
-
119
- // 2. Background cleanup of unlocked old files
122
+ if (currentAppProcess) currentAppProcess.kill();
120
123
  cleanupOldBuilds();
121
124
 
122
- // 3. Generate unique executable name to bypass Antivirus/OS locks
123
- const timestamp = Date.now();
124
- const outputExe = `app_build_${timestamp}.exe`;
125
+ const outputExe = `app_build_${Date.now()}.exe`;
126
+ console.log(`\nšŸ”Ø Compiling with SMART DEPENDENCY GRAPH...`);
125
127
 
126
- console.log(`\nšŸ”Ø Compiling (Standard: C++20)...`);
127
128
  const compileCmd = `cl.exe /std:c++20 /nologo /EHsc ${cppFiles} /Fe"${outputExe}"`;
128
129
 
129
- const success = runSyncCommand(compileCmd);
130
-
131
- if (success) {
130
+ if (runSyncCommand(compileCmd)) {
132
131
  console.log(`🟢 RUNNING -> ${outputExe}\n` + "-".repeat(40));
133
-
134
- // 4. Run the new executable asynchronously so Node.js can keep watching
135
132
  currentAppProcess = spawn(`.\\${outputExe}`, [], { shell: true, stdio: 'inherit' });
136
-
137
133
  currentAppProcess.on('close', (code) => {
138
- if (code !== null) {
139
- console.log("-".repeat(40) + `\nšŸ›‘ Process exited with code ${code}`);
140
- }
134
+ if (code !== null) console.log("-".repeat(40) + `\nšŸ›‘ Process exited with code ${code}`);
141
135
  });
142
136
  } else {
143
137
  console.log(`\nāŒ BUILD FAILED`);
144
138
  }
145
139
  }
146
140
 
147
- // Command: procpp watch
148
141
  function watchProject() {
149
- console.log("šŸ‘€ PRO C++ Watcher Started (C++20 Mode)");
150
- console.log("Press Ctrl+C to stop. Watching for file changes...");
151
-
152
- // Initial build
153
- buildAndRun(true);
142
+ console.log("šŸ‘€ PRO C++ Watcher Started (Mode: Smart C++20 Modules)");
143
+ buildAndRun();
154
144
 
155
- // Watch the current directory for changes
156
- fs.watch(process.cwd(), (eventType, filename) => {
157
- if (filename && (filename.endsWith('.cpp') || filename.endsWith('.h'))) {
158
- // Debounce to prevent multiple rapid triggers when saving
145
+ fs.watch(process.cwd(), { recursive: true }, (eventType, filename) => {
146
+ if (filename && (filename.endsWith('.cpp') || filename.endsWith('.ixx') || filename.endsWith('.h'))) {
159
147
  clearTimeout(watchTimeout);
160
148
  watchTimeout = setTimeout(() => {
161
149
  console.clear();
162
- console.log(`[${new Date().toLocaleTimeString()}] Change detected in ${filename}`);
163
- buildAndRun(true);
164
- }, 300); // 300ms delay
150
+ console.log(`[${new Date().toLocaleTimeString()}] Change detected: ${filename}`);
151
+ buildAndRun();
152
+ }, 300);
165
153
  }
166
154
  });
167
155
  }
168
156
 
169
- // CLI Router
170
157
  switch (command) {
171
- case 'init':
172
- initProject();
173
- break;
174
- case 'run':
175
- buildAndRun(false);
176
- break;
177
- case 'watch':
178
- watchProject();
179
- break;
180
- default:
181
- console.log(`
182
- šŸ› ļø PRO CPP CLI šŸ› ļø
183
- Usage:
184
- procpp init - Scaffold C++ project & VS Code debugger configs
185
- procpp run - Compile and run all .cpp files once
186
- procpp watch - Live reload! Auto-compile and run on file save
187
- `);
188
- break;
158
+ case 'init': initProject(); break;
159
+ case 'run': buildAndRun(); break;
160
+ case 'watch': watchProject(); break;
161
+ default: console.log("šŸ› ļø PRO CPP CLI\nUsage: procpp <init|run|watch>"); break;
189
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pro-cpp-cli-core",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/anton-po-github/pro-cpp-cli-core.git"