78bf02298b
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
84 lines
2.4 KiB
Python
Executable File
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()
|