pro-cpp-cli-core 1.0.4 → 1.0.6

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 +121 -40
  2. package/package.json +7 -3
package/index.js CHANGED
@@ -2,17 +2,34 @@
2
2
 
3
3
  /**
4
4
  * PRO C++ CLI Core (With C++20 Modules Topological Sorter)
5
- * FIX: Kept .ifc files alive for IntelliSense!
5
+ * FIX: Restored initProject!
6
+ * FIX: Smart post-build artifact routing to .build/ directory!
7
+ * NEW: Build time measurement using performance.now()
8
+ * NEW: Native ANSI terminal colors for PRO Developer Experience
6
9
  */
7
10
 
8
11
  const { execSync, spawn } = require('child_process');
9
12
  const fs = require('fs');
10
13
  const path = require('path');
14
+ const { performance } = require('perf_hooks');
11
15
 
12
16
  const [,, command, ...args] = process.argv;
13
17
  let currentAppProcess = null;
14
18
  let watchTimeout = null;
15
19
 
20
+ const BUILD_DIR = path.join(process.cwd(), '.build');
21
+
22
+ // ANSI Color codes for a beautiful console UI (Zero dependencies!)
23
+ const colors = {
24
+ reset: "\x1b[0m",
25
+ cyan: "\x1b[36m",
26
+ green: "\x1b[32m",
27
+ yellow: "\x1b[33m",
28
+ red: "\x1b[31m",
29
+ gray: "\x1b[90m",
30
+ bold: "\x1b[1m"
31
+ };
32
+
16
33
  function runSyncCommand(cmd) {
17
34
  try {
18
35
  execSync(cmd, { stdio: 'inherit' });
@@ -23,11 +40,19 @@ function runSyncCommand(cmd) {
23
40
  }
24
41
 
25
42
  function cleanupOldBuilds() {
26
- const files = fs.readdirSync(process.cwd());
27
- files.forEach(file => {
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) {
43
+ // 1. Clean .build folder
44
+ if (fs.existsSync(BUILD_DIR)) {
45
+ const files = fs.readdirSync(BUILD_DIR);
46
+ files.forEach(file => {
47
+ if (file.endsWith('.obj') || file.endsWith('.pdb') || file.endsWith('.ilk') || file.endsWith('.ifc') || file.startsWith('app_build_')) {
48
+ try { fs.unlinkSync(path.join(BUILD_DIR, file)); } catch (err) {}
49
+ }
50
+ });
51
+ }
52
+ // 2. Clean root folder (just in case)
53
+ const rootFiles = fs.readdirSync(process.cwd());
54
+ rootFiles.forEach(file => {
55
+ if (file.endsWith('.obj') || file.endsWith('.pdb') || file.endsWith('.ilk') || file.endsWith('.ifc') || (file.startsWith('app_build_') && file.endsWith('.exe'))) {
31
56
  try { fs.unlinkSync(path.join(process.cwd(), file)); } catch (err) {}
32
57
  }
33
58
  });
@@ -41,7 +66,8 @@ function getSortedCppFiles() {
41
66
  for (const file of files) {
42
67
  const filePath = path.join(dir, file);
43
68
  if (fs.statSync(filePath).isDirectory()) {
44
- if (file !== 'node_modules' && file !== '.vscode' && file !== 'build') {
69
+ // Ignore .build directory so watcher doesn't loop
70
+ if (file !== 'node_modules' && file !== '.vscode' && file !== '.build') {
45
71
  scanDir(filePath);
46
72
  }
47
73
  } else if (filePath.endsWith('.cpp') || filePath.endsWith('.ixx')) {
@@ -56,11 +82,7 @@ function getSortedCppFiles() {
56
82
  const exportsMatch = content.match(/export\s+module\s+([a-zA-Z0-9_]+)\s*;/);
57
83
  const importsMatches = [...content.matchAll(/import\s+([a-zA-Z0-9_]+)\s*;/g)].map(m => m[1]);
58
84
 
59
- return {
60
- file,
61
- exports: exportsMatch ? exportsMatch[1] : null,
62
- imports: importsMatches
63
- };
85
+ return { file, exports: exportsMatch ? exportsMatch[1] : null, imports: importsMatches };
64
86
  });
65
87
 
66
88
  const sortedFiles = [];
@@ -87,67 +109,124 @@ function getSortedCppFiles() {
87
109
  }
88
110
 
89
111
  function initProject() {
90
- console.log("šŸš€ Initializing PRO C++ Project (C++20 Modules)...");
112
+ console.log(`${colors.cyan}${colors.bold}šŸš€ Initializing PRO C++ Project (C++20 Modules)...${colors.reset}`);
91
113
  const vscodeDir = path.join(process.cwd(), '.vscode');
92
114
  if (!fs.existsSync(vscodeDir)) fs.mkdirSync(vscodeDir);
93
115
 
94
- const mainCppPath = path.join(process.cwd(), 'main.cpp');
95
- const mainCppContent = `import std.core;\n// C++20 Modules ready!\nint main() { return 0; }`;
96
- if (!fs.existsSync(mainCppPath)) fs.writeFileSync(mainCppPath, mainCppContent);
97
-
116
+ // 1. tasks.json
98
117
  const tasksContent = {
99
118
  "version": "2.0.0",
100
- "tasks": [
101
- {
102
- "type": "cppbuild",
103
- "label": "DEBUG-BUILD-MSVC",
104
- "command": "cl.exe",
105
- "args": ["/std:c++20", "/Zi", "/EHsc", "/nologo", "/Fe${fileDirname}\\debug_build.exe", "${file}"],
106
- "problemMatcher": ["$msCompile"],
107
- "group": "build"
108
- }
109
- ]
119
+ "tasks": [{
120
+ "type": "cppbuild",
121
+ "label": "DEBUG-BUILD-MSVC",
122
+ "command": "cl.exe",
123
+ "args": ["/std:c++20", "/Zi", "/EHsc", "/nologo", "/Fe${fileDirname}\\.build\\debug_build.exe", "${file}"],
124
+ "problemMatcher": ["$msCompile"],
125
+ "group": "build"
126
+ }]
110
127
  };
111
128
  fs.writeFileSync(path.join(vscodeDir, 'tasks.json'), JSON.stringify(tasksContent, null, 4));
112
- console.log("āœ… Ready! Standard set to C++20.");
129
+
130
+ // 2. c_cpp_properties.json (FIX FOR IDE SQUIGGLES!)
131
+ const propertiesContent = {
132
+ "configurations": [{
133
+ "name": "Win32",
134
+ "includePath": ["${workspaceFolder}/**"],
135
+ "compilerPath": "cl.exe",
136
+ "cStandard": "c17",
137
+ "cppStandard": "c++20",
138
+ "intelliSenseMode": "windows-msvc-x64",
139
+ "compilerArgs": [
140
+ "/std:c++20",
141
+ "/experimental:module",
142
+ "/ifcSearchDir",
143
+ "${workspaceFolder}/.build"
144
+ ]
145
+ }],
146
+ "version": 4
147
+ };
148
+ fs.writeFileSync(path.join(vscodeDir, 'c_cpp_properties.json'), JSON.stringify(propertiesContent, null, 4));
149
+
150
+ // 3. settings.json (Hide .build folder from UI)
151
+ const settingsContent = {
152
+ "files.exclude": {
153
+ ".build": true,
154
+ "**/.build": true
155
+ },
156
+ "C_Cpp.errorSquiggles": "disabled"
157
+ };
158
+ fs.writeFileSync(path.join(vscodeDir, 'settings.json'), JSON.stringify(settingsContent, null, 4));
159
+
160
+ // 4. main.cpp template
161
+ const mainCppPath = path.join(process.cwd(), 'main.cpp');
162
+ if (!fs.existsSync(mainCppPath)) {
163
+ fs.writeFileSync(mainCppPath, `import std.core;\n// C++20 Modules ready!\nint main() {\n return 0;\n}`);
164
+ }
165
+
166
+ console.log(`${colors.green}āœ… Ready! .vscode configs created. IntelliSense is pointed to .build/${colors.reset}`);
113
167
  }
114
168
 
115
169
  function buildAndRun() {
116
170
  const cppFiles = getSortedCppFiles();
117
171
  if (!cppFiles) {
118
- console.error("āŒ Error: No .cpp or .ixx files found!");
172
+ console.error(`${colors.red}āŒ Error: No .cpp or .ixx files found!${colors.reset}`);
119
173
  return;
120
174
  }
121
175
 
122
176
  if (currentAppProcess) currentAppProcess.kill();
123
177
  cleanupOldBuilds();
178
+ if (!fs.existsSync(BUILD_DIR)) fs.mkdirSync(BUILD_DIR);
124
179
 
125
- const outputExe = `app_build_${Date.now()}.exe`;
126
- console.log(`\nšŸ”Ø Compiling with SMART DEPENDENCY GRAPH...`);
180
+ const outputExeName = `app_build_${Date.now()}.exe`;
181
+
182
+ console.log(`\n${colors.cyan}šŸ”Ø Compiling with SMART DEPENDENCY GRAPH...${colors.reset}`);
127
183
 
128
- const compileCmd = `cl.exe /std:c++20 /nologo /EHsc ${cppFiles} /Fe"${outputExe}"`;
184
+ // Clean compile command, no weird flags
185
+ const compileCmd = `cl.exe /std:c++20 /nologo /EHsc ${cppFiles} /Fe"${outputExeName}"`;
186
+
187
+ // Start the timer!
188
+ const startTime = performance.now();
129
189
 
130
190
  if (runSyncCommand(compileCmd)) {
131
- console.log(`🟢 RUNNING -> ${outputExe}\n` + "-".repeat(40));
132
- currentAppProcess = spawn(`.\\${outputExe}`, [], { shell: true, stdio: 'inherit' });
191
+ // Stop the timer!
192
+ const endTime = performance.now();
193
+ const buildTime = ((endTime - startTime) / 1000).toFixed(2);
194
+
195
+ // Move all artifacts to .build folder
196
+ const files = fs.readdirSync(process.cwd());
197
+ files.forEach(file => {
198
+ if (file.endsWith('.obj') || file.endsWith('.ifc') || file.endsWith('.pdb') || file.endsWith('.ilk') || file === outputExeName) {
199
+ try {
200
+ fs.renameSync(path.join(process.cwd(), file), path.join(BUILD_DIR, file));
201
+ } catch(e) {}
202
+ }
203
+ });
204
+
205
+ console.log(`${colors.green}${colors.bold}⚔ [Success] Compiled in ${buildTime}s${colors.reset}`);
206
+ console.log(`${colors.yellow}🟢 RUNNING -> .build\\${outputExeName}${colors.reset}\n` + `${colors.gray}${"-".repeat(40)}${colors.reset}`);
207
+
208
+ // Run from .build folder
209
+ currentAppProcess = spawn(`.\\.build\\${outputExeName}`, [], { shell: true, stdio: 'inherit' });
133
210
  currentAppProcess.on('close', (code) => {
134
- if (code !== null) console.log("-".repeat(40) + `\nšŸ›‘ Process exited with code ${code}`);
211
+ if (code !== null) console.log(`${colors.gray}${"-".repeat(40)}${colors.reset}\n${colors.red}šŸ›‘ Process exited with code ${code}${colors.reset}`);
135
212
  });
136
213
  } else {
137
- console.log(`\nāŒ BUILD FAILED`);
214
+ console.log(`\n${colors.red}${colors.bold}āŒ BUILD FAILED${colors.reset}`);
138
215
  }
139
216
  }
140
217
 
141
218
  function watchProject() {
142
- console.log("šŸ‘€ PRO C++ Watcher Started (Mode: Smart C++20 Modules)");
219
+ console.clear();
220
+ console.log(`${colors.cyan}${colors.bold}šŸ‘€ PRO C++ Watcher Started (Mode: Smart C++20 Modules)${colors.reset}`);
143
221
  buildAndRun();
144
222
 
145
223
  fs.watch(process.cwd(), { recursive: true }, (eventType, filename) => {
146
- if (filename && (filename.endsWith('.cpp') || filename.endsWith('.ixx') || filename.endsWith('.h'))) {
224
+ // Ignore changes inside .build to prevent infinite loops
225
+ if (filename && (filename.endsWith('.cpp') || filename.endsWith('.ixx') || filename.endsWith('.h')) && !filename.includes('.build')) {
147
226
  clearTimeout(watchTimeout);
148
227
  watchTimeout = setTimeout(() => {
149
228
  console.clear();
150
- console.log(`[${new Date().toLocaleTimeString()}] Change detected: ${filename}`);
229
+ console.log(`${colors.gray}[${new Date().toLocaleTimeString()}] Change detected: ${filename}${colors.reset}`);
151
230
  buildAndRun();
152
231
  }, 300);
153
232
  }
@@ -158,5 +237,7 @@ switch (command) {
158
237
  case 'init': initProject(); break;
159
238
  case 'run': buildAndRun(); break;
160
239
  case 'watch': watchProject(); break;
161
- default: console.log("šŸ› ļø PRO CPP CLI\nUsage: procpp <init|run|watch>"); break;
240
+ default:
241
+ console.log(`${colors.bold}šŸ› ļø PRO CPP CLI${colors.reset}\nUsage: procpp <init|run|watch>`);
242
+ break;
162
243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pro-cpp-cli-core",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/anton-po-github/pro-cpp-cli-core.git"
@@ -9,7 +9,7 @@
9
9
  "url": "https://github.com/anton-po-github/pro-cpp-cli-core/issues"
10
10
  },
11
11
  "homepage": "https://github.com/anton-po-github/pro-cpp-cli-core#readme",
12
- "description": "The ultimate C++ Developer Experience for Windows",
12
+ "description": "The ultimate C++ Developer Experience for Windows. Zero config, hot-reload, C++20 Modules support.",
13
13
  "main": "index.js",
14
14
  "bin": {
15
15
  "procpp": "./index.js"
@@ -22,7 +22,11 @@
22
22
  "c++",
23
23
  "cli",
24
24
  "watch",
25
- "build"
25
+ "build",
26
+ "hot-reload",
27
+ "c++20",
28
+ "modules",
29
+ "msvc"
26
30
  ],
27
31
  "author": "PRO Developer",
28
32
  "license": "MIT"