Skip to content

Commit c4fcd91

Browse files
committed
Show list of added UIDs on the first deploy
1 parent 46089a7 commit c4fcd91

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

packages/app/src/cli/services/context/id-matching.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import {RemoteSource} from './identifiers.js'
44
import {ExtensionInstance} from '../../models/extensions/extension-instance.js'
55
import {testDeveloperPlatformClient, testFunctionExtension, testUIExtension} from '../../models/app/app.test-data.js'
66
import {describe, expect, vi, test, beforeAll} from 'vitest'
7+
import {outputInfo} from '@shopify/cli-kit/node/output'
78

89
vi.mock('../dev/fetch')
910
vi.mock('../dev/create-extension')
11+
vi.mock('@shopify/cli-kit/node/output')
1012

1113
const REGISTRATION_A: RemoteSource = {
1214
uuid: 'UUID_A',
@@ -796,3 +798,35 @@ describe('automaticMatchmaking: with Atomic Deployments enabled', () => {
796798
expect(got).toEqual(expected)
797799
})
798800
})
801+
802+
describe('outputAddedIDs', () => {
803+
test('prints extension IDs when extensions are matched without UID', async () => {
804+
// Clear any previous mock calls
805+
vi.mocked(outputInfo).mockClear()
806+
807+
// Extension B has a valid UID
808+
REGISTRATION_B.id = EXTENSION_B.uid
809+
810+
// When: Extensions are matched by UUID (not by UID)
811+
await automaticMatchmaking(
812+
[EXTENSION_A, EXTENSION_B, EXTENSION_C],
813+
[REGISTRATION_A, REGISTRATION_B, REGISTRATION_C],
814+
{
815+
'extension-a': 'UUID_A',
816+
'extension-b': 'UUID_B',
817+
'extension-c': 'UUID_C',
818+
},
819+
testDeveloperPlatformClient({supportsAtomicDeployments: true}),
820+
)
821+
822+
// Then: outputInfo should be called with the expected messages
823+
expect(outputInfo).toHaveBeenCalledWith('Generating extension IDs\n')
824+
expect(outputInfo).toHaveBeenCalledWith(expect.stringContaining('\x1B[36mextension-a\x1B[39m | Added ID: UUID_A'))
825+
expect(outputInfo).not.toHaveBeenCalledWith(expect.stringContaining('Added ID: UUID_B'))
826+
expect(outputInfo).toHaveBeenCalledWith(expect.stringContaining('\x1B[35mextension-c\x1B[39m | Added ID: UUID_C'))
827+
expect(outputInfo).toHaveBeenCalledWith('\n')
828+
829+
// Verify it was called 4 times total (header + 2 extensions + footer)
830+
expect(outputInfo).toHaveBeenCalledTimes(4)
831+
})
832+
})

packages/app/src/cli/services/context/id-matching.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {groupBy, partition} from '@shopify/cli-kit/common/collection'
55
import {uniqBy, difference} from '@shopify/cli-kit/common/array'
66
import {pickBy} from '@shopify/cli-kit/common/object'
77
import {slugify} from '@shopify/cli-kit/common/string'
8+
import {outputInfo} from '@shopify/cli-kit/node/output'
9+
import colors from '@shopify/cli-kit/node/colors'
810

911
export interface LocalRemoteSource {
1012
local: LocalSource
@@ -79,32 +81,53 @@ function matchByUIDandUUID(
7981
toConfirm: {local: LocalSource; remote: RemoteSource}[]
8082
toManualMatch: {local: LocalSource[]; remote: RemoteSource[]}
8183
} {
82-
const matched: IdentifiersExtensions = {}
84+
const matchedByUID: IdentifiersExtensions = {}
8385
const pendingLocal: LocalSource[] = []
86+
const matchedByUUID: IdentifiersExtensions = {}
8487

8588
// First, try to match by UID, then by UUID.
8689
local.forEach((localSource) => {
8790
const matchByUID = remote.find((remoteSource) => remoteSource.id === localSource.uid)
8891
const matchByUUID = remote.find((remoteSource) => remoteSource.uuid === ids[localSource.localIdentifier])
8992

9093
if (matchByUID) {
91-
matched[localSource.localIdentifier] = matchByUID.id
94+
matchedByUID[localSource.localIdentifier] = matchByUID.id
9295
} else if (matchByUUID) {
93-
matched[localSource.localIdentifier] = matchByUUID.uuid
96+
matchedByUUID[localSource.localIdentifier] = matchByUUID.uuid
9497
} else {
9598
pendingLocal.push(localSource)
9699
}
97100
})
98101

99102
const pendingRemote = remote.filter(
100103
(remoteSource) =>
101-
!Object.values(matched).includes(remoteSource.uuid) && !Object.values(matched).includes(remoteSource.id),
104+
!Object.values(matchedByUUID).includes(remoteSource.uuid) &&
105+
!Object.values(matchedByUID).includes(remoteSource.id),
102106
)
103107

104108
// Then, try to match by name and type as a last resort.
105109
const {matched: matchedByName, toCreate, toConfirm, toManualMatch} = matchByNameAndType(pendingLocal, pendingRemote)
106110

107-
return {matched: {...matched, ...matchedByName}, toCreate, toConfirm, toManualMatch}
111+
// List of modules that were matched using anything other than the UID, meaning that they are being migrated to dev dash
112+
const totalMatchedWithoutUID = {...matchedByUUID, ...matchedByName}
113+
const localMatchedWithoutUID = local.filter((localSource) => totalMatchedWithoutUID[localSource.localIdentifier])
114+
115+
outputAddedIDs(localMatchedWithoutUID)
116+
117+
return {matched: {...matchedByUID, ...totalMatchedWithoutUID}, toCreate, toConfirm, toManualMatch}
118+
}
119+
120+
function outputAddedIDs(localMatchedWithoutUID: LocalSource[]) {
121+
if (localMatchedWithoutUID.length === 0) return
122+
const colorList = [colors.cyan, colors.magenta, colors.blue, colors.green, colors.yellow, colors.red]
123+
124+
const maxHandleLength = localMatchedWithoutUID.reduce((max, local) => Math.max(max, local.handle.length), 0)
125+
outputInfo('Generating extension IDs\n')
126+
localMatchedWithoutUID.forEach((local, index) => {
127+
const color = colorList[index % colorList.length] ?? colors.white
128+
outputInfo(`${color(local.handle.padStart(maxHandleLength))} | Added ID: ${local.uid}`)
129+
})
130+
outputInfo('\n')
108131
}
109132

110133
/**

0 commit comments

Comments
 (0)