10ac341f1SConrad Meyer#!/usr/bin/env python3
20ac341f1SConrad Meyer
30ac341f1SConrad Meyerimport os.path
40ac341f1SConrad Meyerimport re
50ac341f1SConrad Meyerimport sys
60ac341f1SConrad Meyer
70ac341f1SConrad MeyerWINDOWS = [
80ac341f1SConrad Meyer  # --------------------- ----------------- #
90ac341f1SConrad Meyer  # Runtime ID            Platform          #
100ac341f1SConrad Meyer  # --------------------- ----------------- #
110ac341f1SConrad Meyer  ( 'win-x64',            'x64'             ),
120ac341f1SConrad Meyer  ( 'win-x86',            'Win32'           ),
130ac341f1SConrad Meyer  # --------------------- ----------------- #
140ac341f1SConrad Meyer]
150ac341f1SConrad Meyer
160ac341f1SConrad MeyerMACOS = [
170ac341f1SConrad Meyer  # --------------------- ----------------- #
180ac341f1SConrad Meyer  # Runtime ID            Codename          #
190ac341f1SConrad Meyer  # --------------------- ----------------- #
200ac341f1SConrad Meyer  ( 'osx-x64',            'sierra'          ),
210ac341f1SConrad Meyer  # --------------------- ----------------- #
220ac341f1SConrad Meyer]
230ac341f1SConrad Meyer
240ac341f1SConrad MeyerLINUX = [
250ac341f1SConrad Meyer  # --------------------- ----------------- #
260ac341f1SConrad Meyer  # Runtime ID            Docker Image      #
270ac341f1SConrad Meyer  # --------------------- ----------------- #
280ac341f1SConrad Meyer  ( 'linux-x64',          'debian:stretch'  ),
290ac341f1SConrad Meyer  # --------------------- ----------------- #
300ac341f1SConrad Meyer]
310ac341f1SConrad Meyer
320ac341f1SConrad MeyerEXTRAS = [ 'LICENSE', 'AUTHORS', 'ChangeLog' ]
330ac341f1SConrad Meyer
340ac341f1SConrad MeyerPROPSFILE = 'libsodium.props'
350ac341f1SConrad MeyerMAKEFILE = 'Makefile'
360ac341f1SConrad MeyerBUILDDIR = 'build'
370ac341f1SConrad MeyerCACHEDIR = 'cache'
380ac341f1SConrad MeyerTEMPDIR = 'temp'
390ac341f1SConrad Meyer
400ac341f1SConrad MeyerPACKAGE = 'libsodium'
410ac341f1SConrad MeyerLIBRARY = 'libsodium'
420ac341f1SConrad Meyer
430ac341f1SConrad MeyerDOCKER = 'sudo docker'
440ac341f1SConrad Meyer
450ac341f1SConrad Meyerclass Version:
460ac341f1SConrad Meyer
470ac341f1SConrad Meyer  def __init__(self, libsodium_version, package_version):
480ac341f1SConrad Meyer    self.libsodium_version = libsodium_version
490ac341f1SConrad Meyer    self.package_version = package_version
500ac341f1SConrad Meyer
510ac341f1SConrad Meyer    self.builddir = os.path.join(BUILDDIR, libsodium_version)
520ac341f1SConrad Meyer    self.tempdir = os.path.join(TEMPDIR, libsodium_version)
530ac341f1SConrad Meyer    self.projfile = os.path.join(self.builddir, '{0}.{1}.pkgproj'.format(PACKAGE, package_version))
540ac341f1SConrad Meyer    self.propsfile = os.path.join(self.builddir, '{0}.props'.format(PACKAGE))
550ac341f1SConrad Meyer    self.pkgfile = os.path.join(BUILDDIR, '{0}.{1}.nupkg'.format(PACKAGE, package_version))
560ac341f1SConrad Meyer
570ac341f1SConrad Meyerclass WindowsItem:
580ac341f1SConrad Meyer
590ac341f1SConrad Meyer  def __init__(self, version, rid, platform):
600ac341f1SConrad Meyer    self.url = 'https://download.libsodium.org/libsodium/releases/libsodium-{0}-msvc.zip'.format(version.libsodium_version)
610ac341f1SConrad Meyer    self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
620ac341f1SConrad Meyer    self.packfile = os.path.join(version.builddir, 'runtimes', rid, 'native', LIBRARY + '.dll')
630ac341f1SConrad Meyer    self.itemfile = '{0}/Release/v140/dynamic/libsodium.dll'.format(platform)
640ac341f1SConrad Meyer    self.tempdir = os.path.join(version.tempdir, rid)
650ac341f1SConrad Meyer    self.tempfile = os.path.join(self.tempdir, os.path.normpath(self.itemfile))
660ac341f1SConrad Meyer
670ac341f1SConrad Meyer  def make(self, f):
680ac341f1SConrad Meyer    f.write('\n')
690ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
700ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
710ac341f1SConrad Meyer    f.write('\tcp -f $< $@\n')
720ac341f1SConrad Meyer    f.write('\n')
730ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
740ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
750ac341f1SConrad Meyer    f.write('\tcd {0} && unzip -q -DD -o {1} \'{2}\'\n'.format(
760ac341f1SConrad Meyer      self.tempdir,
770ac341f1SConrad Meyer      os.path.relpath(self.cachefile, self.tempdir),
780ac341f1SConrad Meyer      self.itemfile
790ac341f1SConrad Meyer    ))
800ac341f1SConrad Meyer
810ac341f1SConrad Meyerclass MacOSItem:
820ac341f1SConrad Meyer
830ac341f1SConrad Meyer  def __init__(self, version, rid, codename):
840ac341f1SConrad Meyer    self.url = 'https://bintray.com/homebrew/bottles/download_file?file_path=libsodium-{0}.{1}.bottle.tar.gz'.format(version.libsodium_version, codename)
850ac341f1SConrad Meyer    self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
860ac341f1SConrad Meyer    self.packfile = os.path.join(version.builddir, 'runtimes', rid, 'native', LIBRARY + '.dylib')
870ac341f1SConrad Meyer    self.itemfile = 'libsodium/{0}/lib/libsodium.dylib'.format(version.libsodium_version)
880ac341f1SConrad Meyer    self.tempdir = os.path.join(version.tempdir, rid)
890ac341f1SConrad Meyer    self.tempfile = os.path.join(self.tempdir, os.path.normpath(self.itemfile))
900ac341f1SConrad Meyer
910ac341f1SConrad Meyer  def make(self, f):
920ac341f1SConrad Meyer    f.write('\n')
930ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
940ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
950ac341f1SConrad Meyer    f.write('\tcp -f $< $@\n')
960ac341f1SConrad Meyer    f.write('\n')
970ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
980ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
990ac341f1SConrad Meyer    f.write('\tcd {0} && tar xzmf {1} \'{2}\'\n'.format(
1000ac341f1SConrad Meyer      self.tempdir,
1010ac341f1SConrad Meyer      os.path.relpath(self.cachefile, self.tempdir),
1020ac341f1SConrad Meyer      os.path.dirname(self.itemfile)
1030ac341f1SConrad Meyer    ))
1040ac341f1SConrad Meyer
1050ac341f1SConrad Meyerclass LinuxItem:
1060ac341f1SConrad Meyer
1070ac341f1SConrad Meyer  def __init__(self, version, rid, docker_image):
1080ac341f1SConrad Meyer    self.url = 'https://download.libsodium.org/libsodium/releases/libsodium-{0}.tar.gz'.format(version.libsodium_version)
1090ac341f1SConrad Meyer    self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
1100ac341f1SConrad Meyer    self.packfile = os.path.join(version.builddir, 'runtimes', rid, 'native', LIBRARY + '.so')
1110ac341f1SConrad Meyer    self.tempdir = os.path.join(version.tempdir, rid)
1120ac341f1SConrad Meyer    self.tempfile = os.path.join(self.tempdir, 'libsodium.so')
1130ac341f1SConrad Meyer    self.docker_image = docker_image
1140ac341f1SConrad Meyer    self.recipe = rid
1150ac341f1SConrad Meyer
1160ac341f1SConrad Meyer  def make(self, f):
1170ac341f1SConrad Meyer    recipe = self.recipe
1180ac341f1SConrad Meyer    while not os.path.exists(os.path.join('recipes', recipe)):
1190ac341f1SConrad Meyer      m = re.fullmatch(r'([^.-]+)((([.][^.-]+)*)[.][^.-]+)?([-].*)?', recipe)
1200ac341f1SConrad Meyer      if m.group(5) is None:
1210ac341f1SConrad Meyer        recipe = 'build'
1220ac341f1SConrad Meyer        break
1230ac341f1SConrad Meyer      elif m.group(2) is None:
1240ac341f1SConrad Meyer        recipe = m.group(1)
1250ac341f1SConrad Meyer      else:
1260ac341f1SConrad Meyer        recipe = m.group(1) + m.group(3) + m.group(5)
1270ac341f1SConrad Meyer
1280ac341f1SConrad Meyer    f.write('\n')
1290ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
1300ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
1310ac341f1SConrad Meyer    f.write('\tcp -f $< $@\n')
1320ac341f1SConrad Meyer    f.write('\n')
1330ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
1340ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
1350ac341f1SConrad Meyer    f.write('\t{0} run --rm '.format(DOCKER) +
1360ac341f1SConrad Meyer            '-v $(abspath recipes):/io/recipes ' +
1370ac341f1SConrad Meyer            '-v $(abspath $<):/io/libsodium.tar.gz ' +
1380ac341f1SConrad Meyer            '-v $(abspath $(dir $@)):/io/output ' +
1390ac341f1SConrad Meyer            '{0} sh -x -e /io/recipes/{1}\n'.format(self.docker_image, recipe))
1400ac341f1SConrad Meyer
1410ac341f1SConrad Meyerclass ExtraItem:
1420ac341f1SConrad Meyer
1430ac341f1SConrad Meyer  def __init__(self, version, filename):
1440ac341f1SConrad Meyer    self.url = 'https://download.libsodium.org/libsodium/releases/libsodium-{0}.tar.gz'.format(version.libsodium_version)
1450ac341f1SConrad Meyer    self.cachefile = os.path.join(CACHEDIR, re.sub(r'[^A-Za-z0-9.]', '-', self.url))
1460ac341f1SConrad Meyer    self.packfile = os.path.join(version.builddir, filename)
1470ac341f1SConrad Meyer    self.itemfile = 'libsodium-{0}/{1}'.format(version.libsodium_version, filename)
1480ac341f1SConrad Meyer    self.tempdir = os.path.join(version.tempdir, 'extras')
1490ac341f1SConrad Meyer    self.tempfile = os.path.join(self.tempdir, os.path.normpath(self.itemfile))
1500ac341f1SConrad Meyer
1510ac341f1SConrad Meyer  def make(self, f):
1520ac341f1SConrad Meyer    f.write('\n')
1530ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.packfile, self.tempfile))
1540ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
1550ac341f1SConrad Meyer    f.write('\tcp -f $< $@\n')
1560ac341f1SConrad Meyer    f.write('\n')
1570ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(self.tempfile, self.cachefile))
1580ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
1590ac341f1SConrad Meyer    f.write('\tcd {0} && tar xzmf {1} \'{2}\'\n'.format(
1600ac341f1SConrad Meyer      self.tempdir,
1610ac341f1SConrad Meyer      os.path.relpath(self.cachefile, self.tempdir),
1620ac341f1SConrad Meyer      self.itemfile
1630ac341f1SConrad Meyer    ))
1640ac341f1SConrad Meyer
1650ac341f1SConrad Meyerdef main(args):
1660ac341f1SConrad Meyer  m = re.fullmatch(r'((\d+\.\d+\.\d+)(\.\d+)?)(?:-(\w+(?:[_.-]\w+)*))?', args[1]) if len(args) == 2 else None
1670ac341f1SConrad Meyer
1680ac341f1SConrad Meyer  if m is None:
1690ac341f1SConrad Meyer    print('Usage:')
1700ac341f1SConrad Meyer    print('       python3 prepare.py <version>')
1710ac341f1SConrad Meyer    print()
1720ac341f1SConrad Meyer    print('Examples:')
1730ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16-preview-01')
1740ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16-preview-02')
1750ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16-preview-03')
1760ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16')
1770ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16.1-preview-01')
1780ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16.1')
1790ac341f1SConrad Meyer    print('       python3 prepare.py 1.0.16.2')
1800ac341f1SConrad Meyer    return 1
1810ac341f1SConrad Meyer
1820ac341f1SConrad Meyer  version = Version(m.group(2), m.group(0))
1830ac341f1SConrad Meyer
1840ac341f1SConrad Meyer  items = [ WindowsItem(version, rid, platform)   for (rid, platform) in WINDOWS   ] + \
1850ac341f1SConrad Meyer          [ MacOSItem(version, rid, codename)     for (rid, codename) in MACOS     ] + \
1860ac341f1SConrad Meyer          [ LinuxItem(version, rid, docker_image) for (rid, docker_image) in LINUX ] + \
1870ac341f1SConrad Meyer          [ ExtraItem(version, filename)          for filename in EXTRAS           ]
1880ac341f1SConrad Meyer
1890ac341f1SConrad Meyer  downloads = {item.cachefile: item.url for item in items}
1900ac341f1SConrad Meyer
1910ac341f1SConrad Meyer  with open(MAKEFILE, 'w') as f:
1920ac341f1SConrad Meyer    f.write('all: {0}\n'.format(version.pkgfile))
1930ac341f1SConrad Meyer
1940ac341f1SConrad Meyer    for download in sorted(downloads):
1950ac341f1SConrad Meyer      f.write('\n')
1960ac341f1SConrad Meyer      f.write('{0}:\n'.format(download))
1970ac341f1SConrad Meyer      f.write('\t@mkdir -p $(dir $@)\n')
1980ac341f1SConrad Meyer      f.write('\tcurl -f#Lo $@ \'{0}\'\n'.format(downloads[download]))
1990ac341f1SConrad Meyer
2000ac341f1SConrad Meyer    for item in items:
2010ac341f1SConrad Meyer      item.make(f)
2020ac341f1SConrad Meyer
2030ac341f1SConrad Meyer    f.write('\n')
2040ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(version.propsfile, PROPSFILE))
2050ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
2060ac341f1SConrad Meyer    f.write('\tcp -f $< $@\n')
2070ac341f1SConrad Meyer
2080ac341f1SConrad Meyer    f.write('\n')
2090ac341f1SConrad Meyer    f.write('{0}: {1}\n'.format(version.projfile, version.propsfile))
2100ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
2110ac341f1SConrad Meyer    f.write('\techo \'' +
2120ac341f1SConrad Meyer            '<Project Sdk="Microsoft.NET.Sdk">' +
2130ac341f1SConrad Meyer            '<Import Project="{0}" />'.format(os.path.relpath(version.propsfile, os.path.dirname(version.projfile))) +
2140ac341f1SConrad Meyer            '<PropertyGroup>' +
2150ac341f1SConrad Meyer            '<Version>{0}</Version>'.format(version.package_version) +
2160ac341f1SConrad Meyer            '</PropertyGroup>' +
2170ac341f1SConrad Meyer            '</Project>\' > $@\n')
2180ac341f1SConrad Meyer
2190ac341f1SConrad Meyer    f.write('\n')
2200ac341f1SConrad Meyer    f.write('{0}:'.format(version.pkgfile))
2210ac341f1SConrad Meyer    f.write(' \\\n\t\t{0}'.format(version.projfile))
2220ac341f1SConrad Meyer    f.write(' \\\n\t\t{0}'.format(version.propsfile))
2230ac341f1SConrad Meyer    for item in items:
2240ac341f1SConrad Meyer      f.write(' \\\n\t\t{0}'.format(item.packfile))
2250ac341f1SConrad Meyer    f.write('\n')
2260ac341f1SConrad Meyer    f.write('\t@mkdir -p $(dir $@)\n')
2270ac341f1SConrad Meyer    f.write('\t{0} run --rm '.format(DOCKER) +
2280ac341f1SConrad Meyer            '-v $(abspath recipes):/io/recipes ' +
2290ac341f1SConrad Meyer            '-v $(abspath $(dir $<)):/io/input ' +
2300ac341f1SConrad Meyer            '-v $(abspath $(dir $@)):/io/output ' +
2310ac341f1SConrad Meyer            '{0} sh -x -e /io/recipes/{1} {2}\n'.format('microsoft/dotnet:2.0-sdk', 'pack', os.path.relpath(version.projfile, version.builddir)))
2320ac341f1SConrad Meyer
2330ac341f1SConrad Meyer    f.write('\n')
2340ac341f1SConrad Meyer    f.write('test: {0}\n'.format(version.pkgfile))
2350ac341f1SConrad Meyer    f.write('\t{0} run --rm '.format(DOCKER) +
2360ac341f1SConrad Meyer            '-v $(abspath recipes):/io/recipes ' +
2370ac341f1SConrad Meyer            '-v $(abspath $(dir $<)):/io/packages ' +
2380ac341f1SConrad Meyer            '{0} sh -x -e /io/recipes/{1} "{2}"\n'.format('microsoft/dotnet:2.0-sdk', 'test', version.package_version))
2390ac341f1SConrad Meyer
2400ac341f1SConrad Meyer  print('prepared', MAKEFILE, 'to make', version.pkgfile, 'for libsodium', version.libsodium_version)
2410ac341f1SConrad Meyer  return 0
2420ac341f1SConrad Meyer
2430ac341f1SConrad Meyerif __name__ == '__main__':
2440ac341f1SConrad Meyer  sys.exit(main(sys.argv))
245