maiass 5.7.31 → 5.7.33
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/lib/changelog.js +215 -0
- package/maiass.mjs +60 -49
- package/package.json +10 -1
- package/build.js +0 -127
package/lib/changelog.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// Changelog management for MAIASS - matches bashmaiass implementation
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import { log } from './logger.js';
|
|
5
|
+
import { SYMBOLS } from './symbols.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Execute git command and return output
|
|
9
|
+
* @param {string} command - Git command to execute
|
|
10
|
+
* @returns {string|null} Command output or null if failed
|
|
11
|
+
*/
|
|
12
|
+
function executeGitCommand(command) {
|
|
13
|
+
try {
|
|
14
|
+
return execSync(command, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the last changelog commit hash
|
|
22
|
+
* @param {string} changelogPath - Path to changelog file
|
|
23
|
+
* @returns {string|null} Commit hash or null
|
|
24
|
+
*/
|
|
25
|
+
function getLastChangelogCommit(changelogPath) {
|
|
26
|
+
try {
|
|
27
|
+
const content = execSync(`cat "${changelogPath}"`, { encoding: 'utf8' });
|
|
28
|
+
const match = content.match(/^## (.+)$/m);
|
|
29
|
+
if (match) {
|
|
30
|
+
const lastVersion = match[1].trim();
|
|
31
|
+
const hash = executeGitCommand(`git log -1 --format="%H" -S"## ${lastVersion}" -- "${changelogPath}"`);
|
|
32
|
+
if (hash) return hash;
|
|
33
|
+
}
|
|
34
|
+
} catch {}
|
|
35
|
+
|
|
36
|
+
// Fallback to first commit
|
|
37
|
+
return executeGitCommand('git rev-list --max-parents=0 HEAD');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update changelog files with new version and commits
|
|
42
|
+
* @param {string} changelogPath - Directory containing changelog
|
|
43
|
+
* @param {string} version - New version number
|
|
44
|
+
* @returns {Promise<void>}
|
|
45
|
+
*/
|
|
46
|
+
export async function updateChangelog(changelogPath = '.', version) {
|
|
47
|
+
const changelogName = process.env.MAIASS_CHANGELOG_NAME || 'CHANGELOG.md';
|
|
48
|
+
const changelogInternalName = process.env.MAIASS_CHANGELOG_INTERNAL_NAME || '.CHANGELOG_internal.md';
|
|
49
|
+
const changelogInternalPath = process.env.MAIASS_CHANGELOG_INTERNAL_PATH || changelogPath;
|
|
50
|
+
|
|
51
|
+
const changelogFile = `${changelogPath}/${changelogName}`;
|
|
52
|
+
const changelogInternalFile = `${changelogInternalPath}/${changelogInternalName}`;
|
|
53
|
+
|
|
54
|
+
// Get last changelog commit
|
|
55
|
+
let lastChangelogCommit = null;
|
|
56
|
+
try {
|
|
57
|
+
await fs.access(changelogFile);
|
|
58
|
+
lastChangelogCommit = getLastChangelogCommit(changelogFile);
|
|
59
|
+
} catch {}
|
|
60
|
+
|
|
61
|
+
if (!lastChangelogCommit) {
|
|
62
|
+
lastChangelogCommit = executeGitCommand('git rev-list --max-parents=0 HEAD');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!lastChangelogCommit) {
|
|
66
|
+
log.info(SYMBOLS.INFO, 'No commits found, skipping changelog');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const logRange = `${lastChangelogCommit}..HEAD`;
|
|
71
|
+
|
|
72
|
+
// Get commits for main changelog (remove JIRA tickets, filter out merges/bumps)
|
|
73
|
+
const rawCommits = executeGitCommand(`git log ${logRange} --pretty=format:"%B"`);
|
|
74
|
+
|
|
75
|
+
let changelog = '';
|
|
76
|
+
if (rawCommits) {
|
|
77
|
+
// Process commits: filter and format
|
|
78
|
+
const commits = rawCommits.split('\n\n').filter(commit => {
|
|
79
|
+
const firstLine = commit.split('\n')[0].toLowerCase();
|
|
80
|
+
return !firstLine.match(/^(ncl|merge|bump|fixing merge conflicts)/i);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const formattedCommits = commits.map(commit => {
|
|
84
|
+
// Remove JIRA ticket from start
|
|
85
|
+
const cleaned = commit.replace(/^\[?[A-Z]+-[0-9]+\]?[\s:—-]+/gm, '');
|
|
86
|
+
const lines = cleaned.split('\n').filter(l => l.trim());
|
|
87
|
+
|
|
88
|
+
if (lines.length === 0) return '';
|
|
89
|
+
|
|
90
|
+
// First line as bullet, rest as indented sub-bullets
|
|
91
|
+
let result = `- ${lines[0]}`;
|
|
92
|
+
for (let i = 1; i < lines.length; i++) {
|
|
93
|
+
if (lines[i].trim()) {
|
|
94
|
+
result += `\n\t${lines[i]}`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}).filter(c => c);
|
|
99
|
+
|
|
100
|
+
changelog = formattedCommits.join('\n');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Get commits for internal changelog (with author names)
|
|
104
|
+
const rawInternalCommits = executeGitCommand(`git log ${logRange} --pretty=format:"%an%n%B"`);
|
|
105
|
+
|
|
106
|
+
let changelogInternal = '';
|
|
107
|
+
if (rawInternalCommits) {
|
|
108
|
+
// Process internal commits with author
|
|
109
|
+
const commitBlocks = rawInternalCommits.split('\n\n').filter(block => {
|
|
110
|
+
const lines = block.split('\n');
|
|
111
|
+
if (lines.length < 2) return false;
|
|
112
|
+
const subject = lines[1].toLowerCase();
|
|
113
|
+
return !subject.match(/^(ncl|merge|bump|fixing merge conflicts)/i);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const formattedInternal = commitBlocks.map(block => {
|
|
117
|
+
const lines = block.split('\n').filter(l => l.trim());
|
|
118
|
+
if (lines.length < 2) return '';
|
|
119
|
+
|
|
120
|
+
const author = lines[0];
|
|
121
|
+
const subject = lines[1]; // Keep JIRA ticket in internal changelog
|
|
122
|
+
|
|
123
|
+
let result = `- ${author}: ${subject}`;
|
|
124
|
+
for (let i = 2; i < lines.length; i++) {
|
|
125
|
+
if (lines[i].trim()) {
|
|
126
|
+
result += `\n\t${lines[i]}`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}).filter(c => c);
|
|
131
|
+
|
|
132
|
+
changelogInternal = formattedInternal.join('\n');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Get current date
|
|
136
|
+
const now = new Date();
|
|
137
|
+
const humanDate = now.toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' });
|
|
138
|
+
const weekday = now.toLocaleDateString('en-GB', { weekday: 'long' });
|
|
139
|
+
const longHumanDate = `${humanDate} (${weekday})`;
|
|
140
|
+
|
|
141
|
+
// Update main changelog
|
|
142
|
+
if (!changelog) {
|
|
143
|
+
log.info(SYMBOLS.INFO, 'No changelog to add');
|
|
144
|
+
} else {
|
|
145
|
+
try {
|
|
146
|
+
let existingContent = '';
|
|
147
|
+
try {
|
|
148
|
+
existingContent = await fs.readFile(changelogFile, 'utf8');
|
|
149
|
+
} catch {}
|
|
150
|
+
|
|
151
|
+
if (existingContent) {
|
|
152
|
+
const lines = existingContent.split('\n');
|
|
153
|
+
const firstVersion = lines[0]?.match(/^## (.+)$/)?.[1];
|
|
154
|
+
const secondLine = lines[1];
|
|
155
|
+
|
|
156
|
+
// Check if we're updating the same minor version on the same date
|
|
157
|
+
const currentMinor = version.split('.').slice(0, 2).join('.');
|
|
158
|
+
const existingMinor = firstVersion?.split('.').slice(0, 2).join('.');
|
|
159
|
+
|
|
160
|
+
if (currentMinor === existingMinor && secondLine === humanDate) {
|
|
161
|
+
// Replace existing entry
|
|
162
|
+
const newContent = `## ${version}\n${humanDate}\n\n${changelog}\n${lines.slice(3).join('\n')}`;
|
|
163
|
+
await fs.writeFile(changelogFile, newContent, 'utf8');
|
|
164
|
+
} else {
|
|
165
|
+
// Add new entry
|
|
166
|
+
const newContent = `## ${version}\n${humanDate}\n\n${changelog}\n\n${existingContent}`;
|
|
167
|
+
await fs.writeFile(changelogFile, newContent, 'utf8');
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
// Create new file
|
|
171
|
+
await fs.writeFile(changelogFile, `## ${version}\n${humanDate}\n\n${changelog}\n`, 'utf8');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
log.success(SYMBOLS.CHECKMARK, `Updated ${changelogName}`);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
log.error(SYMBOLS.CROSS, `Failed to update ${changelogName}: ${error.message}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Update internal changelog
|
|
181
|
+
if (!changelogInternal) {
|
|
182
|
+
log.info(SYMBOLS.INFO, 'No commits for internal changelog - updating version header only');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
await fs.access(changelogInternalFile);
|
|
187
|
+
|
|
188
|
+
let existingContent = await fs.readFile(changelogInternalFile, 'utf8');
|
|
189
|
+
const lines = existingContent.split('\n');
|
|
190
|
+
const firstVersion = lines[0]?.match(/^## (.+)$/)?.[1];
|
|
191
|
+
const secondLine = lines[1];
|
|
192
|
+
|
|
193
|
+
// Check if we're updating the same minor version on the same date
|
|
194
|
+
const currentMinor = version.split('.').slice(0, 2).join('.');
|
|
195
|
+
const existingMinor = firstVersion?.split('.').slice(0, 2).join('.');
|
|
196
|
+
|
|
197
|
+
const contentToAdd = changelogInternal || '';
|
|
198
|
+
|
|
199
|
+
if (currentMinor === existingMinor && secondLine === longHumanDate) {
|
|
200
|
+
// Replace existing entry
|
|
201
|
+
const newContent = `## ${version}\n${longHumanDate}\n\n${contentToAdd}\n${lines.slice(3).join('\n')}`;
|
|
202
|
+
await fs.writeFile(changelogInternalFile, newContent, 'utf8');
|
|
203
|
+
} else {
|
|
204
|
+
// Add new entry
|
|
205
|
+
const newContent = `## ${version}\n${longHumanDate}\n\n${contentToAdd}\n\n${existingContent}`;
|
|
206
|
+
await fs.writeFile(changelogInternalFile, newContent, 'utf8');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
log.success(SYMBOLS.CHECKMARK, `Updated ${changelogInternalName}`);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
log.info(SYMBOLS.INFO, `Internal changelog ${changelogInternalFile} does not exist, skipping`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export default { updateChangelog };
|
package/maiass.mjs
CHANGED
|
@@ -107,55 +107,66 @@ if (args.includes('--help') || args.includes('-h') || command === 'help') {
|
|
|
107
107
|
process.exit(0);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
// Command routing
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
110
|
+
// Command routing (wrapped in async IIFE to handle async commands)
|
|
111
|
+
(async () => {
|
|
112
|
+
switch (command) {
|
|
113
|
+
case 'hello':
|
|
114
|
+
console.log(colors.BCyan('Hello from MAIASS!'));
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case 'env':
|
|
118
|
+
displayEnvironmentVariables();
|
|
119
|
+
break;
|
|
120
|
+
|
|
121
|
+
case 'git-info':
|
|
122
|
+
const gitInfo = getGitInfo();
|
|
123
|
+
displayGitInfo(gitInfo);
|
|
124
|
+
break;
|
|
125
|
+
|
|
126
|
+
case 'config':
|
|
127
|
+
await handleConfigCommand(process.argv.slice(3));
|
|
128
|
+
break;
|
|
129
|
+
|
|
130
|
+
case 'version':
|
|
131
|
+
await handleVersionCommand(process.argv.slice(3));
|
|
132
|
+
break;
|
|
133
|
+
|
|
134
|
+
case 'account-info':
|
|
135
|
+
await handleAccountInfoCommand({
|
|
136
|
+
json: args.includes('--json')
|
|
137
|
+
});
|
|
138
|
+
break;
|
|
139
|
+
|
|
140
|
+
case 'maiass':
|
|
141
|
+
// Handle the main MAIASS workflow
|
|
142
|
+
await handleMaiassCommand({
|
|
143
|
+
_: process.argv.slice(2).filter(arg => !arg.startsWith('--')),
|
|
144
|
+
'commits-only': args.includes('--commits-only') || args.includes('-c'),
|
|
145
|
+
'auto-stage': args.includes('--auto-stage'),
|
|
146
|
+
'auto': args.includes('--auto'),
|
|
147
|
+
'version-bump': versionBump,
|
|
148
|
+
'dry-run': args.includes('--dry-run') || args.includes('-d'),
|
|
149
|
+
force: args.includes('--force') || args.includes('-f'),
|
|
150
|
+
silent: args.includes('--silent') || args.includes('-s'),
|
|
151
|
+
tag: getArgValue(args, '--tag') || getArgValue(args, '-t')
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
|
|
155
|
+
default:
|
|
156
|
+
console.error(`Unknown command: ${command}`);
|
|
157
|
+
console.log('Run `maiass --help` for available commands.');
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Exit cleanly after successful command execution
|
|
162
|
+
process.exit(0);
|
|
163
|
+
})().catch(error => {
|
|
164
|
+
console.error(colors.Red(`${SYMBOLS.CROSS} Fatal error: ${error.message}`));
|
|
165
|
+
if (process.env.MAIASS_DEBUG === 'true') {
|
|
166
|
+
console.error(colors.Gray(error.stack));
|
|
167
|
+
}
|
|
168
|
+
process.exit(1);
|
|
169
|
+
});
|
|
159
170
|
|
|
160
171
|
// Helper function to get argument values
|
|
161
172
|
function getArgValue(args, flag) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maiass",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.7.
|
|
4
|
+
"version": "5.7.33",
|
|
5
5
|
"description": "MAIASS - Modular AI-Augmented Semantic Scribe - Intelligent Git workflow automation",
|
|
6
6
|
"main": "maiass.mjs",
|
|
7
7
|
"bin": {
|
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
},
|
|
11
11
|
"author": "Velvary Pty Ltd",
|
|
12
12
|
"license": "GPL-3.0-only",
|
|
13
|
+
"files": [
|
|
14
|
+
"lib/",
|
|
15
|
+
"maiass.mjs",
|
|
16
|
+
"maiass.cjs",
|
|
17
|
+
"maiass-standalone.cjs",
|
|
18
|
+
"setup-env.js",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
13
22
|
"engines": {
|
|
14
23
|
"node": ">=18.0.0"
|
|
15
24
|
},
|
package/build.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Cross-platform build script for maiass
|
|
4
|
-
* Builds binaries for all supported platforms and architectures
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { execSync } from 'child_process';
|
|
8
|
-
import fs from 'fs';
|
|
9
|
-
import path from 'path';
|
|
10
|
-
import colors from './lib/colors.js';
|
|
11
|
-
|
|
12
|
-
const targets = [
|
|
13
|
-
'node18-macos-x64',
|
|
14
|
-
'node18-macos-arm64',
|
|
15
|
-
'node18-linux-x64',
|
|
16
|
-
'node18-linux-arm64',
|
|
17
|
-
'node18-win-x64',
|
|
18
|
-
'node18-win-arm64'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
const platformNames = {
|
|
22
|
-
'node18-macos-x64': 'macOS Intel',
|
|
23
|
-
'node18-macos-arm64': 'macOS Apple Silicon',
|
|
24
|
-
'node18-linux-x64': 'Linux x64',
|
|
25
|
-
'node18-linux-arm64': 'Linux ARM64',
|
|
26
|
-
'node18-win-x64': 'Windows x64',
|
|
27
|
-
'node18-win-arm64': 'Windows ARM64'
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
function buildForTarget(target) {
|
|
31
|
-
console.log(colors.BBlue(`Building for ${platformNames[target]}...`));
|
|
32
|
-
|
|
33
|
-
// Map target to output filename
|
|
34
|
-
const outputNames = {
|
|
35
|
-
'node18-macos-x64': 'maiass-macos-x64',
|
|
36
|
-
'node18-macos-arm64': 'maiass-macos-arm64',
|
|
37
|
-
'node18-linux-x64': 'maiass-linux-x64',
|
|
38
|
-
'node18-linux-arm64': 'maiass-linux-arm64',
|
|
39
|
-
'node18-win-x64': 'maiass-win-x64.exe',
|
|
40
|
-
'node18-win-arm64': 'maiass-win-arm64.exe'
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const outputName = outputNames[target];
|
|
44
|
-
const outputPath = `build/${outputName}`;
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
execSync(`npx pkg . --target ${target} --output ${outputPath}`, {
|
|
48
|
-
stdio: 'inherit',
|
|
49
|
-
encoding: 'utf8'
|
|
50
|
-
});
|
|
51
|
-
console.log(colors.Green(`✓ Successfully built for ${platformNames[target]} -> ${outputName}`));
|
|
52
|
-
|
|
53
|
-
// Code sign macOS binaries
|
|
54
|
-
if (target.includes('macos') && process.platform === 'darwin') {
|
|
55
|
-
try {
|
|
56
|
-
console.log(colors.BBlue(` 🔐 Code signing ${outputName}...`));
|
|
57
|
-
execSync(`./scripts/codesign.sh "${outputPath}"`, { stdio: 'pipe' });
|
|
58
|
-
console.log(colors.Green(` ✓ Code signed ${outputName}`));
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.log(colors.Yellow(` ⚠️ Code signing failed for ${outputName} (continuing without signing)`));
|
|
61
|
-
console.log(colors.Gray(` ${error.message.split('\n')[0]}`));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Code sign Windows binaries
|
|
66
|
-
if (target.includes('win')) {
|
|
67
|
-
try {
|
|
68
|
-
console.log(colors.BBlue(` 🔐 Code signing ${outputName}...`));
|
|
69
|
-
execSync(`./scripts/codesign-windows.sh "${outputPath}"`, { stdio: 'pipe' });
|
|
70
|
-
console.log(colors.Green(` ✓ Code signed ${outputName}`));
|
|
71
|
-
} catch (error) {
|
|
72
|
-
console.log(colors.Yellow(` ⚠️ Windows code signing failed for ${outputName} (continuing without signing)`));
|
|
73
|
-
console.log(colors.Gray(` ${error.message.split('\n')[0]}`));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return true;
|
|
78
|
-
} catch (error) {
|
|
79
|
-
console.log(colors.Red(`✗ Failed to build for ${platformNames[target]}: ${error.message}`));
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function main() {
|
|
85
|
-
console.log(colors.Aqua('MAIASS Cross-Platform Build'));
|
|
86
|
-
console.log(colors.White('Building binaries for all supported platforms...\n'));
|
|
87
|
-
|
|
88
|
-
// Ensure build directory exists and is clean
|
|
89
|
-
if (fs.existsSync('build')) {
|
|
90
|
-
// Clean the build directory
|
|
91
|
-
const files = fs.readdirSync('build');
|
|
92
|
-
for (const file of files) {
|
|
93
|
-
if (file !== '.DS_Store') {
|
|
94
|
-
fs.unlinkSync(path.join('build', file));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
} else {
|
|
98
|
-
fs.mkdirSync('build');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
let successful = 0;
|
|
102
|
-
let failed = 0;
|
|
103
|
-
|
|
104
|
-
for (const target of targets) {
|
|
105
|
-
if (buildForTarget(target)) {
|
|
106
|
-
successful++;
|
|
107
|
-
} else {
|
|
108
|
-
failed++;
|
|
109
|
-
}
|
|
110
|
-
console.log(''); // Add spacing between builds
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
console.log(colors.White('\n=== Build Summary ==='));
|
|
114
|
-
console.log(colors.Green(`Successful builds: ${successful}`));
|
|
115
|
-
if (failed > 0) {
|
|
116
|
-
console.log(colors.Red(`Failed builds: ${failed}`));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (successful === targets.length) {
|
|
120
|
-
console.log(colors.Green('\n🎉 All builds completed successfully!'));
|
|
121
|
-
console.log(colors.White('Binaries are available in the build/ directory'));
|
|
122
|
-
} else {
|
|
123
|
-
console.log(colors.Yellow('\n⚠️ Some builds failed. Check the output above for details.'));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
main();
|