Skip to content

Commit 9ef86dd

Browse files
committed
[platform-ios/native_modules] Add platform specificity
Only include pods in targets that target platforms the pod supports.
1 parent 81fb8ef commit 9ef86dd

File tree

4 files changed

+167
-84
lines changed

4 files changed

+167
-84
lines changed

packages/platform-ios/native_modules.rb

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ def use_native_modules!(config = nil)
6060

6161
spec = Pod::Specification.from_file(podspec_path)
6262

63+
# Skip pods that do not support the platform of the current target.
64+
if platform = current_target_definition.platform
65+
next unless spec.supported_on_platform?(platform.name)
66+
else
67+
# TODO: In a future RN version we should update the Podfile template and
68+
# enable this assertion.
69+
#
70+
# raise Pod::Informative, "Cannot invoke `use_native_modules!` before defining the supported `platform`"
71+
end
72+
6373
# We want to do a look up inside the current CocoaPods target
6474
# to see if it's already included, this:
6575
# 1. Gives you the chance to define it beforehand
@@ -117,28 +127,29 @@ def use_native_modules!(config = nil)
117127
# $ yarn jest packages/platform-ios/src/config/__tests__/native_modules.test.ts
118128
if $0 == __FILE__
119129
require "json"
120-
targets = JSON.parse(ARGF.read)
130+
runInput = JSON.parse(ARGF.read)
121131

122-
unless targets["capture_stdout"]
132+
unless runInput["capture_stdout"]
123133
Pod::Config.instance.silent = true
124134
end
125135

126136
podfile = Pod::Podfile.new do
127-
if targets["pods_activated_by_user"]
128-
targets["pods_activated_by_user"].each do |name|
137+
if runInput["pods_activated_by_user"]
138+
runInput["pods_activated_by_user"].each do |name|
129139
pod(name)
130140
end
131141
end
132-
targets.each do |name, config|
133-
next if ["capture_stdout", "pods_activated_by_user"].include?(name)
134-
target(name) do
135-
platform(name.to_sym)
136-
use_native_modules!(config)
137-
end
142+
target 'iOS Target' do
143+
platform :ios
144+
use_native_modules!(runInput["config"])
145+
end
146+
target 'macOS Target' do
147+
platform :osx
148+
use_native_modules!(runInput["config"])
138149
end
139150
end
140151

141-
unless targets["capture_stdout"]
152+
unless runInput["capture_stdout"]
142153
puts podfile.to_hash.to_json
143154
end
144155
end

packages/platform-ios/src/config/__fixtures__/native_modules/node_modules/ios-and-macos-dep/ios-and-macos-dep.podspec

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/platform-ios/src/config/__fixtures__/native_modules/node_modules/macos-dep/macos-dep.podspec

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/platform-ios/src/config/__tests__/native_modules.test.ts

