Skip to content

Commit 138c1a9

Browse files
authored
SwiftPM autolinking: don't warn about spm fields mirrored in swiftpmConfig (#59634)
1 parent a6866a3 commit 138c1a9

2 files changed

Lines changed: 76 additions & 2 deletions

File tree

‎packages/react-native/scripts/spm/__tests__/swiftpm-config-test.js‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,59 @@ describe('readSwiftpmConfig', () => {
173173
warnSpy.mockRestore();
174174
}
175175
});
176+
177+
it('says nothing when swiftpmConfig mirrors every field of the spm block', () => {
178+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
179+
try {
180+
const settings = {
181+
name: 'RNSentry',
182+
dependencies: ['react-native-worklets'],
183+
};
184+
const root = makeRoot({name: 'lib', swiftpmConfig: settings});
185+
const config = readSwiftpmConfig(root, {
186+
spm: {name: 'RNSentry', dependencies: ['react-native-worklets']},
187+
});
188+
expect(config).toEqual(settings);
189+
expect(warnSpy).not.toHaveBeenCalled();
190+
} finally {
191+
warnSpy.mockRestore();
192+
}
193+
});
194+
195+
it('still warns about a field the two places disagree on', () => {
196+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
197+
try {
198+
const root = makeRoot({
199+
name: 'lib',
200+
swiftpmConfig: {name: 'RNSVG', dependencies: ['a']},
201+
});
202+
const config = readSwiftpmConfig(root, {
203+
spm: {name: 'OldName', dependencies: ['a']},
204+
});
205+
expect(config).toEqual({name: 'RNSVG', dependencies: ['a']});
206+
expect(warnSpy).toHaveBeenCalledTimes(1);
207+
const message = warnSpy.mock.calls[0].join(' ');
208+
expect(message).toContain("deprecated 'spm' block (name)");
209+
} finally {
210+
warnSpy.mockRestore();
211+
}
212+
});
213+
214+
it('names only the fields the spm block alone declares', () => {
215+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
216+
try {
217+
const root = makeRoot({name: 'lib', swiftpmConfig: {name: 'RNSVG'}});
218+
const config = readSwiftpmConfig(root, {
219+
spm: {name: 'RNSVG', dependencies: ['a']},
220+
});
221+
expect(config).toEqual({name: 'RNSVG', dependencies: ['a']});
222+
expect(warnSpy).toHaveBeenCalledTimes(1);
223+
const message = warnSpy.mock.calls[0].join(' ');
224+
expect(message).toContain("deprecated 'spm' block (dependencies)");
225+
} finally {
226+
warnSpy.mockRestore();
227+
}
228+
});
176229
});
177230

178231
describe('readSwiftpmConfig (unknown keys)', () => {

‎packages/react-native/scripts/spm/swiftpm-config.js‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict';
1212

1313
const {isValidSwiftName, makeLogger} = require('./spm-utils');
14+
const assert = require('node:assert');
1415
const fs = require('node:fs');
1516
const path = require('node:path');
1617

@@ -100,6 +101,20 @@ function declaredFields(
100101
: SWIFTPM_FIELDS.filter(field => config[field] !== undefined);
101102
}
102103

104+
// util.isDeepStrictEqual is missing from the Flow library definitions.
105+
function sameField(
106+
a /*: ?{readonly [string]: unknown} */,
107+
b /*: ?{readonly [string]: unknown} */,
108+
field /*: string */,
109+
) /*: boolean */ {
110+
try {
111+
assert.deepStrictEqual(a?.[field], b?.[field]);
112+
return true;
113+
} catch {
114+
return false;
115+
}
116+
}
117+
103118
function stringList(value /*: unknown */) /*: Array<string> */ {
104119
return Array.isArray(value) ? value.filter(v => typeof v === 'string') : [];
105120
}
@@ -155,8 +170,14 @@ function readSwiftpmConfig(
155170
}
156171
const deprecated = objectField(rnConfig, 'spm');
157172
const deprecatedFields = declaredFields(deprecated);
158-
if (deprecatedFields.length > 0) {
159-
reportDeprecation(root, deprecatedFields);
173+
// A library that supports React Native versions reading only the `spm`
174+
// block must declare a field in both places, so an identical copy is not
175+
// something it can act on.
176+
const unmirroredFields = deprecatedFields.filter(
177+
field => !sameField(fromPackageJson, deprecated, field),
178+
);
179+
if (unmirroredFields.length > 0) {
180+
reportDeprecation(root, unmirroredFields);
160181
}
161182
if (fromPackageJson == null) {
162183
return deprecatedFields.length > 0 ? deprecated : null;

0 commit comments

Comments
 (0)