UNPKG

3.96 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"""
26
27import StringIO
28import fileinput
29import plistlib
30import os
31import re
32import sys
33from xml.dom import minidom
34from xml.etree import ElementTree
35
36
37def Usage():
38 sys.stderr.write(__doc__)
39 sys.exit(1)
40
41
42def ValueToElement(node_name, key, value):
43 if isinstance(value, bool):
44 value = str(value).lower()
45 return ElementTree.Element(node_name, attrib={'name':key, 'value':str(value)})
46
47
48def AppendDict(d, node, name, ignore=()):
49 for key in sorted(d):
50 if key not in ignore:
51 node.append(ValueToElement(name, key, d[key]))
52
53
54def FindProjectFile(path):
55 # Do an extra abspath here to strip off trailing / if present.
56 path = os.path.abspath(path)
57 if path.endswith('.pbxproj'):
58 return path
59 elif path.endswith('.xcodeproj'):
60 return os.path.join(path, 'project.pbxproj')
61 for f in os.listdir(path):
62 if f.endswith('.xcodeproj'):
63 return os.path.join(path, f, 'project.pbxproj')
64 raise Exception('Invalid project path. Please provide the path to your .xcodeproj directory')
65
66
67def FindPlistFile(search_path):
68 for root, unused_dirnames, file_names in os.walk(search_path):
69 for file_name in file_names:
70 if file_name == 'Cordova.plist':
71 return os.path.join(root, file_name)
72 raise Exception('Could not find a file named "Cordova.plist" within ' + search_path)
73
74
75def ConvertPlist(src_path, dst_path):
76 # Run it through plutil to ensure it's not a binary plist.
77 os.system("plutil -convert xml1 '%s'" % src_path)
78 plist = plistlib.readPlist(src_path)
79 root = ElementTree.Element('cordova')
80
81 AppendDict(plist, root, 'preference', ignore=('Plugins', 'ExternalHosts'))
82
83 plugins = ElementTree.Element('plugins')
84 root.append(plugins)
85 AppendDict(plist['Plugins'], plugins, 'plugin')
86
87 for value in sorted(plist['ExternalHosts']):
88 root.append(ElementTree.Element('access', attrib={'origin':value}))
89
90 tree = ElementTree.ElementTree(root)
91 s = StringIO.StringIO()
92 tree.write(s, encoding='UTF-8')
93 mini_dom = minidom.parseString(s.getvalue())
94 with open(dst_path, 'w') as out:
95 out.write(mini_dom.toprettyxml(encoding='UTF-8'))
96
97
98def UpdateProjectFile(path):
99 file_handle = fileinput.input(path, inplace=1)
100 for line in file_handle:
101 if 'Cordova.plist' in line:
102 line = line.replace('Cordova.plist', 'config.xml')
103 line = line.replace('lastKnownFileType = text.plist.xml', 'lastKnownFileType = text.xml')
104 print line,
105 file_handle.close()
106
107
108def main(argv):
109 if len(argv) != 1:
110 Usage();
111
112 project_file = FindProjectFile(argv[0])
113 plist_file = FindPlistFile(os.path.dirname(os.path.dirname(project_file)))
114
115 config_file = os.path.join(os.path.dirname(plist_file), 'config.xml')
116 sys.stdout.write('Converting %s to %s.\n' % (plist_file, config_file))
117 ConvertPlist(plist_file, config_file)
118
119 sys.stdout.write('Updating references in %s\n' % project_file)
120 UpdateProjectFile(project_file)
121
122 os.unlink(plist_file)
123 sys.stdout.write('Updates Complete.\n')
124
125
126if __name__ == '__main__':
127 main(sys.argv[1:])