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.
- package/index.js +121 -40
- 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:
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
126
|
-
|
|
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
|
-
|
|
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
|
-
|
|
132
|
-
|
|
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)
|
|
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.
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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.
|
|
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"
|