Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion packages/cli-kit/src/public/node/context/local.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
hasGit,
isDevelopment,
isShopify,
_resetIsShopifyMemo,
isTerminalInteractive,
isUnitTest,
analyticsDisabled,
Expand All @@ -14,7 +15,7 @@ import {
import {fileExists} from '../fs.js'
import {exec} from '../system.js'

import {afterEach, expect, describe, vi, test} from 'vitest'
import {afterEach, beforeEach, expect, describe, vi, test} from 'vitest'

vi.mock('../fs.js')
vi.mock('../system.js')
Expand Down Expand Up @@ -97,6 +98,10 @@ describe('isDevelopment', () => {
})

describe('isShopify', () => {
beforeEach(() => {
_resetIsShopifyMemo()
})

test('returns false when the SHOPIFY_RUN_AS_USER env. variable is truthy', async () => {
// Given
const env = {SHOPIFY_RUN_AS_USER: '1'}
Expand All @@ -120,6 +125,21 @@ describe('isShopify', () => {
// When
await expect(isShopify()).resolves.toBe(true)
})

test('memoizes the result when called with the same env', async () => {
// Given
vi.mocked(fileExists).mockResolvedValue(true)

// When
const first = isShopify()
const second = isShopify()

// Then
await expect(first).resolves.toBe(true)
await expect(second).resolves.toBe(true)
expect(first).toBe(second)
expect(fileExists).toHaveBeenCalledTimes(1)
})
})

describe('hasGit', () => {
Expand Down
36 changes: 31 additions & 5 deletions packages/cli-kit/src/public/node/context/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ let memoizedIsVerbose: boolean | undefined
*/
let memoizedIsUnitTest: boolean | undefined

/**
* Memoized value for the Shopify check.
*/
let memoizedIsShopify: Promise<boolean> | undefined

/**
* Returns true if the CLI is running in debug mode.
*
Expand Down Expand Up @@ -76,12 +81,33 @@ export function isVerbose(env = process.env): boolean {
* @param env - The environment variables from the environment of the current process.
* @returns True if the CLI is used in a Shopify environment.
*/
export async function isShopify(env = process.env): Promise<boolean> {
if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) {
return !isTruthy(env[environmentVariables.runAsUser])
export function isShopify(env = process.env): Promise<boolean> {
if (env === process.env && memoizedIsShopify !== undefined) {
// Memoize the result to avoid repeated filesystem checks for the presence of the dev binary.
return memoizedIsShopify
}
const devInstalled = await lazyFileExists(pathConstants.executables.dev)
return devInstalled

const resultPromise = (async () => {
if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) {
return !isTruthy(env[environmentVariables.runAsUser])
}
const devInstalled = await lazyFileExists(pathConstants.executables.dev)
return devInstalled
})()

if (env === process.env) {
memoizedIsShopify = resultPromise
}

return resultPromise
}

/**
* Resets the memoized value for the Shopify check.
* This is only used for testing purposes.
*/
export function _resetIsShopifyMemo(): void {
memoizedIsShopify = undefined
}

/**
Expand Down
Loading