diff --git a/_bin/new.package.py b/_bin/new.package.py index e0dc072..a375cc8 100755 --- a/_bin/new.package.py +++ b/_bin/new.package.py @@ -4,14 +4,17 @@ import re import os import shutil import subprocess -import git # python-gitpython in AUR -import menu3 # python-menu3 in AUR +import hashlib +import urllib2 +import git # python-gitpython in AUR +import menu3 # python-menu3 in AUR +import jinja2 # python-jinja in community from tempfile import gettempdir import pprint ## SETTINGS ## -gpgkey = '748231EBCBD808A14F5E85D28C004C2F93481F6B' # https://wiki.archlinux.org/index.php/PKGBUILD#validpgpkeys +gpgkey = ['748231EBCBD808A14F5E85D28C004C2F93481F6B'] # https://wiki.archlinux.org/index.php/PKGBUILD#validpgpkeys maintname = 'brent s. ' # your name and email address, feel free to obfuscate though pkgbuild_dir = '/opt/dev/arch' # what dir do the pkgbuilds/AUR checkouts live? aur_pkgs_dir = pkgbuild_dir # should be the dir where the aur_pkgs repo checkout lives. it's recommended you keep this the same as pkgbuild_dir @@ -42,15 +45,19 @@ def gui_init(): "Mercurial (hg)", "Bazaar (bzr)"] vcs_menu = m.menu("What type of VCS system?", vcs_options, "VCS type ('q' to quit):") - pkg['name'] = input("\nWhat is the name of your package? (Exclude the '-git' etc. suffix)\n").lower() + pkg['name'] = input("\nWhat is the name of your package? (Exclude the '-git' etc. suffix, that will be added automatically later on)\n").lower() srcurl = input("\nWhat is the checkout URL for {0}?\n(Do not include the directory or VCS type prefix as per\nhttps://wiki.archlinux.org/index.php/VCS_package_guidelines#VCS_sources ...\nit will be added automatically)\n".format(pkg['name'])) pkg['vcstype'] = ["git", "svn", "hg", "bzr"] pkg['srcurl'] = pkg['name'] + "::" + pkg['vcstype'][vcs_menu-1] + srcurl + pkg['name'] = pkg['name'] + "-" + pkg['vcstype'] + pkg['type'] = 'vcs' pkg['srcfile'] = False pkg['ver'] = False + pkg['srchash'] = 'SKIP' + pkg['src_dl'] = False # If they're adding a release package... elif add_menu == 1: @@ -59,6 +66,15 @@ def gui_init(): pkg['ver'] = input("\nWhat is the version of the release you are packaging for {0}?\n".format(pkg['name'])) pkg['srcurl'] = input("\nWhat is the full URL for the tarball/zip file/etc. for {0} (version {1})?\n".format(pkg['name'], pkg['ver'])) pkg['srcfile'] = re.sub('^\s*(https?|ftp).*/(.*)\s*$', '\\2', pkg['srcurl'], re.IGNORECASE) + pkg['type'] = 'release' + # And here's where we download the source file for hashing + pkg['src_dl'] = gettempdir() + "/" + pkg['srcfile'] + print("Please wait while we download {0} to {1}...\n".format(pkg['srcfile'], pkg['src_dl'])) + datastream = urllib2.urlopen(pkg['srcurl']) + data_in = datastream.read() + with open(pkg['src_dl'], "wb") as data_dl: + data_dl.write(data_in) + pkg['srchash'] = hashlib.sha512(open(pkg['src_dl'],'rb').read()).hexdigest() # And this is stuff shared by both types. pkg['desc'] = input("\nWhat is a short description of {0}?\n".format(pkg['name'])) @@ -91,12 +107,40 @@ def sanity_checks(pkg): if exception.errno != errno.EEXIST: raise +## REGISTER IN THE AUR AND MAKE FIRST COMMIT ## def aur_create(pkg): - tmpcheckout = os.path.join(gettempdir(), '.aur_pkgs.{}'.format(pkg['name'])) - pygit2.clone_repository('aur@aur.archlinux.org:' + pkg['name'], tmpcheckout, bare=False, repository=None, remote=None, checkout_branch=None, callbacks=None) + # git clone from AUR to create repository, add .gitignore + tmpcheckout = os.path.join(gettempdir(), '.aur_pkgs') + repo_dir = tmpcheckout + '/' + pkg['name'] + aur_repo = git.Repo.clone_from('aur@aur.archlinux.org:' + pkg['name'], git.osp.join(tmpcheckout, pkg['name']), branch='master') shutil.copy2(aur_pkgs_dir + "/_docs/PKGBUILD.templates.d/gitignore", tmpcheckout + "/.gitignore") + aur_repo.index.add('.gitignore') + # Create the initial PKGBUILD + tpl_dir = aur_pkgs_dir + '/_docs/PKGBUILD.templates.d.python' + tpl_meta = aur_pkgs_dir + '/_docs/PKGBUILD.templates.d.python' + '/' + pkg['type'] + '.all' + tpl_fsloader = jinja2.FileSystemLoader(searchpath = tpl_dir, followlinks = True) + tpl_fsloader2 = jinja2.FileSystemLoader(searchpath = tpl_dir + '/' + pkg['type'], followlinks = True) + pkgbuild_list = tpl_fsloader2.list_templates() + pkgbuild_list[:] = [pkg['type'] + '/' + s for s in pkgbuild_list] + tpl_env = jinja2.Environment(loader = tpl_fsloader) + pkgbuild_out = tpl_env.get_template(pkg['type'] + '.all.j2').render(pkg = pkg, maintname = maintname, gpgkey = gpgkey, pkgbuild_list = pkgbuild_list) + with open(repo_dir + "/PKGBUILD", "wb") as pkgbuild_file: + pkgbuild_file.write(pkgbuild_out) + # Move the source file + if pkg['srcfile']: + os.rename(pkg['src_dl'], repodir + '/' + pkg['srcfile']) + gpg = gnupg.GPG() + datastream = open(pkg['dl_src'], 'rb') + gpg.sign_file(datastream, keyid = gpgkey[0], detach = True, clearsign = False, output = repodir + '/' + pkg['srcfile'] + '.sig') + datastream.close() + aur.repo.indes.add(pkg['srcfile'] + '.sig') + aur.repo.index.add('PKGBUILD') + # commit to git + aur_repo.index.commit("initial commit; setting up .gitignores and skeleton PKGBUILD") + # and push... + aur_repo.push() pprint.pprint(gui_init()) - +#aur_create(gui_init()) diff --git a/_docs/PKGBUILD.templates.d.python/gitignore b/_docs/PKGBUILD.templates.d.python/gitignore new file mode 100644 index 0000000..e16177d --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/gitignore @@ -0,0 +1,18 @@ +*/ +.*.swp +*.pkg.tar.xz +src/ +pkg/ +*.tar +*.tar.bz2 +*.tar.xz +*.tar.gz +*.tgz +*.txz +*.tbz +*.tbz2 +*.zip +*.run +*.7z +*.rar +*.deb diff --git a/_docs/PKGBUILD.templates.d.python/release.all.j2 b/_docs/PKGBUILD.templates.d.python/release.all.j2 new file mode 100644 index 0000000..e1a2de0 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release.all.j2 @@ -0,0 +1,3 @@ +{% for tpl in pkgbuild_list %} +{% include tpl %} +{% endfor %} diff --git a/_docs/PKGBUILD.templates.d.python/release/00.header.j2 b/_docs/PKGBUILD.templates.d.python/release/00.header.j2 new file mode 100644 index 0000000..0e51ec5 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release/00.header.j2 @@ -0,0 +1,2 @@ +# Maintainer: {{ maintname }} +validpgpkeys=({% for gpgkey in gpgkey %}'{{ gpgkey }}'{% endfor %}) diff --git a/_docs/PKGBUILD.templates.d.python/release/01.moreinfo.j2 b/_docs/PKGBUILD.templates.d.python/release/01.moreinfo.j2 new file mode 100644 index 0000000..933af0f --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release/01.moreinfo.j2 @@ -0,0 +1,2 @@ +# Bug reports can be filed at https://bugs.square-r00t.net/index.php?project=3 +# News updates for packages can be followed at https://devblog.square-r00t.net diff --git a/_docs/PKGBUILD.templates.d.python/release/02.pkgmeta.j2 b/_docs/PKGBUILD.templates.d.python/release/02.pkgmeta.j2 new file mode 100644 index 0000000..d5d7b17 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release/02.pkgmeta.j2 @@ -0,0 +1,13 @@ +pkgname={{ pkg['name'] }} +pkgver={{ pkg['ver'] }} +pkgrel=1 +pkgdesc="{{ pkg['desc'] }}" +arch=( 'i686' 'x86_64' ) +url="{{ pkg['site'] }}" +license=({% for license in pkg['license'] %}'{{ license }}' {% endfor %}){% if pkg['deps'] is defined and pkg['deps']|length > 0 %} +depends=( {% for dep in pkg['deps'] %}'{{ dep }}' {% endfor %}){% endif %}{% if pkg['optdeps'] is defined and pkg['optdeps']|length > 0 %} +optdepends=( {% for dep in pkg['optdeps'] %}'{{ dep }}' {% endfor %}){% endif %}{% if pkg['makedeps'] is defined and pkg['makedeps']|length > 0 %} +makedepends=( {% for dep in pkg['makedeps'] %}'{{ dep }}' {% endfor %}){% endif %} +_pkgname={{ pkg['name'] }}{% if pkg['provides'] is defined and pkg['provides']|length > 0 %} +provides=( {% for pkg in pkg['provides'] %}'{{ pkg }}' {% endfor %}){% endif %}{% if pkg['conflicts'] is defined and pkg['conflicts']|length > 0 %} +conflicts=( {% for pkg in pkg['conflicts'] %}'pkg'{% endfor %}){% endif %} diff --git a/_docs/PKGBUILD.templates.d.python/release/03.sources.j2 b/_docs/PKGBUILD.templates.d.python/release/03.sources.j2 new file mode 100644 index 0000000..6559f46 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release/03.sources.j2 @@ -0,0 +1,7 @@ +install= +changelog= +noextract=() +source=("{{ pkg['srcurl'] }}" + "{{ pkg['srcfile'].sig }}") +sha512sums=('{{ pkg['srchash'] }}' + 'SKIP') diff --git a/_docs/PKGBUILD.templates.d.python/release/04.build.j2 b/_docs/PKGBUILD.templates.d.python/release/04.build.j2 new file mode 100644 index 0000000..794bbea --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release/04.build.j2 @@ -0,0 +1,4 @@ +build() { + cd "${srcdir}/${_pkgname}/src" + make prefix=${pkgdir}/usr +} diff --git a/_docs/PKGBUILD.templates.d.python/release/05.package.j2 b/_docs/PKGBUILD.templates.d.python/release/05.package.j2 new file mode 100644 index 0000000..f24d818 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/release/05.package.j2 @@ -0,0 +1,4 @@ +package() { + install -D -m755 ${srcdir}/${_pkgname}/src/${_pkgname} ${pkgdir}/usr/bin/${_pkgname} + install -D -m644 ${srcdir}/${_pkgname}/docs/README.html.en ${pkgdir}/usr/share/doc/${_pkgname}/README.html +} diff --git a/_docs/PKGBUILD.templates.d.python/vcs.all.j2 b/_docs/PKGBUILD.templates.d.python/vcs.all.j2 new file mode 100644 index 0000000..e1a2de0 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs.all.j2 @@ -0,0 +1,3 @@ +{% for tpl in pkgbuild_list %} +{% include tpl %} +{% endfor %} diff --git a/_docs/PKGBUILD.templates.d.python/vcs/00.header.j2 b/_docs/PKGBUILD.templates.d.python/vcs/00.header.j2 new file mode 100644 index 0000000..0e51ec5 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/00.header.j2 @@ -0,0 +1,2 @@ +# Maintainer: {{ maintname }} +validpgpkeys=({% for gpgkey in gpgkey %}'{{ gpgkey }}'{% endfor %}) diff --git a/_docs/PKGBUILD.templates.d.python/vcs/01.moreinfo.j2 b/_docs/PKGBUILD.templates.d.python/vcs/01.moreinfo.j2 new file mode 100644 index 0000000..933af0f --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/01.moreinfo.j2 @@ -0,0 +1,2 @@ +# Bug reports can be filed at https://bugs.square-r00t.net/index.php?project=3 +# News updates for packages can be followed at https://devblog.square-r00t.net diff --git a/_docs/PKGBUILD.templates.d.python/vcs/02.pkgmeta.j2 b/_docs/PKGBUILD.templates.d.python/vcs/02.pkgmeta.j2 new file mode 100644 index 0000000..28b8209 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/02.pkgmeta.j2 @@ -0,0 +1,13 @@ +pkgname={{ pkg['name'] }} +pkgver=0.0001 +pkgrel=1 +pkgdesc="{{ pkg['desc'] }}" +arch=( 'i686' 'x86_64' ) +url="{{ pkg['site'] }}" +license=({% for license in pkg['license'] %}'{{ license }}' {% endfor %}){% if pkg['deps'] is defined and pkg['deps']|length > 0 %} +depends=( {% for dep in pkg['deps'] %}'{{ dep }}' {% endfor %}){% endif %}{% if pkg['optdeps'] is defined and pkg['optdeps']|length > 0 %} +optdepends=( {% for dep in pkg['optdeps'] %}'{{ dep }}' {% endfor %}){% endif %}{% if pkg['makedeps'] is defined and pkg['makedeps']|length > 0 %} +makedepends=( {% for dep in pkg['makedeps'] %}'{{ dep }}' {% endfor %}){% endif %} +_pkgname={{ pkg['name']|replace("-" + pkg['vcstype'],'') }}{% if pkg['provides'] is defined and pkg['provides']|length > 0 %} +provides=( {% for pkg in pkg['provides'] %}'{{ pkg }}' {% endfor %}){% endif %}{% if pkg['conflicts'] is defined and pkg['conflicts']|length > 0 %} +conflicts=( {% for pkg in pkg['conflicts'] %}'pkg'{% endfor %}){% endif %} diff --git a/_docs/PKGBUILD.templates.d.python/vcs/03.sources.j2 b/_docs/PKGBUILD.templates.d.python/vcs/03.sources.j2 new file mode 100644 index 0000000..7e660b3 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/03.sources.j2 @@ -0,0 +1,6 @@ +install= +changelog= +noextract=() +source=("{{ pkg['srcurl'] }}") +# see https://wiki.archlinux.org/index.php/VCS_package_guidelines#Git_Submodules if you require git submodules +sha512sums=('SKIP') diff --git a/_docs/PKGBUILD.templates.d.python/vcs/04.vcsver.j2 b/_docs/PKGBUILD.templates.d.python/vcs/04.vcsver.j2 new file mode 100644 index 0000000..431872e --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/04.vcsver.j2 @@ -0,0 +1,28 @@ +{% if pkg['vcstype'] == 'bzr' %}pkgver() { + cd "${_pkgname}" + printf "r%s" "$(bzr revno)" +}{% endif %}{% if pkg['vcstype'] == 'git' %}pkgver() { + cd "${srcdir}/${_pkgname}" + # no tags, so number of revisions e.g. r1142.a17a017 + printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" + ## most recent annotated tag e.g. 2.0.r6.ga17a017 + #git describe --long | sed 's/\([^-]*-g\)/r\1/;s/-/./g' + ## most recent un-annotated tag e.g. 0.71.r115.gd95ee07 + #git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g' + ## or: + ##git describe --long --tags | sed 's/-/.r/;s/-/./' + ## project uses tags with prefix. e.g. v... + #git describe --long | sed 's/^foo-//;s/\([^-]*-g\)/r\1/;s/-/./g' + ## both with fallback, e.g. 0.9.9.r27.g2b039da with tags, else r1581.2b039da + #( set -o pipefail + # git describe --long 2>/dev/null | sed 's/\([^-]*-g\)/r\1/;s/-/./g' || + # printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" + #) +}{% endif %}{% if pkg['vcstype'] == 'hg' %}pkgver() { + cd "${_pkgname}" + printf "r%s.%s" "$(hg identify -n)" "$(hg identify -i)" +}{% endif %}{% if pkg['vcstype'] == 'svn' %}pkgver() { + cd "${_pkgname}" + local ver="$(svnversion)" + printf "r%s" "${ver//[[:alpha:]]}" +}{% endif %} diff --git a/_docs/PKGBUILD.templates.d.python/vcs/05.build.j2 b/_docs/PKGBUILD.templates.d.python/vcs/05.build.j2 new file mode 100644 index 0000000..794bbea --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/05.build.j2 @@ -0,0 +1,4 @@ +build() { + cd "${srcdir}/${_pkgname}/src" + make prefix=${pkgdir}/usr +} diff --git a/_docs/PKGBUILD.templates.d.python/vcs/06.package.j2 b/_docs/PKGBUILD.templates.d.python/vcs/06.package.j2 new file mode 100644 index 0000000..f24d818 --- /dev/null +++ b/_docs/PKGBUILD.templates.d.python/vcs/06.package.j2 @@ -0,0 +1,4 @@ +package() { + install -D -m755 ${srcdir}/${_pkgname}/src/${_pkgname} ${pkgdir}/usr/bin/${_pkgname} + install -D -m644 ${srcdir}/${_pkgname}/docs/README.html.en ${pkgdir}/usr/share/doc/${_pkgname}/README.html +}