@ryanatkn/gro 0.168.0 → 0.169.1

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 (98) hide show
  1. package/dist/args.d.ts +15 -1
  2. package/dist/args.d.ts.map +1 -1
  3. package/dist/args.js +26 -0
  4. package/dist/changeset.task.d.ts +1 -1
  5. package/dist/changeset.task.d.ts.map +1 -1
  6. package/dist/changeset.task.js +1 -1
  7. package/dist/check.task.d.ts.map +1 -1
  8. package/dist/check.task.js +1 -1
  9. package/dist/clean.task.d.ts +1 -1
  10. package/dist/clean.task.d.ts.map +1 -1
  11. package/dist/clean.task.js +1 -1
  12. package/dist/cli.d.ts +1 -1
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/commit.task.d.ts +1 -1
  15. package/dist/commit.task.d.ts.map +1 -1
  16. package/dist/commit.task.js +1 -1
  17. package/dist/deploy.task.d.ts +3 -3
  18. package/dist/deploy.task.d.ts.map +1 -1
  19. package/dist/deploy.task.js +1 -1
  20. package/dist/disknode.d.ts +1 -1
  21. package/dist/disknode.d.ts.map +1 -1
  22. package/dist/esbuild_plugin_external_worker.d.ts.map +1 -1
  23. package/dist/filer.d.ts +1 -1
  24. package/dist/filer.d.ts.map +1 -1
  25. package/dist/gen.d.ts +1 -1
  26. package/dist/gen.d.ts.map +1 -1
  27. package/dist/gen_helpers.d.ts +1 -1
  28. package/dist/gen_helpers.d.ts.map +1 -1
  29. package/dist/gro_config.d.ts +1 -1
  30. package/dist/gro_config.d.ts.map +1 -1
  31. package/dist/gro_plugin_server.d.ts +2 -2
  32. package/dist/gro_plugin_server.d.ts.map +1 -1
  33. package/dist/input_path.d.ts +1 -1
  34. package/dist/input_path.d.ts.map +1 -1
  35. package/dist/modules.d.ts +1 -1
  36. package/dist/modules.d.ts.map +1 -1
  37. package/dist/package.d.ts.map +1 -1
  38. package/dist/package.js +5 -38
  39. package/dist/package_json.d.ts.map +1 -1
  40. package/dist/package_json.js +4 -0
  41. package/dist/parse_exports.d.ts +1 -1
  42. package/dist/parse_exports.d.ts.map +1 -1
  43. package/dist/parse_imports.d.ts +1 -1
  44. package/dist/parse_imports.d.ts.map +1 -1
  45. package/dist/paths.d.ts +1 -1
  46. package/dist/paths.d.ts.map +1 -1
  47. package/dist/publish.task.d.ts +2 -2
  48. package/dist/publish.task.d.ts.map +1 -1
  49. package/dist/publish.task.js +1 -1
  50. package/dist/resolve_specifier.d.ts +1 -1
  51. package/dist/resolve_specifier.d.ts.map +1 -1
  52. package/dist/search_fs.d.ts +1 -1
  53. package/dist/search_fs.d.ts.map +1 -1
  54. package/dist/task.d.ts +1 -1
  55. package/dist/task.d.ts.map +1 -1
  56. package/dist/test.task.js +2 -2
  57. package/dist/upgrade.task.d.ts +1 -1
  58. package/dist/upgrade.task.d.ts.map +1 -1
  59. package/dist/upgrade.task.js +1 -1
  60. package/dist/watch_dir.d.ts +1 -1
  61. package/dist/watch_dir.d.ts.map +1 -1
  62. package/package.json +6 -2
  63. package/src/lib/args.ts +32 -1
  64. package/src/lib/changeset.task.ts +5 -1
  65. package/src/lib/check.task.ts +1 -1
  66. package/src/lib/clean.task.ts +1 -1
  67. package/src/lib/cli.ts +1 -1
  68. package/src/lib/commit.task.ts +1 -1
  69. package/src/lib/deploy.task.ts +6 -6
  70. package/src/lib/disknode.ts +1 -1
  71. package/src/lib/esbuild_plugin_external_worker.ts +1 -1
  72. package/src/lib/filer.ts +1 -1
  73. package/src/lib/gen.ts +1 -1
  74. package/src/lib/gen_helpers.ts +1 -1
  75. package/src/lib/gro_config.ts +1 -1
  76. package/src/lib/gro_plugin_server.ts +1 -1
  77. package/src/lib/input_path.ts +1 -1
  78. package/src/lib/modules.ts +1 -1
  79. package/src/lib/package.ts +5 -38
  80. package/src/lib/package_json.ts +4 -0
  81. package/src/lib/parse_exports.ts +1 -1
  82. package/src/lib/parse_imports.ts +1 -1
  83. package/src/lib/paths.ts +1 -1
  84. package/src/lib/publish.task.ts +8 -8
  85. package/src/lib/resolve_specifier.ts +1 -1
  86. package/src/lib/search_fs.ts +1 -2
  87. package/src/lib/task.ts +1 -1
  88. package/src/lib/test.task.ts +2 -2
  89. package/src/lib/upgrade.task.ts +1 -1
  90. package/src/lib/watch_dir.ts +1 -2
  91. package/dist/git.d.ts +0 -81
  92. package/dist/git.d.ts.map +0 -1
  93. package/dist/git.js +0 -218
  94. package/dist/path.d.ts +0 -17
  95. package/dist/path.d.ts.map +0 -1
  96. package/dist/path.js +0 -2
  97. package/src/lib/git.ts +0 -298
  98. package/src/lib/path.ts +0 -23
