@shopify/cli-kit 3.92.1 → 3.93.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.
- package/README.md +1 -1
- package/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.d.ts +16 -0
- package/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.js +60 -0
- package/dist/cli/api/graphql/admin/generated/find_development_theme_by_name.js.map +1 -0
- package/dist/private/node/api/graphql.d.ts +10 -0
- package/dist/private/node/api/graphql.js +67 -5
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/conf-store.d.ts +13 -0
- package/dist/private/node/conf-store.js +17 -3
- package/dist/private/node/conf-store.js.map +1 -1
- package/dist/private/node/constants.d.ts +3 -0
- package/dist/private/node/constants.js +3 -0
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/session/exchange.d.ts +22 -8
- package/dist/private/node/session/exchange.js +37 -14
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/schema.d.ts +62 -62
- package/dist/private/node/session/scopes.js +3 -2
- package/dist/private/node/session/scopes.js.map +1 -1
- package/dist/private/node/session/store.d.ts +7 -0
- package/dist/private/node/session/store.js +17 -0
- package/dist/private/node/session/store.js.map +1 -1
- package/dist/private/node/session/validate.d.ts +5 -4
- package/dist/private/node/session/validate.js +34 -7
- package/dist/private/node/session/validate.js.map +1 -1
- package/dist/private/node/session.d.ts +1 -1
- package/dist/private/node/session.js +77 -32
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/testing/ui.js +6 -4
- package/dist/private/node/testing/ui.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.test.js +5 -5
- package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.js +5 -2
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js +2 -2
- package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.test.js +10 -10
- package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
- package/dist/private/node/ui/components/Table/Table.js +2 -2
- package/dist/private/node/ui/components/Table/Table.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.test.js +6 -6
- package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
- package/dist/private/node/ui/components/TextAnimation.test.js +1 -1
- package/dist/private/node/ui/components/TextAnimation.test.js.map +1 -1
- package/dist/private/node/ui/components/TextInput.test.js +4 -4
- package/dist/private/node/ui/components/TextInput.test.js.map +1 -1
- package/dist/private/node/ui/components/TokenizedText.js +1 -0
- package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
- package/dist/private/node/ui/hooks/use-select-state.js +1 -3
- package/dist/private/node/ui/hooks/use-select-state.js.map +1 -1
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/analytics.js +4 -4
- package/dist/public/node/analytics.js.map +1 -1
- package/dist/public/node/api/admin.js +1 -3
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/rest-api-throttler.d.ts +14 -0
- package/dist/public/node/api/rest-api-throttler.js +14 -87
- package/dist/public/node/api/rest-api-throttler.js.map +1 -1
- package/dist/public/node/archiver.js +6 -7
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/cli-launcher.d.ts +1 -1
- package/dist/public/node/cli-launcher.js +9 -9
- package/dist/public/node/cli-launcher.js.map +1 -1
- package/dist/public/node/cli.js +4 -1
- package/dist/public/node/cli.js.map +1 -1
- package/dist/public/node/context/fqdn.js +1 -0
- package/dist/public/node/context/fqdn.js.map +1 -1
- package/dist/public/node/context/local.d.ts +7 -0
- package/dist/public/node/context/local.js +9 -0
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/dot-env.js +1 -1
- package/dist/public/node/dot-env.js.map +1 -1
- package/dist/public/node/environment.d.ts +4 -9
- package/dist/public/node/environment.js +6 -12
- package/dist/public/node/environment.js.map +1 -1
- package/dist/public/node/environments.js +4 -3
- package/dist/public/node/environments.js.map +1 -1
- package/dist/public/node/error-handler.js +1 -1
- package/dist/public/node/error-handler.js.map +1 -1
- package/dist/public/node/error.js +1 -0
- package/dist/public/node/error.js.map +1 -1
- package/dist/public/node/fs.d.ts +9 -1
- package/dist/public/node/fs.js +16 -4
- package/dist/public/node/fs.js.map +1 -1
- package/dist/public/node/git.d.ts +10 -4
- package/dist/public/node/git.js +101 -80
- package/dist/public/node/git.js.map +1 -1
- package/dist/public/node/global-context.js +1 -3
- package/dist/public/node/global-context.js.map +1 -1
- package/dist/public/node/hooks/postrun.d.ts +7 -0
- package/dist/public/node/hooks/postrun.js +61 -1
- package/dist/public/node/hooks/postrun.js.map +1 -1
- package/dist/public/node/hooks/prerun.d.ts +3 -2
- package/dist/public/node/hooks/prerun.js +9 -22
- package/dist/public/node/hooks/prerun.js.map +1 -1
- package/dist/public/node/http.js +1 -1
- package/dist/public/node/http.js.map +1 -1
- package/dist/public/node/import-extractor.d.ts +17 -0
- package/dist/public/node/import-extractor.js +84 -23
- package/dist/public/node/import-extractor.js.map +1 -1
- package/dist/public/node/is-global.d.ts +9 -1
- package/dist/public/node/is-global.js +55 -12
- package/dist/public/node/is-global.js.map +1 -1
- package/dist/public/node/mimes.js +1 -1
- package/dist/public/node/mimes.js.map +1 -1
- package/dist/public/node/node-package-manager.d.ts +1 -1
- package/dist/public/node/node-package-manager.js +4 -1
- package/dist/public/node/node-package-manager.js.map +1 -1
- package/dist/public/node/os.js +1 -0
- package/dist/public/node/os.js.map +1 -1
- package/dist/public/node/output.js +3 -2
- package/dist/public/node/output.js.map +1 -1
- package/dist/public/node/path.d.ts +11 -0
- package/dist/public/node/path.js +30 -1
- package/dist/public/node/path.js.map +1 -1
- package/dist/public/node/result.js +1 -0
- package/dist/public/node/result.js.map +1 -1
- package/dist/public/node/serial-batch-processor.js +1 -3
- package/dist/public/node/serial-batch-processor.js.map +1 -1
- package/dist/public/node/session-prompt.js +10 -2
- package/dist/public/node/session-prompt.js.map +1 -1
- package/dist/public/node/session.js +6 -6
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +1 -0
- package/dist/public/node/themes/api.js +26 -0
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/conf.js +3 -5
- package/dist/public/node/themes/conf.js.map +1 -1
- package/dist/public/node/themes/factories.js +1 -0
- package/dist/public/node/themes/factories.js.map +1 -1
- package/dist/public/node/themes/theme-manager.d.ts +2 -2
- package/dist/public/node/themes/theme-manager.js +13 -8
- package/dist/public/node/themes/theme-manager.js.map +1 -1
- package/dist/public/node/{toml.d.ts → toml/codec.d.ts} +1 -1
- package/dist/public/node/{toml.js → toml/codec.js} +1 -1
- package/dist/public/node/toml/codec.js.map +1 -0
- package/dist/public/node/toml/index.d.ts +1 -0
- package/dist/public/node/toml/index.js +2 -0
- package/dist/public/node/toml/index.js.map +1 -0
- package/dist/public/node/toml/toml-file.d.ts +88 -0
- package/dist/public/node/toml/toml-file.js +159 -0
- package/dist/public/node/toml/toml-file.js.map +1 -0
- package/dist/public/node/tree-kill.js +1 -1
- package/dist/public/node/tree-kill.js.map +1 -1
- package/dist/public/node/ui.js +1 -0
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/upgrade.d.ts +28 -1
- package/dist/public/node/upgrade.js +184 -16
- package/dist/public/node/upgrade.js.map +1 -1
- package/dist/public/node/version.d.ts +9 -0
- package/dist/public/node/version.js +16 -1
- package/dist/public/node/version.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/dist/public/node/custom-oclif-loader.d.ts +0 -6
- package/dist/public/node/custom-oclif-loader.js +0 -79
- package/dist/public/node/custom-oclif-loader.js.map +0 -1
- package/dist/public/node/toml.js.map +0 -1
package/dist/public/node/git.js
CHANGED
|
@@ -4,8 +4,25 @@ import { appendFileSync, detectEOL, fileExists, fileExistsSync, glob, isDirector
|
|
|
4
4
|
import { AbortError } from './error.js';
|
|
5
5
|
import { cwd, joinPath } from './path.js';
|
|
6
6
|
import { runWithTimer } from './metadata.js';
|
|
7
|
-
import
|
|
7
|
+
import { execa } from 'execa';
|
|
8
8
|
import ignore from 'ignore';
|
|
9
|
+
async function gitCommand(args, directory) {
|
|
10
|
+
try {
|
|
11
|
+
const result = await execa('git', args, { cwd: directory });
|
|
12
|
+
return result.stdout;
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
if (err instanceof Error) {
|
|
16
|
+
const abortError = new AbortError(err.message);
|
|
17
|
+
abortError.stack = err.stack;
|
|
18
|
+
if ('exitCode' in err) {
|
|
19
|
+
Object.assign(abortError, { exitCode: err.exitCode });
|
|
20
|
+
}
|
|
21
|
+
throw abortError;
|
|
22
|
+
}
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
9
26
|
/**
|
|
10
27
|
* Initialize a git repository at the given directory.
|
|
11
28
|
*
|
|
@@ -16,10 +33,8 @@ export async function initializeGitRepository(directory, initialBranch = 'main')
|
|
|
16
33
|
outputDebug(outputContent `Initializing git repository at ${outputToken.path(directory)}...`);
|
|
17
34
|
await ensureGitIsPresentOrAbort();
|
|
18
35
|
// We use init and checkout instead of `init --initial-branch` because the latter is only supported in git 2.28+
|
|
19
|
-
await
|
|
20
|
-
|
|
21
|
-
await repo.checkoutLocalBranch(initialBranch);
|
|
22
|
-
});
|
|
36
|
+
await gitCommand(['init'], directory);
|
|
37
|
+
await gitCommand(['checkout', '-b', initialBranch], directory);
|
|
23
38
|
}
|
|
24
39
|
/**
|
|
25
40
|
* Given a Git repository and a list of absolute paths to files contained
|
|
@@ -31,7 +46,16 @@ export async function initializeGitRepository(directory, initialBranch = 'main')
|
|
|
31
46
|
* @returns Files ignored by the lockfile.
|
|
32
47
|
*/
|
|
33
48
|
export async function checkIfIgnoredInGitRepository(directory, files) {
|
|
34
|
-
|
|
49
|
+
try {
|
|
50
|
+
const stdout = await gitCommand(['check-ignore', ...files], directory);
|
|
51
|
+
return stdout.split('\n').filter(Boolean);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// git check-ignore exits with code 1 when no files are ignored
|
|
55
|
+
if (error instanceof AbortError && 'exitCode' in error && error.exitCode === 1)
|
|
56
|
+
return [];
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
35
59
|
}
|
|
36
60
|
/**
|
|
37
61
|
* Create a .gitignore file in the given directory.
|
|
@@ -90,7 +114,7 @@ export function addToGitIgnore(root, entry) {
|
|
|
90
114
|
*/
|
|
91
115
|
export async function downloadGitRepository(cloneOptions) {
|
|
92
116
|
return runWithTimer('cmd_all_timing_network_ms')(async () => {
|
|
93
|
-
const { repoUrl, destination,
|
|
117
|
+
const { repoUrl, destination, shallow, latestTag } = cloneOptions;
|
|
94
118
|
outputDebug(outputContent `Git-cloning repository ${repoUrl} into ${outputToken.path(destination)}...`);
|
|
95
119
|
await ensureGitIsPresentOrAbort();
|
|
96
120
|
// Validate destination directory before attempting to clone
|
|
@@ -110,40 +134,34 @@ export async function downloadGitRepository(cloneOptions) {
|
|
|
110
134
|
}
|
|
111
135
|
}
|
|
112
136
|
const [repository, branch] = repoUrl.split('#');
|
|
113
|
-
const options = { '--recurse-submodules': null };
|
|
114
137
|
if (branch && latestTag) {
|
|
115
138
|
throw new AbortError("Error cloning the repository. Git can't clone the latest release with a 'branch'.");
|
|
116
139
|
}
|
|
117
|
-
if (branch) {
|
|
118
|
-
options['--branch'] = branch;
|
|
119
|
-
}
|
|
120
140
|
if (shallow && latestTag) {
|
|
121
141
|
throw new AbortError("Error cloning the repository. Git can't clone the latest release with the 'shallow' property.");
|
|
122
142
|
}
|
|
143
|
+
const args = ['clone', '--recurse-submodules'];
|
|
144
|
+
if (branch) {
|
|
145
|
+
args.push('--branch', branch);
|
|
146
|
+
}
|
|
123
147
|
if (shallow) {
|
|
124
|
-
|
|
148
|
+
args.push('--depth', '1');
|
|
149
|
+
}
|
|
150
|
+
if (!isTerminalInteractive()) {
|
|
151
|
+
args.push('-c', 'core.askpass=true');
|
|
125
152
|
}
|
|
126
|
-
|
|
127
|
-
const updateString = `${stage}, ${processed}/${total} objects (${progress}% complete)`;
|
|
128
|
-
if (progressUpdater)
|
|
129
|
-
progressUpdater(updateString);
|
|
130
|
-
};
|
|
131
|
-
const simpleGitOptions = {
|
|
132
|
-
progress,
|
|
133
|
-
...(!isTerminalInteractive() && { config: ['core.askpass=true'] }),
|
|
134
|
-
};
|
|
153
|
+
args.push(repository, destination);
|
|
135
154
|
try {
|
|
136
|
-
|
|
137
|
-
// @ts-ignore
|
|
138
|
-
await git(simpleGitOptions).clone(repository, destination, options);
|
|
155
|
+
await execa('git', args);
|
|
139
156
|
if (latestTag) {
|
|
140
|
-
await
|
|
141
|
-
|
|
142
|
-
await localGitRepository.checkout(latestTag);
|
|
143
|
-
});
|
|
157
|
+
const tag = await getLatestTagFromDirectory(destination, repoUrl);
|
|
158
|
+
await gitCommand(['checkout', tag], destination);
|
|
144
159
|
}
|
|
145
160
|
}
|
|
146
161
|
catch (err) {
|
|
162
|
+
if (err instanceof AbortError) {
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
147
165
|
if (err instanceof Error) {
|
|
148
166
|
const abortError = new AbortError(err.message);
|
|
149
167
|
abortError.stack = err.stack;
|
|
@@ -153,19 +171,13 @@ export async function downloadGitRepository(cloneOptions) {
|
|
|
153
171
|
}
|
|
154
172
|
});
|
|
155
173
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
* @param repoUrl - The URL of the repository.
|
|
161
|
-
* @returns The most recent tag of the repository.
|
|
162
|
-
*/
|
|
163
|
-
async function getLocalLatestTag(repository, repoUrl) {
|
|
164
|
-
const latest = (await repository.tags()).latest;
|
|
165
|
-
if (!latest) {
|
|
174
|
+
async function getLatestTagFromDirectory(directory, repoUrl) {
|
|
175
|
+
const stdout = await gitCommand(['describe', '--tags', '--abbrev=0'], directory);
|
|
176
|
+
const tag = stdout.trim();
|
|
177
|
+
if (!tag) {
|
|
166
178
|
throw new AbortError(`Couldn't obtain the most recent tag of the repository ${repoUrl}`);
|
|
167
179
|
}
|
|
168
|
-
return
|
|
180
|
+
return tag;
|
|
169
181
|
}
|
|
170
182
|
/**
|
|
171
183
|
* Get the latest commit of a git repository.
|
|
@@ -174,11 +186,21 @@ async function getLocalLatestTag(repository, repoUrl) {
|
|
|
174
186
|
* @returns The latest commit of the repository.
|
|
175
187
|
*/
|
|
176
188
|
export async function getLatestGitCommit(directory) {
|
|
177
|
-
const
|
|
178
|
-
|
|
189
|
+
const format = '%H%x00%ai%x00%s%x00%D%x00%b%x00%an%x00%ae';
|
|
190
|
+
const stdout = await gitCommand(['log', '-1', `--format=${format}`], directory);
|
|
191
|
+
if (!stdout.trim()) {
|
|
179
192
|
throw new AbortError('Must have at least one commit to run command', outputContent `Run ${outputToken.genericShellCommand("git commit -m 'Initial commit'")} to create your first commit.`);
|
|
180
193
|
}
|
|
181
|
-
|
|
194
|
+
const parts = stdout.split('\x00');
|
|
195
|
+
return {
|
|
196
|
+
hash: parts[0],
|
|
197
|
+
date: parts[1],
|
|
198
|
+
message: parts[2],
|
|
199
|
+
refs: parts[3],
|
|
200
|
+
body: parts[4],
|
|
201
|
+
author_name: parts[5],
|
|
202
|
+
author_email: parts[6],
|
|
203
|
+
};
|
|
182
204
|
}
|
|
183
205
|
/**
|
|
184
206
|
* Add all files to the git index from the given directory.
|
|
@@ -187,7 +209,7 @@ export async function getLatestGitCommit(directory) {
|
|
|
187
209
|
* @returns A promise that resolves when the files are added to the index.
|
|
188
210
|
*/
|
|
189
211
|
export async function addAllToGitFromDirectory(directory) {
|
|
190
|
-
await
|
|
212
|
+
await gitCommand(['add', '--all'], directory);
|
|
191
213
|
}
|
|
192
214
|
/**
|
|
193
215
|
* Create a git commit.
|
|
@@ -197,9 +219,13 @@ export async function addAllToGitFromDirectory(directory) {
|
|
|
197
219
|
* @returns The hash of the created commit.
|
|
198
220
|
*/
|
|
199
221
|
export async function createGitCommit(message, options) {
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
222
|
+
const args = ['commit', '-m', message];
|
|
223
|
+
if (options?.author) {
|
|
224
|
+
args.push('--author', options.author);
|
|
225
|
+
}
|
|
226
|
+
await gitCommand(args, options?.directory);
|
|
227
|
+
const stdout = await gitCommand(['rev-parse', 'HEAD'], options?.directory);
|
|
228
|
+
return stdout.trim();
|
|
203
229
|
}
|
|
204
230
|
/**
|
|
205
231
|
* Get the HEAD symbolic reference of a git repository.
|
|
@@ -208,7 +234,7 @@ export async function createGitCommit(message, options) {
|
|
|
208
234
|
* @returns The HEAD symbolic reference of the repository.
|
|
209
235
|
*/
|
|
210
236
|
export async function getHeadSymbolicRef(directory) {
|
|
211
|
-
const ref = await
|
|
237
|
+
const ref = await gitCommand(['symbolic-ref', '-q', 'HEAD'], directory);
|
|
212
238
|
if (!ref) {
|
|
213
239
|
throw new AbortError("Git HEAD can't be detached to run command", outputContent `Run ${outputToken.genericShellCommand('git checkout [branchName]')} to reattach HEAD or see git ${outputToken.link('documentation', 'https://git-scm.com/book/en/v2/Git-Internals-Git-References')} for more details`);
|
|
214
240
|
}
|
|
@@ -232,10 +258,8 @@ export class OutsideGitDirectoryError extends AbortError {
|
|
|
232
258
|
* @param directory - The directory to check.
|
|
233
259
|
*/
|
|
234
260
|
export async function ensureInsideGitDirectory(directory) {
|
|
235
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
236
|
-
// @ts-ignore
|
|
237
261
|
if (!(await insideGitDirectory(directory))) {
|
|
238
|
-
throw new OutsideGitDirectoryError(`${outputToken.path(directory
|
|
262
|
+
throw new OutsideGitDirectoryError(`${outputToken.path(directory ?? cwd())} is not a Git directory`);
|
|
239
263
|
}
|
|
240
264
|
}
|
|
241
265
|
/**
|
|
@@ -245,7 +269,15 @@ export async function ensureInsideGitDirectory(directory) {
|
|
|
245
269
|
* @returns True if the directory is inside a .git directory tree.
|
|
246
270
|
*/
|
|
247
271
|
export async function insideGitDirectory(directory) {
|
|
248
|
-
|
|
272
|
+
try {
|
|
273
|
+
await execa('git', ['rev-parse', '--git-dir'], { cwd: directory });
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
if (error instanceof Error && 'exitCode' in error && error.exitCode === 128)
|
|
278
|
+
return false;
|
|
279
|
+
throw error;
|
|
280
|
+
}
|
|
249
281
|
}
|
|
250
282
|
export class GitDirectoryNotCleanError extends AbortError {
|
|
251
283
|
}
|
|
@@ -257,7 +289,7 @@ export class GitDirectoryNotCleanError extends AbortError {
|
|
|
257
289
|
*/
|
|
258
290
|
export async function ensureIsClean(directory) {
|
|
259
291
|
if (!(await isClean(directory))) {
|
|
260
|
-
throw new GitDirectoryNotCleanError(`${outputToken.path(directory
|
|
292
|
+
throw new GitDirectoryNotCleanError(`${outputToken.path(directory ?? cwd())} is not a clean Git directory`);
|
|
261
293
|
}
|
|
262
294
|
}
|
|
263
295
|
/**
|
|
@@ -267,7 +299,8 @@ export async function ensureIsClean(directory) {
|
|
|
267
299
|
* @returns True is the .git directory is clean.
|
|
268
300
|
*/
|
|
269
301
|
export async function isClean(directory) {
|
|
270
|
-
|
|
302
|
+
const stdout = await gitCommand(['status', '--porcelain'], directory);
|
|
303
|
+
return stdout.trim() === '';
|
|
271
304
|
}
|
|
272
305
|
/**
|
|
273
306
|
* Returns the latest tag of a git repository.
|
|
@@ -276,8 +309,15 @@ export async function isClean(directory) {
|
|
|
276
309
|
* @returns String with the latest tag or undefined if no tags are found.
|
|
277
310
|
*/
|
|
278
311
|
export async function getLatestTag(directory) {
|
|
279
|
-
|
|
280
|
-
|
|
312
|
+
try {
|
|
313
|
+
const stdout = await gitCommand(['describe', '--tags', '--abbrev=0'], directory);
|
|
314
|
+
return stdout.trim() || undefined;
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (error instanceof AbortError && 'exitCode' in error && error.exitCode === 128)
|
|
318
|
+
return undefined;
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
281
321
|
}
|
|
282
322
|
/**
|
|
283
323
|
* Remove a git remote from the given directory.
|
|
@@ -289,31 +329,12 @@ export async function getLatestTag(directory) {
|
|
|
289
329
|
export async function removeGitRemote(directory, remoteName = 'origin') {
|
|
290
330
|
outputDebug(outputContent `Removing git remote ${remoteName} from ${outputToken.path(directory)}...`);
|
|
291
331
|
await ensureGitIsPresentOrAbort();
|
|
292
|
-
await
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
outputDebug(outputContent `Remote ${remoteName} does not exist, no action needed`);
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
await repo.removeRemote(remoteName);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
async function withGit({ directory, }, callback) {
|
|
304
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
305
|
-
// @ts-ignore
|
|
306
|
-
const repo = git({ baseDir: directory });
|
|
307
|
-
try {
|
|
308
|
-
return await callback(repo);
|
|
309
|
-
}
|
|
310
|
-
catch (err) {
|
|
311
|
-
if (err instanceof Error) {
|
|
312
|
-
const abortError = new AbortError(err.message);
|
|
313
|
-
abortError.stack = err.stack;
|
|
314
|
-
throw abortError;
|
|
315
|
-
}
|
|
316
|
-
throw err;
|
|
332
|
+
const stdout = await gitCommand(['remote'], directory);
|
|
333
|
+
const remotes = stdout.split('\n').filter(Boolean);
|
|
334
|
+
if (!remotes.includes(remoteName)) {
|
|
335
|
+
outputDebug(outputContent `Remote ${remoteName} does not exist, no action needed`);
|
|
336
|
+
return;
|
|
317
337
|
}
|
|
338
|
+
await gitCommand(['remote', 'remove', remoteName], directory);
|
|
318
339
|
}
|
|
319
340
|
//# sourceMappingURL=git.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/public/node/git.ts"],"names":[],"mappings":"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","sourcesContent":["import {outputContent, outputToken, outputDebug} from './output.js'\nimport {hasGit, isTerminalInteractive} from './context/local.js'\nimport {\n appendFileSync,\n detectEOL,\n fileExists,\n fileExistsSync,\n glob,\n isDirectory,\n readFileSync,\n writeFileSync,\n} from './fs.js'\nimport {AbortError} from './error.js'\nimport {cwd, joinPath} from './path.js'\nimport {runWithTimer} from './metadata.js'\nimport git, {TaskOptions, SimpleGitProgressEvent, DefaultLogFields, ListLogLine, SimpleGit} from 'simple-git'\n\nimport ignore from 'ignore'\n\n/**\n * Initialize a git repository at the given directory.\n *\n * @param directory - The directory where the git repository will be initialized.\n * @param initialBranch - The name of the initial branch.\n */\nexport async function initializeGitRepository(directory: string, initialBranch = 'main'): Promise<void> {\n outputDebug(outputContent`Initializing git repository at ${outputToken.path(directory)}...`)\n await ensureGitIsPresentOrAbort()\n // We use init and checkout instead of `init --initial-branch` because the latter is only supported in git 2.28+\n await withGit({directory}, async (repo) => {\n await repo.init()\n await repo.checkoutLocalBranch(initialBranch)\n })\n}\n\n/**\n * Given a Git repository and a list of absolute paths to files contained\n * in the repository, it filters and returns the files that are ignored\n * by the .gitignore.\n *\n * @param directory - The absolute path to the directory containing the files.\n * @param files - The list of files to check against.\n * @returns Files ignored by the lockfile.\n */\nexport async function checkIfIgnoredInGitRepository(directory: string, files: string[]): Promise<string[]> {\n return withGit({directory}, (repo) => repo.checkIgnore(files))\n}\n\nexport type GitIgnoreTemplate = Record<string, string[]>\n/**\n * Create a .gitignore file in the given directory.\n *\n * @param directory - The directory where the .gitignore file will be created.\n * @param template - The template to use to create the .gitignore file.\n */\nexport function createGitIgnore(directory: string, template: GitIgnoreTemplate): void {\n outputDebug(outputContent`Creating .gitignore at ${outputToken.path(directory)}...`)\n const filePath = `${directory}/.gitignore`\n\n let fileContent = ''\n for (const [section, lines] of Object.entries(template)) {\n fileContent += `# ${section}\\n`\n fileContent += `${lines.join('\\n')}\\n\\n`\n }\n\n appendFileSync(filePath, fileContent)\n}\n\n/**\n * Add an entry to an existing .gitignore file.\n *\n * If the .gitignore file doesn't exist, or if the entry is already present,\n * no changes will be made.\n *\n * @param root - The directory containing the .gitignore file.\n * @param entry - The entry to add to the .gitignore file.\n */\nexport function addToGitIgnore(root: string, entry: string): void {\n const gitIgnorePath = joinPath(root, '.gitignore')\n\n if (!fileExistsSync(gitIgnorePath)) {\n // When the .gitignore file does not exist, the CLI should not be opinionated about creating it\n return\n }\n\n const gitIgnoreContent = readFileSync(gitIgnorePath).toString()\n const eol = detectEOL(gitIgnoreContent)\n\n const lines = gitIgnoreContent.split(eol).map((line) => line.trim())\n const ignoreManager = ignore.default({allowRelativePaths: true}).add(lines)\n\n const isIgnoredEntry = ignoreManager.ignores(joinPath(entry))\n const isIgnoredEntryAsDir = ignoreManager.ignores(joinPath(entry, 'ignored.txt'))\n const isAlreadyIgnored = isIgnoredEntry || isIgnoredEntryAsDir\n if (isAlreadyIgnored) {\n // The file is already ignored by an existing pattern\n return\n }\n\n if (gitIgnoreContent.endsWith(eol)) {\n writeFileSync(gitIgnorePath, `${gitIgnoreContent}${entry}${eol}`)\n } else {\n writeFileSync(gitIgnorePath, `${gitIgnoreContent}${eol}${entry}${eol}`)\n }\n}\n\n/**\n * Options to use when cloning a git repository.\n *\n * @param repoUrl - The URL of the repository to clone.\n * @param destination - The directory where the repository will be cloned.\n * @param progressUpdater - A function that will be called with the progress of the clone.\n * @param shallow - Whether to clone the repository shallowly.\n * @param latestTag - Whether to clone the latest tag instead of the default branch.\n */\nexport interface GitCloneOptions {\n repoUrl: string\n destination: string\n progressUpdater?: (statusString: string) => void\n shallow?: boolean\n latestTag?: boolean\n}\n/**\n * Clone a git repository.\n *\n * @param cloneOptions - The options to use to clone the repository.\n * @returns A promise that resolves when the clone is complete.\n */\nexport async function downloadGitRepository(cloneOptions: GitCloneOptions): Promise<void> {\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n const {repoUrl, destination, progressUpdater, shallow, latestTag} = cloneOptions\n outputDebug(outputContent`Git-cloning repository ${repoUrl} into ${outputToken.path(destination)}...`)\n await ensureGitIsPresentOrAbort()\n\n // Validate destination directory before attempting to clone\n if (await fileExists(destination)) {\n // Check if it's a directory\n if (!(await isDirectory(destination))) {\n throw new AbortError(\n outputContent`Can't clone to ${outputToken.path(destination)}`,\n \"The path exists but isn't a directory.\",\n )\n }\n\n // Check if directory is empty\n const entries = await glob(['*', '.*'], {\n cwd: destination,\n deep: 1,\n onlyFiles: false,\n })\n\n if (entries.length > 0) {\n throw new AbortError(\n outputContent`Directory ${outputToken.path(destination)} already exists and is not empty`,\n outputContent`Choose a different name or remove the existing directory first.`,\n )\n }\n }\n\n const [repository, branch] = repoUrl.split('#')\n const options: TaskOptions = {'--recurse-submodules': null}\n\n if (branch && latestTag) {\n throw new AbortError(\"Error cloning the repository. Git can't clone the latest release with a 'branch'.\")\n }\n if (branch) {\n options['--branch'] = branch\n }\n\n if (shallow && latestTag) {\n throw new AbortError(\n \"Error cloning the repository. Git can't clone the latest release with the 'shallow' property.\",\n )\n }\n if (shallow) {\n options['--depth'] = 1\n }\n\n const progress = ({stage, progress, processed, total}: SimpleGitProgressEvent) => {\n const updateString = `${stage}, ${processed}/${total} objects (${progress}% complete)`\n if (progressUpdater) progressUpdater(updateString)\n }\n\n const simpleGitOptions = {\n progress,\n ...(!isTerminalInteractive() && {config: ['core.askpass=true']}),\n }\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n\n await git(simpleGitOptions).clone(repository!, destination, options)\n\n if (latestTag) {\n await withGit({directory: destination}, async (localGitRepository) => {\n const latestTag = await getLocalLatestTag(localGitRepository, repoUrl)\n await localGitRepository.checkout(latestTag)\n })\n }\n } catch (err) {\n if (err instanceof Error) {\n const abortError = new AbortError(err.message)\n abortError.stack = err.stack\n throw abortError\n }\n throw err\n }\n })\n}\n\n/**\n * Get the most recent tag of a local git repository.\n *\n * @param repository - The local git repository.\n * @param repoUrl - The URL of the repository.\n * @returns The most recent tag of the repository.\n */\nasync function getLocalLatestTag(repository: SimpleGit, repoUrl: string): Promise<string> {\n const latest = (await repository.tags()).latest\n\n if (!latest) {\n throw new AbortError(`Couldn't obtain the most recent tag of the repository ${repoUrl}`)\n }\n\n return latest\n}\n\n/**\n * Get the latest commit of a git repository.\n *\n * @param directory - The directory of the git repository.\n * @returns The latest commit of the repository.\n */\nexport async function getLatestGitCommit(directory?: string): Promise<DefaultLogFields & ListLogLine> {\n const logs = await withGit({directory}, (repo) => repo.log({maxCount: 1}))\n if (!logs.latest) {\n throw new AbortError(\n 'Must have at least one commit to run command',\n outputContent`Run ${outputToken.genericShellCommand(\n \"git commit -m 'Initial commit'\",\n )} to create your first commit.`,\n )\n }\n return logs.latest\n}\n\n/**\n * Add all files to the git index from the given directory.\n *\n * @param directory - The directory where the git repository is located.\n * @returns A promise that resolves when the files are added to the index.\n */\nexport async function addAllToGitFromDirectory(directory?: string): Promise<void> {\n await withGit({directory}, (repo) => repo.raw('add', '--all'))\n}\n\nexport interface CreateGitCommitOptions {\n directory?: string\n author?: string\n}\n\n/**\n * Create a git commit.\n *\n * @param message - The message of the commit.\n * @param options - The options to use to create the commit.\n * @returns The hash of the created commit.\n */\nexport async function createGitCommit(message: string, options?: CreateGitCommitOptions): Promise<string> {\n const commitOptions = options?.author ? {'--author': options.author} : undefined\n const result = await withGit({directory: options?.directory}, (repo) => repo.commit(message, commitOptions))\n return result.commit\n}\n\n/**\n * Get the HEAD symbolic reference of a git repository.\n *\n * @param directory - The directory of the git repository.\n * @returns The HEAD symbolic reference of the repository.\n */\nexport async function getHeadSymbolicRef(directory?: string): Promise<string> {\n const ref = await withGit({directory}, (repo) => repo.raw('symbolic-ref', '-q', 'HEAD'))\n if (!ref) {\n throw new AbortError(\n \"Git HEAD can't be detached to run command\",\n outputContent`Run ${outputToken.genericShellCommand(\n 'git checkout [branchName]',\n )} to reattach HEAD or see git ${outputToken.link(\n 'documentation',\n 'https://git-scm.com/book/en/v2/Git-Internals-Git-References',\n )} for more details`,\n )\n }\n return ref.trim()\n}\n\n/**\n * If \"git\" is not present in the environment it throws\n * an abort error.\n */\nexport async function ensureGitIsPresentOrAbort(): Promise<void> {\n if (!(await hasGit())) {\n throw new AbortError(\n `Git is necessary in the environment to continue`,\n outputContent`Install ${outputToken.link(\n 'git',\n 'https://git-scm.com/book/en/v2/Getting-Started-Installing-Git',\n )}`,\n )\n }\n}\n\nexport class OutsideGitDirectoryError extends AbortError {}\n/**\n * If command run from outside a .git directory tree\n * it throws an abort error.\n *\n * @param directory - The directory to check.\n */\nexport async function ensureInsideGitDirectory(directory?: string): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (!(await insideGitDirectory(directory))) {\n throw new OutsideGitDirectoryError(`${outputToken.path(directory || cwd())} is not a Git directory`)\n }\n}\n\n/**\n * Returns true if the given directory is inside a .git directory tree.\n *\n * @param directory - The directory to check.\n * @returns True if the directory is inside a .git directory tree.\n */\nexport async function insideGitDirectory(directory?: string): Promise<boolean> {\n return withGit({directory}, (repo) => repo.checkIsRepo())\n}\n\nexport class GitDirectoryNotCleanError extends AbortError {}\n/**\n * If the .git directory tree is not clean (has uncommitted changes)\n * it throws an abort error.\n *\n * @param directory - The directory to check.\n */\nexport async function ensureIsClean(directory?: string): Promise<void> {\n if (!(await isClean(directory))) {\n throw new GitDirectoryNotCleanError(`${outputToken.path(directory || cwd())} is not a clean Git directory`)\n }\n}\n\n/**\n * Returns true if the .git directory tree is clean (no uncommitted changes).\n *\n * @param directory - The directory to check.\n * @returns True is the .git directory is clean.\n */\nexport async function isClean(directory?: string): Promise<boolean> {\n return (await withGit({directory}, (git: SimpleGit) => git.status())).isClean()\n}\n\n/**\n * Returns the latest tag of a git repository.\n *\n * @param directory - The directory to check.\n * @returns String with the latest tag or undefined if no tags are found.\n */\nexport async function getLatestTag(directory?: string): Promise<string | undefined> {\n const tags = await withGit({directory}, (repo) => repo.tags())\n return tags.latest\n}\n\n/**\n * Remove a git remote from the given directory.\n *\n * @param directory - The directory where the git repository is located.\n * @param remoteName - The name of the remote to remove (defaults to 'origin').\n * @returns A promise that resolves when the remote is removed.\n */\nexport async function removeGitRemote(directory: string, remoteName = 'origin'): Promise<void> {\n outputDebug(outputContent`Removing git remote ${remoteName} from ${outputToken.path(directory)}...`)\n await ensureGitIsPresentOrAbort()\n\n await withGit({directory}, async (repo) => {\n // Check if remote exists first\n const remotes = await repo.getRemotes()\n const remoteExists = remotes.some((remote: {name: string}) => remote.name === remoteName)\n\n if (!remoteExists) {\n outputDebug(outputContent`Remote ${remoteName} does not exist, no action needed`)\n return\n }\n\n await repo.removeRemote(remoteName)\n })\n}\n\nasync function withGit<T>(\n {\n directory,\n }: {\n directory?: string\n },\n callback: (git: SimpleGit) => Promise<T>,\n): Promise<T> {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const repo = git({baseDir: directory})\n try {\n return await callback(repo)\n } catch (err) {\n if (err instanceof Error) {\n const abortError = new AbortError(err.message)\n abortError.stack = err.stack\n throw abortError\n }\n throw err\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/public/node/git.ts"],"names":[],"mappings":"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","sourcesContent":["import {outputContent, outputToken, outputDebug} from './output.js'\nimport {hasGit, isTerminalInteractive} from './context/local.js'\nimport {\n appendFileSync,\n detectEOL,\n fileExists,\n fileExistsSync,\n glob,\n isDirectory,\n readFileSync,\n writeFileSync,\n} from './fs.js'\nimport {AbortError} from './error.js'\nimport {cwd, joinPath} from './path.js'\nimport {runWithTimer} from './metadata.js'\nimport {execa} from 'execa'\n\nimport ignore from 'ignore'\n\nexport interface GitLogEntry {\n hash: string\n date: string\n message: string\n refs: string\n body: string\n author_name: string\n author_email: string\n}\n\nasync function gitCommand(args: string[], directory?: string): Promise<string> {\n try {\n const result = await execa('git', args, {cwd: directory})\n return result.stdout\n } catch (err) {\n if (err instanceof Error) {\n const abortError = new AbortError(err.message)\n abortError.stack = err.stack\n if ('exitCode' in err) {\n Object.assign(abortError, {exitCode: err.exitCode})\n }\n throw abortError\n }\n throw err\n }\n}\n\n/**\n * Initialize a git repository at the given directory.\n *\n * @param directory - The directory where the git repository will be initialized.\n * @param initialBranch - The name of the initial branch.\n */\nexport async function initializeGitRepository(directory: string, initialBranch = 'main'): Promise<void> {\n outputDebug(outputContent`Initializing git repository at ${outputToken.path(directory)}...`)\n await ensureGitIsPresentOrAbort()\n // We use init and checkout instead of `init --initial-branch` because the latter is only supported in git 2.28+\n await gitCommand(['init'], directory)\n await gitCommand(['checkout', '-b', initialBranch], directory)\n}\n\n/**\n * Given a Git repository and a list of absolute paths to files contained\n * in the repository, it filters and returns the files that are ignored\n * by the .gitignore.\n *\n * @param directory - The absolute path to the directory containing the files.\n * @param files - The list of files to check against.\n * @returns Files ignored by the lockfile.\n */\nexport async function checkIfIgnoredInGitRepository(directory: string, files: string[]): Promise<string[]> {\n try {\n const stdout = await gitCommand(['check-ignore', ...files], directory)\n return stdout.split('\\n').filter(Boolean)\n } catch (error) {\n // git check-ignore exits with code 1 when no files are ignored\n if (error instanceof AbortError && 'exitCode' in error && error.exitCode === 1) return []\n throw error\n }\n}\n\nexport type GitIgnoreTemplate = Record<string, string[]>\n/**\n * Create a .gitignore file in the given directory.\n *\n * @param directory - The directory where the .gitignore file will be created.\n * @param template - The template to use to create the .gitignore file.\n */\nexport function createGitIgnore(directory: string, template: GitIgnoreTemplate): void {\n outputDebug(outputContent`Creating .gitignore at ${outputToken.path(directory)}...`)\n const filePath = `${directory}/.gitignore`\n\n let fileContent = ''\n for (const [section, lines] of Object.entries(template)) {\n fileContent += `# ${section}\\n`\n fileContent += `${lines.join('\\n')}\\n\\n`\n }\n\n appendFileSync(filePath, fileContent)\n}\n\n/**\n * Add an entry to an existing .gitignore file.\n *\n * If the .gitignore file doesn't exist, or if the entry is already present,\n * no changes will be made.\n *\n * @param root - The directory containing the .gitignore file.\n * @param entry - The entry to add to the .gitignore file.\n */\nexport function addToGitIgnore(root: string, entry: string): void {\n const gitIgnorePath = joinPath(root, '.gitignore')\n\n if (!fileExistsSync(gitIgnorePath)) {\n // When the .gitignore file does not exist, the CLI should not be opinionated about creating it\n return\n }\n\n const gitIgnoreContent = readFileSync(gitIgnorePath).toString()\n const eol = detectEOL(gitIgnoreContent)\n\n const lines = gitIgnoreContent.split(eol).map((line) => line.trim())\n const ignoreManager = ignore.default({allowRelativePaths: true}).add(lines)\n\n const isIgnoredEntry = ignoreManager.ignores(joinPath(entry))\n const isIgnoredEntryAsDir = ignoreManager.ignores(joinPath(entry, 'ignored.txt'))\n const isAlreadyIgnored = isIgnoredEntry || isIgnoredEntryAsDir\n if (isAlreadyIgnored) {\n // The file is already ignored by an existing pattern\n return\n }\n\n if (gitIgnoreContent.endsWith(eol)) {\n writeFileSync(gitIgnorePath, `${gitIgnoreContent}${entry}${eol}`)\n } else {\n writeFileSync(gitIgnorePath, `${gitIgnoreContent}${eol}${entry}${eol}`)\n }\n}\n\n/**\n * Options to use when cloning a git repository.\n *\n * @param repoUrl - The URL of the repository to clone.\n * @param destination - The directory where the repository will be cloned.\n * @param shallow - Whether to clone the repository shallowly.\n * @param latestTag - Whether to clone the latest tag instead of the default branch.\n */\nexport interface GitCloneOptions {\n repoUrl: string\n destination: string\n shallow?: boolean\n latestTag?: boolean\n}\n/**\n * Clone a git repository.\n *\n * @param cloneOptions - The options to use to clone the repository.\n * @returns A promise that resolves when the clone is complete.\n */\nexport async function downloadGitRepository(cloneOptions: GitCloneOptions): Promise<void> {\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n const {repoUrl, destination, shallow, latestTag} = cloneOptions\n outputDebug(outputContent`Git-cloning repository ${repoUrl} into ${outputToken.path(destination)}...`)\n await ensureGitIsPresentOrAbort()\n\n // Validate destination directory before attempting to clone\n if (await fileExists(destination)) {\n // Check if it's a directory\n if (!(await isDirectory(destination))) {\n throw new AbortError(\n outputContent`Can't clone to ${outputToken.path(destination)}`,\n \"The path exists but isn't a directory.\",\n )\n }\n\n // Check if directory is empty\n const entries = await glob(['*', '.*'], {\n cwd: destination,\n deep: 1,\n onlyFiles: false,\n })\n\n if (entries.length > 0) {\n throw new AbortError(\n outputContent`Directory ${outputToken.path(destination)} already exists and is not empty`,\n outputContent`Choose a different name or remove the existing directory first.`,\n )\n }\n }\n\n const [repository, branch] = repoUrl.split('#')\n\n if (branch && latestTag) {\n throw new AbortError(\"Error cloning the repository. Git can't clone the latest release with a 'branch'.\")\n }\n\n if (shallow && latestTag) {\n throw new AbortError(\n \"Error cloning the repository. Git can't clone the latest release with the 'shallow' property.\",\n )\n }\n\n const args = ['clone', '--recurse-submodules']\n if (branch) {\n args.push('--branch', branch)\n }\n if (shallow) {\n args.push('--depth', '1')\n }\n if (!isTerminalInteractive()) {\n args.push('-c', 'core.askpass=true')\n }\n args.push(repository!, destination)\n\n try {\n await execa('git', args)\n\n if (latestTag) {\n const tag = await getLatestTagFromDirectory(destination, repoUrl)\n await gitCommand(['checkout', tag], destination)\n }\n } catch (err) {\n if (err instanceof AbortError) {\n throw err\n }\n if (err instanceof Error) {\n const abortError = new AbortError(err.message)\n abortError.stack = err.stack\n throw abortError\n }\n throw err\n }\n })\n}\n\nasync function getLatestTagFromDirectory(directory: string, repoUrl: string): Promise<string> {\n const stdout = await gitCommand(['describe', '--tags', '--abbrev=0'], directory)\n const tag = stdout.trim()\n\n if (!tag) {\n throw new AbortError(`Couldn't obtain the most recent tag of the repository ${repoUrl}`)\n }\n\n return tag\n}\n\n/**\n * Get the latest commit of a git repository.\n *\n * @param directory - The directory of the git repository.\n * @returns The latest commit of the repository.\n */\nexport async function getLatestGitCommit(directory?: string): Promise<GitLogEntry> {\n const format = '%H%x00%ai%x00%s%x00%D%x00%b%x00%an%x00%ae'\n const stdout = await gitCommand(['log', '-1', `--format=${format}`], directory)\n if (!stdout.trim()) {\n throw new AbortError(\n 'Must have at least one commit to run command',\n outputContent`Run ${outputToken.genericShellCommand(\n \"git commit -m 'Initial commit'\",\n )} to create your first commit.`,\n )\n }\n const parts = stdout.split('\\x00')\n return {\n hash: parts[0]!,\n date: parts[1]!,\n message: parts[2]!,\n refs: parts[3]!,\n body: parts[4]!,\n author_name: parts[5]!,\n author_email: parts[6]!,\n }\n}\n\n/**\n * Add all files to the git index from the given directory.\n *\n * @param directory - The directory where the git repository is located.\n * @returns A promise that resolves when the files are added to the index.\n */\nexport async function addAllToGitFromDirectory(directory?: string): Promise<void> {\n await gitCommand(['add', '--all'], directory)\n}\n\nexport interface CreateGitCommitOptions {\n directory?: string\n author?: string\n}\n\n/**\n * Create a git commit.\n *\n * @param message - The message of the commit.\n * @param options - The options to use to create the commit.\n * @returns The hash of the created commit.\n */\nexport async function createGitCommit(message: string, options?: CreateGitCommitOptions): Promise<string> {\n const args = ['commit', '-m', message]\n if (options?.author) {\n args.push('--author', options.author)\n }\n await gitCommand(args, options?.directory)\n const stdout = await gitCommand(['rev-parse', 'HEAD'], options?.directory)\n return stdout.trim()\n}\n\n/**\n * Get the HEAD symbolic reference of a git repository.\n *\n * @param directory - The directory of the git repository.\n * @returns The HEAD symbolic reference of the repository.\n */\nexport async function getHeadSymbolicRef(directory?: string): Promise<string> {\n const ref = await gitCommand(['symbolic-ref', '-q', 'HEAD'], directory)\n if (!ref) {\n throw new AbortError(\n \"Git HEAD can't be detached to run command\",\n outputContent`Run ${outputToken.genericShellCommand(\n 'git checkout [branchName]',\n )} to reattach HEAD or see git ${outputToken.link(\n 'documentation',\n 'https://git-scm.com/book/en/v2/Git-Internals-Git-References',\n )} for more details`,\n )\n }\n return ref.trim()\n}\n\n/**\n * If \"git\" is not present in the environment it throws\n * an abort error.\n */\nexport async function ensureGitIsPresentOrAbort(): Promise<void> {\n if (!(await hasGit())) {\n throw new AbortError(\n `Git is necessary in the environment to continue`,\n outputContent`Install ${outputToken.link(\n 'git',\n 'https://git-scm.com/book/en/v2/Getting-Started-Installing-Git',\n )}`,\n )\n }\n}\n\nexport class OutsideGitDirectoryError extends AbortError {}\n/**\n * If command run from outside a .git directory tree\n * it throws an abort error.\n *\n * @param directory - The directory to check.\n */\nexport async function ensureInsideGitDirectory(directory?: string): Promise<void> {\n if (!(await insideGitDirectory(directory))) {\n throw new OutsideGitDirectoryError(`${outputToken.path(directory ?? cwd())} is not a Git directory`)\n }\n}\n\n/**\n * Returns true if the given directory is inside a .git directory tree.\n *\n * @param directory - The directory to check.\n * @returns True if the directory is inside a .git directory tree.\n */\nexport async function insideGitDirectory(directory?: string): Promise<boolean> {\n try {\n await execa('git', ['rev-parse', '--git-dir'], {cwd: directory})\n return true\n } catch (error) {\n if (error instanceof Error && 'exitCode' in error && error.exitCode === 128) return false\n throw error\n }\n}\n\nexport class GitDirectoryNotCleanError extends AbortError {}\n/**\n * If the .git directory tree is not clean (has uncommitted changes)\n * it throws an abort error.\n *\n * @param directory - The directory to check.\n */\nexport async function ensureIsClean(directory?: string): Promise<void> {\n if (!(await isClean(directory))) {\n throw new GitDirectoryNotCleanError(`${outputToken.path(directory ?? cwd())} is not a clean Git directory`)\n }\n}\n\n/**\n * Returns true if the .git directory tree is clean (no uncommitted changes).\n *\n * @param directory - The directory to check.\n * @returns True is the .git directory is clean.\n */\nexport async function isClean(directory?: string): Promise<boolean> {\n const stdout = await gitCommand(['status', '--porcelain'], directory)\n return stdout.trim() === ''\n}\n\n/**\n * Returns the latest tag of a git repository.\n *\n * @param directory - The directory to check.\n * @returns String with the latest tag or undefined if no tags are found.\n */\nexport async function getLatestTag(directory?: string): Promise<string | undefined> {\n try {\n const stdout = await gitCommand(['describe', '--tags', '--abbrev=0'], directory)\n return stdout.trim() || undefined\n } catch (error) {\n if (error instanceof AbortError && 'exitCode' in error && error.exitCode === 128) return undefined\n throw error\n }\n}\n\n/**\n * Remove a git remote from the given directory.\n *\n * @param directory - The directory where the git repository is located.\n * @param remoteName - The name of the remote to remove (defaults to 'origin').\n * @returns A promise that resolves when the remote is removed.\n */\nexport async function removeGitRemote(directory: string, remoteName = 'origin'): Promise<void> {\n outputDebug(outputContent`Removing git remote ${remoteName} from ${outputToken.path(directory)}...`)\n await ensureGitIsPresentOrAbort()\n\n const stdout = await gitCommand(['remote'], directory)\n const remotes = stdout.split('\\n').filter(Boolean)\n\n if (!remotes.includes(remoteName)) {\n outputDebug(outputContent`Remote ${remoteName} does not exist, no action needed`)\n return\n }\n\n await gitCommand(['remote', 'remove', remoteName], directory)\n}\n"]}
|
|
@@ -5,9 +5,7 @@ let _globalContext;
|
|
|
5
5
|
* @returns Global context.
|
|
6
6
|
*/
|
|
7
7
|
function getGlobalContext() {
|
|
8
|
-
|
|
9
|
-
_globalContext = { currentCommandId: '' };
|
|
10
|
-
}
|
|
8
|
+
_globalContext ?? (_globalContext = { currentCommandId: '' });
|
|
11
9
|
return _globalContext;
|
|
12
10
|
}
|
|
13
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-context.js","sourceRoot":"","sources":["../../../src/public/node/global-context.ts"],"names":[],"mappings":"AAIA,IAAI,cAAyC,CAAA;AAE7C;;;;GAIG;AACH,SAAS,gBAAgB;IACvB,
|
|
1
|
+
{"version":3,"file":"global-context.js","sourceRoot":"","sources":["../../../src/public/node/global-context.ts"],"names":[],"mappings":"AAIA,IAAI,cAAyC,CAAA;AAE7C;;;;GAIG;AACH,SAAS,gBAAgB;IACvB,cAAc,KAAd,cAAc,GAAK,EAAC,gBAAgB,EAAE,EAAE,EAAC,EAAA;IACzC,OAAO,cAAc,CAAA;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,gBAAgB,EAAE,CAAC,gBAAgB,CAAA;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,gBAAgB,EAAE,CAAC,gBAAgB,GAAG,SAAS,CAAA;AACjD,CAAC","sourcesContent":["export interface GlobalContext {\n currentCommandId: string\n}\n\nlet _globalContext: GlobalContext | undefined\n\n/**\n * Get the global context.\n *\n * @returns Global context.\n */\nfunction getGlobalContext(): GlobalContext {\n _globalContext ??= {currentCommandId: ''}\n return _globalContext\n}\n\n/**\n * Get the current command ID.\n *\n * @returns Current command ID.\n */\nexport function getCurrentCommandId(): string {\n return getGlobalContext().currentCommandId\n}\n\n/**\n * Set the current command ID.\n *\n * @param commandId - Command ID.\n */\nexport function setCurrentCommandId(commandId: string): void {\n getGlobalContext().currentCommandId = commandId\n}\n"]}
|
|
@@ -6,3 +6,10 @@ import { Hook } from '@oclif/core';
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function postRunHookHasCompleted(): boolean;
|
|
8
8
|
export declare const hook: Hook.Postrun;
|
|
9
|
+
/**
|
|
10
|
+
* Auto-upgrades the CLI after a command completes, if a newer version is available.
|
|
11
|
+
* The entire flow is rate-limited to once per day unless forced via SHOPIFY_CLI_FORCE_AUTO_UPGRADE.
|
|
12
|
+
*
|
|
13
|
+
* @returns Resolves when the upgrade attempt (or fallback warning) is complete.
|
|
14
|
+
*/
|
|
15
|
+
export declare function autoUpgradeIfNeeded(): Promise<void>;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { postrun as deprecationsHook } from './deprecations.js';
|
|
2
2
|
import { reportAnalyticsEvent } from '../analytics.js';
|
|
3
|
-
import { outputDebug } from '../output.js';
|
|
3
|
+
import { outputDebug, outputWarn } from '../output.js';
|
|
4
|
+
import { getOutputUpdateCLIReminder, runCLIUpgrade, versionToAutoUpgrade, warnIfUpgradeAvailable } from '../upgrade.js';
|
|
5
|
+
import { inferPackageManagerForGlobalCLI } from '../is-global.js';
|
|
4
6
|
import * as metadata from '../metadata.js';
|
|
7
|
+
import { runAtMinimumInterval } from '../../../private/node/conf-store.js';
|
|
8
|
+
import { CLI_KIT_VERSION } from '../../common/version.js';
|
|
9
|
+
import { isMajorVersionChange } from '../version.js';
|
|
5
10
|
let postRunHookCompleted = false;
|
|
6
11
|
/**
|
|
7
12
|
* Check if post run hook has completed.
|
|
@@ -19,7 +24,62 @@ export const hook = async ({ config, Command }) => {
|
|
|
19
24
|
const command = Command.id.replace(/:/g, ' ');
|
|
20
25
|
outputDebug(`Completed command ${command}`);
|
|
21
26
|
postRunHookCompleted = true;
|
|
27
|
+
if (!Command.id?.includes('upgrade') && !Command.id?.startsWith('notifications')) {
|
|
28
|
+
try {
|
|
29
|
+
await autoUpgradeIfNeeded();
|
|
30
|
+
// eslint-disable-next-line no-catch-all/no-catch-all
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
outputDebug(`Auto-upgrade check failed: ${error}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
22
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Auto-upgrades the CLI after a command completes, if a newer version is available.
|
|
39
|
+
* The entire flow is rate-limited to once per day unless forced via SHOPIFY_CLI_FORCE_AUTO_UPGRADE.
|
|
40
|
+
*
|
|
41
|
+
* @returns Resolves when the upgrade attempt (or fallback warning) is complete.
|
|
42
|
+
*/
|
|
43
|
+
export async function autoUpgradeIfNeeded() {
|
|
44
|
+
const newerVersion = versionToAutoUpgrade();
|
|
45
|
+
if (!newerVersion) {
|
|
46
|
+
await warnIfUpgradeAvailable();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const forced = process.env.SHOPIFY_CLI_FORCE_AUTO_UPGRADE === '1';
|
|
50
|
+
// SHOPIFY_CLI_FORCE_AUTO_UPGRADE bypasses the daily rate limit so tests and intentional upgrades always run.
|
|
51
|
+
if (forced) {
|
|
52
|
+
await performAutoUpgrade(newerVersion);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Rate-limit the entire upgrade flow to once per day to avoid repeated attempts and major-version warnings.
|
|
56
|
+
await runAtMinimumInterval('auto-upgrade', { days: 1 }, async () => {
|
|
57
|
+
await performAutoUpgrade(newerVersion);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function performAutoUpgrade(newerVersion) {
|
|
62
|
+
if (isMajorVersionChange(CLI_KIT_VERSION, newerVersion)) {
|
|
63
|
+
return outputWarn(getOutputUpdateCLIReminder(newerVersion));
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
await runCLIUpgrade();
|
|
67
|
+
// eslint-disable-next-line no-catch-all/no-catch-all
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const errorMessage = `Auto-upgrade failed: ${error}`;
|
|
71
|
+
outputDebug(errorMessage);
|
|
72
|
+
outputWarn(getOutputUpdateCLIReminder(newerVersion));
|
|
73
|
+
// Report to Observe as a handled error without showing anything extra to the user
|
|
74
|
+
const { sendErrorToBugsnag } = await import('../error-handler.js');
|
|
75
|
+
const enrichedError = Object.assign(new Error(errorMessage), {
|
|
76
|
+
packageManager: inferPackageManagerForGlobalCLI(),
|
|
77
|
+
platform: process.platform,
|
|
78
|
+
cliVersion: CLI_KIT_VERSION,
|
|
79
|
+
});
|
|
80
|
+
await sendErrorToBugsnag(enrichedError, 'expected_error');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
23
83
|
/**
|
|
24
84
|
* Override the command name with the stop one for analytics purposes.
|
|
25
85
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/postrun.ts"],"names":[],"mappings":"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","sourcesContent":["import {postrun as deprecationsHook} from './deprecations.js'\nimport {reportAnalyticsEvent} from '../analytics.js'\nimport {outputDebug, outputWarn} from '../output.js'\nimport {getOutputUpdateCLIReminder, runCLIUpgrade, versionToAutoUpgrade, warnIfUpgradeAvailable} from '../upgrade.js'\nimport {inferPackageManagerForGlobalCLI} from '../is-global.js'\nimport BaseCommand from '../base-command.js'\nimport * as metadata from '../metadata.js'\nimport {runAtMinimumInterval} from '../../../private/node/conf-store.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {isMajorVersionChange} from '../version.js'\nimport {Command, Hook} from '@oclif/core'\n\nlet postRunHookCompleted = false\n\n/**\n * Check if post run hook has completed.\n *\n * @returns Whether post run hook has completed.\n */\nexport function postRunHookHasCompleted(): boolean {\n return postRunHookCompleted\n}\n\n// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Postrun = async ({config, Command}) => {\n await detectStopCommand(Command as unknown as typeof Command)\n await reportAnalyticsEvent({config, exitMode: 'ok'})\n deprecationsHook(Command)\n\n const command = Command.id.replace(/:/g, ' ')\n outputDebug(`Completed command ${command}`)\n postRunHookCompleted = true\n\n if (!Command.id?.includes('upgrade') && !Command.id?.startsWith('notifications')) {\n try {\n await autoUpgradeIfNeeded()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n outputDebug(`Auto-upgrade check failed: ${error}`)\n }\n }\n}\n\n/**\n * Auto-upgrades the CLI after a command completes, if a newer version is available.\n * The entire flow is rate-limited to once per day unless forced via SHOPIFY_CLI_FORCE_AUTO_UPGRADE.\n *\n * @returns Resolves when the upgrade attempt (or fallback warning) is complete.\n */\nexport async function autoUpgradeIfNeeded(): Promise<void> {\n const newerVersion = versionToAutoUpgrade()\n if (!newerVersion) {\n await warnIfUpgradeAvailable()\n return\n }\n\n const forced = process.env.SHOPIFY_CLI_FORCE_AUTO_UPGRADE === '1'\n\n // SHOPIFY_CLI_FORCE_AUTO_UPGRADE bypasses the daily rate limit so tests and intentional upgrades always run.\n if (forced) {\n await performAutoUpgrade(newerVersion)\n } else {\n // Rate-limit the entire upgrade flow to once per day to avoid repeated attempts and major-version warnings.\n await runAtMinimumInterval('auto-upgrade', {days: 1}, async () => {\n await performAutoUpgrade(newerVersion)\n })\n }\n}\n\nasync function performAutoUpgrade(newerVersion: string): Promise<void> {\n if (isMajorVersionChange(CLI_KIT_VERSION, newerVersion)) {\n return outputWarn(getOutputUpdateCLIReminder(newerVersion))\n }\n\n try {\n await runCLIUpgrade()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n const errorMessage = `Auto-upgrade failed: ${error}`\n outputDebug(errorMessage)\n outputWarn(getOutputUpdateCLIReminder(newerVersion))\n // Report to Observe as a handled error without showing anything extra to the user\n const {sendErrorToBugsnag} = await import('../error-handler.js')\n const enrichedError = Object.assign(new Error(errorMessage), {\n packageManager: inferPackageManagerForGlobalCLI(),\n platform: process.platform,\n cliVersion: CLI_KIT_VERSION,\n })\n await sendErrorToBugsnag(enrichedError, 'expected_error')\n }\n}\n\n/**\n * Override the command name with the stop one for analytics purposes.\n *\n * @param commandClass - Oclif command class.\n */\nasync function detectStopCommand(commandClass: Command.Class | typeof BaseCommand): Promise<void> {\n const currentTime = new Date().getTime()\n if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsStopCommand')) {\n const stopCommand = (commandClass as typeof BaseCommand).analyticsStopCommand()\n if (stopCommand) {\n const {commandStartOptions} = metadata.getAllSensitiveMetadata()\n if (!commandStartOptions) return\n await metadata.addSensitiveMetadata(() => ({\n commandStartOptions: {\n ...commandStartOptions,\n startTime: currentTime,\n startCommand: stopCommand,\n },\n }))\n }\n }\n}\n"]}
|
|
@@ -11,6 +11,7 @@ export declare function parseCommandContent(cmdInfo: {
|
|
|
11
11
|
pluginAlias?: string;
|
|
12
12
|
}): CommandContent;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Triggers a background check for a newer CLI version (non-blocking).
|
|
15
|
+
* The result is cached and consumed by the postrun hook for auto-upgrade.
|
|
15
16
|
*/
|
|
16
|
-
export declare function
|
|
17
|
+
export declare function checkForNewVersionInBackground(): void;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { CLI_KIT_VERSION } from '../../common/version.js';
|
|
2
|
-
import {
|
|
2
|
+
import { isPreReleaseVersion } from '../version.js';
|
|
3
|
+
import { checkForNewVersion } from '../node-package-manager.js';
|
|
3
4
|
import { startAnalytics } from '../../../private/node/analytics.js';
|
|
4
|
-
import { outputDebug
|
|
5
|
-
import { getOutputUpdateCLIReminder } from '../upgrade.js';
|
|
6
|
-
import { runAtMinimumInterval } from '../../../private/node/conf-store.js';
|
|
5
|
+
import { outputDebug } from '../output.js';
|
|
7
6
|
import { fetchNotificationsInBackground } from '../notifications-system.js';
|
|
8
|
-
import { isPreReleaseVersion } from '../version.js';
|
|
9
7
|
// This hook is called before each command run. More info: https://oclif.io/docs/hooks
|
|
10
8
|
export const hook = async (options) => {
|
|
11
9
|
const commandContent = parseCommandContent({
|
|
@@ -14,16 +12,14 @@ export const hook = async (options) => {
|
|
|
14
12
|
pluginAlias: options.Command.plugin?.alias,
|
|
15
13
|
});
|
|
16
14
|
const args = options.argv;
|
|
17
|
-
|
|
15
|
+
checkForNewVersionInBackground();
|
|
18
16
|
outputDebug(`Running command ${commandContent.command}`);
|
|
19
17
|
await startAnalytics({ commandContent, args, commandClass: options.Command });
|
|
20
18
|
fetchNotificationsInBackground(options.Command.id);
|
|
21
19
|
};
|
|
22
20
|
export function parseCommandContent(cmdInfo) {
|
|
23
21
|
let commandContent = parseCreateCommand(cmdInfo.pluginAlias);
|
|
24
|
-
|
|
25
|
-
commandContent = parseNormalCommand(cmdInfo.id, cmdInfo.aliases);
|
|
26
|
-
}
|
|
22
|
+
commandContent ?? (commandContent = parseNormalCommand(cmdInfo.id, cmdInfo.aliases));
|
|
27
23
|
return commandContent;
|
|
28
24
|
}
|
|
29
25
|
function parseNormalCommand(id, aliases) {
|
|
@@ -72,24 +68,15 @@ function findAlias(aliases) {
|
|
|
72
68
|
}
|
|
73
69
|
}
|
|
74
70
|
/**
|
|
75
|
-
*
|
|
71
|
+
* Triggers a background check for a newer CLI version (non-blocking).
|
|
72
|
+
* The result is cached and consumed by the postrun hook for auto-upgrade.
|
|
76
73
|
*/
|
|
77
|
-
export
|
|
78
|
-
const cliDependency = '@shopify/cli';
|
|
74
|
+
export function checkForNewVersionInBackground() {
|
|
79
75
|
const currentVersion = CLI_KIT_VERSION;
|
|
80
76
|
if (isPreReleaseVersion(currentVersion)) {
|
|
81
|
-
// This is a nightly/snapshot/experimental version, so we don't want to check for updates
|
|
82
77
|
return;
|
|
83
78
|
}
|
|
84
|
-
// Check in the background, once daily
|
|
85
79
|
// eslint-disable-next-line no-void
|
|
86
|
-
void checkForNewVersion(
|
|
87
|
-
// Warn if we previously found a new version
|
|
88
|
-
await runAtMinimumInterval('warn-on-available-upgrade', { days: 1 }, async () => {
|
|
89
|
-
const newerVersion = checkForCachedNewVersion(cliDependency, currentVersion);
|
|
90
|
-
if (newerVersion) {
|
|
91
|
-
outputWarn(getOutputUpdateCLIReminder(newerVersion));
|
|
92
|
-
}
|
|
93
|
-
});
|
|
80
|
+
void checkForNewVersion('@shopify/cli', currentVersion, { cacheExpiryInHours: 24 });
|
|
94
81
|
}
|
|
95
82
|
//# sourceMappingURL=prerun.js.map
|