forked from baz/ios-build-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate_manifest.py
executable file
·137 lines (118 loc) · 5.28 KB
/
generate_manifest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/python
from optparse import OptionParser
import shutil
import fileinput
import os
import sys
import glob
import subprocess
import plistlib
import urlparse
import string
import fnmatch
parser = OptionParser()
parser.add_option('-f', '--app-bundle', action='store', dest='app_bundle', help='Path to app bundle')
parser.add_option('-a', '--archive-name', action='store', dest='archive_name', help='Legacy archive filename')
parser.add_option('-d', '--deployment-address', action='store', dest='deployment_address', help='Remote deployment path, where the app will eventually be hosted')
parser.add_option('-c', '--changes', action='store', dest='changes', help='The changes that went into this build')
(options, args) = parser.parse_args()
if options.app_bundle == None:
parser.error("Please specify the file path to the app bundle.")
elif options.deployment_address == None:
parser.error("Please specify the deployment address.")
elif options.archive_name == None:
parser.error("Please specify the filename of the legacy archive.")
elif options.changes == None:
parser.error("Please specify the changes in this build.")
class IPAGenerator(object):
"Generate index.html"
def generate_html(self, app_name):
HTML_FILENAME = 'index.html'
index_file = open(HTML_FILENAME, 'w')
index_file.write(self.template(app_name))
return HTML_FILENAME
"Locates the app's Info.plist"
def info_plist_filename(self):
filename = 'Info.plist'
for file in os.listdir(options.app_bundle):
if fnmatch.fnmatch(file, '*Info.plist'):
filename = file
break
return filename
"Generate manifest by parsing values from the app's Info.plist"
def generate_manifest(self, app_name):
filename = self.info_plist_filename()
info_plist_filepath = os.path.join(options.app_bundle, filename)
info_plist_xml_filename = 'info_plist.xml'
# Use plutil to ensure that we are dealing with XML rather than the binary format
subprocess.Popen('plutil -convert xml1 -o ' + info_plist_xml_filename + ' ' + "'" + info_plist_filepath + "'", shell=True).wait()
info_plist_xml_file = open(info_plist_xml_filename, 'r')
app_plist = plistlib.readPlist(info_plist_xml_file)
os.remove(info_plist_xml_filename)
MANIFEST_FILENAME = 'manifest.plist'
manifest_plist = {
'items' : [
{
'assets' : [
{
'kind' : 'software-package',
'url' : urlparse.urljoin(options.deployment_address, app_name + '.ipa'),
}
],
'metadata' : {
'bundle-identifier' : app_plist['CFBundleIdentifier'],
'bundle-version' : app_plist['CFBundleVersion'],
'kind' : 'software',
'title' : app_plist['CFBundleName'],
}
}
]
}
plistlib.writePlist(manifest_plist, MANIFEST_FILENAME)
return MANIFEST_FILENAME
"Template from http://github.com/HunterHillegas/iOS-BetaBuilder"
def template(self, app_name):
template_html = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>[BETA_NAME] - Beta Release</title>
<style type="text/css">
body {background:#fff;margin:0;padding:0;font-family:arial,helvetica,sans-serif;text-align:center;padding:10px;color:#333;font-size:16px;}
#container {width:300px;margin:0 auto;}
h1 {margin:0;padding:0;font-size:14px;}
p {font-size:13px;}
.link {background:#ecf5ff;border-top:1px solid #fff;border:1px solid #dfebf8;margin-top:.5em;padding:.3em;}
.link a {text-decoration:none;font-size:15px;display:block;color:#069;}
</style>
</head>
<body>
<div id="container">
<h1>iOS 4.0 Users:</h1>
<div class="link"><a href="itms-services://?action=download-manifest&url=[DEPLOYMENT_PATH]">Tap here to install<br />[BETA_NAME]<br />On Your Device</a></div>
<p><strong>Link didn't work?</strong><br />
Make sure you're visiting this page on your device, not your computer.</p>
<p><strong>On a version of iOS before 4.0?</strong><br />
Reload this page in your computer browser and download a zipped archive and provisioning profile here:
</p>
<div class="link"><a href="[BETA_ARCHIVE_FILENAME]">[BETA_NAME]<br />Archive w/ Provisioning Profile</a></div>
<p><strong>Last commit:</strong><br /><pre>[BUILD_CHANGES]</pre></p>
</div>
</body>
</html>
"""
TEMPLATE_PLACEHOLDER_NAME = '[BETA_NAME]'
TEMPLATE_PLACEHOLDER_DEPLOYMENT_PATH = '[DEPLOYMENT_PATH]'
TEMPLATE_PLACEHOLDER_ARCHIVE_FILENAME = '[BETA_ARCHIVE_FILENAME]'
TEMPLATE_PLACEHOLDER_BUILD_CHANGES = '[BUILD_CHANGES]'
template_html = string.replace(template_html, TEMPLATE_PLACEHOLDER_NAME, app_name)
template_html = string.replace(template_html, TEMPLATE_PLACEHOLDER_DEPLOYMENT_PATH, options.deployment_address)
template_html = string.replace(template_html, TEMPLATE_PLACEHOLDER_ARCHIVE_FILENAME, options.archive_name)
template_html = string.replace(template_html, TEMPLATE_PLACEHOLDER_BUILD_CHANGES, options.changes)
return template_html
generator = IPAGenerator()
app_name = os.path.splitext(options.app_bundle)[0]
html_filename = generator.generate_html(app_name)
manifest_filename = generator.generate_manifest(app_name)