requirements/cmds/normalize
Haikel Guemar 78bf02298b Add new normalize utility
Purpose: cleanup requirements.txt in order to be more readable

Implemented features:
- comments are preceded by two spaces and separated from '#' by one space (PEP8 style)
- specificiers are ordered

Change-Id: Ic9a4c044b2740b1d0167c237b67822a9794356c8
2016-06-22 10:11:29 +02:00

84 lines
2.4 KiB
Python
Executable File

#! /usr/bin/env python
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import argparse
from distutils.version import LooseVersion
import pkg_resources
def cmp_specifier(a, b):
weight = {'>=': 0, '>': 0,
'==': 1 , '~=': 1, '!=': 1,
'<': 2., '<=': 2}
wa, wb = weight[a[0]], weight[b[0]]
res = cmp(wa, wb)
if res != 0:
return res
else:
return cmp(LooseVersion(a[1]), LooseVersion(b[1]))
def lint(requirements):
output = []
for line in requirements:
# comments and empty lines are untouched
if line.startswith("#") or line == "":
output.append(line)
continue
# split comments
parts = line.split('#', 1)
if len(parts) > 1:
base, comments = parts
else:
base, comments = parts[0], ""
base, comments = base.strip(), comments.strip()
# split extras specifiers
parts = base.split(';', 1)
if len(parts) > 1:
base, extras = parts
else:
base, extras = parts[0], ""
base, extras = base.strip(), extras.strip()
req = pkg_resources.Requirement.parse(base)
name = req.key
# FIXME: not py3 compliant
specs = ["%s%s" % x for x in sorted(req.specs, cmp=cmp_specifier)]
name += ','.join(specs)
if extras != "":
name += ";%s" % extras
if comments != "":
name += " #%s" % comments
output.append(name)
return output
def main():
parser = argparse.ArgumentParser(description="Normalize requirements files")
parser.add_argument('requirements',
help=['requirements file input'])
args = parser.parse_args()
with open(args.requirements) as f:
requirements = [line.strip() for line in f.readlines()]
for line in lint(requirements):
print(line)
if __name__ == '__main__':
main()