-
Notifications
You must be signed in to change notification settings - Fork 906
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make
react-native link
play nicely with CocoaPods-based iOS projects.
Summary: The core React Native codebase already has full support for CocoaPods. However, `react-native link` doesn’t play nicely with CocoaPods, so installing third-party libs from the RN ecosystem is really hard. This change will allow to link projects that contains its own `.podspec` file to CocoaPods-based projects. In case `link` detect `Podfile` in `iOS` directory, it will look for related `.podspec` file in linked project directory, and add it to `Podfile`. If `Podfile` and `.podspec` files are not present, it will fall back to previous implementation. **Test Plan** 1. Build a React Native project where the iOS part uses CocoaPods to manage its dependencies. The most common scenario here is to have React Native be a Pod dependency, among others. 2. Install a RN-related library, that contains `.podspec` file, with `react-native link` (as an example it could be: [react-native-maps](https://github.com/airbnb/react-native-maps) 3. Building the resulting iOS workspace should succeed (and there should be new entry in `Podfile`) Closes facebook/react-native#15460 Differential Revision: D6078649 Pulled By: hramos fbshipit-source-id: 9651085875892fd66299563ca0e42fb2bcc00825
- Loading branch information
1 parent
daee51d
commit f2d2de9
Showing
28 changed files
with
541 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
'use strict'; | ||
|
||
jest.mock('fs'); | ||
|
||
const findPodfilePath = require('../../ios/findPodfilePath'); | ||
const fs = require('fs'); | ||
const projects = require('../../__fixtures__/projects'); | ||
const ios = require('../../__fixtures__/ios'); | ||
|
||
describe('ios::findPodfilePath', () => { | ||
it('returns null if there is no Podfile', () => { | ||
fs.__setMockFilesystem(ios.valid); | ||
expect(findPodfilePath('')).toBeNull(); | ||
}); | ||
|
||
it('returns Podfile path if it exists', () => { | ||
fs.__setMockFilesystem(projects.withPods); | ||
expect(findPodfilePath('/ios')).toContain('Podfile'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
'use strict'; | ||
|
||
jest.mock('fs'); | ||
|
||
const findPodspecName = require('../../ios/findPodspecName'); | ||
const fs = require('fs'); | ||
const projects = require('../../__fixtures__/projects'); | ||
const ios = require('../../__fixtures__/ios'); | ||
|
||
describe('ios::findPodspecName', () => { | ||
it('returns null if there is not podspec file', () => { | ||
fs.__setMockFilesystem(projects.flat); | ||
expect(findPodspecName('')).toBeNull(); | ||
}); | ||
|
||
it('returns podspec name if only one exists', () => { | ||
fs.__setMockFilesystem(ios.pod); | ||
expect(findPodspecName('/')).toBe('TestPod'); | ||
}); | ||
|
||
it('returns podspec name that match packet directory', () => { | ||
fs.__setMockFilesystem({ | ||
user: { | ||
PacketName: { | ||
'Another.podspec': 'empty', | ||
'PacketName.podspec': 'empty' | ||
} | ||
} | ||
}); | ||
expect(findPodspecName('/user/PacketName')).toBe('PacketName'); | ||
}); | ||
|
||
it('returns first podspec name if not match in directory', () => { | ||
fs.__setMockFilesystem({ | ||
user: { | ||
packet: { | ||
'Another.podspec': 'empty', | ||
'PacketName.podspec': 'empty' | ||
} | ||
} | ||
}); | ||
expect(findPodspecName('/user/packet')).toBe('Another'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
'use strict'; | ||
|
||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
module.exports = function findPodfilePath(projectFolder) { | ||
const podFilePath = path.join(projectFolder, '..', 'Podfile'); | ||
const podFileExists = fs.existsSync(podFilePath); | ||
|
||
return podFileExists ? podFilePath : null; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
'use strict'; | ||
|
||
const glob = require('glob'); | ||
const path = require('path'); | ||
|
||
module.exports = function findPodspecName(folder) { | ||
const podspecs = glob.sync('*.podspec', { cwd: folder }); | ||
let podspecFile = null; | ||
if (podspecs.length === 0) { | ||
return null; | ||
} | ||
else if (podspecs.length === 1) { | ||
podspecFile = podspecs[0]; | ||
} | ||
else { | ||
const folderParts = folder.split(path.sep); | ||
const currentFolder = folderParts[folderParts.length - 1]; | ||
const toSelect = podspecs.indexOf(currentFolder + '.podspec'); | ||
if (toSelect === -1) { | ||
podspecFile = podspecs[0]; | ||
} | ||
else { | ||
podspecFile = podspecs[toSelect]; | ||
} | ||
} | ||
|
||
return podspecFile.replace('.podspec', ''); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
source 'https://github.com/CocoaPods/Specs.git' | ||
platform :ios, '9.0' | ||
|
||
target 'Testing' do | ||
pod 'TestPod', '~> 3.1' | ||
|
||
# test should point to this line | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
source 'https://github.com/CocoaPods/Specs.git' | ||
platform :ios, '9.0' | ||
|
||
target 'none' do | ||
pod 'React', | ||
:path => "../node_modules/react-native", | ||
:subspecs => [ | ||
"Core", | ||
"ART", | ||
"RCTActionSheet", | ||
"RCTAnimation", | ||
"RCTCameraRoll", | ||
"RCTGeolocation", | ||
"RCTImage", | ||
"RCTNetwork", | ||
"RCTText", | ||
"RCTVibration", | ||
"RCTWebSocket", | ||
"DevSupport", | ||
"BatchedBridge" | ||
] | ||
|
||
pod 'Yoga', | ||
:path => "../node_modules/react-native/ReactCommon/yoga" | ||
|
||
# test should point to this line | ||
post_install do |installer| | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
source 'https://github.com/CocoaPods/Specs.git' | ||
# platform :ios, '9.0' | ||
|
||
target 'None' do | ||
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks | ||
# use_frameworks! | ||
# Your 'node_modules' directory is probably in the root of your project, # but if not, adjust the `:path` accordingly | ||
pod 'React', :path => '../node_modules/react-native', :subspecs => [ | ||
'Core', | ||
'RCTText', | ||
'RCTNetwork', | ||
'BatchedBridge', | ||
'RCTImage', | ||
'RCTWebSocket', # needed for debugging | ||
# Add any other subspecs you want to use in your project | ||
] | ||
|
||
# Add new pods below this line | ||
|
||
# test should point to this line | ||
target 'NoneTests' do | ||
inherit! :search_paths | ||
# Pods for testing | ||
end | ||
end | ||
|
||
target 'Second' do | ||
|
||
target 'NoneUITests' do | ||
inherit! :search_paths | ||
# Add new pods below this line | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
source 'https://github.com/CocoaPods/Specs.git' | ||
# platform :ios, '9.0' | ||
|
||
target 'None' do | ||
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks | ||
# use_frameworks! | ||
# Your 'node_modules' directory is probably in the root of your project, # but if not, adjust the `:path` accordingly | ||
pod 'React', :path => '../node_modules/react-native', :subspecs => [ | ||
'Core', | ||
'RCTText', | ||
'RCTNetwork', | ||
'BatchedBridge', | ||
'RCTImage', | ||
'RCTWebSocket', # needed for debugging | ||
# Add any other subspecs you want to use in your project | ||
] | ||
|
||
# Explicitly include Yoga if you are using RN >= 0.42.0 | ||
pod "Yoga", :path => "../node_modules/react-native/ReactCommon/yoga" | ||
|
||
# test should point to this line | ||
target 'NoneTests' do | ||
inherit! :search_paths | ||
# Pods for testing | ||
end | ||
|
||
target 'NoneUITests' do | ||
inherit! :search_paths | ||
# Pods for testing | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
const findLineToAddPod = require('../../pods/findLineToAddPod'); | ||
const readPodfile = require('../../pods/readPodfile'); | ||
|
||
const PODFILES_PATH = path.join(__dirname, '../../__fixtures__/pods'); | ||
const LINE_AFTER_TARGET_IN_TEST_PODFILE = 4; | ||
|
||
describe('pods::findLineToAddPod', () => { | ||
it('returns null if file is not Podfile', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, '../Info.plist')); | ||
expect(findLineToAddPod(podfile, LINE_AFTER_TARGET_IN_TEST_PODFILE)).toBeNull(); | ||
}); | ||
|
||
it('returns correct line number for Simple Podfile', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileSimple')); | ||
expect(findLineToAddPod(podfile, LINE_AFTER_TARGET_IN_TEST_PODFILE)).toEqual({ line: 7, indentation: 2 }); | ||
}); | ||
|
||
it('returns correct line number for Podfile with target', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileWithTarget')); | ||
expect(findLineToAddPod(podfile, LINE_AFTER_TARGET_IN_TEST_PODFILE)).toEqual({ line: 21, indentation: 2 }); | ||
}); | ||
|
||
it('returns correct line number for Podfile with function', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileWithFunction')); | ||
expect(findLineToAddPod(podfile, LINE_AFTER_TARGET_IN_TEST_PODFILE)).toEqual({ line: 26, indentation: 2 }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
const readPodfile = require('../../pods/readPodfile'); | ||
const findMarkedLinesInPodfile = require('../../pods/findMarkedLinesInPodfile'); | ||
|
||
const PODFILES_PATH = path.join(__dirname, '../../__fixtures__/pods'); | ||
const LINE_AFTER_TARGET_IN_TEST_PODFILE = 4; | ||
|
||
describe('pods::findMarkedLinesInPodfile', () => { | ||
it('returns empty array if file is not Podfile', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, '../Info.plist')); | ||
expect(findMarkedLinesInPodfile(podfile)).toEqual([]); | ||
}); | ||
|
||
it('returns empty array for Simple Podfile', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileSimple')); | ||
expect(findMarkedLinesInPodfile(podfile, LINE_AFTER_TARGET_IN_TEST_PODFILE)).toEqual([]); | ||
}); | ||
|
||
it('returns correct line numbers for Podfile with marker', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileWithMarkers')); | ||
const expectedObject = [{ line: 18, indentation: 2 }, { line: 31, indentation: 4 }]; | ||
expect(findMarkedLinesInPodfile(podfile, LINE_AFTER_TARGET_IN_TEST_PODFILE)).toEqual(expectedObject); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
const findPodTargetLine = require('../../pods/findPodTargetLine'); | ||
const readPodfile = require('../../pods/readPodfile'); | ||
|
||
const PODFILES_PATH = path.join(__dirname, '../../__fixtures__/pods'); | ||
|
||
describe('pods::findPodTargetLine', () => { | ||
it('returns null if file is not Podfile', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, '../Info.plist')); | ||
expect(findPodTargetLine(podfile, 'name')).toBeNull(); | ||
}); | ||
|
||
it('returns null if there is not matching project name', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileSimple')); | ||
expect(findPodTargetLine(podfile, 'invalidName')).toBeNull(); | ||
}); | ||
|
||
it('returns null if there is not matching project name', () => { | ||
const podfile = readPodfile(path.join(PODFILES_PATH, 'PodfileSimple')); | ||
expect(findPodTargetLine(podfile, 'Testing')).toBe(4); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
const isInstalled = require('../../pods/isInstalled'); | ||
|
||
const PODFILES_PATH = path.join(__dirname, '../../__fixtures__/pods'); | ||
|
||
describe('pods::isInstalled', () => { | ||
it('returns false if pod is missing', () => { | ||
const project = { podfile: path.join(PODFILES_PATH, 'PodfileSimple') }; | ||
const podspecName = { podspec: 'NotExisting' }; | ||
expect(isInstalled(project, podspecName)).toBe(false); | ||
}); | ||
|
||
it('returns true for existing pod with version number', () => { | ||
const project = { podfile: path.join(PODFILES_PATH, 'PodfileSimple') }; | ||
const podspecName = { podspec: 'TestPod' }; | ||
expect(isInstalled(project, podspecName)).toBe(true); | ||
}); | ||
|
||
it('returns true for existing pod with path', () => { | ||
const project = { podfile: path.join(PODFILES_PATH, 'PodfileWithTarget') }; | ||
const podspecName = { podspec: 'Yoga' }; | ||
expect(isInstalled(project, podspecName)).toBe(true); | ||
}); | ||
|
||
it('returns true for existing pod with multiline definition', () => { | ||
const project = { podfile: path.join(PODFILES_PATH, 'PodfileWithFunction') }; | ||
const podspecName = { podspec: 'React' }; | ||
expect(isInstalled(project, podspecName)).toBe(true); | ||
}); | ||
}); |
Oops, something went wrong.