UNPKG

4 kBPlain TextView Raw
1#!/usr/bin/python
2#
3# Licensed to the Apache Software Foundation (ASF) under one
4# or more contributor license agreements. See the NOTICE file
5# distributed with this work for additional information
6# regarding copyright ownership. The ASF licenses this file
7# to you under the Apache License, Version 2.0 (the
8# "License"); you may not use this file except in compliance
9# with the License. You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing,
14# software distributed under the License is distributed on an
15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16# KIND, either express or implied. See the License for the
17# specific language governing permissions and limitations
18# under the License.
19#
20"""
21Converts a project's Cordova.plist file into a config.xml one. This conversion is required for Cordova 2.3.
22
23Usage:
24 plist2xml.py path/to/project
25"""
26from __future__ import print_function
27
28import fileinput
29import io
30import os
31import plistlib
32import re
33import sys
34from xml.dom import minidom
35from xml.etree import ElementTree
36
37
38def Usage():
39 sys.stderr.write(__doc__)
40 sys.exit(1)
41
42
43def ValueToElement(node_name, key, value):
44 if isinstance(value, bool):
45 value = str(value).lower()
46 return ElementTree.Element(node_name, attrib={'name':key, 'value':str(value)})
47
48
49def AppendDict(d, node, name, ignore=()):
50 for key in sorted(d):
51 if key not in ignore:
52 node.append(ValueToElement(name, key, d[key]))
53
54
55def FindProjectFile(path):
56 # Do an extra abspath here to strip off trailing / if present.
57 path = os.path.abspath(path)
58 if path.endswith('.pbxproj'):
59 return path
60 elif path.endswith('.xcodeproj'):
61 return os.path.join(path, 'project.pbxproj')
62 for f in os.listdir(path):
63 if f.endswith('.xcodeproj'):
64 return os.path.join(path, f, 'project.pbxproj')
65 raise Exception('Invalid project path. Please provide the path to your .xcodeproj directory')
66
67
68def FindPlistFile(search_path):
69 for root, unused_dirnames, file_names in os.walk(search_path):
70 for file_name in file_names:
71 if file_name == 'Cordova.plist':
72 return os.path.join(root, file_name)
73 raise Exception('Could not find a file named "Cordova.plist" within ' + search_path)
74
75
76def ConvertPlist(src_path, dst_path):
77 # Run it through plutil to ensure it's not a binary plist.
78 os.system("plutil -convert xml1 '%s'" % src_path)
79 plist = plistlib.readPlist(src_path)
80 root = ElementTree.Element('cordova')
81
82 AppendDict(plist, root, 'preference', ignore=('Plugins', 'ExternalHosts'))
83
84 plugins = ElementTree.Element('plugins')
85 root.append(plugins)
86 AppendDict(plist['Plugins'], plugins, 'plugin')
87
88 for value in sorted(plist['ExternalHosts']):
89 root.append(ElementTree.Element('access', attrib={'origin':value}))
90
91 tree = ElementTree.ElementTree(root)
92 with io.BytesIO() as s:
93 tree.write(s, encoding='UTF-8')
94 mini_dom = minidom.parseString(s.getvalue())
95 with open(dst_path, 'wb') as out:
96 out.write(mini_dom.toprettyxml(encoding='UTF-8'))
97
98
99def UpdateProjectFile(path):
100 file_handle = fileinput.input(path, inplace=1)
101 for line in file_handle:
102 if 'Cordova.plist' in line:
103 line = line.replace('Cordova.plist', 'config.xml')
104 line = line.replace('lastKnownFileType = text.plist.xml', 'lastKnownFileType = text.xml')
105 print(line, end=' ')
106 file_handle.close()
107
108
109def main(argv):
110 if len(argv) != 1:
111 Usage();
112
113 project_file = FindProjectFile(argv[0])
114 plist_file = FindPlistFile(os.path.dirname(os.path.dirname(project_file)))
115
116 config_file = os.path.join(os.path.dirname(plist_file), 'config.xml')
117 sys.stdout.write('Converting %s to %s.\n' % (plist_file, config_file))
118 ConvertPlist(plist_file, config_file)
119
120 sys.stdout.write('Updating references in %s\n' % project_file)
121 UpdateProjectFile(project_file)
122
123 os.unlink(plist_file)
124 sys.stdout.write('Updates Complete.\n')
125
126
127if __name__ == '__main__':
128 main(sys.argv[1:])