From fa2127cde48738447fb8697cfe224f63924b354b Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@gmail.com> Date: Mon, 11 Jan 2021 18:25:49 +0100 Subject: [PATCH] Implement auto filtering of Cargo.toml --- filter-toml.py | 141 ++++++++++++++++++++++++++++++++++++++++++++ make-srpms | 39 ++++++++++++ rust-package-dir.sh | 36 ----------- rust-package.sh | 40 ------------- 4 files changed, 180 insertions(+), 76 deletions(-) create mode 100755 filter-toml.py create mode 100755 make-srpms delete mode 100755 rust-package-dir.sh delete mode 100755 rust-package.sh diff --git a/filter-toml.py b/filter-toml.py new file mode 100755 index 0000000..8d0f353 --- /dev/null +++ b/filter-toml.py @@ -0,0 +1,141 @@ +#!/usr/bin/python3 + +import sys +import re +import subprocess +from pyparsing import Keyword, QuotedString, Suppress, Regex, OneOrMore +from pyparsing import Forward, Group, Dict, delimitedList +from pyparsing import lineno + +class Cfg: + + def __init__(self): + self.cfg = {} + def cfg(s): + m = re.match('([^=]+)(?:="(.*)")?', s) + return m.group(1), m.group(2) or True + self.cfg = dict([ cfg(l) for l + in subprocess.check_output( + [ 'rustc', '--print=cfg'], + encoding='utf8').splitlines() ]) + pass + + def compare(self, key, value): + if key in self.cfg: + return value == self.cfg[key] + return False + + pass + +cfg = Cfg() + +""" +https://doc.rust-lang.org/reference/conditional-compilation.html + +ConfigurationPredicate : + ConfigurationOption + | ConfigurationAll + | ConfigurationAny + | ConfigurationNot + +ConfigurationOption : + IDENTIFIER (= (STRING_LITERAL | RAW_STRING_LITERAL))? + +ConfigurationAll + all ( ConfigurationPredicateList? ) + +ConfigurationAny + any ( ConfigurationPredicateList? ) + +ConfigurationNot + not ( ConfigurationPredicate ) + +ConfigurationPredicateList + ConfigurationPredicate (, ConfigurationPredicate)* ,? +""" + +_predicate_ = Forward() + +_all_ = ( + Suppress(Keyword('all')) + + Suppress('(') + + delimitedList(_predicate_) + + Suppress(')') +).setParseAction(lambda predicates: set([True]) == set(predicates)) + +_any_ = ( + Suppress(Keyword('any')) + + Suppress('(') + + delimitedList(_predicate_) + + Suppress(')') +).setParseAction(lambda predicates: True in set(predicates)) + +_not_ = ( + Suppress(Keyword('not')) + + Suppress('(') + + _predicate_ + + Suppress(')') +).setParseAction(lambda predicate: not predicate[0]) + +_option_ = ( + ( + Regex('[A-Za-z_]+') + + Suppress('=') + + QuotedString('"') + ).setParseAction(lambda i_s: cfg.compare(i_s[0], i_s[1])) | + ( + Regex('[A-Za-z_]+') + ).setParseAction(lambda i: cfg.compare(i[0], True)) +) + +_predicate_ <<= ( + _all_ | + _any_ | + _not_ | + _option_ +) + +_cfg_ = ( + Suppress(Keyword('cfg')) + + Suppress('(') + + _predicate_ + + Suppress(')') +) + +def evaluate_cfg(s): + result = _cfg_.parseString(s.replace('\\', '')) + return result[0] + +def filter_dependencies(f): + result = [] + suppress = False + for l in f.split('\n'): + if m := re.match(r'^\[target\.(.)(cfg\(.*)\1\.dependencies\.', l): + cfg = m.group(2).replace('\\', '') + suppress = not evaluate_cfg(cfg) + pass + elif l.startswith('['): + suppress = False + pass + if not suppress: + result.append(l) + pass + else: + print("# Suppress", l, file=sys.stderr) + pass + pass + return '\n'.join(result) + pass + +if __name__ == '__main__': + for p in sys.argv[1:]: + old = open(p).read() + new = filter_dependencies(old) + if old != new: + print("# ", p, file=sys.stderr) + with open(p, 'w') as f: + f.write(new) + pass + pass + pass + pass diff --git a/make-srpms b/make-srpms new file mode 100755 index 0000000..3825458 --- /dev/null +++ b/make-srpms @@ -0,0 +1,39 @@ +#!/bin/bash + +set -e + +DEFAULT_TARGET=$(eval $(rustc --print cfg | grep target) ; \ + echo $target_arch-$target_vendor-$target_os-$target_env) + +export EDITOR=$(realpath $(dirname $0)/filter-toml.py) +#export TMPDIR=$(mktemp -d /var/tmp/make-srpms-XXXXXX) +export TMPDIR=/var/tmp/make-srpms +export PROJECTDIR=$(realpath .) +export RPMDIR=${PROJECTDIR}/rpms +export CARGO_HOME=${TMPDIR}/cargo +mkdir -p "${RPMDIR}" + +# Fetch dependencies and build SRPMS +cargo fetch --target ${DEFAULT_TARGET} +cargo package +cd ${TMPDIR} +for crate in $(find "${CARGO_HOME}" \ + "${PROJECTDIR}/target/package" -name '*.crate') ; do + if [[ "$(basename ${crate})" =~ ^(.*)-([^-]*)$ ]] ; then + set -x + NAME=${BASH_REMATCH[1]} + VERSION=${BASH_REMATCH[2]} + rust2rpm --target fedora \ + --patch \ + --store-crate \ + --no-dynamic-buildrequires \ + ${crate} + sed -i -re 's/(BuildRequires:\s*)\((crate[\(][^\)]+\)).*/&\n\1\2/' \ + "${TMPDIR}/rust-${NAME}.spec" + rpmbuild -bs \ + --define "_sourcedir ${TMPDIR}" \ + --define "_srcrpmdir ${TMPDIR}" \ + "${TMPDIR}/rust-${NAME}.spec" + fi +done +mv ${TMPDIR}/*.src.rpm ${RPMDIR}/ diff --git a/rust-package-dir.sh b/rust-package-dir.sh deleted file mode 100755 index 413a77e..0000000 --- a/rust-package-dir.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -e -set -x - -post_package() { - if [ -x post-package-$1-$2 ] ; then - $(realpath post-package-$1-$2) $3 - elif [ -x post-package-$1 ] ; then - $(realpath post-package-$1) $3 - elif [ -x post-package ] ; then - $(realpath post-package) $3 - fi -} - -CACHE=${HOME}/.cache/rust2rpm -cargo package -mkdir -p ${CACHE} -for f in $(pwd)/target/package/*.crate ; do - echo $f - SYMLINK=${CACHE}/$(basename "$f") - if [ -L "${SYMLINK}" ] ; then - rm -f "${SYMLINK}" - fi - ln -s "$f" "${SYMLINK}" - if [[ "$(basename "$f")" =~ (.*)-(.*).crate ]] ; then - NAME=${BASH_REMATCH[1]} - VERSION=${BASH_REMATCH[2]} - SPEC=rust-${NAME}-${VERSION}.spec - rust2rpm -t plain --stdout ${NAME} ${VERSION} > ${SPEC} - sed -i -re 's/(BuildRequires:\s*)\((crate[\(][^\)]+\)).*/&\n\1\2/' \ - ${SPEC} - post_package ${NAME} ${VERSION} ${SPEC} - rpmbuild -bs ${SPEC} -D'_sourcedir target/package/.' -D'_srcrpmdir .' - fi -done diff --git a/rust-package.sh b/rust-package.sh deleted file mode 100755 index a3c62d9..0000000 --- a/rust-package.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -set -e - -TARGET="-t plain" - -POSITIONAL=() -while [ $# -gt 0 ] ; do - case $1 in - -p|--patch) - PATCH="$1" - shift - ;; - -t|--target) - TARGET="$1 $2" - shift - shift - ;; - *) # unknown option - POSITIONAL+=("$1") - shift # past argument - ;; - esac -done -set -- "${POSITIONAL[@]}" # restore positional parameters -NAME=${POSITIONAL[0]} - -rust2rpm ${PATCH} ${TARGET} ${POSITIONAL[@]} -sed -i -re 's/(BuildRequires:\s*)\((crate[\(][^\)]+\)).*/&\n\1\2/' \ - rust-${NAME}.spec -DOWNLOAD=$(rpmspec -P rust-${NAME}.spec \ - | grep Source0 \ - | sed -re 's/^Source0:\s+(.*)$/\1/') -curl -L ${DOWNLOAD} > ${HOME}/rpmbuild/SOURCES/$(basename ${DOWNLOAD}) -if [ -n "${PATCH}" ] ; then - DIFF=$(basename ${DOWNLOAD} | sed -e 's/.crate//')-fix-metadata.diff - cp ${DIFF} ${HOME}/rpmbuild/SOURCES/ -fi -rpmbuild -bb rust-${NAME}.spec -rpmbuild -bs rust-${NAME}.spec -- GitLab