@docupace/pipeline 1.0.77-alpha.2 → 1.0.77

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 (69) hide show
  1. package/.prettierrc.cjs +12 -12
  2. package/README.md +135 -135
  3. package/bin/azuread_update_callbacks_for_app.sh +58 -58
  4. package/bin/next-changeset-validate.sh +8 -8
  5. package/bitbucket-pipelines.yml +59 -59
  6. package/eslint.config.js +49 -49
  7. package/jest.config.js +15 -15
  8. package/next/changeset.sh +75 -75
  9. package/next/copy.sh +34 -34
  10. package/next/deploy.sh +40 -40
  11. package/next/execute.sh +123 -123
  12. package/next/sonar.sh +23 -23
  13. package/package.json +1 -1
  14. package/src/auth0/alias.js +79 -79
  15. package/src/auth0/alias.test.js +172 -172
  16. package/src/auth0/cli.js +82 -82
  17. package/src/auth0/configure.js +902 -902
  18. package/src/auth0/configure.test.js +167 -167
  19. package/src/auth0/export.js +48 -48
  20. package/src/auth0/export.test.js +103 -103
  21. package/src/auth0/metadata.js +141 -141
  22. package/src/auth0/metadata.test.js +186 -186
  23. package/src/auth0/vault.js +60 -60
  24. package/src/auth0/vault.test.js +134 -134
  25. package/src/changeset/changelog-wiki.js +328 -328
  26. package/src/changeset/changeset-config.js +34 -34
  27. package/src/changeset/cli.js +237 -237
  28. package/src/changeset/create.js +215 -215
  29. package/src/changeset/package-util.js +87 -87
  30. package/src/changeset/util.js +43 -43
  31. package/src/changeset/validate.js +91 -91
  32. package/src/changeset/version.js +102 -102
  33. package/src/jenkins/setParams.groovy +58 -58
  34. package/src/lib/merge-driver.js +204 -204
  35. package/src/merge/cli-merge-all.js +507 -507
  36. package/src/merge/cli-merge.js +492 -492
  37. package/src/merge/cli-resolve.js +399 -399
  38. package/src/merge/cli.js +38 -38
  39. package/src/merge/merge-changelog.js +87 -87
  40. package/src/merge/merge-package.js +106 -106
  41. package/src/merge/merge-types.js +82 -82
  42. package/src/merge/pr.js +231 -231
  43. package/src/micro/cli.js +71 -0
  44. package/src/micro/ms-deploy.js +271 -0
  45. package/src/micro/{publish-ms.js → ms-publish.js} +6 -8
  46. package/src/next/alias.js +53 -53
  47. package/src/next/apache.js +81 -81
  48. package/src/next/cli.js +1 -10
  49. package/src/next/config.js +137 -137
  50. package/src/next/connect.js +226 -226
  51. package/src/next/copy.js +61 -61
  52. package/src/next/deploy.js +633 -633
  53. package/src/next/git-to-semver.js +79 -79
  54. package/src/next/haproxy.js +76 -76
  55. package/src/next/jenkins.js +123 -123
  56. package/src/next/jira.js +84 -84
  57. package/src/next/logger.js +17 -17
  58. package/src/next/pipline.js +114 -114
  59. package/src/next/publish.js +71 -71
  60. package/src/next/pull.js +7 -7
  61. package/src/next/sonar.js +23 -23
  62. package/src/next/test.js +5 -5
  63. package/src/next/util.js +93 -95
  64. package/src/next/vault.js +45 -45
  65. package/terraform/apply.sh +37 -37
  66. package/terraform/init.sh +72 -72
  67. package/terraform/plan.sh +76 -76
  68. package/terraform/validate.sh +17 -17
  69. package/src/micro/deploy-microservice.js +0 -153
