gstreamer/subprojects/gstreamer-sharp/nuget.py

195 lines
7.1 KiB
Python

#!/usr/bin/python3
import argparse
import getpass
import os
import sys
import shutil
import subprocess
from datetime import datetime
from urllib.request import urlretrieve
from zipfile import ZipFile
NUSPEC_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>{package_name}</id>
<authors>{author}</authors>
<owners>{owner}</owners>
<licenseUrl>{license_url}</licenseUrl>
<projectUrl>{project_url}</projectUrl>
<iconUrl>{icon_url}</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>{description}.</description>
<copyright>{copyright}</copyright>
<tags>{tags}</tags>
<version>{version}</version>
<dependencies>
{dependencies} </dependencies>
</metadata>
<files>
{files} </files>
</package>
"""
TARGETS_TEMPLATE = r"""<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="{package_name}CopyMapConfigs" AfterTargets="AfterBuild">
<CreateItem Include="$(MSBuildThisFileDirectory)\{frameworkdir}\*.config">
<Output TaskParameter="Include" ItemName="MapConfigs" />
</CreateItem>
<Copy SourceFiles="@(MapConfigs)" DestinationFiles="@(MapConfigs->'$(OutDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
</Project>"""
class Nugetifier:
def cleanup_args(self):
self.nugetdir = os.path.join(self.builddir,
self.package_name + 'nupkg')
self.frameworkdir = 'net45'
self.nuget_build_dir = os.path.join(
self.nugetdir, 'build', self.frameworkdir)
self.nuget_lib_dir = os.path.join(
self.nugetdir, 'lib', self.frameworkdir)
self.nuspecfile = os.path.join(
self.nugetdir, '%s.nuspec' % self.package_name)
self.nugettargets = os.path.join(
self.nuget_build_dir, "%s.targets" % self.package_name)
self.nuget = shutil.which('nuget')
if not self.nuget:
print("Could not find the `nuget` tool, install it and retry!")
return -1
for d in [self.nugetdir, self.nuget_lib_dir, self.nuget_build_dir]:
os.makedirs(d, exist_ok=True)
if not self.description:
self.description = "%s c# bindings" % self.package_name
if not self.copyright:
self.copyright = "Copyright %s" % datetime.now().year
if not self.tags:
self.tags = self.package_name
return 0
def run(self):
res = self.cleanup_args()
if res:
return res
self.files = ''
def add_file(path, target="lib"):
f = ' <file src="%s" target="%s"/>\n' % (
path, os.path.join(target, os.path.basename(path)))
self.files += f
self.dependencies = ''
for dependency in self.dependency:
_id, version = dependency.split(":")
self.dependencies += ' <dependency id="%s" version="%s" />\n' % (
_id, version)
for assembly in self.assembly:
add_file(assembly, os.path.join('lib', self.frameworkdir))
for f in [assembly + '.config', assembly[:-3] + 'pdb']:
if os.path.exists(f):
add_file(f, os.path.join('build', self.frameworkdir))
with open(self.nugettargets, 'w') as _:
print(TARGETS_TEMPLATE.format(**self.__dict__), file=_)
add_file(self.nugettargets, 'build')
with open(self.nuspecfile, 'w') as _:
print(NUSPEC_TEMPLATE.format(**self.__dict__), file=_)
subprocess.check_call([self.nuget, 'pack', self.nuspecfile],
cwd=self.builddir)
class NugetDownloader:
def reporthook(self, blocknum, blocksize, totalsize):
readsofar = blocknum * blocksize
if totalsize > 0:
percent = readsofar * 1e2 / totalsize
s = "\r%5.1f%% %*d / %d" % (
percent, len(str(totalsize)), readsofar, totalsize)
sys.stderr.write(s)
if readsofar >= totalsize: # near the end
sys.stderr.write("\n")
else: # total size is unknown
sys.stderr.write("read %d\n" % (readsofar,))
def run(self):
url = "https://www.nuget.org/api/v2/package/{nuget_name}/{nuget_version}".format(
**self.__dict__)
workdir = os.path.join(self.current_builddir,
self.nuget_name, self.nuget_version)
os.makedirs(workdir, exist_ok=True)
try:
with open(os.path.join(workdir, 'linkline'), 'r') as f:
print(f.read())
return
except FileNotFoundError:
pass
nugetpath = os.path.join(workdir, self.nuget_name) + '.zip'
print("Downloading %s into %s" % (url, nugetpath), file=sys.stderr)
urlretrieve(url, nugetpath, self.reporthook)
lib_path = os.path.join('lib', self.csharp_version)
dll_path = os.path.join(self.nuget_name, self.nuget_version)
extract_dir = os.path.join(self.current_builddir, dll_path)
os.makedirs(extract_dir, exist_ok=True)
linkline = ''
print("%s - %s" % (self.builddir, extract_dir), file=sys.stderr)
with ZipFile(nugetpath) as zip:
for f in zip.infolist():
if f.filename.startswith(lib_path):
zip.extract(f, path=extract_dir)
if f.filename.endswith('.dll'):
linkline += ' -r:' + \
os.path.relpath(os.path.join(
extract_dir, f.filename), self.builddir)
with open(os.path.join(workdir, 'linkline'), 'w') as f:
print(linkline.strip(), file=f)
print(linkline.strip())
if __name__ == "__main__":
if "get" not in sys.argv:
parser = argparse.ArgumentParser()
parser.add_argument('--builddir')
parser.add_argument('--package-name')
parser.add_argument('--author', default=getpass.getuser())
parser.add_argument('--owner', default=getpass.getuser())
parser.add_argument('--native', action='append', default=[])
parser.add_argument('--assembly', action='append', default=[])
parser.add_argument('--out')
parser.add_argument('--description')
parser.add_argument('--copyright')
parser.add_argument('--version')
parser.add_argument('--icon-url', default='')
parser.add_argument('--project-url', default='')
parser.add_argument('--license-url', default='')
parser.add_argument('--tags', default='')
parser.add_argument('--dependency', default=[], action='append')
runner = Nugetifier()
else:
sys.argv.remove('get')
parser = argparse.ArgumentParser()
parser.add_argument('--builddir')
parser.add_argument('--current-builddir')
parser.add_argument('--nuget-name')
parser.add_argument('--nuget-version')
parser.add_argument('--csharp-version')
runner = NugetDownloader()
options = parser.parse_args(namespace=runner)
exit(runner.run())