submodule-version 2.3.2 → 3.0.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 (120) hide show
  1. package/README.md +103 -20
  2. package/dist/runner/handleErrors/handleErrors.d.ts +1 -1
  3. package/dist/runner/handleErrors/handleErrors.js +3 -10
  4. package/dist/runner/handleErrors/handleErrors.js.map +1 -1
  5. package/dist/runner/index.js +0 -0
  6. package/dist/runner/runner.d.ts +4 -0
  7. package/dist/runner/runner.js +91 -37
  8. package/dist/runner/runner.js.map +1 -1
  9. package/dist/src/PubGrub/PubGrub.d.ts +28 -0
  10. package/dist/src/PubGrub/PubGrub.js +366 -0
  11. package/dist/src/PubGrub/PubGrub.js.map +1 -0
  12. package/dist/src/PubGrub/index.d.ts +2 -0
  13. package/dist/src/PubGrub/index.js +7 -0
  14. package/dist/src/PubGrub/index.js.map +1 -0
  15. package/dist/src/PubGrub/types.d.ts +56 -0
  16. package/dist/src/PubGrub/types.js +3 -0
  17. package/dist/src/PubGrub/types.js.map +1 -0
  18. package/dist/src/entryStore.d.ts +16 -0
  19. package/dist/src/entryStore.js +152 -0
  20. package/dist/src/entryStore.js.map +1 -0
  21. package/dist/src/errors.d.ts +28 -0
  22. package/dist/src/errors.js +30 -0
  23. package/dist/src/errors.js.map +1 -0
  24. package/dist/src/git/api/GithubError.d.ts +4 -0
  25. package/dist/src/git/api/GithubError.js +11 -0
  26. package/dist/src/git/api/GithubError.js.map +1 -0
  27. package/dist/src/git/api/api.d.ts +8 -0
  28. package/dist/src/git/api/api.js +133 -0
  29. package/dist/src/git/api/api.js.map +1 -0
  30. package/dist/src/git/api/index.d.ts +3 -0
  31. package/dist/src/git/api/index.js +8 -0
  32. package/dist/src/git/api/index.js.map +1 -0
  33. package/dist/src/git/git.d.ts +30 -23
  34. package/dist/src/git/git.js +8 -258
  35. package/dist/src/git/git.js.map +1 -1
  36. package/dist/src/git/index.d.ts +1 -0
  37. package/dist/src/git/index.js +3 -1
  38. package/dist/src/git/index.js.map +1 -1
  39. package/dist/src/git/local/index.d.ts +1 -0
  40. package/dist/src/git/local/index.js +6 -0
  41. package/dist/src/git/local/index.js.map +1 -0
  42. package/dist/src/git/local/local.d.ts +26 -0
  43. package/dist/src/git/local/local.js +288 -0
  44. package/dist/src/git/local/local.js.map +1 -0
  45. package/dist/src/index.d.ts +7 -0
  46. package/dist/src/index.js +16 -1
  47. package/dist/src/index.js.map +1 -1
  48. package/dist/src/printError.d.ts +1 -0
  49. package/dist/src/printError.js +158 -0
  50. package/dist/src/printError.js.map +1 -0
  51. package/dist/src/sv.d.ts +18 -8
  52. package/dist/src/sv.js +235 -131
  53. package/dist/src/sv.js.map +1 -1
  54. package/dist/src/versionUtil/index.d.ts +2 -0
  55. package/dist/src/versionUtil/index.js +6 -0
  56. package/dist/src/versionUtil/index.js.map +1 -0
  57. package/dist/src/versionUtil/versionUtil.d.ts +16 -0
  58. package/dist/src/versionUtil/versionUtil.js +70 -0
  59. package/dist/src/versionUtil/versionUtil.js.map +1 -0
  60. package/package.json +4 -2
  61. package/runner/handleErrors/handleErrors.ts +3 -10
  62. package/runner/runner.ts +128 -46
  63. package/src/PubGrub/PubGrub.ts +578 -0
  64. package/src/PubGrub/__tests__/PubGrub.test.ts +351 -0
  65. package/src/PubGrub/index.ts +12 -0
  66. package/src/PubGrub/types.ts +72 -0
  67. package/src/__tests__/entryStore.test.ts +248 -0
  68. package/src/__tests__/printError.test.ts +148 -0
  69. package/src/__tests__/sv.test.ts +441 -0
  70. package/src/entryStore.ts +212 -0
  71. package/src/errors.ts +39 -0
  72. package/src/git/api/GithubError.ts +5 -0
  73. package/src/git/api/api.ts +180 -0
  74. package/src/git/api/index.ts +3 -0
  75. package/src/git/git.ts +8 -396
  76. package/src/git/index.ts +1 -0
  77. package/src/git/local/index.ts +1 -0
  78. package/src/git/local/local.ts +430 -0
  79. package/src/index.ts +17 -0
  80. package/src/printError.ts +189 -0
  81. package/src/sv.ts +321 -134
  82. package/src/versionUtil/__tests__/versionUtil.test.ts +62 -0
  83. package/src/versionUtil/index.ts +2 -0
  84. package/src/versionUtil/versionUtil.ts +103 -0
  85. package/tsconfig.json +1 -1
  86. package/dist/runner/handleErrors/handleBuildGraphError.d.ts +0 -1
  87. package/dist/runner/handleErrors/handleBuildGraphError.js +0 -42
  88. package/dist/runner/handleErrors/handleBuildGraphError.js.map +0 -1
  89. package/dist/runner/handleErrors/handleGitError.d.ts +0 -1
  90. package/dist/runner/handleErrors/handleGitError.js +0 -27
  91. package/dist/runner/handleErrors/handleGitError.js.map +0 -1
  92. package/dist/runner/handleErrors/handleInstallError.d.ts +0 -1
  93. package/dist/runner/handleErrors/handleInstallError.js +0 -30
  94. package/dist/runner/handleErrors/handleInstallError.js.map +0 -1
  95. package/dist/src/__tests__/versionUtil.test.d.ts +0 -1
  96. package/dist/src/__tests__/versionUtil.test.js +0 -80
  97. package/dist/src/__tests__/versionUtil.test.js.map +0 -1
  98. package/dist/src/buildGraph/GraphError.d.ts +0 -11
  99. package/dist/src/buildGraph/GraphError.js +0 -11
  100. package/dist/src/buildGraph/GraphError.js.map +0 -1
  101. package/dist/src/buildGraph/buildGraph.d.ts +0 -8
  102. package/dist/src/buildGraph/buildGraph.js +0 -100
  103. package/dist/src/buildGraph/buildGraph.js.map +0 -1
  104. package/dist/src/buildGraph/index.d.ts +0 -2
  105. package/dist/src/buildGraph/index.js +0 -8
  106. package/dist/src/buildGraph/index.js.map +0 -1
  107. package/dist/src/git/__tests__/parseGitUrl.test.d.ts +0 -1
  108. package/dist/src/git/__tests__/parseGitUrl.test.js +0 -30
  109. package/dist/src/git/__tests__/parseGitUrl.test.js.map +0 -1
  110. package/dist/src/versionUtil.d.ts +0 -13
  111. package/dist/src/versionUtil.js +0 -79
  112. package/dist/src/versionUtil.js.map +0 -1
  113. package/runner/handleErrors/handleBuildGraphError.ts +0 -49
  114. package/runner/handleErrors/handleGitError.ts +0 -28
  115. package/runner/handleErrors/handleInstallError.ts +0 -26
  116. package/src/__tests__/versionUtil.test.ts +0 -96
  117. package/src/buildGraph/GraphError.ts +0 -12
  118. package/src/buildGraph/buildGraph.ts +0 -150
  119. package/src/buildGraph/index.ts +0 -2
  120. package/src/versionUtil.ts +0 -97
