pro-cpp-cli-core 1.0.6 → 1.0.7
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/README.md +6 -0
- package/index.js +65 -78
- package/package.json +2 -15
package/README.md
CHANGED
|
@@ -56,6 +56,12 @@ Now `cl.exe` is recognized, and `procpp` can build your code!
|
|
|
56
56
|
|
|
57
57
|
---
|
|
58
58
|
|
|
59
|
+
🧐 Why this package?
|
|
60
|
+
|
|
61
|
+
Tired of configuring CMake and tasks.json for days just to test a simple C++ idea? pro-cpp-cli brings modern Web Development DX (like Vite/Nodemon) to the C++ world. Zero configuration. Native C++20 Modules support. Just write code.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
59
65
|
🐞 Debugging
|
|
60
66
|
|
|
61
67
|
Just press F5! Our `init` command sets up a "Bulletproof" debugger configuration that won't conflict with the watcher.
|
package/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* PRO C++ CLI Core (
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* PRO C++ CLI Core (V1.0.7)
|
|
5
|
+
* - Added Environment Check (cl.exe validation)
|
|
6
|
+
* - Added Versioning (-v, --version)
|
|
7
|
+
* - Improved 'init' template for 100% success rate
|
|
8
|
+
* - Native ANSI Colors & Performance Tracking
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const { execSync, spawn } = require('child_process');
|
|
@@ -13,13 +13,13 @@ const fs = require('fs');
|
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const { performance } = require('perf_hooks');
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const packageJson = require('./package.json');
|
|
17
|
+
const [,, command] = process.argv;
|
|
17
18
|
let currentAppProcess = null;
|
|
18
19
|
let watchTimeout = null;
|
|
19
20
|
|
|
20
21
|
const BUILD_DIR = path.join(process.cwd(), '.build');
|
|
21
22
|
|
|
22
|
-
// ANSI Color codes for a beautiful console UI (Zero dependencies!)
|
|
23
23
|
const colors = {
|
|
24
24
|
reset: "\x1b[0m",
|
|
25
25
|
cyan: "\x1b[36m",
|
|
@@ -30,6 +30,19 @@ const colors = {
|
|
|
30
30
|
bold: "\x1b[1m"
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
// --- UTILS ---
|
|
34
|
+
|
|
35
|
+
function checkEnv() {
|
|
36
|
+
try {
|
|
37
|
+
execSync('cl.exe', { stdio: 'ignore' });
|
|
38
|
+
return true;
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error(`\n${colors.red}${colors.bold}❌ MSVC Compiler (cl.exe) NOT FOUND!${colors.reset}`);
|
|
41
|
+
console.log(`${colors.yellow}💡 Fix: Please use "Developer PowerShell for VS 2022" or "Developer Command Prompt".${colors.reset}\n`);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
function runSyncCommand(cmd) {
|
|
34
47
|
try {
|
|
35
48
|
execSync(cmd, { stdio: 'inherit' });
|
|
@@ -40,34 +53,26 @@ function runSyncCommand(cmd) {
|
|
|
40
53
|
}
|
|
41
54
|
|
|
42
55
|
function cleanupOldBuilds() {
|
|
43
|
-
// 1. Clean .build folder
|
|
44
56
|
if (fs.existsSync(BUILD_DIR)) {
|
|
45
57
|
const files = fs.readdirSync(BUILD_DIR);
|
|
46
58
|
files.forEach(file => {
|
|
47
|
-
if (
|
|
59
|
+
if (['.obj', '.pdb', '.ilk', '.ifc'].some(ext => file.endsWith(ext)) || file.startsWith('app_build_')) {
|
|
48
60
|
try { fs.unlinkSync(path.join(BUILD_DIR, file)); } catch (err) {}
|
|
49
61
|
}
|
|
50
62
|
});
|
|
51
63
|
}
|
|
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'))) {
|
|
56
|
-
try { fs.unlinkSync(path.join(process.cwd(), file)); } catch (err) {}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
function getSortedCppFiles() {
|
|
62
67
|
const fileList = [];
|
|
63
|
-
|
|
64
68
|
function scanDir(dir) {
|
|
69
|
+
if (!fs.existsSync(dir)) return;
|
|
65
70
|
const files = fs.readdirSync(dir);
|
|
66
71
|
for (const file of files) {
|
|
67
72
|
const filePath = path.join(dir, file);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (file !== 'node_modules' && file !== '.vscode' && file !== '.build') {
|
|
73
|
+
const stat = fs.statSync(filePath);
|
|
74
|
+
if (stat.isDirectory()) {
|
|
75
|
+
if (file !== 'node_modules' && file !== '.vscode' && file !== '.build' && !file.startsWith('.')) {
|
|
71
76
|
scanDir(filePath);
|
|
72
77
|
}
|
|
73
78
|
} else if (filePath.endsWith('.cpp') || filePath.endsWith('.ixx')) {
|
|
@@ -77,11 +82,12 @@ function getSortedCppFiles() {
|
|
|
77
82
|
}
|
|
78
83
|
scanDir(process.cwd());
|
|
79
84
|
|
|
85
|
+
if (fileList.length === 0) return null;
|
|
86
|
+
|
|
80
87
|
const fileData = fileList.map(file => {
|
|
81
88
|
const content = fs.readFileSync(file, 'utf8');
|
|
82
89
|
const exportsMatch = content.match(/export\s+module\s+([a-zA-Z0-9_]+)\s*;/);
|
|
83
90
|
const importsMatches = [...content.matchAll(/import\s+([a-zA-Z0-9_]+)\s*;/g)].map(m => m[1]);
|
|
84
|
-
|
|
85
91
|
return { file, exports: exportsMatch ? exportsMatch[1] : null, imports: importsMatches };
|
|
86
92
|
});
|
|
87
93
|
|
|
@@ -93,12 +99,10 @@ function getSortedCppFiles() {
|
|
|
93
99
|
if (visited.has(node.file)) return;
|
|
94
100
|
if (processing.has(node.file)) return;
|
|
95
101
|
processing.add(node.file);
|
|
96
|
-
|
|
97
102
|
node.imports.forEach(imp => {
|
|
98
103
|
const dep = fileData.find(f => f.exports === imp);
|
|
99
104
|
if (dep) visit(dep);
|
|
100
105
|
});
|
|
101
|
-
|
|
102
106
|
processing.delete(node.file);
|
|
103
107
|
visited.add(node.file);
|
|
104
108
|
sortedFiles.push(`"${node.file}"`);
|
|
@@ -108,65 +112,49 @@ function getSortedCppFiles() {
|
|
|
108
112
|
return sortedFiles.join(' ');
|
|
109
113
|
}
|
|
110
114
|
|
|
115
|
+
// --- COMMANDS ---
|
|
116
|
+
|
|
111
117
|
function initProject() {
|
|
112
|
-
console.log(`${colors.cyan}${colors.bold}🚀 Initializing PRO C++ Project
|
|
118
|
+
console.log(`${colors.cyan}${colors.bold}🚀 Initializing PRO C++ Project...${colors.reset}`);
|
|
113
119
|
const vscodeDir = path.join(process.cwd(), '.vscode');
|
|
114
120
|
if (!fs.existsSync(vscodeDir)) fs.mkdirSync(vscodeDir);
|
|
115
121
|
|
|
116
|
-
|
|
117
|
-
const tasksContent = {
|
|
122
|
+
const tasks = {
|
|
118
123
|
"version": "2.0.0",
|
|
119
124
|
"tasks": [{
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"command": "
|
|
123
|
-
"
|
|
124
|
-
"problemMatcher": ["$msCompile"],
|
|
125
|
-
"group": "build"
|
|
125
|
+
"label": "PRO-CPP-BUILD",
|
|
126
|
+
"type": "shell",
|
|
127
|
+
"command": "procpp run",
|
|
128
|
+
"group": { "kind": "build", "isDefault": true }
|
|
126
129
|
}]
|
|
127
130
|
};
|
|
128
|
-
fs.writeFileSync(path.join(vscodeDir, 'tasks.json'), JSON.stringify(
|
|
131
|
+
fs.writeFileSync(path.join(vscodeDir, 'tasks.json'), JSON.stringify(tasks, null, 4));
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
const propertiesContent = {
|
|
133
|
+
const props = {
|
|
132
134
|
"configurations": [{
|
|
133
135
|
"name": "Win32",
|
|
134
136
|
"includePath": ["${workspaceFolder}/**"],
|
|
135
137
|
"compilerPath": "cl.exe",
|
|
136
|
-
"cStandard": "c17",
|
|
137
138
|
"cppStandard": "c++20",
|
|
138
139
|
"intelliSenseMode": "windows-msvc-x64",
|
|
139
|
-
"compilerArgs": [
|
|
140
|
-
"/std:c++20",
|
|
141
|
-
"/experimental:module",
|
|
142
|
-
"/ifcSearchDir",
|
|
143
|
-
"${workspaceFolder}/.build"
|
|
144
|
-
]
|
|
140
|
+
"compilerArgs": ["/std:c++20", "/experimental:module", "/ifcSearchDir", "${workspaceFolder}/.build"]
|
|
145
141
|
}],
|
|
146
142
|
"version": 4
|
|
147
143
|
};
|
|
148
|
-
fs.writeFileSync(path.join(vscodeDir, 'c_cpp_properties.json'), JSON.stringify(
|
|
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));
|
|
144
|
+
fs.writeFileSync(path.join(vscodeDir, 'c_cpp_properties.json'), JSON.stringify(props, null, 4));
|
|
159
145
|
|
|
160
|
-
// 4. main.cpp template
|
|
161
146
|
const mainCppPath = path.join(process.cwd(), 'main.cpp');
|
|
162
147
|
if (!fs.existsSync(mainCppPath)) {
|
|
163
|
-
|
|
148
|
+
// Using standard include for max compatibility in template
|
|
149
|
+
fs.writeFileSync(mainCppPath, `#include <iostream>\n\nint main() {\n std::cout << "🚀 PRO C++ is running!" << std::endl;\n return 0;\n}`);
|
|
164
150
|
}
|
|
165
151
|
|
|
166
|
-
console.log(`${colors.green}✅ Ready!
|
|
152
|
+
console.log(`${colors.green}✅ Ready! Use 'procpp watch' to start developing.${colors.reset}`);
|
|
167
153
|
}
|
|
168
154
|
|
|
169
155
|
function buildAndRun() {
|
|
156
|
+
if (!checkEnv()) return;
|
|
157
|
+
|
|
170
158
|
const cppFiles = getSortedCppFiles();
|
|
171
159
|
if (!cppFiles) {
|
|
172
160
|
console.error(`${colors.red}❌ Error: No .cpp or .ixx files found!${colors.reset}`);
|
|
@@ -178,37 +166,27 @@ function buildAndRun() {
|
|
|
178
166
|
if (!fs.existsSync(BUILD_DIR)) fs.mkdirSync(BUILD_DIR);
|
|
179
167
|
|
|
180
168
|
const outputExeName = `app_build_${Date.now()}.exe`;
|
|
169
|
+
console.log(`\n${colors.cyan}🔨 Compiling...${colors.reset}`);
|
|
181
170
|
|
|
182
|
-
console.log(`\n${colors.cyan}🔨 Compiling with SMART DEPENDENCY GRAPH...${colors.reset}`);
|
|
183
|
-
|
|
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
171
|
const startTime = performance.now();
|
|
172
|
+
const compileCmd = `cl.exe /std:c++20 /nologo /EHsc /Zi ${cppFiles} /Fe"${outputExeName}"`;
|
|
189
173
|
|
|
190
174
|
if (runSyncCommand(compileCmd)) {
|
|
191
|
-
|
|
192
|
-
const endTime = performance.now();
|
|
193
|
-
const buildTime = ((endTime - startTime) / 1000).toFixed(2);
|
|
175
|
+
const buildTime = ((performance.now() - startTime) / 1000).toFixed(2);
|
|
194
176
|
|
|
195
|
-
// Move
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
fs.renameSync(path.join(process.cwd(), file), path.join(BUILD_DIR, file));
|
|
201
|
-
} catch(e) {}
|
|
177
|
+
// Move artifacts to .build
|
|
178
|
+
fs.readdirSync(process.cwd()).forEach(file => {
|
|
179
|
+
if (['.obj', '.ifc', '.pdb', '.ilk'].some(ext => file.endsWith(ext)) || file === outputExeName) {
|
|
180
|
+
try { fs.renameSync(path.join(process.cwd(), file), path.join(BUILD_DIR, file)); } catch(e) {}
|
|
202
181
|
}
|
|
203
182
|
});
|
|
204
183
|
|
|
205
184
|
console.log(`${colors.green}${colors.bold}⚡ [Success] Compiled in ${buildTime}s${colors.reset}`);
|
|
206
|
-
console.log(`${colors.yellow}🟢 RUNNING ->
|
|
185
|
+
console.log(`${colors.yellow}🟢 RUNNING -> ${outputExeName}${colors.reset}\n` + `${colors.gray}${"-".repeat(40)}${colors.reset}`);
|
|
207
186
|
|
|
208
|
-
// Run from .build folder
|
|
209
187
|
currentAppProcess = spawn(`.\\.build\\${outputExeName}`, [], { shell: true, stdio: 'inherit' });
|
|
210
188
|
currentAppProcess.on('close', (code) => {
|
|
211
|
-
if (code !== null) console.log(`${colors.gray}${"-".repeat(40)}${colors.reset}\n${colors.red}🛑 Process exited
|
|
189
|
+
if (code !== null) console.log(`${colors.gray}${"-".repeat(40)}${colors.reset}\n${colors.red}🛑 Process exited (code ${code})${colors.reset}`);
|
|
212
190
|
});
|
|
213
191
|
} else {
|
|
214
192
|
console.log(`\n${colors.red}${colors.bold}❌ BUILD FAILED${colors.reset}`);
|
|
@@ -216,12 +194,12 @@ function buildAndRun() {
|
|
|
216
194
|
}
|
|
217
195
|
|
|
218
196
|
function watchProject() {
|
|
197
|
+
if (!checkEnv()) return;
|
|
219
198
|
console.clear();
|
|
220
|
-
console.log(`${colors.cyan}${colors.bold}👀 PRO C++ Watcher Started
|
|
199
|
+
console.log(`${colors.cyan}${colors.bold}👀 PRO C++ Watcher Started${colors.reset}`);
|
|
221
200
|
buildAndRun();
|
|
222
201
|
|
|
223
202
|
fs.watch(process.cwd(), { recursive: true }, (eventType, filename) => {
|
|
224
|
-
// Ignore changes inside .build to prevent infinite loops
|
|
225
203
|
if (filename && (filename.endsWith('.cpp') || filename.endsWith('.ixx') || filename.endsWith('.h')) && !filename.includes('.build')) {
|
|
226
204
|
clearTimeout(watchTimeout);
|
|
227
205
|
watchTimeout = setTimeout(() => {
|
|
@@ -233,11 +211,20 @@ function watchProject() {
|
|
|
233
211
|
});
|
|
234
212
|
}
|
|
235
213
|
|
|
214
|
+
// --- CLI ROUTER ---
|
|
215
|
+
|
|
216
|
+
const versionFlags = ['-v', '--version', 'version'];
|
|
217
|
+
if (versionFlags.includes(command)) {
|
|
218
|
+
console.log(`${colors.bold}pro-cpp-cli-core v${packageJson.version}${colors.reset}`);
|
|
219
|
+
process.exit(0);
|
|
220
|
+
}
|
|
221
|
+
|
|
236
222
|
switch (command) {
|
|
237
223
|
case 'init': initProject(); break;
|
|
238
224
|
case 'run': buildAndRun(); break;
|
|
239
225
|
case 'watch': watchProject(); break;
|
|
240
226
|
default:
|
|
241
|
-
console.log(`${colors.bold}🛠️ PRO CPP CLI${colors.reset}
|
|
227
|
+
console.log(`${colors.bold}🛠️ PRO CPP CLI v${packageJson.version}${colors.reset}`);
|
|
228
|
+
console.log(`Usage: procpp <init|run|watch|version>`);
|
|
242
229
|
break;
|
|
243
230
|
}
|
package/package.json
CHANGED
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pro-cpp-cli-core",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"
|
|
5
|
-
"type": "git",
|
|
6
|
-
"url": "git+https://github.com/anton-po-github/pro-cpp-cli-core.git"
|
|
7
|
-
},
|
|
8
|
-
"bugs": {
|
|
9
|
-
"url": "https://github.com/anton-po-github/pro-cpp-cli-core/issues"
|
|
10
|
-
},
|
|
11
|
-
"homepage": "https://github.com/anton-po-github/pro-cpp-cli-core#readme",
|
|
12
|
-
"description": "The ultimate C++ Developer Experience for Windows. Zero config, hot-reload, C++20 Modules support.",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"description": "The ultimate C++ Developer Experience for Windows.",
|
|
13
5
|
"main": "index.js",
|
|
14
6
|
"bin": {
|
|
15
7
|
"procpp": "./index.js"
|
|
16
8
|
},
|
|
17
|
-
"scripts": {
|
|
18
|
-
"start": "node index.js"
|
|
19
|
-
},
|
|
20
9
|
"keywords": [
|
|
21
10
|
"cpp",
|
|
22
11
|
"c++",
|
|
23
12
|
"cli",
|
|
24
13
|
"watch",
|
|
25
|
-
"build",
|
|
26
14
|
"hot-reload",
|
|
27
15
|
"c++20",
|
|
28
|
-
"modules",
|
|
29
16
|
"msvc"
|
|
30
17
|
],
|
|
31
18
|
"author": "PRO Developer",
|