diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2019-04-06 22:56:53 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2019-04-07 00:00:23 -0400 |
commit | 057767ca8df1b7c84f86413e3d2aa208fddbb5ec (patch) | |
tree | 459f6d30083481b2f2d88ac6e573ed9a5c5422a7 | |
parent | d624faea3d62a5dab5dce6d7a14b6c27f8fddea9 (diff) |
list-depends: Get much more robust with parsing requirements.txt
-rwxr-xr-x | list-depends | 28 | ||||
-rwxr-xr-x | pip2pacman | 78 |
2 files changed, 80 insertions, 26 deletions
diff --git a/list-depends b/list-depends index ddcef9e..f248ccb 100755 --- a/list-depends +++ b/list-depends @@ -18,29 +18,5 @@ [[ -n $stat_file ]] || stat_file='depends_static.txt' [[ -n $prod_file ]] || prod_file='https://projects.parabolagnulinux.org/parabolaweb.git/plain/requirements_prod.txt' -cat "${stat_file}" | -sed -r \ - -e 's/\s*#.*//' - -curl -s "${prod_file}" | -sed -r \ - -e 's|^-e .*/fredj/cssmin.git@master#egg=cssmin$|python2-cssmin-fredj|' \ - -e 's/.*/\L&/' \ - -e 's/^(python2?-)?/python2-/' | -while read -r dep; do - # This one is a little more complicated, because with == - # depends, I don't want to actually lock to that precise of a - # version; it would be a nightmare with keeping things in - # sync. So, let's turn == into >=, but also make sure the - # first two segments match. - if [[ $dep = *==* ]]; then - name="${dep%%==*}" - ver="${dep#*==}" - IFS=. - read major minor patch <<<"$ver" - echo "$name>=$ver" - echo "$name<$major.$((minor+1))" - else - echo "$dep" - fi -done +sed -r -e 's/\s*#.*//' <"${stat_file}" +"$(dirname -- "$0")/pip2pacman" "${prod_file}" diff --git a/pip2pacman b/pip2pacman new file mode 100755 index 0000000..ff1975b --- /dev/null +++ b/pip2pacman @@ -0,0 +1,78 @@ +#!/usr/bin/env python + +# Copyright (c) 2013, 2015, 2019 Luke Shumaker <lukeshu@parabola.nu> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import re + +from pip._internal.req import parse_requirements +from pip._internal.download import PipSession +from packaging.specifiers import Specifier + +vcspkgs = { + 'git+git://github.com/fredj/cssmin.git@master#egg=cssmin': 'python2-cssmin-fredj', +} + + +def nextver(ver): + parts = re.sub(r"(a|b|rc|\.dev|\.post|\+).*", '', ver).split('.') + parts.pop() + parts += [str(int(parts.pop())+1)] + return '.'.join(parts) + + +# https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format +# https://setuptools.readthedocs.io/en/latest/pkg_resources.html#requirements-parsing +# https://www.python.org/dev/peps/pep-0440/ +def main(args): + for filename in args: + for req in parse_requirements(filename, session=PipSession()): + depname = re.sub(r"^(python2?-)?", 'python2-', req.name.lower()) + if req.link: + if req.link.url not in vcspkgs: + raise f"no known package for VCS dep {req}" + depname = vcspkgs[req.link.url] + if req.specifier: + for spec in req.specifier: + # Hack: Allow some slop with '==', otherwise it would be a + # nightmare with keeping things in sync. + if spec.operator == "==": + if len(spec.version.split('.')) <= 2: + spec = Specifier(f"=={spec.version}.*") + else: + spec = Specifier(f"~={spec.version}") + + if spec.operator == "~=": + print(f"{depname}>={spec.version} {depname}<{nextver(spec.version)}") + elif spec.operator == "==": + if spec.version.endswith(".*"): + print(f"{depname}>={spec.version[:-2]} {depname}<{nextver(spec.version)}") + else: + print(f"{depname}={spec.version}") + elif spec.operator == '!=': + raise f"version exclusion is not supported: {req}" + elif spec.operator in {'<=', '>=', '<', '>'}: + print(f"{depname}{spec.operator}{spec.version}") + elif spec.operator == "===": + print(f"{depname}={spec.version}") + else: + raise f"unknown specifier operator: {spec.operator}: {req}" + else: + print(f"{depname}") + + +if __name__ == '__main__': + import sys + main(sys.argv[1:]) |