pro-cpp-cli-core 1.0.6 โ†’ 1.0.8

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 +76 -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
+ * - Fixed UTF-8 Encoding in C++ template (No more "ะะฏะชะ")
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,60 @@ 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
+ // FIXED TEMPLATE: Added Windows UTF-8 support to fix "ะะฏะชะ"
149
+ const template =
150
+ `#include <iostream>
151
+ #include <windows.h>
152
+
153
+ int main() {
154
+ // Set console output to UTF-8 to support emojis and international text
155
+ SetConsoleOutputCP(CP_UTF8);
156
+
157
+ std::cout << "๐Ÿš€ PRO C++ is running!" << std::endl;
158
+ return 0;
159
+ }`;
160
+ fs.writeFileSync(mainCppPath, template);
164
161
  }
165
162
 
166
- console.log(`${colors.green}โœ… Ready! .vscode configs created. IntelliSense is pointed to .build/${colors.reset}`);
163
+ console.log(`${colors.green}โœ… Ready! Use 'procpp watch' to start developing.${colors.reset}`);
167
164
  }
168
165
 
169
166
  function buildAndRun() {
167
+ if (!checkEnv()) return;
168
+
170
169
  const cppFiles = getSortedCppFiles();
171
170
  if (!cppFiles) {
172
171
  console.error(`${colors.red}โŒ Error: No .cpp or .ixx files found!${colors.reset}`);
@@ -178,37 +177,27 @@ function buildAndRun() {
178
177
  if (!fs.existsSync(BUILD_DIR)) fs.mkdirSync(BUILD_DIR);
179
178
 
180
179
  const outputExeName = `app_build_${Date.now()}.exe`;
180
+ console.log(`\n${colors.cyan}๐Ÿ”จ Compiling...${colors.reset}`);
181
181
 
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
182
  const startTime = performance.now();
183
+ const compileCmd = `cl.exe /std:c++20 /nologo /EHsc /Zi ${cppFiles} /Fe"${outputExeName}"`;
189
184
 
190
185
  if (runSyncCommand(compileCmd)) {
191
- // Stop the timer!
192
- const endTime = performance.now();
193
- const buildTime = ((endTime - startTime) / 1000).toFixed(2);
186
+ const buildTime = ((performance.now() - startTime) / 1000).toFixed(2);
194
187
 
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) {}
188
+ // Move artifacts to .build
189
+ fs.readdirSync(process.cwd()).forEach(file => {
190
+ if (['.obj', '.ifc', '.pdb', '.ilk'].some(ext => file.endsWith(ext)) || file === outputExeName) {
191
+ try { fs.renameSync(path.join(process.cwd(), file), path.join(BUILD_DIR, file)); } catch(e) {}
202
192
  }
203
193
  });
204
194
 
205
195
  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}`);
196
+ console.log(`${colors.yellow}๐ŸŸข RUNNING -> ${outputExeName}${colors.reset}\n` + `${colors.gray}${"-".repeat(40)}${colors.reset}`);
207
197
 
208
- // Run from .build folder
209
198
  currentAppProcess = spawn(`.\\.build\\${outputExeName}`, [], { shell: true, stdio: 'inherit' });
210
199
  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}`);
200
+ if (code !== null) console.log(`${colors.gray}${"-".repeat(40)}${colors.reset}\n${colors.red}๐Ÿ›‘ Process exited (code ${code})${colors.reset}`);
212
201
  });
213
202
  } else {
214
203
  console.log(`\n${colors.red}${colors.bold}โŒ BUILD FAILED${colors.reset}`);
@@ -216,12 +205,12 @@ function buildAndRun() {
216
205
  }
217
206
 
218
207
  function watchProject() {
208
+ if (!checkEnv()) return;
219
209
  console.clear();
220
- console.log(`${colors.cyan}${colors.bold}๐Ÿ‘€ PRO C++ Watcher Started (Mode: Smart C++20 Modules)${colors.reset}`);
210
+ console.log(`${colors.cyan}${colors.bold}๐Ÿ‘€ PRO C++ Watcher Started${colors.reset}`);
221
211
  buildAndRun();
222
212
 
223
213
  fs.watch(process.cwd(), { recursive: true }, (eventType, filename) => {
224
- // Ignore changes inside .build to prevent infinite loops
225
214
  if (filename && (filename.endsWith('.cpp') || filename.endsWith('.ixx') || filename.endsWith('.h')) && !filename.includes('.build')) {
226
215
  clearTimeout(watchTimeout);
227
216
  watchTimeout = setTimeout(() => {
@@ -233,11 +222,20 @@ function watchProject() {
233
222
  });
234
223
  }
235
224
 
225
+ // --- CLI ROUTER ---
226
+
227
+ const versionFlags = ['-v', '--version', 'version'];
228
+ if (versionFlags.includes(command)) {
229
+ console.log(`${colors.bold}pro-cpp-cli-core v${packageJson.version}${colors.reset}`);
230
+ process.exit(0);
231
+ }
232
+
236
233
  switch (command) {
237
234
  case 'init': initProject(); break;
238
235
  case 'run': buildAndRun(); break;
239
236
  case 'watch': watchProject(); break;
240
237
  default:
241
- console.log(`${colors.bold}๐Ÿ› ๏ธ PRO CPP CLI${colors.reset}\nUsage: procpp <init|run|watch>`);
238
+ console.log(`${colors.bold}๐Ÿ› ๏ธ PRO CPP CLI v${packageJson.version}${colors.reset}`);
239
+ console.log(`Usage: procpp <init|run|watch|version>`);
242
240
  break;
243
241
  }
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.8",
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",