@shopify/cli-kit 3.3.2 → 3.5.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/CHANGELOG.md +34 -0
- package/dist/api/admin.js +20 -34
- package/dist/api/admin.js.map +1 -1
- package/dist/api/common.d.ts +11 -1
- package/dist/api/common.js +50 -4
- package/dist/api/common.js.map +1 -1
- package/dist/api/identity.js +3 -3
- package/dist/api/identity.js.map +1 -1
- package/dist/api/partners.d.ts +0 -5
- package/dist/api/partners.js +22 -42
- package/dist/api/partners.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -2
- package/dist/constants.js.map +1 -1
- package/dist/environment/local.d.ts +1 -0
- package/dist/environment/local.js +3 -0
- package/dist/environment/local.js.map +1 -1
- package/dist/environment/service.d.ts +2 -1
- package/dist/environment/service.js +16 -0
- package/dist/environment/service.js.map +1 -1
- package/dist/error.d.ts +5 -0
- package/dist/error.js +10 -4
- package/dist/error.js.map +1 -1
- package/dist/file.d.ts +2 -0
- package/dist/file.js +13 -1
- package/dist/file.js.map +1 -1
- package/dist/git.js +12 -4
- package/dist/git.js.map +1 -1
- package/dist/http/fetch.d.ts +9 -2
- package/dist/http/fetch.js +11 -2
- package/dist/http/fetch.js.map +1 -1
- package/dist/http/graphql.d.ts +15 -0
- package/dist/http/graphql.js +12 -0
- package/dist/http/graphql.js.map +1 -0
- package/dist/http.d.ts +24 -0
- package/dist/http.js +27 -0
- package/dist/http.js.map +1 -1
- package/dist/network/service.d.ts +1 -1
- package/dist/network/service.js.map +1 -1
- package/dist/node/archiver.d.ts +4 -1
- package/dist/node/archiver.js +22 -13
- package/dist/node/archiver.js.map +1 -1
- package/dist/node/base-command.d.ts +1 -0
- package/dist/node/base-command.js +10 -1
- package/dist/node/base-command.js.map +1 -1
- package/dist/node/cli.d.ts +0 -2
- package/dist/node/cli.js +0 -4
- package/dist/node/cli.js.map +1 -1
- package/dist/node/error-handler.d.ts +20 -0
- package/dist/node/error-handler.js +40 -3
- package/dist/node/error-handler.js.map +1 -1
- package/dist/node/hooks/init.d.ts +2 -0
- package/dist/node/hooks/init.js +7 -0
- package/dist/node/hooks/init.js.map +1 -0
- package/dist/node/hooks/postrun.js +4 -1
- package/dist/node/hooks/postrun.js.map +1 -1
- package/dist/node/hooks/prerun.js +2 -0
- package/dist/node/hooks/prerun.js.map +1 -1
- package/dist/node/ruby.d.ts +7 -2
- package/dist/node/ruby.js +24 -12
- package/dist/node/ruby.js.map +1 -1
- package/dist/output.d.ts +18 -11
- package/dist/output.js +96 -28
- package/dist/output.js.map +1 -1
- package/dist/path.d.ts +3 -3
- package/dist/path.js +2 -4
- package/dist/path.js.map +1 -1
- package/dist/session/exchange.js +2 -2
- package/dist/session/exchange.js.map +1 -1
- package/dist/session/validate.js +3 -0
- package/dist/session/validate.js.map +1 -1
- package/dist/session.js +7 -1
- package/dist/session.js.map +1 -1
- package/dist/store.js +0 -2
- package/dist/store.js.map +1 -1
- package/dist/string.js +3 -1
- package/dist/string.js.map +1 -1
- package/dist/system.d.ts +4 -3
- package/dist/system.js +5 -2
- package/dist/system.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/typing/overloaded-parameters.d.ts +6 -0
- package/dist/typing/overloaded-parameters.js +2 -0
- package/dist/typing/overloaded-parameters.js.map +1 -0
- package/dist/typing/simple-definitions.d.ts +4 -0
- package/dist/typing/simple-definitions.js +2 -0
- package/dist/typing/simple-definitions.js.map +1 -0
- package/dist/ui.d.ts +11 -0
- package/dist/ui.js +35 -5
- package/dist/ui.js.map +1 -1
- package/package.json +25 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/node/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EACf,MAAM,IAAI,WAAW,EACrB,YAAY,IAAI,iBAAiB,EACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../error.js'\nimport {info} from '../output.js'\nimport {reportEvent} from '../analytics.js'\nimport * as path from '../path.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(error: Error & {exitCode?: number | undefined}) {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error: Error) => {\n return handler(error)\n })\n .then(reportError)\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: Error): Promise<Error> => {\n await reportEvent({errorMessage: error.message})\n if (settings.debug || !shouldReportError(error)) return error\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n // eslint-disable-next-line no-prototype-builtins\n if (Error.prototype.isPrototypeOf(error)) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && (error as string).trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return reportableError\n}\n\n/**\n * If the given file path comes from within a plugin, return the relative path, plus the plugin name.\n *\n * This gives us very consistent paths for errors thrown from plugin code.\n *\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation))\n }\n return currentFilePath\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(plugins: Interfaces.Plugin[]) {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalize(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalize(followSymlinks)}\n }),\n )\n Bugsnag.addOnError((event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n })\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/node/hooks/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAC,qBAAqB,EAAC,MAAM,gBAAgB,CAAA;AAGpD,MAAM,CAAC,MAAM,IAAI,GAAc,KAAK,EAAE,OAAO,EAAE,EAAE;IAC/C,MAAM,qBAAqB,EAAE,CAAA;IAC7B,eAAe,EAAE,CAAA;AACnB,CAAC,CAAA","sourcesContent":["import {initiateLogging} from '../../output.js'\nimport {initializeCliKitStore} from '../../store.js'\nimport {Hook} from '@oclif/core'\n\nexport const hook: Hook.Init = async (options) => {\n await initializeCliKitStore()\n initiateLogging()\n}\n"]}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { reportEvent } from '../../analytics.js';
|
|
2
|
+
import { debug } from '../../output.js';
|
|
2
3
|
// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks
|
|
3
|
-
export const hookPost = async (
|
|
4
|
+
export const hookPost = async (options) => {
|
|
4
5
|
await reportEvent();
|
|
6
|
+
const command = options.Command?.id?.replace(/:/g, ' ');
|
|
7
|
+
debug(`Completed command ${command}`);
|
|
5
8
|
};
|
|
6
9
|
//# sourceMappingURL=postrun.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../src/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../src/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAGrC,gGAAgG;AAChG,MAAM,CAAC,MAAM,QAAQ,GAAiB,KAAK,EAAE,OAAO,EAAE,EAAE;IACtD,MAAM,WAAW,EAAE,CAAA;IACnB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACvD,KAAK,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAA;AACvC,CAAC,CAAA","sourcesContent":["import {reportEvent} from '../../analytics.js'\nimport {debug} from '../../output.js'\nimport {Hook} from '@oclif/core'\n\n// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks\nexport const hookPost: Hook.Postrun = async (options) => {\n await reportEvent()\n const command = options.Command?.id?.replace(/:/g, ' ')\n debug(`Completed command ${command}`)\n}\n"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { start } from '../../analytics.js';
|
|
2
|
+
import { debug } from '../../output.js';
|
|
2
3
|
// This hook is called before each command run. More info: https://oclif.io/docs/hooks
|
|
3
4
|
export const hook = async (options) => {
|
|
4
5
|
const cmd = options.Command.aliases.length === 0 ? options.Command.id : options.Command.aliases[0];
|
|
5
6
|
const command = cmd.replace(/:/g, ' ');
|
|
6
7
|
const args = options.argv;
|
|
8
|
+
debug(`Running command ${command}`);
|
|
7
9
|
start({ command, args });
|
|
8
10
|
};
|
|
9
11
|
//# sourceMappingURL=prerun.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../src/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../src/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAGrC,sFAAsF;AACtF,MAAM,CAAC,MAAM,IAAI,GAAgB,KAAK,EAAE,OAAO,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAClG,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAA;IACnC,KAAK,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,CAAA;AACxB,CAAC,CAAA","sourcesContent":["import {start} from '../../analytics.js'\nimport {debug} from '../../output.js'\nimport {Hook} from '@oclif/core'\n\n// This hook is called before each command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Prerun = async (options) => {\n const cmd = options.Command.aliases.length === 0 ? options.Command.id : options.Command.aliases[0]\n const command = cmd.replace(/:/g, ' ')\n const args = options.argv\n debug(`Running command ${command}`)\n start({command, args})\n}\n"]}
|
package/dist/node/ruby.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { AdminSession } from '../session.js';
|
|
3
3
|
import { Writable } from 'node:stream';
|
|
4
|
+
interface ExecCLI2Options {
|
|
5
|
+
adminSession?: AdminSession;
|
|
6
|
+
storefrontToken?: string;
|
|
7
|
+
directory?: string;
|
|
8
|
+
}
|
|
4
9
|
/**
|
|
5
10
|
* Execute CLI 2.0 commands.
|
|
6
11
|
* Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.
|
|
7
12
|
* User must have a valid ruby+bundler environment to run any command.
|
|
8
13
|
*
|
|
9
14
|
* @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])
|
|
10
|
-
* @param
|
|
15
|
+
* @param options {ExecCLI2Options}
|
|
11
16
|
*/
|
|
12
|
-
export declare function execCLI2(args: string[], adminSession?:
|
|
17
|
+
export declare function execCLI2(args: string[], { adminSession, storefrontToken, directory }?: ExecCLI2Options): Promise<void>;
|
|
13
18
|
interface ExecThemeCheckCLIOptions {
|
|
14
19
|
/** A list of directories in which theme-check should run */
|
|
15
20
|
directories: string[];
|
package/dist/node/ruby.js
CHANGED
|
@@ -6,10 +6,8 @@ import { glob, join } from '../path.js';
|
|
|
6
6
|
import constants from '../constants.js';
|
|
7
7
|
import { coerce } from '../semver.js';
|
|
8
8
|
import { content, token } from '../output.js';
|
|
9
|
-
// eslint-disable-next-line no-restricted-imports
|
|
10
|
-
import { spawn } from 'child_process';
|
|
11
9
|
import { Writable } from 'node:stream';
|
|
12
|
-
const RubyCLIVersion = '2.
|
|
10
|
+
const RubyCLIVersion = '2.20.1';
|
|
13
11
|
const ThemeCheckVersion = '1.10.3';
|
|
14
12
|
const MinBundlerVersion = '2.3.8';
|
|
15
13
|
const MinRubyVersion = '2.3.0';
|
|
@@ -20,19 +18,23 @@ const MinRubyGemVersion = '2.5.0';
|
|
|
20
18
|
* User must have a valid ruby+bundler environment to run any command.
|
|
21
19
|
*
|
|
22
20
|
* @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])
|
|
23
|
-
* @param
|
|
21
|
+
* @param options {ExecCLI2Options}
|
|
24
22
|
*/
|
|
25
|
-
export async function execCLI2(args, adminSession) {
|
|
23
|
+
export async function execCLI2(args, { adminSession, storefrontToken, directory } = {}) {
|
|
26
24
|
await installCLIDependencies();
|
|
27
25
|
const env = {
|
|
28
26
|
...process.env,
|
|
27
|
+
SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,
|
|
29
28
|
SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,
|
|
30
29
|
SHOPIFY_CLI_STORE: adminSession?.storeFqdn,
|
|
30
|
+
// Bundler uses this Gemfile to understand which gems are available in the
|
|
31
|
+
// environment. We use this to specify our own Gemfile for CLI2, which exists
|
|
32
|
+
// outside the user's project directory.
|
|
33
|
+
BUNDLE_GEMFILE: join(shopifyCLIDirectory(), 'Gemfile'),
|
|
31
34
|
};
|
|
32
|
-
|
|
35
|
+
await system.exec('bundle', ['exec', 'shopify'].concat(args), {
|
|
33
36
|
stdio: 'inherit',
|
|
34
|
-
cwd:
|
|
35
|
-
shell: true,
|
|
37
|
+
cwd: directory ?? process.cwd(),
|
|
36
38
|
env,
|
|
37
39
|
});
|
|
38
40
|
}
|
|
@@ -109,10 +111,16 @@ async function installCLIDependencies() {
|
|
|
109
111
|
{
|
|
110
112
|
title: 'Installing theme dependencies',
|
|
111
113
|
task: async () => {
|
|
114
|
+
const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY);
|
|
112
115
|
await validateRubyEnv();
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
if (usingLocalCLI2) {
|
|
117
|
+
await bundleInstallLocalShopifyCLI();
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
await createShopifyCLIWorkingDirectory();
|
|
121
|
+
await createShopifyCLIGemfile();
|
|
122
|
+
await bundleInstallShopifyCLI();
|
|
123
|
+
}
|
|
116
124
|
},
|
|
117
125
|
},
|
|
118
126
|
], { renderer });
|
|
@@ -173,6 +181,9 @@ async function createThemeCheckGemfile() {
|
|
|
173
181
|
const gemPath = join(themeCheckDirectory(), 'Gemfile');
|
|
174
182
|
await file.write(gemPath, `source 'https://rubygems.org'\ngem 'theme-check', '${ThemeCheckVersion}'`);
|
|
175
183
|
}
|
|
184
|
+
async function bundleInstallLocalShopifyCLI() {
|
|
185
|
+
await system.exec('bundle', ['install'], { cwd: shopifyCLIDirectory() });
|
|
186
|
+
}
|
|
176
187
|
async function bundleInstallShopifyCLI() {
|
|
177
188
|
await system.exec('bundle', ['config', 'set', '--local', 'path', shopifyCLIDirectory()], { cwd: shopifyCLIDirectory() });
|
|
178
189
|
await system.exec('bundle', ['install'], { cwd: shopifyCLIDirectory() });
|
|
@@ -182,7 +193,8 @@ async function bundleInstallThemeCheck() {
|
|
|
182
193
|
await system.exec('bundle', ['install'], { cwd: themeCheckDirectory() });
|
|
183
194
|
}
|
|
184
195
|
function shopifyCLIDirectory() {
|
|
185
|
-
return
|
|
196
|
+
return (process.env.SHOPIFY_CLI_2_0_DIRECTORY ??
|
|
197
|
+
join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion));
|
|
186
198
|
}
|
|
187
199
|
function themeCheckDirectory() {
|
|
188
200
|
return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion);
|
package/dist/node/ruby.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../src/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import * as file from '../file.js'\nimport * as ui from '../ui.js'\nimport * as system from '../system.js'\nimport {Abort} from '../error.js'\nimport {glob, join} from '../path.js'\nimport constants from '../constants.js'\nimport {coerce} from '../semver.js'\nimport {AdminSession} from '../session.js'\nimport {content, token} from '../output.js'\n// eslint-disable-next-line no-restricted-imports\nimport {spawn} from 'child_process'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.16.0'\nconst ThemeCheckVersion = '1.10.3'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.3.0'\nconst MinRubyGemVersion = '2.5.0'\n\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])\n * @param adminSession {AdminSession} Contains token and store to pass to CLI 2.0, which will be set as environment variables\n */\nexport async function execCLI2(args: string[], adminSession?: AdminSession) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_CLI_STORE: adminSession?.storeFqdn,\n }\n\n spawn('bundle', ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: shopifyCLIDirectory(),\n shell: true,\n env,\n })\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run */\n directories: string[]\n /** Arguments to pass to the theme-check CLI */\n args?: string[]\n /** Writable to send standard output content through */\n stdout: Writable\n /** Writable to send standard error content through */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n * @param options {ExecThemeCheckCLIOptions} Options to customize the execution of theme-check.\n * @returns {Promise<void>} A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI({\n directories,\n args,\n stdout,\n stderr,\n}: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(stdout)\n\n const processes = directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await glob(join(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n stdout.write(chunk, ...args)\n } else {\n stderr.write(chunk, ...args)\n }\n },\n })\n await system.exec('bundle', ['exec', 'theme-check'].concat([directory, ...(args || [])]), {\n stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.exists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n },\n },\n ],\n {renderer: 'silent'},\n )\n await list.run()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI\n */\nasync function installCLIDependencies() {\n const exists = await file.exists(shopifyCLIDirectory())\n const renderer = exists ? 'silent' : 'default'\n\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateRubyGems()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput('ruby', ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system: ${\n content`${token.link('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system: ${\n content`${token.link('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateRubyGems() {\n const stdout = await system.captureOutput('gem', ['-v'])\n const version = coerce(stdout)\n\n const isValid = version?.compare(MinRubyGemVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `RubyGems version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `To update to the latest version of RubyGems, run ${\n content`${token.genericShellCommand('gem update --system')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput('bundler', ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand('gem install bundler')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand('gem install bundler')}`.value\n }`,\n )\n }\n}\n\nfunction createShopifyCLIWorkingDirectory() {\n return file.mkdir(shopifyCLIDirectory())\n}\n\nfunction createThemeCheckCLIWorkingDirectory() {\n return file.mkdir(themeCheckDirectory())\n}\n\nasync function createShopifyCLIGemfile() {\n const gemPath = join(shopifyCLIDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'shopify-cli', '${RubyCLIVersion}'`)\n}\n\nasync function createThemeCheckGemfile() {\n const gemPath = join(themeCheckDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\nasync function bundleInstallShopifyCLI() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {cwd: shopifyCLIDirectory()})\n await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', themeCheckDirectory()], {cwd: themeCheckDirectory()})\n await system.exec('bundle', ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n}\n\nfunction themeCheckDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return system\n .captureOutput('ruby', ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../src/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import * as file from '../file.js'\nimport * as ui from '../ui.js'\nimport * as system from '../system.js'\nimport {Abort} from '../error.js'\nimport {glob, join} from '../path.js'\nimport constants from '../constants.js'\nimport {coerce} from '../semver.js'\nimport {AdminSession} from '../session.js'\nimport {content, token} from '../output.js'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.20.1'\nconst ThemeCheckVersion = '1.10.3'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.3.0'\nconst MinRubyGemVersion = '2.5.0'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])\n * @param options {ExecCLI2Options}\n */\nexport async function execCLI2(args: string[], {adminSession, storefrontToken, directory}: ExecCLI2Options = {}) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_CLI_STORE: adminSession?.storeFqdn,\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: join(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n await system.exec('bundle', ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: directory ?? process.cwd(),\n env,\n })\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run */\n directories: string[]\n /** Arguments to pass to the theme-check CLI */\n args?: string[]\n /** Writable to send standard output content through */\n stdout: Writable\n /** Writable to send standard error content through */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n * @param options {ExecThemeCheckCLIOptions} Options to customize the execution of theme-check.\n * @returns {Promise<void>} A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI({\n directories,\n args,\n stdout,\n stderr,\n}: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(stdout)\n\n const processes = directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await glob(join(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n stdout.write(chunk, ...args)\n } else {\n stderr.write(chunk, ...args)\n }\n },\n })\n await system.exec('bundle', ['exec', 'theme-check'].concat([directory, ...(args || [])]), {\n stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.exists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n },\n },\n ],\n {renderer: 'silent'},\n )\n await list.run()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI\n */\nasync function installCLIDependencies() {\n const exists = await file.exists(shopifyCLIDirectory())\n const renderer = exists ? 'silent' : 'default'\n\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateRubyGems()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput('ruby', ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system: ${\n content`${token.link('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system: ${\n content`${token.link('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateRubyGems() {\n const stdout = await system.captureOutput('gem', ['-v'])\n const version = coerce(stdout)\n\n const isValid = version?.compare(MinRubyGemVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `RubyGems version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `To update to the latest version of RubyGems, run ${\n content`${token.genericShellCommand('gem update --system')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput('bundler', ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand('gem install bundler')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version!.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand('gem install bundler')}`.value\n }`,\n )\n }\n}\n\nfunction createShopifyCLIWorkingDirectory() {\n return file.mkdir(shopifyCLIDirectory())\n}\n\nfunction createThemeCheckCLIWorkingDirectory() {\n return file.mkdir(themeCheckDirectory())\n}\n\nasync function createShopifyCLIGemfile() {\n const gemPath = join(shopifyCLIDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'shopify-cli', '${RubyCLIVersion}'`)\n}\n\nasync function createThemeCheckGemfile() {\n const gemPath = join(themeCheckDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\nasync function bundleInstallLocalShopifyCLI() {\n await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallShopifyCLI() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {cwd: shopifyCLIDirectory()})\n await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec('bundle', ['config', 'set', '--local', 'path', themeCheckDirectory()], {cwd: themeCheckDirectory()})\n await system.exec('bundle', ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\nfunction themeCheckDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return system\n .captureOutput('ruby', ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n"]}
|
package/dist/output.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ import { Fatal } from './error.js';
|
|
|
3
3
|
import { PackageManager } from './node/node-package-manager.js';
|
|
4
4
|
import { AbortSignal } from 'abort-controller';
|
|
5
5
|
import { Writable } from 'node:stream';
|
|
6
|
-
export
|
|
6
|
+
export { default as logUpdate } from 'log-update';
|
|
7
|
+
export declare function initiateLogging(options?: {
|
|
7
8
|
logDir?: string;
|
|
8
|
-
filename?: string;
|
|
9
9
|
}): void;
|
|
10
10
|
declare enum ContentTokenType {
|
|
11
11
|
Raw = 0,
|
|
@@ -25,6 +25,7 @@ declare enum ContentTokenType {
|
|
|
25
25
|
interface ContentMetadata {
|
|
26
26
|
link?: string;
|
|
27
27
|
}
|
|
28
|
+
export declare type Logger = (message: string) => void;
|
|
28
29
|
declare class ContentToken {
|
|
29
30
|
type: ContentTokenType;
|
|
30
31
|
value: Message;
|
|
@@ -68,40 +69,45 @@ export declare let collectedLogs: {
|
|
|
68
69
|
};
|
|
69
70
|
export declare const clearCollectedLogs: () => void;
|
|
70
71
|
/**
|
|
71
|
-
* Ouputs information to the user.
|
|
72
|
+
* Ouputs information to the user.
|
|
72
73
|
* Info messages don't get additional formatting.
|
|
73
74
|
* Note: Info messages are sent through the standard output.
|
|
74
75
|
* @param content {string} The content to be output to the user.
|
|
76
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
75
77
|
*/
|
|
76
|
-
export declare const info: (content: Message) => void;
|
|
78
|
+
export declare const info: (content: Message, logger?: Logger) => void;
|
|
77
79
|
/**
|
|
78
80
|
* Outputs a success message to the user.
|
|
79
|
-
* Success
|
|
81
|
+
* Success messages receive a special formatting to make them stand out in the console.
|
|
80
82
|
* Note: Success messages are sent through the standard output.
|
|
81
83
|
* @param content {string} The content to be output to the user.
|
|
84
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
82
85
|
*/
|
|
83
|
-
export declare const success: (content: Message) => void;
|
|
86
|
+
export declare const success: (content: Message, logger?: Logger) => void;
|
|
84
87
|
/**
|
|
85
88
|
* Outputs a completed message to the user.
|
|
86
89
|
* Completed message receive a special formatting to make them stand out in the console.
|
|
87
90
|
* Note: Completed messages are sent through the standard output.
|
|
88
91
|
* @param content {string} The content to be output to the user.
|
|
92
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
89
93
|
*/
|
|
90
|
-
export declare const completed: (content: Message) => void;
|
|
94
|
+
export declare const completed: (content: Message, logger?: Logger) => void;
|
|
91
95
|
/**
|
|
92
96
|
* Ouputs debug information to the user. By default these output is hidden unless the user calls the CLI with --verbose.
|
|
93
97
|
* Debug messages don't get additional formatting.
|
|
94
98
|
* Note: Debug messages are sent through the standard output.
|
|
95
99
|
* @param content {string} The content to be output to the user.
|
|
100
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
96
101
|
*/
|
|
97
|
-
export declare const debug: (content: Message) => void;
|
|
102
|
+
export declare const debug: (content: Message, logger?: Logger) => void;
|
|
98
103
|
/**
|
|
99
104
|
* Outputs a warning message to the user.
|
|
100
105
|
* Warning messages receive a special formatting to make them stand out in the console.
|
|
101
106
|
* Note: Warning messages are sent through the standard output.
|
|
102
107
|
* @param content {string} The content to be output to the user.
|
|
108
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
103
109
|
*/
|
|
104
|
-
export declare const warn: (content: Message) => void;
|
|
110
|
+
export declare const warn: (content: Message, logger?: Logger) => void;
|
|
105
111
|
/**
|
|
106
112
|
* Prints a new line in the terminal.
|
|
107
113
|
*/
|
|
@@ -138,7 +144,9 @@ export declare function logFileExists(): boolean;
|
|
|
138
144
|
export declare function logToFile(message: string, logLevel: string): void;
|
|
139
145
|
export declare function unstyled(message: string): string;
|
|
140
146
|
export declare function shouldDisplayColors(): boolean;
|
|
141
|
-
export declare function pageLogs(
|
|
147
|
+
export declare function pageLogs({ lastCommand }: {
|
|
148
|
+
lastCommand: boolean;
|
|
149
|
+
}): Promise<void>;
|
|
142
150
|
/**
|
|
143
151
|
*
|
|
144
152
|
* @param packageManager {PackageManager} The package manager that is being used.
|
|
@@ -146,4 +154,3 @@ export declare function pageLogs(): Promise<void>;
|
|
|
146
154
|
* @returns {te}
|
|
147
155
|
*/
|
|
148
156
|
export declare function getOutputUpdateCLIReminder(packageManager: PackageManager, version: string): string;
|
|
149
|
-
export {};
|
package/dist/output.js
CHANGED
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
import { Bug } from './error.js';
|
|
2
|
+
import { Bug, cleanSingleStackTracePath } from './error.js';
|
|
3
3
|
import { isUnitTest, isVerbose } from './environment/local.js';
|
|
4
4
|
import constants from './constants.js';
|
|
5
|
-
import {
|
|
5
|
+
import { generateRandomUUID } from './id.js';
|
|
6
|
+
import { mkdirSync as fileMkdirSync, readSync as fileReadSync, sizeSync as fileSizeSync, writeSync as fileWriteSync, touchSync as fileTouchSync, } from './file.js';
|
|
6
7
|
import { join as pathJoin, relativize as relativizePath } from './path.js';
|
|
7
8
|
import { page } from './system.js';
|
|
8
9
|
import { colors } from './node/colors.js';
|
|
9
10
|
import terminalLink from 'terminal-link';
|
|
10
11
|
import StackTracey from 'stacktracey';
|
|
11
12
|
import { AbortController } from 'abort-controller';
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
13
|
-
// @ts-ignore
|
|
14
13
|
import cjs from 'color-json';
|
|
15
14
|
import stripAnsi from 'strip-ansi';
|
|
16
15
|
import { Writable } from 'node:stream';
|
|
17
|
-
|
|
18
|
-
export
|
|
16
|
+
import { createWriteStream } from 'node:fs';
|
|
17
|
+
export { default as logUpdate } from 'log-update';
|
|
18
|
+
const logFileName = 'shopify.cli.log';
|
|
19
|
+
let logFileStream;
|
|
20
|
+
let commandUuid;
|
|
21
|
+
export function initiateLogging(options = {}) {
|
|
22
|
+
if (isUnitTest())
|
|
23
|
+
return;
|
|
24
|
+
const logDir = options.logDir || constants.paths.directories.cache.path();
|
|
25
|
+
commandUuid = generateRandomUUID();
|
|
19
26
|
fileMkdirSync(logDir);
|
|
20
|
-
logFile = pathJoin(logDir,
|
|
27
|
+
const logFile = pathJoin(logDir, logFileName);
|
|
21
28
|
fileTouchSync(logFile);
|
|
22
|
-
truncateLogs();
|
|
29
|
+
truncateLogs(logFile);
|
|
30
|
+
logFileStream = createWriteStream(logFile, { flags: 'a' });
|
|
23
31
|
}
|
|
24
32
|
// Shaves off the first 10,000 log lines (circa 1MB) if logs are over 5MB long.
|
|
25
33
|
// Rescues in case the file hasn't been created yet.
|
|
26
|
-
function truncateLogs() {
|
|
34
|
+
function truncateLogs(logFile) {
|
|
27
35
|
try {
|
|
28
36
|
if (fileSizeSync(logFile) > 5 * 1024 * 1024) {
|
|
29
37
|
const contents = fileReadSync(logFile);
|
|
@@ -259,61 +267,69 @@ export const clearCollectedLogs = () => {
|
|
|
259
267
|
collectedLogs = {};
|
|
260
268
|
};
|
|
261
269
|
/**
|
|
262
|
-
* Ouputs information to the user.
|
|
270
|
+
* Ouputs information to the user.
|
|
263
271
|
* Info messages don't get additional formatting.
|
|
264
272
|
* Note: Info messages are sent through the standard output.
|
|
265
273
|
* @param content {string} The content to be output to the user.
|
|
274
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
266
275
|
*/
|
|
267
|
-
export const info = (content) => {
|
|
276
|
+
export const info = (content, logger = consoleLog) => {
|
|
277
|
+
const message = stringifyMessage(content);
|
|
268
278
|
if (isUnitTest())
|
|
269
279
|
collectLog('info', content);
|
|
270
|
-
|
|
280
|
+
outputWhereAppropriate('info', logger, message);
|
|
271
281
|
};
|
|
272
282
|
/**
|
|
273
283
|
* Outputs a success message to the user.
|
|
274
|
-
* Success
|
|
284
|
+
* Success messages receive a special formatting to make them stand out in the console.
|
|
275
285
|
* Note: Success messages are sent through the standard output.
|
|
276
286
|
* @param content {string} The content to be output to the user.
|
|
287
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
277
288
|
*/
|
|
278
|
-
export const success = (content) => {
|
|
289
|
+
export const success = (content, logger = consoleLog) => {
|
|
279
290
|
const message = colors.bold(`✅ Success! ${stringifyMessage(content)}.`);
|
|
280
291
|
if (isUnitTest())
|
|
281
292
|
collectLog('success', content);
|
|
282
|
-
outputWhereAppropriate('info',
|
|
293
|
+
outputWhereAppropriate('info', logger, message);
|
|
283
294
|
};
|
|
284
295
|
/**
|
|
285
296
|
* Outputs a completed message to the user.
|
|
286
297
|
* Completed message receive a special formatting to make them stand out in the console.
|
|
287
298
|
* Note: Completed messages are sent through the standard output.
|
|
288
299
|
* @param content {string} The content to be output to the user.
|
|
300
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
289
301
|
*/
|
|
290
|
-
export const completed = (content) => {
|
|
302
|
+
export const completed = (content, logger = consoleLog) => {
|
|
291
303
|
const message = `${colors.green('✔')} ${stringifyMessage(content)}`;
|
|
292
304
|
if (isUnitTest())
|
|
293
305
|
collectLog('completed', content);
|
|
294
|
-
outputWhereAppropriate('info',
|
|
306
|
+
outputWhereAppropriate('info', logger, message);
|
|
295
307
|
};
|
|
296
308
|
/**
|
|
297
309
|
* Ouputs debug information to the user. By default these output is hidden unless the user calls the CLI with --verbose.
|
|
298
310
|
* Debug messages don't get additional formatting.
|
|
299
311
|
* Note: Debug messages are sent through the standard output.
|
|
300
312
|
* @param content {string} The content to be output to the user.
|
|
313
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
301
314
|
*/
|
|
302
|
-
export const debug = (content) => {
|
|
315
|
+
export const debug = (content, logger = consoleLog) => {
|
|
303
316
|
if (isUnitTest())
|
|
304
317
|
collectLog('debug', content);
|
|
305
|
-
message
|
|
318
|
+
const message = colors.gray(stringifyMessage(content));
|
|
319
|
+
outputWhereAppropriate('debug', logger, message);
|
|
306
320
|
};
|
|
307
321
|
/**
|
|
308
322
|
* Outputs a warning message to the user.
|
|
309
323
|
* Warning messages receive a special formatting to make them stand out in the console.
|
|
310
324
|
* Note: Warning messages are sent through the standard output.
|
|
311
325
|
* @param content {string} The content to be output to the user.
|
|
326
|
+
* @param logger {Function} The logging function to use to output to the user.
|
|
312
327
|
*/
|
|
313
|
-
export const warn = (content) => {
|
|
328
|
+
export const warn = (content, logger = consoleWarn) => {
|
|
314
329
|
if (isUnitTest())
|
|
315
330
|
collectLog('warn', content);
|
|
316
|
-
|
|
331
|
+
const message = colors.yellow(stringifyMessage(content));
|
|
332
|
+
outputWhereAppropriate('warn', logger, message);
|
|
317
333
|
};
|
|
318
334
|
/**
|
|
319
335
|
* Prints a new line in the terminal.
|
|
@@ -349,7 +365,11 @@ export const error = async (content) => {
|
|
|
349
365
|
outputString += `${padding}${line}\n`;
|
|
350
366
|
}
|
|
351
367
|
}
|
|
352
|
-
let stack =
|
|
368
|
+
let stack = new StackTracey(content);
|
|
369
|
+
stack.items.forEach((item) => {
|
|
370
|
+
item.file = cleanSingleStackTracePath(item.file);
|
|
371
|
+
});
|
|
372
|
+
stack = await stack.withSourcesAsync();
|
|
353
373
|
stack = stack
|
|
354
374
|
.filter((entry) => {
|
|
355
375
|
return !entry.file.includes('@oclif/core');
|
|
@@ -465,14 +485,14 @@ function consoleError(message) {
|
|
|
465
485
|
function consoleWarn(message) {
|
|
466
486
|
console.warn(withOrWithoutStyle(message));
|
|
467
487
|
}
|
|
468
|
-
function outputWhereAppropriate(logLevel,
|
|
488
|
+
function outputWhereAppropriate(logLevel, logger, message) {
|
|
469
489
|
if (shouldOutput(logLevel)) {
|
|
470
|
-
|
|
490
|
+
logger(message);
|
|
471
491
|
}
|
|
472
492
|
logToFile(message, logLevel.toUpperCase());
|
|
473
493
|
}
|
|
474
494
|
export function logFileExists() {
|
|
475
|
-
return Boolean(
|
|
495
|
+
return Boolean(logFileStream);
|
|
476
496
|
}
|
|
477
497
|
// DO NOT USE THIS FUNCTION DIRECTLY under normal circumstances.
|
|
478
498
|
// It is exported purely for use in cases where output is already being logged
|
|
@@ -482,7 +502,8 @@ export function logToFile(message, logLevel) {
|
|
|
482
502
|
if (!logFileExists())
|
|
483
503
|
return;
|
|
484
504
|
const timestamp = new Date().toISOString();
|
|
485
|
-
|
|
505
|
+
const logContents = `[${timestamp} ${commandUuid} ${logLevel}]: ${message}\n`;
|
|
506
|
+
logFileStream.write(logContents);
|
|
486
507
|
}
|
|
487
508
|
function withOrWithoutStyle(message) {
|
|
488
509
|
if (shouldDisplayColors()) {
|
|
@@ -498,8 +519,55 @@ export function unstyled(message) {
|
|
|
498
519
|
export function shouldDisplayColors() {
|
|
499
520
|
return Boolean(process.stdout.isTTY || process.env.FORCE_COLOR);
|
|
500
521
|
}
|
|
501
|
-
export async function pageLogs() {
|
|
502
|
-
|
|
522
|
+
export async function pageLogs({ lastCommand }) {
|
|
523
|
+
const logDir = constants.paths.directories.cache.path();
|
|
524
|
+
const logFile = pathJoin(logDir, logFileName);
|
|
525
|
+
// Ensure file exists in case they deleted it or something
|
|
526
|
+
fileTouchSync(logFile);
|
|
527
|
+
if (lastCommand) {
|
|
528
|
+
printLastCommand(logFile);
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
await page(logFile);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function printLastCommand(logFile) {
|
|
535
|
+
const contents = fileReadSync(logFile).split('\n');
|
|
536
|
+
const uuids = contents
|
|
537
|
+
.map(logfileLineUUID)
|
|
538
|
+
.filter((uuid) => uuid)
|
|
539
|
+
.reverse();
|
|
540
|
+
// 2nd unique UUID, because the currently running command will be the 1st
|
|
541
|
+
const relevantUuid = Array.from(new Set(uuids))[1];
|
|
542
|
+
if (relevantUuid) {
|
|
543
|
+
consoleLog(relevantLines(contents, relevantUuid).join('\n'));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function relevantLines(contents, relevantUuid) {
|
|
547
|
+
// We run through the file line by line, keeping track of the most recently
|
|
548
|
+
// encountered UUID.
|
|
549
|
+
//
|
|
550
|
+
// If the current line has a UUID, it's a new logged unit and should be
|
|
551
|
+
// considered. Otherwise, the line is related to the most recent UUID.
|
|
552
|
+
let mostRecentUuid = '';
|
|
553
|
+
return contents.filter((line) => {
|
|
554
|
+
const currentUuid = logfileLineUUID(line) || mostRecentUuid;
|
|
555
|
+
mostRecentUuid = currentUuid;
|
|
556
|
+
return currentUuid === relevantUuid;
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
function logfileLineUUID(line) {
|
|
560
|
+
// Log lines look like:
|
|
561
|
+
//
|
|
562
|
+
// timestamp UUID contents
|
|
563
|
+
// ===========================================================================================
|
|
564
|
+
// [2022-07-20T08:51:40.296Z 5288e1da-a06a-4f96-b1a6-e34fcdd7b416 DEBUG]: Running command logs
|
|
565
|
+
// ===========================================================================================
|
|
566
|
+
//
|
|
567
|
+
// There may be subsequent lines if the contents section is multi-line.
|
|
568
|
+
//
|
|
569
|
+
const match = line.match(/^\[\S+ ([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}) [A-Z]+\]/);
|
|
570
|
+
return match && match[1];
|
|
503
571
|
}
|
|
504
572
|
/**
|
|
505
573
|
*
|