gitgrip 0.2.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.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -0
  3. package/actions/cross-repo-sync/action.yml +55 -0
  4. package/assets/banner.svg +73 -0
  5. package/assets/icon.svg +30 -0
  6. package/assets/logo-dark.svg +36 -0
  7. package/assets/logo.svg +36 -0
  8. package/dist/commands/add.d.ts +9 -0
  9. package/dist/commands/add.d.ts.map +1 -0
  10. package/dist/commands/add.js +80 -0
  11. package/dist/commands/add.js.map +1 -0
  12. package/dist/commands/bench.d.ts +12 -0
  13. package/dist/commands/bench.d.ts.map +1 -0
  14. package/dist/commands/bench.js +136 -0
  15. package/dist/commands/bench.js.map +1 -0
  16. package/dist/commands/branch.d.ts +15 -0
  17. package/dist/commands/branch.d.ts.map +1 -0
  18. package/dist/commands/branch.js +159 -0
  19. package/dist/commands/branch.js.map +1 -0
  20. package/dist/commands/checkout.d.ts +10 -0
  21. package/dist/commands/checkout.d.ts.map +1 -0
  22. package/dist/commands/checkout.js +85 -0
  23. package/dist/commands/checkout.js.map +1 -0
  24. package/dist/commands/commit.d.ts +10 -0
  25. package/dist/commands/commit.d.ts.map +1 -0
  26. package/dist/commands/commit.js +94 -0
  27. package/dist/commands/commit.js.map +1 -0
  28. package/dist/commands/diff.d.ts +11 -0
  29. package/dist/commands/diff.d.ts.map +1 -0
  30. package/dist/commands/diff.js +105 -0
  31. package/dist/commands/diff.js.map +1 -0
  32. package/dist/commands/env.d.ts +8 -0
  33. package/dist/commands/env.d.ts.map +1 -0
  34. package/dist/commands/env.js +35 -0
  35. package/dist/commands/env.js.map +1 -0
  36. package/dist/commands/forall.d.ts +13 -0
  37. package/dist/commands/forall.d.ts.map +1 -0
  38. package/dist/commands/forall.js +116 -0
  39. package/dist/commands/forall.js.map +1 -0
  40. package/dist/commands/init.d.ts +15 -0
  41. package/dist/commands/init.d.ts.map +1 -0
  42. package/dist/commands/init.js +106 -0
  43. package/dist/commands/init.js.map +1 -0
  44. package/dist/commands/link.d.ts +11 -0
  45. package/dist/commands/link.d.ts.map +1 -0
  46. package/dist/commands/link.js +205 -0
  47. package/dist/commands/link.js.map +1 -0
  48. package/dist/commands/migrate.d.ts +17 -0
  49. package/dist/commands/migrate.d.ts.map +1 -0
  50. package/dist/commands/migrate.js +180 -0
  51. package/dist/commands/migrate.js.map +1 -0
  52. package/dist/commands/pr/create.d.ts +13 -0
  53. package/dist/commands/pr/create.d.ts.map +1 -0
  54. package/dist/commands/pr/create.js +202 -0
  55. package/dist/commands/pr/create.js.map +1 -0
  56. package/dist/commands/pr/index.d.ts +4 -0
  57. package/dist/commands/pr/index.d.ts.map +1 -0
  58. package/dist/commands/pr/index.js +4 -0
  59. package/dist/commands/pr/index.js.map +1 -0
  60. package/dist/commands/pr/merge.d.ts +11 -0
  61. package/dist/commands/pr/merge.d.ts.map +1 -0
  62. package/dist/commands/pr/merge.js +168 -0
  63. package/dist/commands/pr/merge.js.map +1 -0
  64. package/dist/commands/pr/status.d.ts +9 -0
  65. package/dist/commands/pr/status.d.ts.map +1 -0
  66. package/dist/commands/pr/status.js +139 -0
  67. package/dist/commands/pr/status.js.map +1 -0
  68. package/dist/commands/push.d.ts +10 -0
  69. package/dist/commands/push.d.ts.map +1 -0
  70. package/dist/commands/push.js +101 -0
  71. package/dist/commands/push.js.map +1 -0
  72. package/dist/commands/run.d.ts +8 -0
  73. package/dist/commands/run.d.ts.map +1 -0
  74. package/dist/commands/run.js +75 -0
  75. package/dist/commands/run.js.map +1 -0
  76. package/dist/commands/status.d.ts +9 -0
  77. package/dist/commands/status.d.ts.map +1 -0
  78. package/dist/commands/status.js +201 -0
  79. package/dist/commands/status.js.map +1 -0
  80. package/dist/commands/sync.d.ts +13 -0
  81. package/dist/commands/sync.d.ts.map +1 -0
  82. package/dist/commands/sync.js +183 -0
  83. package/dist/commands/sync.js.map +1 -0
  84. package/dist/index.d.ts +3 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +352 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/lib/__bench__/files.bench.d.ts +2 -0
  89. package/dist/lib/__bench__/files.bench.d.ts.map +1 -0
  90. package/dist/lib/__bench__/files.bench.js +52 -0
  91. package/dist/lib/__bench__/files.bench.js.map +1 -0
  92. package/dist/lib/__bench__/manifest.bench.d.ts +2 -0
  93. package/dist/lib/__bench__/manifest.bench.d.ts.map +1 -0
  94. package/dist/lib/__bench__/manifest.bench.js +74 -0
  95. package/dist/lib/__bench__/manifest.bench.js.map +1 -0
  96. package/dist/lib/files.d.ts +84 -0
  97. package/dist/lib/files.d.ts.map +1 -0
  98. package/dist/lib/files.js +492 -0
  99. package/dist/lib/files.js.map +1 -0
  100. package/dist/lib/git.d.ts +125 -0
  101. package/dist/lib/git.d.ts.map +1 -0
  102. package/dist/lib/git.js +370 -0
  103. package/dist/lib/git.js.map +1 -0
  104. package/dist/lib/github.d.ts +92 -0
  105. package/dist/lib/github.d.ts.map +1 -0
  106. package/dist/lib/github.js +284 -0
  107. package/dist/lib/github.js.map +1 -0
  108. package/dist/lib/hooks.d.ts +19 -0
  109. package/dist/lib/hooks.d.ts.map +1 -0
  110. package/dist/lib/hooks.js +63 -0
  111. package/dist/lib/hooks.js.map +1 -0
  112. package/dist/lib/linker.d.ts +56 -0
  113. package/dist/lib/linker.d.ts.map +1 -0
  114. package/dist/lib/linker.js +185 -0
  115. package/dist/lib/linker.js.map +1 -0
  116. package/dist/lib/manifest.d.ts +73 -0
  117. package/dist/lib/manifest.d.ts.map +1 -0
  118. package/dist/lib/manifest.js +400 -0
  119. package/dist/lib/manifest.js.map +1 -0
  120. package/dist/lib/scripts.d.ts +26 -0
  121. package/dist/lib/scripts.d.ts.map +1 -0
  122. package/dist/lib/scripts.js +123 -0
  123. package/dist/lib/scripts.js.map +1 -0
  124. package/dist/lib/timing.d.ts +100 -0
  125. package/dist/lib/timing.d.ts.map +1 -0
  126. package/dist/lib/timing.js +293 -0
  127. package/dist/lib/timing.js.map +1 -0
  128. package/dist/types.d.ts +312 -0
  129. package/dist/types.d.ts.map +1 -0
  130. package/dist/types.js +2 -0
  131. package/dist/types.js.map +1 -0
  132. package/package.json +60 -0