package/src/git/git.ts CHANGED
@@ -1,401 +1,13 @@
1
- import { exec } from 'child_process';
2
- import { promisify } from 'util';
3
- import path from 'path';
4
1
  import { parseGitUrl } from './parseGitUrl';
5
- import { versionUtil } from '../versionUtil';
6
- import { RunOptions } from '../runOptions';
7
- import { GitError } from './GitError';
8
-
9
- const execAsync = promisify(exec);
2
+ import { local } from './local';
3
+ import { api } from './api';
10
4
 
5
+ /*
6
+ * Единая точка доступа к git: local — операции локального git CLI,
7
+ * api — удалённый GitHub GraphQL API (без клонирования).
8
+ */
11
9
  export const git = {
12
10
  parseUrl: parseGitUrl,
13
-
14
- addSumbmodule: async (url: string): Promise<void> => {
15
- const { name } = parseGitUrl(url);
16
- const module = path.join(RunOptions.modulesDir, name);
17
-
18
- try {
19
- await execAsync(
20
- `git submodule add ${url} ${module}`,
21
- { cwd: RunOptions.cwd },
22
- );
23
- } catch {
24
- throw new GitError('GIT_NOT_A_REPO');
25
- }
26
- },
27
-
28
- checkout: async (name: string, version: string): Promise<void> => {
29
- const module = path.join(RunOptions.modulesDir, name);
30
-
31
- try {
32
- await execAsync(
33
- `git -C ${module} checkout ${version} -q`,
34
- { cwd: RunOptions.cwd },
35
- );
36
- } catch {
37
- throw new GitError('GIT_MODULE_CHECKOUT_FAILED');
38
- }
39
- },
40
-
41
- listVersions: async (projectName: string): Promise<string[]> => {
42
- const module = path.join(RunOptions.modulesDir, projectName);
43
-
44
- return git.listTags(module);
45
- },
46
-
47
- status: async (dir: string): Promise<string> => {
48
- const res = await execAsync(
49
- `git -C ${dir} status --porcelain`,
50
- { cwd: RunOptions.cwd },
51
- );
52
-
53
- return res.stdout.toString();
54
- },
55
-
56
- hasChanges: async (dir: string): Promise<boolean> => {
57
- const status = await git.status(dir);
58
-
59
- return status.trim().length > 0;
60
- },
61
-
62
- hasUnpushedCommits: async (dir: string): Promise<boolean> => {
63
- await git.fetch(dir);
64
-
65
- const branch = await git.currentBranch(dir);
66
-
67
- if (branch) {
68
- let upstream: string | null = null;
69
-
70
- try {
71
- const res = await execAsync(
72
- `git -C ${dir} rev-parse --abbrev-ref --symbolic-full-name @{u}`,
73
- { cwd: RunOptions.cwd },
74
- );
75
-
76
- upstream = res.stdout.toString().trim() || null;
77
- } catch {
78
- upstream = null;
79
- }
80
-
81
- if (!upstream) {
82
- try {
83
- await execAsync(
84
- `git -C ${dir} rev-parse --verify --quiet origin/${branch}`,
85
- { cwd: RunOptions.cwd },
86
- );
87
- upstream = `origin/${branch}`;
88
- } catch {
89
- upstream = null;
90
- }
91
- }
92
-
93
- /* Ветки на remote нет — всё локальное не опубликовано */
94
- if (!upstream) return true;
95
-
96
- const res = await execAsync(
97
- `git -C ${dir} rev-list ${upstream}..HEAD --count`,
98
- { cwd: RunOptions.cwd },
99
- );
100
-
101
- return Number(res.stdout.toString().trim()) > 0;
102
- }
103
-
104
- /*
105
- * Detached HEAD (checkout на тег): локальные теги не доказывают публикацию
106
- * (могут быть не запушены) — сверяем HEAD с фактическими рефами remote.
107
- */
108
- let remoteOutput = '';
109
-
110
- try {
111
- const res = await execAsync(
112
- `git -C ${dir} ls-remote origin`,
113
- { cwd: RunOptions.cwd },
114
- );
115
-
116
- remoteOutput = res.stdout.toString();
117
- } catch {
118
- /* Remote недоступен/не настроен — считаем всё неопубликованным */
119
- return true;
120
- }
121
-
122
- const remoteShas = remoteOutput.split(/\r?\n/)
123
- .map(line => line.split(/\s+/)[0])
124
- .filter(sha => /^[0-9a-f]{40}$/.test(sha));
125
-
126
- for (const sha of remoteShas) {
127
- try {
128
- await execAsync(
129
- `git -C ${dir} merge-base --is-ancestor HEAD ${sha}`,
130
- { cwd: RunOptions.cwd },
131
- );
132
-
133
- /* HEAD достижим из remote-рефа — опубликован */
134
- return false;
135
- } catch {
136
- // HEAD не предок этого рефа — проверяем остальные
137
- }
138
- }
139
-
140
- return true;
141
- },
142
-
143
- isGitRepo: async (dir: string): Promise<boolean> => {
144
- try {
145
- await execAsync(
146
- `git -C ${dir} rev-parse --is-inside-work-tree`,
147
- { cwd: RunOptions.cwd },
148
- );
149
-
150
- return true;
151
- } catch {
152
- return false;
153
- }
154
- },
155
-
156
- getRemote: async (dir: string): Promise<string | null> => {
157
- try {
158
- const res = await execAsync(
159
- `git -C ${dir} remote get-url origin`,
160
- { cwd: RunOptions.cwd },
161
- );
162
-
163
- return res.stdout.toString().trim() || null;
164
- } catch {
165
- return null;
166
- }
167
- },
168
-
169
- init: async (dir: string): Promise<void> => {
170
- await execAsync(
171
- `git -C ${dir} init`,
172
- { cwd: RunOptions.cwd },
173
- );
174
- },
175
-
176
- addRemote: async (dir: string, url: string): Promise<void> => {
177
- const existing = await git.getRemote(dir);
178
-
179
- const command = existing
180
- ? `git -C ${dir} remote set-url origin ${url}`
181
- : `git -C ${dir} remote add origin ${url}`;
182
-
183
- await execAsync(command, { cwd: RunOptions.cwd });
184
- },
185
-
186
- currentBranch: async (dir: string): Promise<string | null> => {
187
- try {
188
- const res = await execAsync(
189
- `git -C ${dir} symbolic-ref --short -q HEAD`,
190
- { cwd: RunOptions.cwd },
191
- );
192
-
193
- return res.stdout.toString().trim() || null;
194
- } catch {
195
- return null;
196
- }
197
- },
198
-
199
- defaultRemoteBranch: async (dir: string): Promise<string | null> => {
200
- try {
201
- const res = await execAsync(
202
- `git -C ${dir} symbolic-ref --short refs/remotes/origin/HEAD`,
203
- { cwd: RunOptions.cwd },
204
- );
205
-
206
- return res.stdout.toString().trim().replace(/^origin\//, '') || null;
207
- } catch {
208
- // origin/HEAD not set - probe common defaults
209
- }
210
-
211
- for (const candidate of ['main', 'master']) {
212
- try {
213
- await execAsync(
214
- `git -C ${dir} rev-parse --verify --quiet origin/${candidate}`,
215
- { cwd: RunOptions.cwd },
216
- );
217
-
218
- return candidate;
219
- } catch {
220
- // No such remote branch
221
- }
222
- }
223
-
224
- return null;
225
- },
226
-
227
- /*
228
- * Аддоны checkout'нуты на тег (detached HEAD). Перед коммитом поднимаем
229
- * локальную ветку на текущем коммите и привязываем её к remote-ветке,
230
- * чтобы sync/push работали по ветке, а не в оторванной голове.
231
- */
232
- ensureBranch: async (dir: string): Promise<void> => {
233
- const branch = await git.currentBranch(dir);
234
- if (branch) return;
235
-
236
- await git.fetch(dir);
237
- const remoteBranch = await git.defaultRemoteBranch(dir);
238
- const target = remoteBranch || 'main';
239
-
240
- await execAsync(
241
- `git -C ${dir} checkout -B ${target}`,
242
- { cwd: RunOptions.cwd },
243
- );
244
-
245
- if (remoteBranch) {
246
- await execAsync(
247
- // eslint-disable-next-line max-len
248
- `git -C ${dir} branch --set-upstream-to=origin/${remoteBranch} ${target}`,
249
- { cwd: RunOptions.cwd },
250
- );
251
- }
252
- },
253
-
254
- commitAll: async (dir: string, message: string): Promise<void> => {
255
- await execAsync(
256
- `git -C ${dir} add -A`,
257
- { cwd: RunOptions.cwd },
258
- );
259
-
260
- await execAsync(
261
- `git -C ${dir} commit -m ${JSON.stringify(message)}`,
262
- { cwd: RunOptions.cwd },
263
- );
264
- },
265
-
266
- addTag: async (dir: string, version: string): Promise<void> => {
267
- await execAsync(
268
- `git -C ${dir} tag ${version}`,
269
- { cwd: RunOptions.cwd },
270
- );
271
- },
272
-
273
- push: async (dir: string, tag?: string): Promise<void> => {
274
- await execAsync(
275
- `git -C ${dir} push -u origin HEAD`,
276
- { cwd: RunOptions.cwd },
277
- );
278
-
279
- if (tag) {
280
- await execAsync(
281
- `git -C ${dir} push origin ${tag}`,
282
- { cwd: RunOptions.cwd },
283
- );
284
- }
285
- },
286
-
287
- fetch: async (dir: string): Promise<void> => {
288
- try {
289
- await execAsync(
290
- `git -C ${dir} fetch origin`,
291
- { cwd: RunOptions.cwd },
292
- );
293
- } catch {
294
- // Fresh repo without upstream yet - nothing to fetch
295
- }
296
- },
297
-
298
- isRemoteAhead: async (dir: string): Promise<boolean> => {
299
- await git.fetch(dir);
300
-
301
- try {
302
- const res = await execAsync(
303
- `git -C ${dir} rev-list HEAD..@{u} --count`,
304
- { cwd: RunOptions.cwd },
305
- );
306
-
307
- return Number(res.stdout.toString().trim()) > 0;
308
- } catch {
309
- // No upstream configured - remote is not ahead
310
- return false;
311
- }
312
- },
313
-
314
- pullRebaseAutostash: async (dir: string): Promise<void> => {
315
- try {
316
- await execAsync(
317
- `git -C ${dir} pull --rebase --autostash`,
318
- { cwd: RunOptions.cwd },
319
- );
320
- } catch {
321
- try {
322
- await execAsync(
323
- `git -C ${dir} rebase --abort`,
324
- { cwd: RunOptions.cwd },
325
- );
326
- } catch {
327
- // Best effort - no rebase in progress
328
- }
329
-
330
- try {
331
- await execAsync(
332
- `git -C ${dir} stash pop`,
333
- { cwd: RunOptions.cwd },
334
- );
335
- } catch {
336
- // Best effort - nothing stashed
337
- }
338
-
339
- throw new GitError('GIT_SYNC_CONFLICT');
340
- }
341
- },
342
-
343
- tagsAtHead: async (dir: string): Promise<string[]> => {
344
- try {
345
- const res = await execAsync(
346
- `git -C ${dir} tag --points-at HEAD`,
347
- { cwd: RunOptions.cwd },
348
- );
349
-
350
- return res.stdout.toString().split(/\r?\n/)
351
- .filter(tag => tag && versionUtil.validate(tag));
352
- } catch {
353
- return [];
354
- }
355
- },
356
-
357
- currentVersion: async (name: string): Promise<string | null> => {
358
- const module = path.join(RunOptions.modulesDir, name);
359
- const tags = await git.tagsAtHead(module);
360
-
361
- return versionUtil.latest(tags) || null;
362
- },
363
-
364
- listTags: async (dir: string): Promise<string[]> => {
365
- try {
366
- await execAsync(
367
- `git -C ${dir} fetch --tags`,
368
- { cwd: RunOptions.cwd },
369
- );
370
- } catch {
371
- // Repo without remote - local tags only
372
- }
373
-
374
- const res = await execAsync(
375
- `git -C ${dir} tag -l`,
376
- { cwd: RunOptions.cwd },
377
- );
378
-
379
- const tagList = res.stdout.toString().split(/\r?\n/);
380
-
381
- return tagList.filter(tag => {
382
- if (!tag) return false;
383
-
384
- return versionUtil.validate(tag);
385
- });
386
- },
387
-
388
- rm: async (submoduleName: string) => {
389
- const modulePath = path.join(RunOptions.modulesDir, submoduleName);
390
-
391
- await execAsync(
392
- `git rm -rf ${modulePath}`,
393
- { cwd: RunOptions.cwd },
394
- );
395
-
396
- await execAsync(
397
- `rm -rf ${path.join('.git/modules', modulePath)}`,
398
- { cwd: RunOptions.cwd },
399
- );
400
- },
11
+ local,
12
+ api,
401
13
  };
package/src/git/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { git } from './git';
2
2
  export { GitError } from './GitError';
3
+ export { GithubError } from './api';
@@ -0,0 +1 @@
1
+ export { local } from './local';