1 #!/usr/bin/env python3
2
3 import os.path
4 import re
5 import sys
6
7 WINDOWS = [
8 # --------------------- ----------------- #
9 # Runtime ID Platform #
10 # --------------------- ----------------- #
11 ( 'win-x64', 'x64' ),
12 ( 'win-x86', 'Win32' ),
13 # --------------------- ----------------- #
14 ]
15
16 MACOS = [
17 # --------------------- ----------------- #
18 # Runtime ID Codename #
19 # --------------------- ----------------- #
20 ( 'osx-x64', 'sierra' ),
21 # --------------------- ----------------- #
22 ]
23
24 LINUX = [
25 # --------------------- ----------------- #
26 # Runtime ID Docker Image #
27 # --------------------- ----------------- #
28 ( 'linux-x64', 'debian:stretch' ),
29 # --------------------- ----------------- #
30 ]
31
32 EXTRAS = [ 'LICENSE', 'AUTHORS', 'ChangeLog' ]
33
34 PROPSFILE = 'libsodium.props'
35 MAKEFILE = 'Makefile'
36 BUILDDIR = 'build'
37 CACHEDIR = 'cache'
38 TEMPDIR = 'temp'
39
40 PACKAGE = 'libsodium'
41 LIBRARY = 'libsodium'
42
43 DOCKER = 'sudo docker'
44
45 class Version:
46
47 def __init__(self, libsodium_version, package_version):
48 self.libsodium_version = libsodium_version
49 self.package_version = package_version
50
51 self.builddir = os.path.join(BUILDDIR, libsodium_version)
52 self.tempdir = os.path.join(TEMPDIR, libsodium_version)
53 self.projfile = os.path.join(self.builddir, '{0}.{1}.pkgproj'.format(PACKAGE, package_version))
54 self.propsfile = os.path.join(self.builddir, '{0}.props'.format(PACKAGE))
55 self.pkgfile = os.path.join(BUILDDIR, '{0}.{1}.nupkg'.format(PACKAGE, package_version))
56
57 class WindowsItem:
58
59 def __init__(self, version, rid, platform):
60 self.url = 'https://download.libsodium.org/libsodium/releases/libsodium-{0}-msvc.zip'.format(version.libsodium_version)
61 self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
62 self.packfile = os.path.join(version.builddir, 'runtimes', rid, 'native', LIBRARY + '.dll')
63 self.itemfile = '{0}/Release/v140/dynamic/libsodium.dll'.format(platform)
64 self.tempdir = os.path.join(version.tempdir, rid)
65 self.tempfile = os.path.join(self.tempdir, os.path.normpath(self.itemfile))
66
67 def make(self, f):
68 f.write('\n')
69 f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
70 f.write('\t@mkdir -p $(dir $@)\n')
71 f.write('\tcp -f $< $@\n')
72 f.write('\n')
73 f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
74 f.write('\t@mkdir -p $(dir $@)\n')
75 f.write('\tcd {0} && unzip -q -DD -o {1} \'{2}\'\n'.format(
76 self.tempdir,
77 os.path.relpath(self.cachefile, self.tempdir),
78 self.itemfile
79 ))
80
81 class MacOSItem:
82
83 def __init__(self, version, rid, codename):
84 self.url = 'https://bintray.com/homebrew/bottles/download_file?file_path=libsodium-{0}.{1}.bottle.tar.gz'.format(version.libsodium_version, codename)
85 self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
86 self.packfile = os.path.join(version.builddir, 'runtimes', rid, 'native', LIBRARY + '.dylib')
87 self.itemfile = 'libsodium/{0}/lib/libsodium.dylib'.format(version.libsodium_version)
88 self.tempdir = os.path.join(version.tempdir, rid)
89 self.tempfile = os.path.join(self.tempdir, os.path.normpath(self.itemfile))
90
91 def make(self, f):
92 f.write('\n')
93 f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
94 f.write('\t@mkdir -p $(dir $@)\n')
95 f.write('\tcp -f $< $@\n')
96 f.write('\n')
97 f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
98 f.write('\t@mkdir -p $(dir $@)\n')
99 f.write('\tcd {0} && tar xzmf {1} \'{2}\'\n'.format(
100 self.tempdir,
101 os.path.relpath(self.cachefile, self.tempdir),
102 os.path.dirname(self.itemfile)
103 ))
104
105 class LinuxItem:
106
107 def __init__(self, version, rid, docker_image):
108 self.url = 'https://download.libsodium.org/libsodium/releases/libsodium-{0}.tar.gz'.format(version.libsodium_version)
109 self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
110 self.packfile = os.path.join(version.builddir, 'runtimes', rid, 'native', LIBRARY + '.so')
111 self.tempdir = os.path.join(version.tempdir, rid)
112 self.tempfile = os.path.join(self.tempdir, 'libsodium.so')
113 self.docker_image = docker_image
114 self.recipe = rid
115
116 def make(self, f):
117 recipe = self.recipe
118 while not os.path.exists(os.path.join('recipes', recipe)):
119 m = re.fullmatch(r'([^.-]+)((([.][^.-]+)*)[.][^.-]+)?([-].*)?', recipe)
120 if m.group(5) is None:
121 recipe = 'build'
122 break
123 elif m.group(2) is None:
124 recipe = m.group(1)
125 else:
126 recipe = m.group(1) + m.group(3) + m.group(5)
127
128 f.write('\n')
129 f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
130 f.write('\t@mkdir -p $(dir $@)\n')
131 f.write('\tcp -f $< $@\n')
132 f.write('\n')
133 f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
134 f.write('\t@mkdir -p $(dir $@)\n')
135 f.write('\t{0} run --rm '.format(DOCKER) +
136 '-v $(abspath recipes):/io/recipes ' +
137 '-v $(abspath $<):/io/libsodium.tar.gz ' +
138 '-v $(abspath $(dir $@)):/io/output ' +
139 '{0} sh -x -e /io/recipes/{1}\n'.format(self.docker_image, recipe))
140
141 class ExtraItem:
142
143 def __init__(self, version, filename):
144 self.url = 'https://download.libsodium.org/libsodium/releases/libsodium-{0}.tar.gz'.format(version.libsodium_version)
145 self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
146 self.packfile = os.path.join(version.builddir, filename)
147 self.itemfile = 'libsodium-{0}/{1}'.format(version.libsodium_version, filename)
148 self.tempdir = os.path.join(version.tempdir, 'extras')
149 self.tempfile = os.path.join(self.tempdir, os.path.normpath(self.itemfile))
150
151 def make(self, f):
152 f.write('\n')
153 f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
154 f.write('\t@mkdir -p $(dir $@)\n')
155 f.write('\tcp -f $< $@\n')
156 f.write('\n')
157 f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
158 f.write('\t@mkdir -p $(dir $@)\n')
159 f.write('\tcd {0} && tar xzmf {1} \'{2}\'\n'.format(
160 self.tempdir,
161 os.path.relpath(self.cachefile, self.tempdir),
162 self.itemfile
163 ))
164
165 def main(args):
166 m = re.fullmatch(r'((\d+\.\d+\.\d+)(\.\d+)?)(?:-(\w+(?:[_.-]\w+)*))?', args[1]) if len(args) == 2 else None
167
168 if m is None:
169 print('Usage:')
170 print(' python3 prepare.py <version>')
171 print()
172 print('Examples:')
173 print(' python3 prepare.py 1.0.16-preview-01')
174 print(' python3 prepare.py 1.0.16-preview-02')
175 print(' python3 prepare.py 1.0.16-preview-03')
176 print(' python3 prepare.py 1.0.16')
177 print(' python3 prepare.py 1.0.16.1-preview-01')
178 print(' python3 prepare.py 1.0.16.1')
179 print(' python3 prepare.py 1.0.16.2')
180 return 1
181
182 version = Version(m.group(2), m.group(0))
183
184 items = [ WindowsItem(version, rid, platform) for (rid, platform) in WINDOWS ] + \
185 [ MacOSItem(version, rid, codename) for (rid, codename) in MACOS ] + \
186 [ LinuxItem(version, rid, docker_image) for (rid, docker_image) in LINUX ] + \
187 [ ExtraItem(version, filename) for filename in EXTRAS ]
188
189 downloads = {item.cachefile: item.url for item in items}
190
191 with open(MAKEFILE, 'w') as f:
192 f.write('all: {0}\n'.format(version.pkgfile))
193
194 for download in sorted(downloads):
195 f.write('\n')
196 f.write('{0}:\n'.format(download))
197 f.write('\t@mkdir -p $(dir $@)\n')
198 f.write('\tcurl -f#Lo $@ \'{0}\'\n'.format(downloads[download]))
199
200 for item in items:
201 item.make(f)
202
203 f.write('\n')
204 f.write('{0}: {1}\n'.format(version.propsfile, PROPSFILE))
205 f.write('\t@mkdir -p $(dir $@)\n')
206 f.write('\tcp -f $< $@\n')
207
208 f.write('\n')
209 f.write('{0}: {1}\n'.format(version.projfile, version.propsfile))
210 f.write('\t@mkdir -p $(dir $@)\n')
211 f.write('\techo \'' +
212 '<Project Sdk="Microsoft.NET.Sdk">' +
213 '<Import Project="{0}" />'.format(os.path.relpath(version.propsfile, os.path.dirname(version.projfile))) +
214 '<PropertyGroup>' +
215 '<Version>{0}</Version>'.format(version.package_version) +
216 '</PropertyGroup>' +
217 '</Project>\' > $@\n')
218
219 f.write('\n')
220 f.write('{0}:'.format(version.pkgfile))
221 f.write(' \\\n\t\t{0}'.format(version.projfile))
222 f.write(' \\\n\t\t{0}'.format(version.propsfile))
223 for item in items:
224 f.write(' \\\n\t\t{0}'.format(item.packfile))
225 f.write('\n')
226 f.write('\t@mkdir -p $(dir $@)\n')
227 f.write('\t{0} run --rm '.format(DOCKER) +
228 '-v $(abspath recipes):/io/recipes ' +
229 '-v $(abspath $(dir $<)):/io/input ' +
230 '-v $(abspath $(dir $@)):/io/output ' +
231 '{0} sh -x -e /io/recipes/{1} {2}\n'.format('microsoft/dotnet:2.0-sdk', 'pack', os.path.relpath(version.projfile, version.builddir)))
232
233 f.write('\n')
234 f.write('test: {0}\n'.format(version.pkgfile))
235 f.write('\t{0} run --rm '.format(DOCKER) +
236 '-v $(abspath recipes):/io/recipes ' +
237 '-v $(abspath $(dir $<)):/io/packages ' +
238 '{0} sh -x -e /io/recipes/{1} "{2}"\n'.format('microsoft/dotnet:2.0-sdk', 'test', version.package_version))
239
240 print('prepared', MAKEFILE, 'to make', version.pkgfile, 'for libsodium', version.libsodium_version)
241 return 0
242
243 if __name__ == '__main__':
244 sys.exit(main(sys.argv))
Cache object: 2d7a7b74ec84c529e9bcbf10633bd4cd
|