Lines changed: 137 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ interface SerializedPodfile {
2727
interface RunInput {
2828
capture_stdout?: boolean;
2929
pods_activated_by_user?: string[];
30-
ios: IOSNativeModulesConfig;
30+
config: IOSNativeModulesConfig;
3131
}
3232

33-
function run(config: RunInput) {
33+
function run(runInput: RunInput) {
3434
return new Promise<SerializedTargetDefinition | string>((resolve, reject) => {
3535
const child = spawn('ruby', [SCRIPT_PATH]);
36-
child.stdin.write(JSON.stringify(config));
36+
child.stdin.write(JSON.stringify(runInput));
3737
child.stdin.end();
3838
const stdoutData: Buffer[] = [];
3939
const stderrData: Buffer[] = [];
@@ -46,7 +46,7 @@ function run(config: RunInput) {
4646
child.on('close', code => {
4747
if (code === 0) {
4848
const data = Buffer.concat(stdoutData).toString();
49-
if (config.capture_stdout) {
49+
if (runInput.capture_stdout) {
5050
resolve(data.trimRight());
5151
} else {
5252
const podfile: SerializedPodfile = JSON.parse(data);
@@ -60,15 +60,15 @@ function run(config: RunInput) {
6060
}
6161

6262
describe('native_modules.rb', () => {
63-
let config: RunInput;
63+
let runInput: RunInput;
6464

6565
beforeEach(() => {
6666
const iosDepPodspecPath = path.join(
6767
FIXTURES_ROOT,
6868
'node_modules/ios-dep/ios-dep.podspec',
6969
);
70-
config = {
71-
ios: {
70+
runInput = {
71+
config: {
7272
project: {ios: {sourceDir: FIXTURES_ROOT}},
7373
dependencies: {
7474
'ios-dep': {
@@ -90,29 +90,117 @@ describe('native_modules.rb', () => {
9090
};
9191
});
9292

93-
it('activates iOS pods', () => {
94-
return run(config).then(rootTargetDefinition => {
93+
describe('concerning platform specificity', () => {
94+
beforeEach(() => {
95+
runInput.config.dependencies['macos-dep'] = {
96+
root: path.join(FIXTURES_ROOT, 'node_modules/macos-dep'),
97+
platforms: {
98+
ios: {
99+
podspecPath: path.join(
100+
FIXTURES_ROOT,
101+
'node_modules/macos-dep/macos-dep.podspec',
102+
),
103+
},
104+
android: null,
105+
},
106+
};
107+
runInput.config.dependencies['ios-and-macos-dep'] = {
108+
root: path.join(FIXTURES_ROOT, 'node_modules/ios-and-macos-dep'),
109+
platforms: {
110+
ios: {
111+
podspecPath: path.join(
112+
FIXTURES_ROOT,
113+
'node_modules/ios-and-macos-dep/ios-and-macos-dep.podspec',
114+
),
115+
},
116+
android: null,
117+
},
118+
};
119+
});
120+
121+
it('only activates pods that support iOS in targets that target `ios`', () => {
122+
return run(runInput).then(
123+
(rootTargetDefinition: SerializedTargetDefinition) => {
124+
expect(
125+
rootTargetDefinition.children.find(
126+
target => target.name === 'iOS Target',
127+
).dependencies,
128+
).toMatchInlineSnapshot(`
129+
Array [
130+
Object {
131+
"ios-dep": Array [
132+
Object {
133+
"path": "node_modules/ios-dep",
134+
},
135+
],
136+
},
137+
Object {
138+
"ios-and-macos-dep": Array [
139+
Object {
140+
"path": "node_modules/ios-and-macos-dep",
141+
},
142+
],
143+
},
144+
]
145+
`);
146+
},
147+
);
148+
});
149+
150+
it('only activates pods that support macOS in targets that target `osx`', () => {
151+
return run(runInput).then(
152+
(rootTargetDefinition: SerializedTargetDefinition) => {
153+
expect(
154+
rootTargetDefinition.children.find(
155+
target => target.name === 'macOS Target',
156+
).dependencies,
157+
).toMatchInlineSnapshot(`
158+
Array [
159+
Object {
160+
"macos-dep": Array [
161+
Object {
162+
"path": "node_modules/macos-dep",
163+
},
164+
],
165+
},
166+
Object {
167+
"ios-and-macos-dep": Array [
168+
Object {
169+
"path": "node_modules/ios-and-macos-dep",
170+
},
171+
],
172+
},
173+
]
174+
`);
175+
},
176+
);
177+
});
178+
});
179+
180+
it('does not activate pods that were already activated previously (by the user in their Podfile)', () => {
181+
return run({
182+
pods_activated_by_user: ['ios-dep'],
183+
...runInput,
184+
}).then(rootTargetDefinition => {
95185
expect(rootTargetDefinition).toMatchInlineSnapshot(`
96186
Object {
97187
"abstract": true,
98188
"children": Array [
99189
Object {
100-
"dependencies": Array [
101-
Object {
102-
"ios-dep": Array [
103-
Object {
104-
"path": "node_modules/ios-dep",
105-
},
106-
],
107-
},
108-
],
190+
"dependencies": null,
109191
"inheritance": "complete",
110-
"name": "ios",
192+
"name": "iOS Target",
111193
"platform": "ios",
112194
"podspecs": null,
113195
},
196+
Object {
197+
"name": "macOS Target",
198+
"platform": "osx",
199+
},
200+
],
201+
"dependencies": Array [
202+
"ios-dep",
114203
],
115-
"dependencies": null,
116204
"name": "Pods",
117205
"platform": null,
118206
"podspecs": null,
@@ -121,82 +209,58 @@ describe('native_modules.rb', () => {
121209
});
122210
});
123211

124-
it('does not activate pods that were already activated previously (by the user in their Podfile)', () => {
125-
return run({
126-
pods_activated_by_user: ['ios-dep'],
127-
...config,
128-
}).then(rootTargetDefinition => {
129-
expect(rootTargetDefinition).toMatchInlineSnapshot(`
130-
Object {
131-
"abstract": true,
132-
"children": Array [
133-
Object {
134-
"dependencies": null,
135-
"inheritance": "complete",
136-
"name": "ios",
137-
"platform": "ios",
138-
"podspecs": null,
139-
},
140-
],
141-
"dependencies": Array [
142-
"ios-dep",
143-
],
144-
"name": "Pods",
145-
"platform": null,
146-
"podspecs": null,
147-
}
148-
`);
149-
});
150-
});
151-
152212
it('does not activate pods whose root spec were already activated previously (by the user in their Podfile)', () => {
153213
return run({
154214
pods_activated_by_user: ['ios-dep/foo/bar'],
155-
...config,
215+
...runInput,
156216
}).then(rootTargetDefinition => {
157217
expect(rootTargetDefinition).toMatchInlineSnapshot(`
158-
Object {
159-
"abstract": true,
160-
"children": Array [
161-
Object {
162-
"dependencies": null,
163-
"inheritance": "complete",
164-
"name": "ios",
165-
"platform": "ios",
166-
"podspecs": null,
167-
},
168-
],
169-
"dependencies": Array [
170-
"ios-dep/foo/bar",
171-
],
172-
"name": "Pods",
173-
"platform": null,
174-
"podspecs": null,
175-
}
176-
`);
218+
Object {
219+
"abstract": true,
220+
"children": Array [
221+
Object {
222+
"dependencies": null,
223+
"inheritance": "complete",
224+
"name": "iOS Target",
225+
"platform": "ios",
226+
"podspecs": null,
227+
},
228+
Object {
229+
"name": "macOS Target",
230+
"platform": "osx",
231+
},
232+
],
233+
"dependencies": Array [
234+
"ios-dep/foo/bar",
235+
],
236+
"name": "Pods",
237+
"platform": null,
238+
"podspecs": null,
239+
}
240+
`);
177241
});
178242
});
179243

180244
// TODO: Add a second pod
181245
it('prints out the native module pods that were found', () => {
182246
return run({
183247
capture_stdout: true,
184-
...config,
248+
...runInput,
185249
}).then(stdout => {
186250
expect(stdout).toEqual('Detected React Native module pod for ios-dep');
187251
});
188252
});
189253

190254
describe('concerning script_phases', () => {
191255
it('uses the options directly', () => {
192-
config.ios.dependencies['ios-dep'].platforms.ios.scriptPhases = [
256+
runInput.config.dependencies['ios-dep'].platforms.ios.scriptPhases = [
193257
{
194258
script: '123',
195259
name: 'My Name',
196260
execution_position: 'before_compile',
197261
},
198262
];
199-
return run(config).then(
263+
return run(runInput).then(
200264
(rootTargetDefinition: SerializedTargetDefinition) => {
201265
expect(rootTargetDefinition.children[0].script_phases)
202266
.toMatchInlineSnapshot(`
@@ -213,14 +277,14 @@ describe('native_modules.rb', () => {
213277
});
214278

215279
it('reads a script file relative to the package root', () => {
216-
config.ios.dependencies['ios-dep'].platforms.ios.scriptPhases = [
280+
runInput.config.dependencies['ios-dep'].platforms.ios.scriptPhases = [
217281
{
218282
path: './some_shell_script.sh',
219283
name: 'My Name',
220284
execution_position: 'before_compile',
221285
},
222286
];
223-
return run(config).then(
287+
return run(runInput).then(
224288
(rootTargetDefinition: SerializedTargetDefinition) => {
225289
expect(rootTargetDefinition.children[0].script_phases)
226290
.toMatchInlineSnapshot(`

0 commit comments

Comments
 (0)