pro-cpp-cli-core 1.0.0
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 +189 -0
- package/package.json +21 -0
package/index.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync, spawn } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const [,, command, ...args] = process.argv;
|
|
8
|
+
|
|
9
|
+
let currentAppProcess = null;
|
|
10
|
+
let watchTimeout = null;
|
|
11
|
+
|
|
12
|
+
// Helper: Safely execute synchronous shell commands
|
|
13
|
+
function runSyncCommand(cmd) {
|
|
14
|
+
try {
|
|
15
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
16
|
+
return true;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Helper: Clean up old build files to save disk space
|
|
23
|
+
function cleanupOldBuilds() {
|
|
24
|
+
const files = fs.readdirSync(process.cwd());
|
|
25
|
+
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
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
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(' ');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Command: procpp init
|
|
43
|
+
function initProject() {
|
|
44
|
+
console.log("š Initializing PRO C++ Project...");
|
|
45
|
+
|
|
46
|
+
const vscodeDir = path.join(process.cwd(), '.vscode');
|
|
47
|
+
if (!fs.existsSync(vscodeDir)) {
|
|
48
|
+
fs.mkdirSync(vscodeDir);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
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`;
|
|
53
|
+
|
|
54
|
+
if (!fs.existsSync(mainCppPath)) {
|
|
55
|
+
fs.writeFileSync(mainCppPath, mainCppContent);
|
|
56
|
+
console.log("ā
Created main.cpp");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Generate tasks.json for bulletproof debugging
|
|
60
|
+
const tasksContent = {
|
|
61
|
+
"version": "2.0.0",
|
|
62
|
+
"tasks": [
|
|
63
|
+
{
|
|
64
|
+
"type": "cppbuild",
|
|
65
|
+
"label": "DEBUG-BUILD-MSVC",
|
|
66
|
+
"command": "cl.exe",
|
|
67
|
+
"args": [
|
|
68
|
+
"/Zi", "/EHsc", "/nologo",
|
|
69
|
+
"/Fe${fileDirname}\\debug_build_999.exe",
|
|
70
|
+
"${file}"
|
|
71
|
+
],
|
|
72
|
+
"options": { "cwd": "${fileDirname}" },
|
|
73
|
+
"problemMatcher": ["$msCompile"],
|
|
74
|
+
"group": "build"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
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 (F5 ready!)");
|
|
101
|
+
console.log("šÆ Project initialized! Run 'procpp watch' to start developing.");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Core Build and Run Logic
|
|
105
|
+
function buildAndRun(isWatchMode = false) {
|
|
106
|
+
const cppFiles = getCppFiles();
|
|
107
|
+
|
|
108
|
+
if (!cppFiles) {
|
|
109
|
+
console.error("ā No .cpp files found in this directory!");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
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
|
|
120
|
+
cleanupOldBuilds();
|
|
121
|
+
|
|
122
|
+
// 3. Generate unique executable name to bypass Antivirus/OS locks
|
|
123
|
+
const timestamp = Date.now();
|
|
124
|
+
const outputExe = `app_build_${timestamp}.exe`;
|
|
125
|
+
|
|
126
|
+
console.log(`\nšØ Compiling...`);
|
|
127
|
+
const compileCmd = `cl.exe /nologo /EHsc ${cppFiles} /Fe"${outputExe}"`;
|
|
128
|
+
|
|
129
|
+
const success = runSyncCommand(compileCmd);
|
|
130
|
+
|
|
131
|
+
if (success) {
|
|
132
|
+
console.log(`š¢ RUNNING -> ${outputExe}\n` + "-".repeat(40));
|
|
133
|
+
|
|
134
|
+
// 4. Run the new executable asynchronously so Node.js can keep watching
|
|
135
|
+
currentAppProcess = spawn(`.\\${outputExe}`, [], { shell: true, stdio: 'inherit' });
|
|
136
|
+
|
|
137
|
+
currentAppProcess.on('close', (code) => {
|
|
138
|
+
if (code !== null) {
|
|
139
|
+
console.log("-".repeat(40) + `\nš Process exited with code ${code}`);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
} else {
|
|
143
|
+
console.log(`\nā BUILD FAILED`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Command: procpp watch
|
|
148
|
+
function watchProject() {
|
|
149
|
+
console.log("š PRO C++ Watcher Started!");
|
|
150
|
+
console.log("Press Ctrl+C to stop. Watching for file changes...");
|
|
151
|
+
|
|
152
|
+
// Initial build
|
|
153
|
+
buildAndRun(true);
|
|
154
|
+
|
|
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
|
|
159
|
+
clearTimeout(watchTimeout);
|
|
160
|
+
watchTimeout = setTimeout(() => {
|
|
161
|
+
console.clear();
|
|
162
|
+
console.log(`[${new Date().toLocaleTimeString()}] Change detected in ${filename}`);
|
|
163
|
+
buildAndRun(true);
|
|
164
|
+
}, 300); // 300ms delay
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// CLI Router
|
|
170
|
+
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;
|
|
189
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pro-cpp-cli-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The ultimate C++ Developer Experience for Windows",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"procpp": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node index.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"cpp",
|
|
14
|
+
"c++",
|
|
15
|
+
"cli",
|
|
16
|
+
"watch",
|
|
17
|
+
"build"
|
|
18
|
+
],
|
|
19
|
+
"author": "PRO Developer",
|
|
20
|
+
"license": "MIT"
|
|
21
|
+
}
|