@@ -4,7 +4,7 @@ import {spawn_cli} from '@ryanatkn/gro/cli.js';
4
4
  import {Task_Error, type Task} from './task.ts';
5
5
  import {find_cli} from './cli.ts';
6
6
  import {has_dep} from './package_json.ts';
7
- import {serialize_args, to_forwarded_args} from './args.ts';
7
+ import {serialize_args, to_implicit_forwarded_args} from './args.ts';
8
8
  import {VITEST_CLI} from './constants.ts';
9
9
  import {paths} from './paths.ts';
10
10
 
@@ -46,7 +46,7 @@ export const task: Task<Args> = {
46
46
  if (t) {
47
47
  vitest_args.push('-t', t);
48
48
  }
49
- vitest_args.push(...serialize_args(to_forwarded_args(VITEST_CLI)));
49
+ vitest_args.push(...serialize_args(to_implicit_forwarded_args(VITEST_CLI)));
50
50
 
51
51
  const spawned = await spawn_cli(VITEST_CLI, vitest_args);
52
52
  if (!spawned?.ok) {
@@ -1,10 +1,10 @@
1
1
  import {spawn} from '@ryanatkn/belt/process.js';
2
2
  import {z} from 'zod';
3
3
  import {rmSync} from 'node:fs';
4
+ import {Git_Origin, git_pull} from '@ryanatkn/belt/git.js';
4
5
 
5
6
  import {Task_Error, type Task} from './task.ts';
6
7
  import {extract_deps, load_package_json, type Package_Json_Dep} from './package_json.ts';
7
- import {Git_Origin, git_pull} from './git.ts';
8
8
  import {spawn_cli} from './cli.ts';
9
9
  import {serialize_args, to_forwarded_args} from './args.ts';
10
10
  import {NODE_MODULES_DIRNAME} from './constants.ts';
@@ -2,10 +2,9 @@ import {watch, type ChokidarOptions, type FSWatcher, type Matcher} from 'chokida
2
2
  import {relative} from 'node:path';
3
3
  import {statSync} from 'node:fs';
4
4
  import {create_deferred, type Deferred} from '@ryanatkn/belt/async.js';
5
+ import type {Path_Filter} from '@ryanatkn/belt/path.js';
5
6
  import {EMPTY_OBJECT} from '@ryanatkn/belt/object.js';
6
7
 
7
- import type {Path_Filter} from './path.ts';
8
-
9
8
  const TMP_FILE_PATTERN = /\.tmp\./;
10
9
 
11
10
  // TODO pretty hacky
package/dist/git.d.ts DELETED
@@ -1,81 +0,0 @@
1
- import type { SpawnOptions } from 'node:child_process';
2
- import { z } from 'zod';
3
- import type { Flavored } from '@ryanatkn/belt/types.js';
4
- export declare const Git_Origin: z.ZodString;
5
- export type Git_Origin = Flavored<string, 'Git_Origin'>;
6
- export declare const Git_Branch: z.ZodString;
7
- export type Git_Branch = Flavored<string, 'Git_Branch'>;
8
- /**
9
- * Returns the current git branch name or throws if something goes wrong.
10
- */
11
- export declare const git_current_branch_name: (options?: SpawnOptions) => Promise<Git_Branch>;
12
- /**
13
- * @returns a boolean indicating if the remote git branch exists
14
- */
15
- export declare const git_remote_branch_exists: (origin?: Git_Origin, branch?: Git_Branch, options?: SpawnOptions) => Promise<boolean>;
16
- /**
17
- * @returns a boolean indicating if the local git branch exists
18
- */
19
- export declare const git_local_branch_exists: (branch: Git_Branch, options?: SpawnOptions) => Promise<boolean>;
20
- /**
21
- * TODO make this return an enum and separate the text into a different function
22
- * @returns an error message if the git workspace has any unstaged or uncommitted changes, or `null` if it's clean
23
- */
24
- export declare const git_check_clean_workspace: (options?: SpawnOptions) => Promise<string | null>;
25
- /**
26
- * TODO make this return an enum and separate the text into a different function
27
- * @returns an error message if the git workspace has any unstaged stages, or `null` if it's clean
28
- */
29
- export declare const git_check_fully_staged_workspace: (options?: SpawnOptions) => Promise<string | null>;
30
- /**
31
- * Calls `git fetch` and throws if anything goes wrong.
32
- */
33
- export declare const git_fetch: (origin?: Git_Origin, branch?: Git_Branch, options?: SpawnOptions) => Promise<void>;
34
- /**
35
- * Calls `git checkout` and throws if anything goes wrong.
36
- * @returns the previous branch name, if it changed
37
- */
38
- export declare const git_checkout: (branch: Git_Branch, options?: SpawnOptions) => Promise<Git_Branch | null>;
39
- /**
40
- * Calls `git pull` and throws if anything goes wrong.
41
- */
42
- export declare const git_pull: (origin?: Git_Origin, branch?: Git_Branch, options?: SpawnOptions) => Promise<void>;
43
- /**
44
- * Calls `git push` and throws if anything goes wrong.
45
- */
46
- export declare const git_push: (origin: Git_Origin, branch?: Git_Branch, options?: SpawnOptions, set_upstream?: boolean) => Promise<void>;
47
- /**
48
- * Calls `git push` and throws if anything goes wrong.
49
- */
50
- export declare const git_push_to_create: (origin?: Git_Origin, branch?: Git_Branch, options?: SpawnOptions) => Promise<void>;
51
- /**
52
- * Deletes a branch locally and throws if anything goes wrong.
53
- */
54
- export declare const git_delete_local_branch: (branch: Git_Branch, options?: SpawnOptions) => Promise<void>;
55
- /**
56
- * Deletes a branch remotely and throws if anything goes wrong.
57
- */
58
- export declare const git_delete_remote_branch: (origin: Git_Origin, branch: Git_Branch, options?: SpawnOptions) => Promise<void>;
59
- /**
60
- * Resets the `target` branch back to its first commit both locally and remotely.
61
- */
62
- export declare const git_reset_branch_to_first_commit: (origin: Git_Origin, branch: Git_Branch, options?: SpawnOptions) => Promise<void>;
63
- /**
64
- * Returns the branch's latest commit hash or throws if something goes wrong.
65
- */
66
- export declare const git_current_commit_hash: (branch?: string, options?: SpawnOptions) => Promise<string | null>;
67
- /**
68
- * Returns the hash of the current branch's first commit or throws if something goes wrong.
69
- */
70
- export declare const git_current_branch_first_commit_hash: (options?: SpawnOptions) => Promise<string>;
71
- /**
72
- * Returns the global git config setting for `pull.rebase`.
73
- * Gro is currently written to expect `true`,
74
- * but the restriction could be loosened with additional work.
75
- */
76
- export declare const git_check_setting_pull_rebase: (options?: SpawnOptions) => Promise<boolean>;
77
- /**
78
- * Clones a branch locally to another directory and updates the origin to match the source.
79
- */
80
- export declare const git_clone_locally: (origin: Git_Origin, branch: Git_Branch, source_dir: string, target_dir: string, options?: SpawnOptions) => Promise<void>;
81
- //# sourceMappingURL=git.d.ts.map
package/dist/git.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/git.ts"],"names":[],"mappings":"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"}
package/dist/git.js DELETED
@@ -1,218 +0,0 @@
1
- import { spawn, spawn_out } from '@ryanatkn/belt/process.js';
2
- import { z } from 'zod';
3
- import { existsSync } from 'node:fs';
4
- import { to_file_path } from "./path.js";
5
- // TODO maybe extract to `util-git`
6
- export const Git_Origin = z.string();
7
- export const Git_Branch = z.string();
8
- /**
9
- * Returns the current git branch name or throws if something goes wrong.
10
- */
11
- export const git_current_branch_name = async (options) => {
12
- const { stdout } = await spawn_out('git', ['rev-parse', '--abbrev-ref', 'HEAD'], options);
13
- if (!stdout)
14
- throw Error('git_current_branch_name failed');
15
- const branch_name = stdout.trim();
16
- return branch_name;
17
- };
18
- /**
19
- * @returns a boolean indicating if the remote git branch exists
20
- */
21
- export const git_remote_branch_exists = async (origin = 'origin', branch, options) => {
22
- const final_branch = branch ?? (await git_current_branch_name(options));
23
- if (options?.cwd && !existsSync(to_file_path(options.cwd))) {
24
- return false;
25
- }
26
- const result = await spawn('git', ['ls-remote', '--exit-code', '--heads', origin, 'refs/heads/' + final_branch], options);
27
- if (result.ok) {
28
- return true;
29
- }
30
- else if (result.code === 2) {
31
- return false;
32
- }
33
- else {
34
- throw Error(`git_remote_branch_exists failed for origin '${origin}' and branch '${final_branch}' with code ${result.code}`);
35
- }
36
- };
37
- /**
38
- * @returns a boolean indicating if the local git branch exists
39
- */
40
- export const git_local_branch_exists = async (branch, options) => {
41
- if (options?.cwd && !existsSync(to_file_path(options.cwd))) {
42
- return false;
43
- }
44
- const result = await spawn('git', ['show-ref', '--quiet', 'refs/heads/' + branch], options);
45
- return result.ok;
46
- };
47
- /**
48
- * TODO make this return an enum and separate the text into a different function
49
- * @returns an error message if the git workspace has any unstaged or uncommitted changes, or `null` if it's clean
50
- */
51
- export const git_check_clean_workspace = async (options) => {
52
- const unstaged_result = await spawn('git', ['diff', '--exit-code', '--quiet'], options);
53
- if (!unstaged_result.ok) {
54
- return 'git has unstaged changes';
55
- }
56
- const staged_result = await spawn('git', ['diff', '--exit-code', '--cached', '--quiet'], options);
57
- if (!staged_result.ok) {
58
- return 'git has staged but uncommitted changes';
59
- }
60
- const status_result = await spawn_out('git', ['status', '--porcelain'], options);
61
- if (status_result.stdout?.length) {
62
- return 'git has untracked files';
63
- }
64
- return null;
65
- };
66
- /**
67
- * TODO make this return an enum and separate the text into a different function
68
- * @returns an error message if the git workspace has any unstaged stages, or `null` if it's clean
69
- */
70
- export const git_check_fully_staged_workspace = async (options) => {
71
- const unstaged_result = await spawn('git', ['diff', '--exit-code', '--quiet'], options);
72
- if (!unstaged_result.ok) {
73
- return 'git has unstaged changes';
74
- }
75
- const status_result = await spawn_out('git', ['status', '--porcelain'], options);
76
- if (status_result.stdout?.includes('??')) {
77
- return 'git has untracked files';
78
- }
79
- return null;
80
- };
81
- /**
82
- * Calls `git fetch` and throws if anything goes wrong.
83
- */
84
- export const git_fetch = async (origin = 'origin', branch, options) => {
85
- const args = ['fetch', origin];
86
- if (branch)
87
- args.push(branch);
88
- const result = await spawn('git', args, options);
89
- if (!result.ok) {
90
- throw Error(`git_fetch failed for origin '${origin}' and branch '${branch}' with code ${result.code}`);
91
- }
92
- };
93
- /**
94
- * Calls `git checkout` and throws if anything goes wrong.
95
- * @returns the previous branch name, if it changed
96
- */
97
- export const git_checkout = async (branch, options) => {
98
- const current_branch = await git_current_branch_name(options);
99
- if (branch === current_branch) {
100
- return null;
101
- }
102
- const result = await spawn('git', ['checkout', branch], options);
103
- if (!result.ok) {
104
- throw Error(`git_checkout failed for branch '${branch}' with code ${result.code}`);
105
- }
106
- return current_branch;
107
- };
108
- /**
109
- * Calls `git pull` and throws if anything goes wrong.
110
- */
111
- export const git_pull = async (origin = 'origin', branch, options) => {
112
- const args = ['pull', origin];
113
- if (branch)
114
- args.push(branch);
115
- const result = await spawn('git', args, options);
116
- if (!result.ok) {
117
- throw Error(`git_pull failed for branch '${branch}' with code ${result.code}`);
118
- }
119
- };
120
- /**
121
- * Calls `git push` and throws if anything goes wrong.
122
- */
123
- export const git_push = async (origin, branch, options, set_upstream = false) => {
124
- const final_branch = branch ?? (await git_current_branch_name(options));
125
- const args = ['push', origin, final_branch];
126
- if (set_upstream)
127
- args.push('-u');
128
- const result = await spawn('git', args, options);
129
- if (!result.ok) {
130
- throw Error(`git_push failed for branch '${final_branch}' with code ${result.code}`);
131
- }
132
- };
133
- /**
134
- * Calls `git push` and throws if anything goes wrong.
135
- */
136
- export const git_push_to_create = async (origin = 'origin', branch, options) => {
137
- const final_branch = branch ?? (await git_current_branch_name(options));
138
- const push_args = ['push'];
139
- if (await git_remote_branch_exists(origin, final_branch, options)) {
140
- push_args.push(origin);
141
- }
142
- else {
143
- push_args.push('-u', origin);
144
- }
145
- push_args.push(final_branch);
146
- const result = await spawn('git', push_args, options);
147
- if (!result.ok) {
148
- throw Error(`git_push failed for branch '${final_branch}' with code ${result.code}`);
149
- }
150
- };
151
- /**
152
- * Deletes a branch locally and throws if anything goes wrong.
153
- */
154
- export const git_delete_local_branch = async (branch, options) => {
155
- const result = await spawn('git', ['branch', '-D', branch], options);
156
- if (!result.ok) {
157
- throw Error(`git_delete_local_branch failed for branch '${branch}' with code ${result.code}`);
158
- }
159
- };
160
- /**
161
- * Deletes a branch remotely and throws if anything goes wrong.
162
- */
163
- export const git_delete_remote_branch = async (origin, branch, options) => {
164
- const result = await spawn('git', ['push', origin, ':' + branch], options);
165
- if (!result.ok) {
166
- throw Error(`git_delete_remote_branch failed for branch '${branch}' with code ${result.code}`);
167
- }
168
- };
169
- /**
170
- * Resets the `target` branch back to its first commit both locally and remotely.
171
- */
172
- export const git_reset_branch_to_first_commit = async (origin, branch, options) => {
173
- const previous_branch = await git_checkout(branch, options);
174
- const first_commit_hash = await git_current_branch_first_commit_hash(options);
175
- await spawn('git', ['reset', '--hard', first_commit_hash], options);
176
- await spawn('git', ['push', origin, branch, '--force'], options);
177
- if (previous_branch) {
178
- await git_checkout(previous_branch, options);
179
- }
180
- };
181
- /**
182
- * Returns the branch's latest commit hash or throws if something goes wrong.
183
- */
184
- export const git_current_commit_hash = async (branch, options) => {
185
- const final_branch = branch ?? (await git_current_branch_name(options));
186
- const { stdout } = await spawn_out('git', ['show-ref', '-s', final_branch], options);
187
- if (!stdout)
188
- return null; // TODO hack for CI
189
- return stdout.split('\n')[0].trim();
190
- };
191
- /**
192
- * Returns the hash of the current branch's first commit or throws if something goes wrong.
193
- */
194
- export const git_current_branch_first_commit_hash = async (options) => {
195
- const { stdout } = await spawn_out('git', ['rev-list', '--max-parents=0', '--abbrev-commit', 'HEAD'], options);
196
- if (!stdout)
197
- throw Error('git_current_branch_first_commit_hash failed');
198
- return stdout.trim();
199
- };
200
- /**
201
- * Returns the global git config setting for `pull.rebase`.
202
- * Gro is currently written to expect `true`,
203
- * but the restriction could be loosened with additional work.
204
- */
205
- export const git_check_setting_pull_rebase = async (options) => {
206
- const value = await spawn_out('git', ['config', '--global', 'pull.rebase'], options);
207
- return value.stdout?.trim() === 'true';
208
- };
209
- /**
210
- * Clones a branch locally to another directory and updates the origin to match the source.
211
- */
212
- export const git_clone_locally = async (origin, branch, source_dir, target_dir, options) => {
213
- await spawn('git', ['clone', '-b', branch, '--single-branch', source_dir, target_dir], options);
214
- const origin_url = (await spawn_out('git', ['remote', 'get-url', origin], { ...options, cwd: source_dir })).stdout?.trim();
215
- if (!origin_url)
216
- throw Error('Failed to get the origin url with git in ' + source_dir);
217
- await spawn('git', ['remote', 'set-url', origin, origin_url], { ...options, cwd: target_dir });
218
- };
package/dist/path.d.ts DELETED
@@ -1,17 +0,0 @@
1
- import { type URL } from 'node:url';
2
- import type { Flavored } from '@ryanatkn/belt/types.js';
3
- /**
4
- * An absolute path on the filesystem. Named "id" to be consistent with Rollup.
5
- */
6
- export type Path_Id = Flavored<string, 'Path_Id'>;
7
- export interface Path_Info {
8
- id: Path_Id;
9
- is_directory: boolean;
10
- }
11
- export interface Resolved_Path extends Path_Info {
12
- path: string;
13
- }
14
- export type Path_Filter = (path: string, is_directory: boolean) => boolean;
15
- export type File_Filter = (path: string) => boolean;
16
- export declare const to_file_path: (path_or_url: string | URL) => string;
17
- //# sourceMappingURL=path.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,GAAG,EAAC,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAElD,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC/C,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,KAAK,OAAO,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAEpD,eAAO,MAAM,YAAY,GAAI,aAAa,MAAM,GAAG,GAAG,KAAG,MACuB,CAAC"}
package/dist/path.js DELETED
@@ -1,2 +0,0 @@
1
- import { fileURLToPath } from 'node:url';
2
- export const to_file_path = (path_or_url) => typeof path_or_url === 'string' ? path_or_url : fileURLToPath(path_or_url.href);
package/src/lib/git.ts DELETED
@@ -1,298 +0,0 @@
1
- import {spawn, spawn_out} from '@ryanatkn/belt/process.js';
2
- import type {SpawnOptions} from 'node:child_process';
3
- import {z} from 'zod';
4
- import {existsSync} from 'node:fs';
5
- import type {Flavored} from '@ryanatkn/belt/types.js';
6
-
7
- import {to_file_path} from './path.ts';
8
-
9
- // TODO maybe extract to `util-git`
10
-
11
- export const Git_Origin = z.string();
12
- export type Git_Origin = Flavored<string, 'Git_Origin'>;
13
-
14
- export const Git_Branch = z.string();
15
- export type Git_Branch = Flavored<string, 'Git_Branch'>;
16
-
17
- /**
18
- * Returns the current git branch name or throws if something goes wrong.
19
- */
20
- export const git_current_branch_name = async (options?: SpawnOptions): Promise<Git_Branch> => {
21
- const {stdout} = await spawn_out('git', ['rev-parse', '--abbrev-ref', 'HEAD'], options);
22
- if (!stdout) throw Error('git_current_branch_name failed');
23
- const branch_name = stdout.trim() as Git_Branch;
24
- return branch_name;
25
- };
26
-
27
- /**
28
- * @returns a boolean indicating if the remote git branch exists
29
- */
30
- export const git_remote_branch_exists = async (
31
- origin: Git_Origin = 'origin' as Git_Origin,
32
- branch?: Git_Branch,
33
- options?: SpawnOptions,
34
- ): Promise<boolean> => {
35
- const final_branch = branch ?? (await git_current_branch_name(options));
36
- if (options?.cwd && !existsSync(to_file_path(options.cwd))) {
37
- return false;
38
- }
39
- const result = await spawn(
40
- 'git',
41
- ['ls-remote', '--exit-code', '--heads', origin, 'refs/heads/' + final_branch],
42
- options,
43
- );
44
- if (result.ok) {
45
- return true;
46
- } else if (result.code === 2) {
47
- return false;
48
- } else {
49
- throw Error(
50
- `git_remote_branch_exists failed for origin '${origin}' and branch '${final_branch}' with code ${result.code}`,
51
- );
52
- }
53
- };
54
-
55
- /**
56
- * @returns a boolean indicating if the local git branch exists
57
- */
58
- export const git_local_branch_exists = async (
59
- branch: Git_Branch,
60
- options?: SpawnOptions,
61
- ): Promise<boolean> => {
62
- if (options?.cwd && !existsSync(to_file_path(options.cwd))) {
63
- return false;
64
- }
65
- const result = await spawn('git', ['show-ref', '--quiet', 'refs/heads/' + branch], options);
66
- return result.ok;
67
- };
68
-
69
- /**
70
- * TODO make this return an enum and separate the text into a different function
71
- * @returns an error message if the git workspace has any unstaged or uncommitted changes, or `null` if it's clean
72
- */
73
- export const git_check_clean_workspace = async (options?: SpawnOptions): Promise<string | null> => {
74
- const unstaged_result = await spawn('git', ['diff', '--exit-code', '--quiet'], options);
75
- if (!unstaged_result.ok) {
76
- return 'git has unstaged changes';
77
- }
78
- const staged_result = await spawn('git', ['diff', '--exit-code', '--cached', '--quiet'], options);
79
- if (!staged_result.ok) {
80
- return 'git has staged but uncommitted changes';
81
- }
82
- const status_result = await spawn_out('git', ['status', '--porcelain'], options);
83
- if (status_result.stdout?.length) {
84
- return 'git has untracked files';
85
- }
86
- return null;
87
- };
88
-
89
- /**
90
- * TODO make this return an enum and separate the text into a different function
91
- * @returns an error message if the git workspace has any unstaged stages, or `null` if it's clean
92
- */
93
- export const git_check_fully_staged_workspace = async (
94
- options?: SpawnOptions,
95
- ): Promise<string | null> => {
96
- const unstaged_result = await spawn('git', ['diff', '--exit-code', '--quiet'], options);
97
- if (!unstaged_result.ok) {
98
- return 'git has unstaged changes';
99
- }
100
- const status_result = await spawn_out('git', ['status', '--porcelain'], options);
101
- if (status_result.stdout?.includes('??')) {
102
- return 'git has untracked files';
103
- }
104
- return null;
105
- };
106
-
107
- /**
108
- * Calls `git fetch` and throws if anything goes wrong.
109
- */
110
- export const git_fetch = async (
111
- origin: Git_Origin = 'origin' as Git_Origin,
112
- branch?: Git_Branch,
113
- options?: SpawnOptions,
114
- ): Promise<void> => {
115
- const args = ['fetch', origin];
116
- if (branch) args.push(branch);
117
- const result = await spawn('git', args, options);
118
- if (!result.ok) {
119
- throw Error(
120
- `git_fetch failed for origin '${origin}' and branch '${branch}' with code ${result.code}`,
121
- );
122
- }
123
- };
124
-
125
- /**
126
- * Calls `git checkout` and throws if anything goes wrong.
127
- * @returns the previous branch name, if it changed
128
- */
129
- export const git_checkout = async (
130
- branch: Git_Branch,
131
- options?: SpawnOptions,
132
- ): Promise<Git_Branch | null> => {
133
- const current_branch = await git_current_branch_name(options);
134
- if (branch === current_branch) {
135
- return null;
136
- }
137
- const result = await spawn('git', ['checkout', branch], options);
138
- if (!result.ok) {
139
- throw Error(`git_checkout failed for branch '${branch}' with code ${result.code}`);
140
- }
141
- return current_branch;
142
- };
143
-
144
- /**
145
- * Calls `git pull` and throws if anything goes wrong.
146
- */
147
- export const git_pull = async (
148
- origin: Git_Origin = 'origin' as Git_Origin,
149
- branch?: Git_Branch,
150
- options?: SpawnOptions,
151
- ): Promise<void> => {
152
- const args = ['pull', origin];
153
- if (branch) args.push(branch);
154
- const result = await spawn('git', args, options);
155
- if (!result.ok) {
156
- throw Error(`git_pull failed for branch '${branch}' with code ${result.code}`);
157
- }
158
- };
159
-
160
- /**
161
- * Calls `git push` and throws if anything goes wrong.
162
- */
163
- export const git_push = async (
164
- origin: Git_Origin,
165
- branch?: Git_Branch,
166
- options?: SpawnOptions,
167
- set_upstream = false,
168
- ): Promise<void> => {
169
- const final_branch = branch ?? (await git_current_branch_name(options));
170
- const args = ['push', origin, final_branch];
171
- if (set_upstream) args.push('-u');
172
- const result = await spawn('git', args, options);
173
- if (!result.ok) {
174
- throw Error(`git_push failed for branch '${final_branch}' with code ${result.code}`);
175
- }
176
- };
177
-
178
- /**
179
- * Calls `git push` and throws if anything goes wrong.
180
- */
181
- export const git_push_to_create = async (
182
- origin: Git_Origin = 'origin' as Git_Origin,
183
- branch?: Git_Branch,
184
- options?: SpawnOptions,
185
- ): Promise<void> => {
186
- const final_branch = branch ?? (await git_current_branch_name(options));
187
- const push_args = ['push'];
188
- if (await git_remote_branch_exists(origin, final_branch, options)) {
189
- push_args.push(origin);
190
- } else {
191
- push_args.push('-u', origin);
192
- }
193
- push_args.push(final_branch);
194
- const result = await spawn('git', push_args, options);
195
- if (!result.ok) {
196
- throw Error(`git_push failed for branch '${final_branch}' with code ${result.code}`);
197
- }
198
- };
199
-
200
- /**
201
- * Deletes a branch locally and throws if anything goes wrong.
202
- */
203
- export const git_delete_local_branch = async (
204
- branch: Git_Branch,
205
- options?: SpawnOptions,
206
- ): Promise<void> => {
207
- const result = await spawn('git', ['branch', '-D', branch], options);
208
- if (!result.ok) {
209
- throw Error(`git_delete_local_branch failed for branch '${branch}' with code ${result.code}`);
210
- }
211
- };
212
-
213
- /**
214
- * Deletes a branch remotely and throws if anything goes wrong.
215
- */
216
- export const git_delete_remote_branch = async (
217
- origin: Git_Origin,
218
- branch: Git_Branch,
219
- options?: SpawnOptions,
220
- ): Promise<void> => {
221
- const result = await spawn('git', ['push', origin, ':' + branch], options);
222
- if (!result.ok) {
223
- throw Error(`git_delete_remote_branch failed for branch '${branch}' with code ${result.code}`);
224
- }
225
- };
226
-
227
- /**
228
- * Resets the `target` branch back to its first commit both locally and remotely.
229
- */
230
- export const git_reset_branch_to_first_commit = async (
231
- origin: Git_Origin,
232
- branch: Git_Branch,
233
- options?: SpawnOptions,
234
- ): Promise<void> => {
235
- const previous_branch = await git_checkout(branch, options);
236
- const first_commit_hash = await git_current_branch_first_commit_hash(options);
237
- await spawn('git', ['reset', '--hard', first_commit_hash], options);
238
- await spawn('git', ['push', origin, branch, '--force'], options);
239
- if (previous_branch) {
240
- await git_checkout(previous_branch, options);
241
- }
242
- };
243
-
244
- /**
245
- * Returns the branch's latest commit hash or throws if something goes wrong.
246
- */
247
- export const git_current_commit_hash = async (
248
- branch?: string,
249
- options?: SpawnOptions,
250
- ): Promise<string | null> => {
251
- const final_branch = branch ?? (await git_current_branch_name(options));
252
- const {stdout} = await spawn_out('git', ['show-ref', '-s', final_branch], options);
253
- if (!stdout) return null; // TODO hack for CI
254
- return stdout.split('\n')[0].trim();
255
- };
256
-
257
- /**
258
- * Returns the hash of the current branch's first commit or throws if something goes wrong.
259
- */
260
- export const git_current_branch_first_commit_hash = async (
261
- options?: SpawnOptions,
262
- ): Promise<string> => {
263
- const {stdout} = await spawn_out(
264
- 'git',
265
- ['rev-list', '--max-parents=0', '--abbrev-commit', 'HEAD'],
266
- options,
267
- );
268
- if (!stdout) throw Error('git_current_branch_first_commit_hash failed');
269
- return stdout.trim();
270
- };
271
-
272
- /**
273
- * Returns the global git config setting for `pull.rebase`.
274
- * Gro is currently written to expect `true`,
275
- * but the restriction could be loosened with additional work.
276
- */
277
- export const git_check_setting_pull_rebase = async (options?: SpawnOptions): Promise<boolean> => {
278
- const value = await spawn_out('git', ['config', '--global', 'pull.rebase'], options);
279
- return value.stdout?.trim() === 'true';
280
- };
281
-
282
- /**
283
- * Clones a branch locally to another directory and updates the origin to match the source.
284
- */
285
- export const git_clone_locally = async (
286
- origin: Git_Origin,
287
- branch: Git_Branch,
288
- source_dir: string,
289
- target_dir: string,
290
- options?: SpawnOptions,
291
- ): Promise<void> => {
292
- await spawn('git', ['clone', '-b', branch, '--single-branch', source_dir, target_dir], options);
293
- const origin_url = (
294
- await spawn_out('git', ['remote', 'get-url', origin], {...options, cwd: source_dir})
295
- ).stdout?.trim();
296
- if (!origin_url) throw Error('Failed to get the origin url with git in ' + source_dir);
297
- await spawn('git', ['remote', 'set-url', origin, origin_url], {...options, cwd: target_dir});
298
- };