UNPKG

5.14 kBJavaScriptView Raw
1const fs = require('fs')
2const log = require('npmlog')
3const path = require('path')
4const xcode = require('xcode')
5
6log.heading = 'react-native-branch'
7
8function addBranchConfigToXcodeProject() {
9 const projectName = findXcodeProjectName()
10 if (!projectName) {
11 log.error('could not find an Xcode project')
12 return
13 }
14
15 const xcodeprojPath = path.join('.', 'ios', projectName + '.xcodeproj')
16 const projectPbxprojPath = path.join(xcodeprojPath, 'project.pbxproj')
17
18 const project = xcode.project(projectPbxprojPath)
19 project.parse(function(error) {
20 if (error) {
21 log.error('Error loading ' + xcodeprojPath)
22 return
23 }
24
25 if (fs.existsSync(path.join('.', 'branch.ios.json'))) {
26 includePathInProject(project, projectName, path.join('..', 'branch.ios.json'))
27 }
28 else if (fs.existsSync(path.join('.', 'branch.json'))) {
29 includePathInProject(project, projectName, path.join('..', 'branch.json'))
30 }
31
32 if (fs.existsSync(path.join('.', 'branch.ios.debug.json'))) {
33 includePathInProject(project, projectName, path.join('..', 'branch.ios.debug.json'))
34 }
35 else if (fs.existsSync(path.join('.', 'branch.debug.json'))) {
36 includePathInProject(project, projectName, path.join('..', 'branch.debug.json'))
37 }
38
39 if (fs.writeFileSync(projectPbxprojPath, project.writeSync()) <= 0) {
40 log.error('error writing updated project')
41 return
42 }
43
44 log.info('Added Branch configuration to project ' + xcodeprojPath)
45 })
46}
47
48function removeBranchConfigFromXcodeProject() {
49 const projectName = findXcodeProjectName()
50 if (!projectName) {
51 log.error('could not find an Xcode project')
52 return
53 }
54
55 const xcodeprojPath = path.join('.', 'ios', projectName + '.xcodeproj')
56 const projectPbxprojPath = path.join(xcodeprojPath, 'project.pbxproj')
57
58 const project = xcode.project(projectPbxprojPath)
59 project.parse(function(error) {
60 if (error) {
61 log.error('Error loading ' + xcodeprojPath)
62 return
63 }
64
65 // paths relative to group
66 removePathFromProject(project, projectName, path.join('..', 'branch.json'))
67 removePathFromProject(project, projectName, path.join('..', 'branch.debug.json'))
68 removePathFromProject(project, projectName, path.join('..', 'branch.ios.json'))
69 removePathFromProject(project, projectName, path.join('..', 'branch.ios.debug.json'))
70
71 if (fs.writeFileSync(projectPbxprojPath, project.writeSync()) <= 0) {
72 log.error('error writing updated project')
73 return
74 }
75
76 log.info('Removed Branch configuration from project ' + xcodeprojPath)
77 })
78}
79
80function includePathInProject(project, groupName, path) {
81 const groupKey = getGroupKeyByName(project, groupName)
82 if (!groupKey) {
83 log.error('Could not find key for group ' + groupName)
84 return
85 }
86
87 // path relative to group
88 const file = project.addFile(path, groupKey)
89 if (!file) {
90 // TODO: Can get here if the file is already in the project
91 log.error('Failed to add file to project')
92 return
93 }
94
95 file.uuid = project.generateUuid()
96 file.target = getTargetKeyByName(project, groupName)
97 correctForPath(file, project, groupName)
98
99 project.addToPbxBuildFileSection(file)
100 project.addToPbxResourcesBuildPhase(file)
101}
102
103function removePathFromProject(project, groupName, path) {
104 const file = project.removeFile(path, {})
105 if (!file) {
106 log.warn('Did not find ' + path + ' in project')
107 return
108 }
109
110 file.target = getTargetKeyByName(project, groupName)
111 correctForPath(file, project, groupName)
112
113 const groupKey = getGroupKeyByName(project, groupName)
114 if (!groupKey) {
115 log.error('Could not find key for group ' + groupName)
116 return
117 }
118
119 project.removeFromPbxBuildFileSection(file)
120 project.removeFromPbxResourcesBuildPhase(file)
121 project.removeFromPbxGroup(file, groupKey)
122}
123
124function getGroupKeyByName(project, groupName) {
125 const objects = project.hash.project.objects['PBXGroup']
126 for (const key in objects) {
127 const name = objects[key].name
128 if (name == groupName) return key
129 }
130 return null
131}
132
133function getTargetKeyByName(project, targetName) {
134 const targets = project.pbxNativeTargetSection()
135 for (const key in targets) {
136 const name = targets[key].name
137 if (name == targetName) return key
138 }
139 return null
140}
141
142function correctForPath(file, project, group) {
143 const r_group_dir = new RegExp('^' + group + '[\\\\/]');
144
145 if (project.pbxGroupByName(group).path)
146 file.path = file.path.replace(r_group_dir, '');
147
148 return file;
149}
150
151function findXcodeProjectName() {
152 // look for a .xcodeproj directory under ios
153 files = fs.readdirSync(path.join('.', 'ios'))
154
155 const regex = /^([^/]+)\.xcodeproj$/
156
157 projectDir = files.find(function(filename) {
158 if (!filename.match(regex)) {
159 return false
160 }
161
162 stats = fs.statSync(path.join('.', 'ios', filename))
163
164 return stats.isDirectory()
165 })
166
167 if (!projectDir) return null
168
169 const result = regex.exec(projectDir)
170 return result[1]
171}
172
173module.exports = {
174 addBranchConfigToXcodeProject: addBranchConfigToXcodeProject,
175 removeBranchConfigFromXcodeProject: removeBranchConfigFromXcodeProject
176}