@@ -1,399 +1,399 @@
1
- import { mergeChangelogFile } from './merge-changelog.js';
2
- import mergeTypes, { mergeTypesFile } from './merge-types.js';
3
- import { existsSync, readFileSync, writeFileSync } from 'fs';
4
- import mergePackageFile from './merge-package.js';
5
- import { execSync } from 'child_process';
6
-
7
- // Default merge configuration
8
- const defaultMergeConfig = {
9
- 'CHANGELOG.md': 'changelog',
10
- '*/CHANGELOG.md': 'changelog',
11
- '**/CHANGELOG.md': 'changelog',
12
- 'src/types/graphql.ts': 'types',
13
- 'codegen.ts': 'ours',
14
- 'package.json': 'package',
15
- '*/package.json': 'package',
16
- '**/package.json': 'package',
17
- };
18
-
19
- // Available merge strategies
20
- const mergeStrategies = {
21
- changelog: mergeChangelogFile,
22
- package: mergePackageFile,
23
- types: mergeTypesFile,
24
- ours: (filePath) => {
25
- // Keep our version by checking out the HEAD version (removes conflicts)
26
- try {
27
- execSync(`git checkout --ours ${filePath}`);
28
- execSync(`git add ${filePath}`);
29
- console.log(
30
- `šŸ“ Using 'ours' strategy for ${filePath} - reset to HEAD version and marked as resolved`,
31
- );
32
- return true;
33
- } catch (error) {
34
- throw new Error(`Failed to apply 'ours' strategy: ${error.message}`);
35
- }
36
- },
37
- theirs: (filePath) => {
38
- // Take their version
39
- try {
40
- execSync(`git checkout --theirs ${filePath}`);
41
- execSync(`git add ${filePath}`);
42
- console.log(
43
- `šŸ“ Using 'theirs' strategy for ${filePath} - marked as resolved`,
44
- );
45
- return true;
46
- } catch (error) {
47
- throw new Error(`Failed to apply 'theirs' strategy: ${error.message}`);
48
- }
49
- },
50
- };
51
-
52
- /**
53
- * Get list of conflicted files from git status
54
- */
55
- function getConflictedFiles() {
56
- try {
57
- const statusOutput = execSync('git status --porcelain', {
58
- encoding: 'utf-8',
59
- });
60
- const conflictedFiles = statusOutput
61
- .split('\n')
62
- .filter(
63
- (line) =>
64
- line.startsWith('UU ') ||
65
- line.startsWith('AA ') ||
66
- line.startsWith('DD '),
67
- )
68
- .map((line) => line.substring(3).trim())
69
- .filter((file) => file.length > 0);
70
- return conflictedFiles;
71
- } catch (error) {
72
- throw new Error(`Failed to get git status: ${error.message}`);
73
- }
74
- }
75
-
76
- /**
77
- * Load merge configuration from .mergerc file or use defaults
78
- */
79
- function loadMergeConfig() {
80
- const configPath = '.mergerc';
81
-
82
- if (existsSync(configPath)) {
83
- try {
84
- const configContent = readFileSync(configPath, 'utf-8');
85
- const config = {};
86
-
87
- configContent.split('\n').forEach((line) => {
88
- line = line.trim();
89
- if (line && !line.startsWith('#')) {
90
- const [pattern, strategy] = line
91
- .split(/\s+merge=/)
92
- .map((s) => s.trim());
93
- if (pattern && strategy) {
94
- config[pattern] = strategy;
95
- }
96
- }
97
- });
98
-
99
- return config;
100
- } catch (error) {
101
- console.warn(
102
- `Warning: Could not read ${configPath}, using defaults: ${error.message}`,
103
- );
104
- }
105
- }
106
-
107
- return defaultMergeConfig;
108
- }
109
-
110
- /**
111
- * Match file path against patterns (supports * and ** wildcards)
112
- */
113
- function matchPattern(filePath, pattern) {
114
- // Handle ** at the beginning of pattern
115
- if (pattern.startsWith('**/')) {
116
- // Remove the **/ and check if the path ends with the remaining pattern
117
- const remainingPattern = pattern.slice(3);
118
- const regexPattern = remainingPattern
119
- .replace(/\*/g, '[^/]*')
120
- .replace(/\./g, '\\.')
121
- .replace(/\//g, '\\/');
122
-
123
- const regex = new RegExp(`(^|/)${regexPattern}$`);
124
- return regex.test(filePath);
125
- }
126
-
127
- // For other cases, convert pattern to regex
128
- const regexPattern = pattern
129
- .replace(/\*\*/g, '___DOUBLESTAR___')
130
- .replace(/\*/g, '[^/]*')
131
- .replace(/___DOUBLESTAR___/g, '.*?')
132
- .replace(/\./g, '\\.')
133
- .replace(/\//g, '\\/');
134
-
135
- const regex = new RegExp(`^${regexPattern}$`);
136
- return regex.test(filePath);
137
- }
138
-
139
- /**
140
- * Find merge strategy for a given file
141
- */
142
- function findMergeStrategy(filePath, config) {
143
- // Check exact match first
144
- if (config[filePath]) {
145
- return config[filePath];
146
- }
147
-
148
- // Check pattern matches
149
- for (const [pattern, strategy] of Object.entries(config)) {
150
- if (matchPattern(filePath, pattern)) {
151
- return strategy;
152
- }
153
- }
154
-
155
- return null;
156
- }
157
-
158
- /**
159
- * Create default .mergerc file
160
- */
161
- function createDefaultConfig() {
162
- const configContent = `# Merge configuration file
163
- # Format: <file-pattern> merge=<strategy>
164
- # Strategies: changelog, package, types, ours, theirs
165
-
166
- CHANGELOG.md merge=changelog
167
- */CHANGELOG.md merge=changelog
168
- **/CHANGELOG.md merge=changelog
169
- src/types/graphql.ts merge=types
170
- codegen.ts merge=ours
171
- package.json merge=package
172
- */package.json merge=package
173
- **/package.json merge=package
174
- `;
175
-
176
- writeFileSync('.mergerc', configContent);
177
- console.log('āœ… Created default .mergerc configuration file');
178
- }
179
-
180
- export async function autoResolveConflicts(options = {}) {
181
- const { dryRun = false, verbose = false } = options;
182
-
183
- // Get conflicted files
184
- const conflictedFiles = getConflictedFiles();
185
-
186
- if (conflictedFiles.length === 0) {
187
- if (verbose) console.log('āœ… No conflicted files found');
188
- return { success: true, resolvedCount: 0, skippedCount: 0, totalCount: 0 };
189
- }
190
-
191
- if (verbose) {
192
- console.log(`Found ${conflictedFiles.length} conflicted files:`);
193
- conflictedFiles.forEach((file) => console.log(` - ${file}`));
194
- console.log('');
195
- }
196
-
197
- // Load configuration
198
- const config = loadMergeConfig();
199
-
200
- if (verbose) {
201
- console.log('Merge configuration:');
202
- Object.entries(config).forEach(([pattern, strategy]) => {
203
- console.log(` ${pattern} -> ${strategy}`);
204
- });
205
- console.log('');
206
- }
207
-
208
- let resolvedCount = 0;
209
- let skippedCount = 0;
210
-
211
- // Process each conflicted file
212
- for (const filePath of conflictedFiles) {
213
- const strategy = findMergeStrategy(filePath, config);
214
-
215
- if (!strategy) {
216
- if (verbose)
217
- console.log(`āš ļø No strategy found for ${filePath} - skipping`);
218
- skippedCount++;
219
- continue;
220
- }
221
-
222
- const mergeFunction = mergeStrategies[strategy];
223
- if (!mergeFunction) {
224
- if (verbose)
225
- console.log(
226
- `āš ļø Unknown strategy '${strategy}' for ${filePath} - skipping`,
227
- );
228
- skippedCount++;
229
- continue;
230
- }
231
-
232
- if (dryRun) {
233
- if (verbose)
234
- console.log(`Would apply '${strategy}' strategy to ${filePath}`);
235
- continue;
236
- }
237
-
238
- try {
239
- if (verbose)
240
- console.log(`šŸ”§ Applying '${strategy}' strategy to ${filePath}`);
241
- const result = await mergeFunction(filePath);
242
- if (result.success) {
243
- resolvedCount++;
244
- } else {
245
- skippedCount++;
246
- }
247
- } catch (error) {
248
- console.error(`āŒ Failed to resolve ${filePath}: ${error.message}`);
249
- skippedCount++;
250
- }
251
- }
252
-
253
- const result = {
254
- success: skippedCount === 0,
255
- resolvedCount,
256
- skippedCount,
257
- totalCount: conflictedFiles.length,
258
- };
259
-
260
- // Summary
261
- if (verbose) {
262
- console.log(`\nšŸ“Š Summary:`);
263
- console.log(` Resolved: ${resolvedCount}`);
264
- console.log(` Skipped: ${skippedCount}`);
265
- console.log(` Total: ${conflictedFiles.length}`);
266
-
267
- if (resolvedCount > 0 && !dryRun) {
268
- console.log(`\nāœ… Successfully resolved ${resolvedCount} conflicts`);
269
- if (skippedCount === 0) {
270
- console.log(
271
- 'šŸŽ‰ All conflicts resolved! You can now commit the changes.',
272
- );
273
- }
274
- }
275
- }
276
-
277
- return result;
278
- }
279
-
280
- export function setupResolve(program) {
281
- program
282
- .command('resolve-conflicts')
283
- .description('Automatically resolve conflicts based on configuration')
284
- .option(
285
- '-c, --config <path>',
286
- 'Path to merge configuration file',
287
- '.mergerc',
288
- )
289
- .option('-n, --dry-run', 'Show what would be done without making changes')
290
- .option('-v, --verbose', 'Verbose output')
291
- .action(async (options) => {
292
- try {
293
- const result = await autoResolveConflicts(options);
294
-
295
- if (!result.success) {
296
- console.error(
297
- `āŒ Auto-resolve failed: ${result.skippedCount} files could not be resolved`,
298
- );
299
- process.exit(1);
300
- }
301
- } catch (error) {
302
- console.error(`āŒ Auto-resolve failed: ${error.message}`);
303
- process.exit(1);
304
- }
305
- });
306
-
307
- // New merge command
308
-
309
- // Individual strategy commands
310
- program
311
- .command('resolve-changelog-conflicts')
312
- .description('Merge changelog files by removing conflict markers')
313
- .argument('<file>', 'File with merge conflicts')
314
- .action(async (file) => {
315
- try {
316
- mergeChangelogFile(file);
317
- console.log('āœ… Changelog merge completed successfully');
318
- } catch (error) {
319
- console.error(`āŒ Changelog merge failed: ${error.message}`);
320
- process.exit(1);
321
- }
322
- });
323
-
324
- program
325
- .command('resolve-package-conflicts')
326
- .description('Merge package.json files by resolving version conflicts')
327
- .argument('<file>', 'File with merge conflicts')
328
- .action(async (file) => {
329
- try {
330
- await mergePackageFile(file);
331
- console.log('āœ… Package merge completed successfully');
332
- } catch (error) {
333
- console.error(`āŒ Package merge failed: ${error.message}`);
334
- process.exit(1);
335
- }
336
- });
337
-
338
- program
339
- .command('resolve-type-conflicts')
340
- .description('Merge types files with balanced brace checking')
341
- .argument('<file>', 'File with merge conflicts')
342
- .action(async (file) => {
343
- try {
344
- await mergeTypes(file);
345
- console.log('āœ… Types merge completed successfully');
346
- } catch (error) {
347
- console.error(`āŒ Types merge failed: ${error.message}`);
348
- process.exit(1);
349
- }
350
- });
351
-
352
- // Configuration commands
353
- program
354
- .command('init')
355
- .description('Create default .mergerc configuration file')
356
- .action(() => {
357
- if (existsSync('.mergerc')) {
358
- console.log('āš ļø .mergerc already exists. Use --force to overwrite.');
359
- return;
360
- }
361
- createDefaultConfig();
362
- });
363
-
364
- program
365
- .command('config')
366
- .description('Show current merge configuration')
367
- .action(() => {
368
- const config = loadMergeConfig();
369
- console.log('Current merge configuration:');
370
- Object.entries(config).forEach(([pattern, strategy]) => {
371
- console.log(` ${pattern.padEnd(30)} -> ${strategy}`);
372
- });
373
- });
374
-
375
- program
376
- .command('status')
377
- .description('Show conflicted files and their assigned strategies')
378
- .action(() => {
379
- try {
380
- const conflictedFiles = getConflictedFiles();
381
- const config = loadMergeConfig();
382
-
383
- if (conflictedFiles.length === 0) {
384
- console.log('āœ… No conflicted files found');
385
- return;
386
- }
387
-
388
- console.log('Conflicted files and their strategies:');
389
- conflictedFiles.forEach((file) => {
390
- const strategy = findMergeStrategy(file, config);
391
- const status = strategy ? `-> ${strategy}` : '-> no strategy';
392
- console.log(` ${file.padEnd(40)} ${status}`);
393
- });
394
- } catch (error) {
395
- console.error(`āŒ Failed to get status: ${error.message}`);
396
- process.exit(1);
397
- }
398
- });
399
- }
1
+ import { mergeChangelogFile } from './merge-changelog.js';
2
+ import mergeTypes, { mergeTypesFile } from './merge-types.js';
3
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
4
+ import mergePackageFile from './merge-package.js';
5
+ import { execSync } from 'child_process';
6
+
7
+ // Default merge configuration
8
+ const defaultMergeConfig = {
9
+ 'CHANGELOG.md': 'changelog',
10
+ '*/CHANGELOG.md': 'changelog',
11
+ '**/CHANGELOG.md': 'changelog',
12
+ 'src/types/graphql.ts': 'types',
13
+ 'codegen.ts': 'ours',
14
+ 'package.json': 'package',
15
+ '*/package.json': 'package',
16
+ '**/package.json': 'package',
17
+ };
18
+
19
+ // Available merge strategies
20
+ const mergeStrategies = {
21
+ changelog: mergeChangelogFile,
22
+ package: mergePackageFile,
23
+ types: mergeTypesFile,
24
+ ours: (filePath) => {
25
+ // Keep our version by checking out the HEAD version (removes conflicts)
26
+ try {
27
+ execSync(`git checkout --ours ${filePath}`);
28
+ execSync(`git add ${filePath}`);
29
+ console.log(
30
+ `šŸ“ Using 'ours' strategy for ${filePath} - reset to HEAD version and marked as resolved`,
31
+ );
32
+ return true;
33
+ } catch (error) {
34
+ throw new Error(`Failed to apply 'ours' strategy: ${error.message}`);
35
+ }
36
+ },
37
+ theirs: (filePath) => {
38
+ // Take their version
39
+ try {
40
+ execSync(`git checkout --theirs ${filePath}`);
41
+ execSync(`git add ${filePath}`);
42
+ console.log(
43
+ `šŸ“ Using 'theirs' strategy for ${filePath} - marked as resolved`,
44
+ );
45
+ return true;
46
+ } catch (error) {
47
+ throw new Error(`Failed to apply 'theirs' strategy: ${error.message}`);
48
+ }
49
+ },
50
+ };
51
+
52
+ /**
53
+ * Get list of conflicted files from git status
54
+ */
55
+ function getConflictedFiles() {
56
+ try {
57
+ const statusOutput = execSync('git status --porcelain', {
58
+ encoding: 'utf-8',
59
+ });
60
+ const conflictedFiles = statusOutput
61
+ .split('\n')
62
+ .filter(
63
+ (line) =>
64
+ line.startsWith('UU ') ||
65
+ line.startsWith('AA ') ||
66
+ line.startsWith('DD '),
67
+ )
68
+ .map((line) => line.substring(3).trim())
69
+ .filter((file) => file.length > 0);
70
+ return conflictedFiles;
71
+ } catch (error) {
72
+ throw new Error(`Failed to get git status: ${error.message}`);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Load merge configuration from .mergerc file or use defaults
78
+ */
79
+ function loadMergeConfig() {
80
+ const configPath = '.mergerc';
81
+
82
+ if (existsSync(configPath)) {
83
+ try {
84
+ const configContent = readFileSync(configPath, 'utf-8');
85
+ const config = {};
86
+
87
+ configContent.split('\n').forEach((line) => {
88
+ line = line.trim();
89
+ if (line && !line.startsWith('#')) {
90
+ const [pattern, strategy] = line
91
+ .split(/\s+merge=/)
92
+ .map((s) => s.trim());
93
+ if (pattern && strategy) {
94
+ config[pattern] = strategy;
95
+ }
96
+ }
97
+ });
98
+
99
+ return config;
100
+ } catch (error) {
101
+ console.warn(
102
+ `Warning: Could not read ${configPath}, using defaults: ${error.message}`,
103
+ );
104
+ }
105
+ }
106
+
107
+ return defaultMergeConfig;
108
+ }
109
+
110
+ /**
111
+ * Match file path against patterns (supports * and ** wildcards)
112
+ */
113
+ function matchPattern(filePath, pattern) {
114
+ // Handle ** at the beginning of pattern
115
+ if (pattern.startsWith('**/')) {
116
+ // Remove the **/ and check if the path ends with the remaining pattern
117
+ const remainingPattern = pattern.slice(3);
118
+ const regexPattern = remainingPattern
119
+ .replace(/\*/g, '[^/]*')
120
+ .replace(/\./g, '\\.')
121
+ .replace(/\//g, '\\/');
122
+
123
+ const regex = new RegExp(`(^|/)${regexPattern}$`);
124
+ return regex.test(filePath);
125
+ }
126
+
127
+ // For other cases, convert pattern to regex
128
+ const regexPattern = pattern
129
+ .replace(/\*\*/g, '___DOUBLESTAR___')
130
+ .replace(/\*/g, '[^/]*')
131
+ .replace(/___DOUBLESTAR___/g, '.*?')
132
+ .replace(/\./g, '\\.')
133
+ .replace(/\//g, '\\/');
134
+
135
+ const regex = new RegExp(`^${regexPattern}$`);
136
+ return regex.test(filePath);
137
+ }
138
+
139
+ /**
140
+ * Find merge strategy for a given file
141
+ */
142
+ function findMergeStrategy(filePath, config) {
143
+ // Check exact match first
144
+ if (config[filePath]) {
145
+ return config[filePath];
146
+ }
147
+
148
+ // Check pattern matches
149
+ for (const [pattern, strategy] of Object.entries(config)) {
150
+ if (matchPattern(filePath, pattern)) {
151
+ return strategy;
152
+ }
153
+ }
154
+
155
+ return null;
156
+ }
157
+
158
+ /**
159
+ * Create default .mergerc file
160
+ */
161
+ function createDefaultConfig() {
162
+ const configContent = `# Merge configuration file
163
+ # Format: <file-pattern> merge=<strategy>
164
+ # Strategies: changelog, package, types, ours, theirs
165
+
166
+ CHANGELOG.md merge=changelog
167
+ */CHANGELOG.md merge=changelog
168
+ **/CHANGELOG.md merge=changelog
169
+ src/types/graphql.ts merge=types
170
+ codegen.ts merge=ours
171
+ package.json merge=package
172
+ */package.json merge=package
173
+ **/package.json merge=package
174
+ `;
175
+
176
+ writeFileSync('.mergerc', configContent);
177
+ console.log('āœ… Created default .mergerc configuration file');
178
+ }
179
+
180
+ export async function autoResolveConflicts(options = {}) {
181
+ const { dryRun = false, verbose = false } = options;
182
+
183
+ // Get conflicted files
184
+ const conflictedFiles = getConflictedFiles();
185
+
186
+ if (conflictedFiles.length === 0) {
187
+ if (verbose) console.log('āœ… No conflicted files found');
188
+ return { success: true, resolvedCount: 0, skippedCount: 0, totalCount: 0 };
189
+ }
190
+
191
+ if (verbose) {
192
+ console.log(`Found ${conflictedFiles.length} conflicted files:`);
193
+ conflictedFiles.forEach((file) => console.log(` - ${file}`));
194
+ console.log('');
195
+ }
196
+
197
+ // Load configuration
198
+ const config = loadMergeConfig();
199
+
200
+ if (verbose) {
201
+ console.log('Merge configuration:');
202
+ Object.entries(config).forEach(([pattern, strategy]) => {
203
+ console.log(` ${pattern} -> ${strategy}`);
204
+ });
205
+ console.log('');
206
+ }
207
+
208
+ let resolvedCount = 0;
209
+ let skippedCount = 0;
210
+
211
+ // Process each conflicted file
212
+ for (const filePath of conflictedFiles) {
213
+ const strategy = findMergeStrategy(filePath, config);
214
+
215
+ if (!strategy) {
216
+ if (verbose)
217
+ console.log(`āš ļø No strategy found for ${filePath} - skipping`);
218
+ skippedCount++;
219
+ continue;
220
+ }
221
+
222
+ const mergeFunction = mergeStrategies[strategy];
223
+ if (!mergeFunction) {
224
+ if (verbose)
225
+ console.log(
226
+ `āš ļø Unknown strategy '${strategy}' for ${filePath} - skipping`,
227
+ );
228
+ skippedCount++;
229
+ continue;
230
+ }
231
+
232
+ if (dryRun) {
233
+ if (verbose)
234
+ console.log(`Would apply '${strategy}' strategy to ${filePath}`);
235
+ continue;
236
+ }
237
+
238
+ try {
239
+ if (verbose)
240
+ console.log(`šŸ”§ Applying '${strategy}' strategy to ${filePath}`);
241
+ const result = await mergeFunction(filePath);
242
+ if (result.success) {
243
+ resolvedCount++;
244
+ } else {
245
+ skippedCount++;
246
+ }
247
+ } catch (error) {
248
+ console.error(`āŒ Failed to resolve ${filePath}: ${error.message}`);
249
+ skippedCount++;
250
+ }
251
+ }
252
+
253
+ const result = {
254
+ success: skippedCount === 0,
255
+ resolvedCount,
256
+ skippedCount,
257
+ totalCount: conflictedFiles.length,
258
+ };
259
+
260
+ // Summary
261
+ if (verbose) {
262
+ console.log(`\nšŸ“Š Summary:`);
263
+ console.log(` Resolved: ${resolvedCount}`);
264
+ console.log(` Skipped: ${skippedCount}`);
265
+ console.log(` Total: ${conflictedFiles.length}`);
266
+
267
+ if (resolvedCount > 0 && !dryRun) {
268
+ console.log(`\nāœ… Successfully resolved ${resolvedCount} conflicts`);
269
+ if (skippedCount === 0) {
270
+ console.log(
271
+ 'šŸŽ‰ All conflicts resolved! You can now commit the changes.',
272
+ );
273
+ }
274
+ }
275
+ }
276
+
277
+ return result;
278
+ }
279
+
280
+ export function setupResolve(program) {
281
+ program
282
+ .command('resolve-conflicts')
283
+ .description('Automatically resolve conflicts based on configuration')
284
+ .option(
285
+ '-c, --config <path>',
286
+ 'Path to merge configuration file',
287
+ '.mergerc',
288
+ )
289
+ .option('-n, --dry-run', 'Show what would be done without making changes')
290
+ .option('-v, --verbose', 'Verbose output')
291
+ .action(async (options) => {
292
+ try {
293
+ const result = await autoResolveConflicts(options);
294
+
295
+ if (!result.success) {
296
+ console.error(
297
+ `āŒ Auto-resolve failed: ${result.skippedCount} files could not be resolved`,
298
+ );
299
+ process.exit(1);
300
+ }
301
+ } catch (error) {
302
+ console.error(`āŒ Auto-resolve failed: ${error.message}`);
303
+ process.exit(1);
304
+ }
305
+ });
306
+
307
+ // New merge command
308
+
309
+ // Individual strategy commands
310
+ program
311
+ .command('resolve-changelog-conflicts')
312
+ .description('Merge changelog files by removing conflict markers')
313
+ .argument('<file>', 'File with merge conflicts')
314
+ .action(async (file) => {
315
+ try {
316
+ mergeChangelogFile(file);
317
+ console.log('āœ… Changelog merge completed successfully');
318
+ } catch (error) {
319
+ console.error(`āŒ Changelog merge failed: ${error.message}`);
320
+ process.exit(1);
321
+ }
322
+ });
323
+
324
+ program
325
+ .command('resolve-package-conflicts')
326
+ .description('Merge package.json files by resolving version conflicts')
327
+ .argument('<file>', 'File with merge conflicts')
328
+ .action(async (file) => {
329
+ try {
330
+ await mergePackageFile(file);
331
+ console.log('āœ… Package merge completed successfully');
332
+ } catch (error) {
333
+ console.error(`āŒ Package merge failed: ${error.message}`);
334
+ process.exit(1);
335
+ }
336
+ });
337
+
338
+ program
339
+ .command('resolve-type-conflicts')
340
+ .description('Merge types files with balanced brace checking')
341
+ .argument('<file>', 'File with merge conflicts')
342
+ .action(async (file) => {
343
+ try {
344
+ await mergeTypes(file);
345
+ console.log('āœ… Types merge completed successfully');
346
+ } catch (error) {
347
+ console.error(`āŒ Types merge failed: ${error.message}`);
348
+ process.exit(1);
349
+ }
350
+ });
351
+
352
+ // Configuration commands
353
+ program
354
+ .command('init')
355
+ .description('Create default .mergerc configuration file')
356
+ .action(() => {
357
+ if (existsSync('.mergerc')) {
358
+ console.log('āš ļø .mergerc already exists. Use --force to overwrite.');
359
+ return;
360
+ }
361
+ createDefaultConfig();
362
+ });
363
+
364
+ program
365
+ .command('config')
366
+ .description('Show current merge configuration')
367
+ .action(() => {
368
+ const config = loadMergeConfig();
369
+ console.log('Current merge configuration:');
370
+ Object.entries(config).forEach(([pattern, strategy]) => {
371
+ console.log(` ${pattern.padEnd(30)} -> ${strategy}`);
372
+ });
373
+ });
374
+
375
+ program
376
+ .command('status')
377
+ .description('Show conflicted files and their assigned strategies')
378
+ .action(() => {
379
+ try {
380
+ const conflictedFiles = getConflictedFiles();
381
+ const config = loadMergeConfig();
382
+
383
+ if (conflictedFiles.length === 0) {
384
+ console.log('āœ… No conflicted files found');
385
+ return;
386
+ }
387
+
388
+ console.log('Conflicted files and their strategies:');
389
+ conflictedFiles.forEach((file) => {
390
+ const strategy = findMergeStrategy(file, config);
391
+ const status = strategy ? `-> ${strategy}` : '-> no strategy';
392
+ console.log(` ${file.padEnd(40)} ${status}`);
393
+ });
394
+ } catch (error) {
395
+ console.error(`āŒ Failed to get status: ${error.message}`);
396
+ process.exit(1);
397
+ }
398
+ });
399
+ }