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.
Files changed (3) hide show
  1. package/README.md +6 -0
  2. package/index.js +65 -78
  3. 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 (With C++20 Modules Topological Sorter)
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
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 [,, command, ...args] = process.argv;
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 (file.endsWith('.obj') || file.endsWith('.pdb') || file.endsWith('.ilk') || file.endsWith('.ifc') || file.startsWith('app_build_')) {
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
- if (fs.statSync(filePath).isDirectory()) {
69
- // Ignore .build directory so watcher doesn't loop
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 (C++20 Modules)...${colors.reset}`);
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
- // 1. tasks.json
117
- const tasksContent = {
122
+ const tasks = {
118
123
  "version": "2.0.0",
119
124
  "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"
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(tasksContent, null, 4));
131
+ fs.writeFileSync(path.join(vscodeDir, 'tasks.json'), JSON.stringify(tasks, null, 4));
129
132
 
130
- // 2. c_cpp_properties.json (FIX FOR IDE SQUIGGLES!)
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(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));
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
- fs.writeFileSync(mainCppPath, `import std.core;\n// C++20 Modules ready!\nint main() {\n return 0;\n}`);
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! .vscode configs created. IntelliSense is pointed to .build/${colors.reset}`);
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
- // Stop the timer!
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 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) {}
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 -> .build\\${outputExeName}${colors.reset}\n` + `${colors.gray}${"-".repeat(40)}${colors.reset}`);
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 with code ${code}${colors.reset}`);
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 (Mode: Smart C++20 Modules)${colors.reset}`);
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}\nUsage: procpp <init|run|watch>`);
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.6",
4
- "repository": {
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",