@@ -0,0 +1,205 @@
1
+ import chalk from 'chalk';
2
+ import { loadManifest, getManifestsDir } from '../lib/manifest.js';
3
+ import { processAllLinks, getAllLinkStatus, cleanOrphanedLinks } from '../lib/files.js';
4
+ /**
5
+ * Format a link status for display
6
+ */
7
+ function formatLinkStatus(link) {
8
+ const typeLabel = link.type === 'copyfile' ? 'copy' : 'link';
9
+ const icon = {
10
+ valid: chalk.green('\u2713'),
11
+ missing: chalk.yellow('!'),
12
+ broken: chalk.red('\u2717'),
13
+ conflict: chalk.red('?'),
14
+ }[link.status];
15
+ const statusColor = {
16
+ valid: chalk.green,
17
+ missing: chalk.yellow,
18
+ broken: chalk.red,
19
+ conflict: chalk.red,
20
+ }[link.status];
21
+ const line = ` ${icon} [${typeLabel}] ${chalk.dim(link.repoName)}: ${link.dest}`;
22
+ if (link.message) {
23
+ return `${line} ${chalk.dim(`(${link.message})`)}`;
24
+ }
25
+ return line;
26
+ }
27
+ /**
28
+ * Show status of all links
29
+ */
30
+ async function showStatus() {
31
+ const { manifest, rootDir } = await loadManifest();
32
+ const manifestsDir = getManifestsDir(rootDir);
33
+ const statuses = await getAllLinkStatus(manifest, rootDir, manifestsDir);
34
+ if (statuses.length === 0) {
35
+ console.log(chalk.dim('No copyfile or linkfile entries defined in manifest'));
36
+ return;
37
+ }
38
+ console.log(chalk.blue('Link Status\n'));
39
+ // Group by status
40
+ const byStatus = {
41
+ valid: [],
42
+ missing: [],
43
+ broken: [],
44
+ conflict: [],
45
+ };
46
+ for (const status of statuses) {
47
+ byStatus[status.status].push(status);
48
+ }
49
+ // Show each group
50
+ if (byStatus.valid.length > 0) {
51
+ console.log(chalk.green(`Valid (${byStatus.valid.length}):`));
52
+ for (const link of byStatus.valid) {
53
+ console.log(formatLinkStatus(link));
54
+ }
55
+ console.log('');
56
+ }
57
+ if (byStatus.missing.length > 0) {
58
+ console.log(chalk.yellow(`Missing (${byStatus.missing.length}):`));
59
+ for (const link of byStatus.missing) {
60
+ console.log(formatLinkStatus(link));
61
+ }
62
+ console.log('');
63
+ }
64
+ if (byStatus.broken.length > 0) {
65
+ console.log(chalk.red(`Broken (${byStatus.broken.length}):`));
66
+ for (const link of byStatus.broken) {
67
+ console.log(formatLinkStatus(link));
68
+ }
69
+ console.log('');
70
+ }
71
+ if (byStatus.conflict.length > 0) {
72
+ console.log(chalk.red(`Conflicts (${byStatus.conflict.length}):`));
73
+ for (const link of byStatus.conflict) {
74
+ console.log(formatLinkStatus(link));
75
+ }
76
+ console.log('');
77
+ }
78
+ // Summary
79
+ const total = statuses.length;
80
+ const valid = byStatus.valid.length;
81
+ const issues = total - valid;
82
+ if (issues === 0) {
83
+ console.log(chalk.green(`All ${total} links are valid.`));
84
+ }
85
+ else {
86
+ console.log(chalk.yellow(`${valid}/${total} links valid, ${issues} need attention.`));
87
+ console.log(chalk.dim(`Run 'cr link' to create missing links, or 'cr link --force' to fix conflicts.`));
88
+ }
89
+ }
90
+ /**
91
+ * Clean orphaned links
92
+ */
93
+ async function cleanLinks(options) {
94
+ const { manifest, rootDir } = await loadManifest();
95
+ console.log(chalk.blue('Cleaning orphaned links...\n'));
96
+ const results = await cleanOrphanedLinks(manifest, rootDir, { dryRun: options.dryRun });
97
+ if (results.length === 0) {
98
+ console.log(chalk.dim('No orphaned links found.'));
99
+ return;
100
+ }
101
+ for (const result of results) {
102
+ if (result.removed) {
103
+ console.log(chalk.green(` \u2713 Removed: ${result.path}`));
104
+ }
105
+ else if (result.message?.startsWith('Would remove')) {
106
+ console.log(chalk.yellow(` ! ${result.message}`));
107
+ }
108
+ else {
109
+ console.log(chalk.red(` \u2717 Failed: ${result.path} - ${result.message}`));
110
+ }
111
+ }
112
+ console.log('');
113
+ const removed = results.filter((r) => r.removed).length;
114
+ const wouldRemove = results.filter((r) => r.message?.startsWith('Would remove')).length;
115
+ if (options.dryRun) {
116
+ console.log(chalk.dim(`Would remove ${wouldRemove} orphaned link(s). Run without --dry-run to execute.`));
117
+ }
118
+ else {
119
+ console.log(chalk.green(`Removed ${removed} orphaned link(s).`));
120
+ }
121
+ }
122
+ /**
123
+ * Create/update all links
124
+ */
125
+ async function createLinks(options) {
126
+ const { manifest, rootDir } = await loadManifest();
127
+ const manifestsDir = getManifestsDir(rootDir);
128
+ console.log(chalk.blue(`${options.dryRun ? 'Previewing' : 'Processing'} links...\n`));
129
+ const results = await processAllLinks(manifest, rootDir, {
130
+ force: options.force,
131
+ dryRun: options.dryRun,
132
+ }, manifestsDir);
133
+ let totalCopied = 0;
134
+ let totalLinked = 0;
135
+ let totalFailed = 0;
136
+ for (const result of results) {
137
+ const hasOperations = result.copyfiles.length > 0 || result.linkfiles.length > 0;
138
+ if (!hasOperations)
139
+ continue;
140
+ console.log(chalk.bold(result.repoName));
141
+ for (const copy of result.copyfiles) {
142
+ if (copy.success) {
143
+ totalCopied++;
144
+ if (options.dryRun) {
145
+ console.log(chalk.dim(` ${copy.message}`));
146
+ }
147
+ else {
148
+ console.log(chalk.green(` \u2713 [copy] ${copy.dest}`));
149
+ }
150
+ }
151
+ else {
152
+ totalFailed++;
153
+ console.log(chalk.yellow(` ! [copy] ${copy.dest}: ${copy.message}`));
154
+ }
155
+ }
156
+ for (const link of result.linkfiles) {
157
+ if (link.success) {
158
+ totalLinked++;
159
+ if (options.dryRun) {
160
+ console.log(chalk.dim(` ${link.message}`));
161
+ }
162
+ else {
163
+ console.log(chalk.green(` \u2713 [link] ${link.dest}`));
164
+ }
165
+ }
166
+ else {
167
+ totalFailed++;
168
+ console.log(chalk.yellow(` ! [link] ${link.dest}: ${link.message}`));
169
+ }
170
+ }
171
+ console.log('');
172
+ }
173
+ // Summary
174
+ const total = totalCopied + totalLinked;
175
+ if (total === 0 && totalFailed === 0) {
176
+ console.log(chalk.dim('No copyfile or linkfile entries defined in manifest.'));
177
+ }
178
+ else if (options.dryRun) {
179
+ console.log(chalk.dim(`Would create ${total} link(s). ${totalFailed > 0 ? `${totalFailed} would fail.` : ''}`));
180
+ console.log(chalk.dim(`Run without --dry-run to execute.`));
181
+ }
182
+ else {
183
+ if (totalFailed === 0) {
184
+ console.log(chalk.green(`Created ${totalCopied} copy file(s), ${totalLinked} symlink(s).`));
185
+ }
186
+ else {
187
+ console.log(chalk.yellow(`Created ${totalCopied} copy file(s), ${totalLinked} symlink(s). ${totalFailed} failed.`));
188
+ }
189
+ }
190
+ }
191
+ /**
192
+ * Main link command handler
193
+ */
194
+ export async function link(options = {}) {
195
+ if (options.status) {
196
+ await showStatus();
197
+ }
198
+ else if (options.clean) {
199
+ await cleanLinks({ dryRun: options.dryRun });
200
+ }
201
+ else {
202
+ await createLinks({ force: options.force, dryRun: options.dryRun });
203
+ }
204
+ }
205
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ interface MigrateOptions {
2
+ force?: boolean;
3
+ remote?: string;
4
+ }
5
+ /**
6
+ * Migrate from old codi-repos.yaml format to new .gitgrip/manifests/ structure
7
+ *
8
+ * This command:
9
+ * 1. Finds codi-repos.yaml in current or parent directory
10
+ * 2. Creates .gitgrip/manifests/ as a new git repo
11
+ * 3. Moves codi-repos.yaml to .gitgrip/manifests/manifest.yaml
12
+ * 4. Commits the manifest
13
+ * 5. Optionally pushes to a remote
14
+ */
15
+ export declare function migrate(options?: MigrateOptions): Promise<void>;
16
+ export {};
17
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAaA,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyKzE"}
@@ -0,0 +1,180 @@
1
+ import { mkdir, readFile, writeFile, rm } from 'fs/promises';
2
+ import { resolve, dirname } from 'path';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import inquirer from 'inquirer';
6
+ import { simpleGit } from 'simple-git';
7
+ import { findLegacyManifestPath, getNewGitgripDir, getManifestsDir, } from '../lib/manifest.js';
8
+ import { pathExists } from '../lib/git.js';
9
+ /**
10
+ * Migrate from old codi-repos.yaml format to new .gitgrip/manifests/ structure
11
+ *
12
+ * This command:
13
+ * 1. Finds codi-repos.yaml in current or parent directory
14
+ * 2. Creates .gitgrip/manifests/ as a new git repo
15
+ * 3. Moves codi-repos.yaml to .gitgrip/manifests/manifest.yaml
16
+ * 4. Commits the manifest
17
+ * 5. Optionally pushes to a remote
18
+ */
19
+ export async function migrate(options = {}) {
20
+ // Find legacy manifest
21
+ const legacyPath = await findLegacyManifestPath();
22
+ if (!legacyPath) {
23
+ console.log(chalk.yellow('No legacy codi-repos.yaml found.'));
24
+ console.log(chalk.dim('This workspace may already be using the new format, or not initialized.'));
25
+ return;
26
+ }
27
+ const workspaceRoot = dirname(legacyPath);
28
+ const gitgripDir = getNewGitgripDir(workspaceRoot);
29
+ const manifestsDir = getManifestsDir(workspaceRoot);
30
+ console.log(chalk.blue('Migration Plan:'));
31
+ console.log(chalk.dim(` From: ${legacyPath}`));
32
+ console.log(chalk.dim(` To: ${manifestsDir}/manifest.yaml`));
33
+ console.log('');
34
+ // Check if .gitgrip already exists
35
+ if (await pathExists(gitgripDir)) {
36
+ if (!options.force) {
37
+ const { proceed } = await inquirer.prompt([
38
+ {
39
+ type: 'confirm',
40
+ name: 'proceed',
41
+ message: '.gitgrip/ already exists. Overwrite?',
42
+ default: false,
43
+ },
44
+ ]);
45
+ if (!proceed) {
46
+ console.log('Migration cancelled.');
47
+ return;
48
+ }
49
+ }
50
+ // Remove existing .gitgrip
51
+ await rm(gitgripDir, { recursive: true, force: true });
52
+ }
53
+ // Ask for confirmation
54
+ if (!options.force) {
55
+ const { confirm } = await inquirer.prompt([
56
+ {
57
+ type: 'confirm',
58
+ name: 'confirm',
59
+ message: 'Proceed with migration?',
60
+ default: true,
61
+ },
62
+ ]);
63
+ if (!confirm) {
64
+ console.log('Migration cancelled.');
65
+ return;
66
+ }
67
+ }
68
+ // Create .gitgrip/manifests/ directory
69
+ const mkdirSpinner = ora('Creating .gitgrip/manifests/...').start();
70
+ try {
71
+ await mkdir(manifestsDir, { recursive: true });
72
+ mkdirSpinner.succeed('Created .gitgrip/manifests/');
73
+ }
74
+ catch (error) {
75
+ mkdirSpinner.fail('Failed to create directories');
76
+ throw error;
77
+ }
78
+ // Read legacy manifest content
79
+ const legacyContent = await readFile(legacyPath, 'utf-8');
80
+ // Write to new location
81
+ const writeSpinner = ora('Moving manifest...').start();
82
+ try {
83
+ await writeFile(resolve(manifestsDir, 'manifest.yaml'), legacyContent, 'utf-8');
84
+ writeSpinner.succeed('Created manifest.yaml');
85
+ }
86
+ catch (error) {
87
+ writeSpinner.fail('Failed to write manifest.yaml');
88
+ throw error;
89
+ }
90
+ // Initialize git repo in manifests directory
91
+ const gitSpinner = ora('Initializing git repository...').start();
92
+ try {
93
+ const git = simpleGit(manifestsDir);
94
+ await git.init();
95
+ await git.add('manifest.yaml');
96
+ await git.commit('chore: migrate manifest from codi-repos.yaml');
97
+ gitSpinner.succeed('Initialized git repository with initial commit');
98
+ }
99
+ catch (error) {
100
+ gitSpinner.fail('Failed to initialize git repository');
101
+ throw error;
102
+ }
103
+ // Optionally add remote and push
104
+ let remoteUrl = options.remote;
105
+ if (!remoteUrl) {
106
+ const { addRemote } = await inquirer.prompt([
107
+ {
108
+ type: 'confirm',
109
+ name: 'addRemote',
110
+ message: 'Would you like to push the manifest to a remote repository?',
111
+ default: false,
112
+ },
113
+ ]);
114
+ if (addRemote) {
115
+ const { url } = await inquirer.prompt([
116
+ {
117
+ type: 'input',
118
+ name: 'url',
119
+ message: 'Enter the remote URL (e.g., git@github.com:user/manifests.git):',
120
+ },
121
+ ]);
122
+ remoteUrl = url;
123
+ }
124
+ }
125
+ if (remoteUrl) {
126
+ const pushSpinner = ora('Pushing to remote...').start();
127
+ try {
128
+ const git = simpleGit(manifestsDir);
129
+ await git.addRemote('origin', remoteUrl);
130
+ await git.push(['-u', 'origin', 'main']);
131
+ pushSpinner.succeed(`Pushed to ${remoteUrl}`);
132
+ }
133
+ catch (error) {
134
+ pushSpinner.fail('Failed to push to remote');
135
+ console.error(chalk.dim(`Error: ${error instanceof Error ? error.message : error}`));
136
+ console.log(chalk.dim('You can add the remote manually later.'));
137
+ }
138
+ }
139
+ // Remove old manifest file
140
+ const removeSpinner = ora('Removing old codi-repos.yaml...').start();
141
+ try {
142
+ await rm(legacyPath);
143
+ removeSpinner.succeed('Removed old codi-repos.yaml');
144
+ }
145
+ catch (error) {
146
+ removeSpinner.warn('Could not remove old codi-repos.yaml (you may want to remove it manually)');
147
+ }
148
+ // Remove old .gitgrip entries from .gitignore if present
149
+ const gitignorePath = resolve(workspaceRoot, '.gitignore');
150
+ if (await pathExists(gitignorePath)) {
151
+ try {
152
+ const gitignoreContent = await readFile(gitignorePath, 'utf-8');
153
+ // The workspace is no longer a git repo, but clean up anyway
154
+ console.log(chalk.dim('Note: .gitignore file remains; you may want to remove it if the workspace is no longer a git repo.'));
155
+ }
156
+ catch {
157
+ // Ignore
158
+ }
159
+ }
160
+ console.log('');
161
+ console.log(chalk.green('Migration complete!'));
162
+ console.log('');
163
+ console.log(chalk.dim('Your workspace is now using the AOSP-style structure:'));
164
+ console.log(chalk.cyan(` ${workspaceRoot}/`));
165
+ console.log(chalk.cyan(' ├── .gitgrip/'));
166
+ console.log(chalk.cyan(' │ └── manifests/'));
167
+ console.log(chalk.cyan(' │ ├── .git/'));
168
+ console.log(chalk.cyan(' │ └── manifest.yaml'));
169
+ console.log(chalk.cyan(' └── <your repos>/'));
170
+ console.log('');
171
+ console.log(chalk.dim('Run `gr status` to verify everything is working.'));
172
+ if (!remoteUrl) {
173
+ console.log('');
174
+ console.log(chalk.yellow('Tip: Consider pushing your manifest to a remote for team sharing:'));
175
+ console.log(chalk.dim(` cd ${manifestsDir}`));
176
+ console.log(chalk.dim(' git remote add origin <your-manifest-repo-url>'));
177
+ console.log(chalk.dim(' git push -u origin main'));
178
+ }
179
+ }
180
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ interface CreateOptions {
2
+ title?: string;
3
+ body?: string;
4
+ draft?: boolean;
5
+ base?: string;
6
+ push?: boolean;
7
+ }
8
+ /**
9
+ * Create linked PRs across all repositories with changes
10
+ */
11
+ export declare function createPR(options?: CreateOptions): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/create.ts"],"names":[],"mappings":"AAqBA,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6NzE"}
@@ -0,0 +1,202 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import inquirer from 'inquirer';
4
+ import { loadManifest, getAllRepoInfo, loadState, saveState, getManifestRepoInfo } from '../../lib/manifest.js';
5
+ import { pathExists, getCurrentBranch, hasCommitsAhead, pushBranch, remoteBranchExists, isGitRepo, } from '../../lib/git.js';
6
+ import { createPullRequest, createLinkedPRs, } from '../../lib/github.js';
7
+ /**
8
+ * Create linked PRs across all repositories with changes
9
+ */
10
+ export async function createPR(options = {}) {
11
+ const { manifest, rootDir } = await loadManifest();
12
+ const repos = getAllRepoInfo(manifest, rootDir);
13
+ // Check which repos are cloned
14
+ const clonedRepos = [];
15
+ for (const repo of repos) {
16
+ if (await pathExists(repo.absolutePath)) {
17
+ clonedRepos.push(repo);
18
+ }
19
+ }
20
+ if (clonedRepos.length === 0) {
21
+ console.log(chalk.yellow('No repositories are cloned.'));
22
+ return;
23
+ }
24
+ // Get current branch and check for changes in each repo
25
+ const repoStatus = await Promise.all(clonedRepos.map(async (repo) => {
26
+ const branch = await getCurrentBranch(repo.absolutePath);
27
+ const hasChanges = await hasCommitsAhead(repo.absolutePath, repo.default_branch);
28
+ const needsPush = hasChanges && !(await remoteBranchExists(repo.absolutePath, branch));
29
+ return { repo, branch, hasChanges, needsPush };
30
+ }));
31
+ // Check manifest for changes too
32
+ const manifestInfo = getManifestRepoInfo(manifest, rootDir);
33
+ let manifestBranch = null;
34
+ let manifestHasChanges = false;
35
+ let manifestNeedsPush = false;
36
+ if (manifestInfo && await isGitRepo(manifestInfo.absolutePath)) {
37
+ manifestBranch = await getCurrentBranch(manifestInfo.absolutePath);
38
+ manifestHasChanges = await hasCommitsAhead(manifestInfo.absolutePath, manifestInfo.default_branch);
39
+ manifestNeedsPush = manifestHasChanges && !(await remoteBranchExists(manifestInfo.absolutePath, manifestBranch));
40
+ }
41
+ // Filter to repos with changes
42
+ const withChanges = repoStatus.filter((r) => r.hasChanges);
43
+ if (withChanges.length === 0 && !manifestHasChanges) {
44
+ console.log(chalk.yellow('No repositories have commits ahead of their default branch.'));
45
+ console.log(chalk.dim('Make some commits first, then run this command again.'));
46
+ return;
47
+ }
48
+ // Only check branch consistency for repos WITH CHANGES (not all repos)
49
+ const branchesWithChanges = withChanges.map((r) => r.branch);
50
+ if (manifestHasChanges && manifestBranch) {
51
+ branchesWithChanges.push(manifestBranch);
52
+ }
53
+ const uniqueBranches = [...new Set(branchesWithChanges)];
54
+ if (uniqueBranches.length > 1) {
55
+ console.log(chalk.yellow('Repositories with changes are on different branches:'));
56
+ for (const { repo, branch } of withChanges) {
57
+ console.log(` ${repo.name}: ${chalk.cyan(branch)}`);
58
+ }
59
+ if (manifestHasChanges && manifestInfo && manifestBranch) {
60
+ console.log(` ${manifestInfo.name}: ${chalk.cyan(manifestBranch)}`);
61
+ }
62
+ console.log('');
63
+ console.log(chalk.dim('Use `gitgrip checkout <branch>` to sync branches first.'));
64
+ return;
65
+ }
66
+ const branchName = uniqueBranches[0];
67
+ // Check it's not the default branch
68
+ const onDefaultBranch = withChanges.some((r) => r.repo.default_branch === branchName);
69
+ if (onDefaultBranch) {
70
+ console.log(chalk.yellow(`You're on the default branch (${branchName}).`));
71
+ console.log(chalk.dim('Create a feature branch first with `gitgrip branch <name>`.'));
72
+ return;
73
+ }
74
+ console.log(chalk.blue(`Creating PRs for branch: ${chalk.cyan(branchName)}\n`));
75
+ const totalChanges = withChanges.length + (manifestHasChanges ? 1 : 0);
76
+ console.log(`Found changes in ${totalChanges} repos:`);
77
+ for (const { repo } of withChanges) {
78
+ console.log(` ${chalk.green('•')} ${repo.name}`);
79
+ }
80
+ if (manifestHasChanges && manifestInfo) {
81
+ console.log(` ${chalk.green('•')} ${manifestInfo.name}`);
82
+ }
83
+ console.log('');
84
+ // Check if any need to be pushed first (including manifest)
85
+ const needsPush = withChanges.filter((r) => r.needsPush);
86
+ const allNeedsPush = [...needsPush];
87
+ if (manifestNeedsPush && manifestInfo) {
88
+ allNeedsPush.push({ repo: manifestInfo, needsPush: true });
89
+ }
90
+ if (allNeedsPush.length > 0) {
91
+ if (options.push) {
92
+ console.log(chalk.dim('Pushing branches to remote...\n'));
93
+ for (const { repo } of allNeedsPush) {
94
+ const spinner = ora(`Pushing ${repo.name}...`).start();
95
+ try {
96
+ await pushBranch(repo.absolutePath, branchName, 'origin', true);
97
+ spinner.succeed(`${repo.name}: pushed`);
98
+ }
99
+ catch (error) {
100
+ spinner.fail(`${repo.name}: ${error instanceof Error ? error.message : error}`);
101
+ console.log(chalk.red('\nFailed to push. Fix the error and try again.'));
102
+ return;
103
+ }
104
+ }
105
+ console.log('');
106
+ }
107
+ else {
108
+ console.log(chalk.yellow('Some branches need to be pushed to remote first:'));
109
+ for (const { repo } of allNeedsPush) {
110
+ console.log(` ${repo.name}`);
111
+ }
112
+ console.log('');
113
+ console.log(chalk.dim('Run with --push flag to push automatically, or push manually.'));
114
+ return;
115
+ }
116
+ }
117
+ // Get PR title if not provided
118
+ let title = options.title ?? '';
119
+ if (!title) {
120
+ const answers = await inquirer.prompt([
121
+ {
122
+ type: 'input',
123
+ name: 'title',
124
+ message: 'PR title:',
125
+ default: branchName.replace(/[-_]/g, ' ').replace(/^feature\//, ''),
126
+ validate: (input) => input.length > 0 || 'Title is required',
127
+ },
128
+ ]);
129
+ title = answers.title;
130
+ }
131
+ // Get PR body if not provided
132
+ let body = options.body ?? '';
133
+ if (!body) {
134
+ const answers = await inquirer.prompt([
135
+ {
136
+ type: 'editor',
137
+ name: 'body',
138
+ message: 'PR description (optional):',
139
+ default: '',
140
+ },
141
+ ]);
142
+ body = answers.body.trim();
143
+ }
144
+ // Create PRs
145
+ const spinner = ora('Creating pull requests...').start();
146
+ try {
147
+ const reposForPR = withChanges.map((r) => r.repo);
148
+ const prOptions = {
149
+ title,
150
+ body,
151
+ draft: options.draft,
152
+ base: options.base,
153
+ };
154
+ // Create PRs in each repo
155
+ const linkedPRs = await createLinkedPRs(reposForPR, branchName, prOptions);
156
+ // Create manifest PR if manifest has changes
157
+ let manifestPR = null;
158
+ if (manifestHasChanges && manifestInfo) {
159
+ try {
160
+ const manifestPRResult = await createPullRequest(manifestInfo.owner, manifestInfo.repo, branchName, manifestInfo.default_branch, title, body, options.draft);
161
+ manifestPR = {
162
+ repoName: manifestInfo.name,
163
+ owner: manifestInfo.owner,
164
+ repo: manifestInfo.repo,
165
+ number: manifestPRResult.number,
166
+ url: manifestPRResult.url,
167
+ state: 'open',
168
+ approved: false,
169
+ checksPass: true,
170
+ mergeable: true,
171
+ };
172
+ }
173
+ catch (error) {
174
+ // Don't fail the whole operation if manifest PR fails
175
+ console.log(chalk.yellow(`\nWarning: Could not create manifest PR: ${error instanceof Error ? error.message : error}`));
176
+ }
177
+ }
178
+ spinner.succeed('Pull requests created!\n');
179
+ // Display results
180
+ console.log(chalk.green('Created PRs:'));
181
+ for (const pr of linkedPRs) {
182
+ console.log(` ${pr.repoName}: ${chalk.cyan(pr.url)}`);
183
+ }
184
+ if (manifestPR) {
185
+ console.log(` ${manifestPR.repoName}: ${chalk.cyan(manifestPR.url)}`);
186
+ }
187
+ // Generate a summary for the user
188
+ console.log('');
189
+ console.log(chalk.dim('To view PR status: gitgrip pr status'));
190
+ console.log(chalk.dim('To merge all PRs: gitgrip pr merge'));
191
+ // Save state
192
+ const state = await loadState(rootDir);
193
+ // We don't have a manifest PR number in simple mode, use branch name as key
194
+ state.branchToPR[branchName] = manifestPR?.number ?? -1;
195
+ await saveState(rootDir, state);
196
+ }
197
+ catch (error) {
198
+ spinner.fail('Failed to create PRs');
199
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
200
+ }
201
+ }
202
+ //# sourceMappingURL=create.js.map