diff --git a/packages/cli-kit/src/public/node/context/local.test.ts b/packages/cli-kit/src/public/node/context/local.test.ts index abe71bb52b7..930a11b8ae5 100644 --- a/packages/cli-kit/src/public/node/context/local.test.ts +++ b/packages/cli-kit/src/public/node/context/local.test.ts @@ -3,6 +3,7 @@ import { hasGit, isDevelopment, isShopify, + _resetIsShopifyCache, isTerminalInteractive, isUnitTest, analyticsDisabled, @@ -97,6 +98,10 @@ describe('isDevelopment', () => { }) describe('isShopify', () => { + afterEach(() => { + _resetIsShopifyCache() + }) + test('returns false when the SHOPIFY_RUN_AS_USER env. variable is truthy', async () => { // Given const env = {SHOPIFY_RUN_AS_USER: '1'} @@ -120,6 +125,18 @@ describe('isShopify', () => { // When await expect(isShopify()).resolves.toBe(true) }) + + test('memoizes the result', async () => { + // Given + vi.mocked(fileExists).mockResolvedValue(true) + + // When + await isShopify() + await isShopify() + + // Then + expect(fileExists).toHaveBeenCalledTimes(1) + }) }) describe('hasGit', () => { diff --git a/packages/cli-kit/src/public/node/context/local.ts b/packages/cli-kit/src/public/node/context/local.ts index ad816399db9..675292e2ad9 100644 --- a/packages/cli-kit/src/public/node/context/local.ts +++ b/packages/cli-kit/src/public/node/context/local.ts @@ -44,6 +44,11 @@ let memoizedIsVerbose: boolean | undefined */ let memoizedIsUnitTest: boolean | undefined +/** + * Memoized value for the shopify check. + */ +let memoizedIsShopify: Promise | undefined + /** * Returns true if the CLI is running in debug mode. * @@ -77,11 +82,22 @@ export function isVerbose(env = process.env): boolean { * @returns True if the CLI is used in a Shopify environment. */ export async function isShopify(env = process.env): Promise { - if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) { - return !isTruthy(env[environmentVariables.runAsUser]) + if (env === process.env && memoizedIsShopify !== undefined) { + return memoizedIsShopify + } + + const resultPromise = (async () => { + if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) { + return !isTruthy(env[environmentVariables.runAsUser]) + } else { + return lazyFileExists(pathConstants.executables.dev) + } + })() + + if (env === process.env) { + memoizedIsShopify = resultPromise } - const devInstalled = await lazyFileExists(pathConstants.executables.dev) - return devInstalled + return resultPromise } /** @@ -325,4 +341,12 @@ export function opentelemetryDomain(env = process.env): string { return isSet(domain) ? domain : 'https://otlp-http-production-cli.shopifysvc.com' } +/** + * This function is only used during UnitTesting. + * It resets the memoized value of the shopify check. + */ +export function _resetIsShopifyCache(): void { + memoizedIsShopify = undefined +} + export type CIMetadata = Metadata