File size: 1,944 Bytes
3ee0381
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
""" Parse requirements.txt and pyproject.toml and move versions to pyproject.toml """
from pathlib import Path
import re
import sys
import toml

def get_requirement_versions(path='requirements.txt'):
    """ Read requirements.txt file and return dict of package versions """
    path = Path(path or '')
    if path.is_dir():
        path = next(iter(path.glob('**/requirements.txt')))
    reqdict = {}
    text = Path(path).open().read()
    for line in text.splitlines():
        if line.strip():
            match = re.match(r'([-_a-zA-Z0-9]+)\s*([ >=<~^,.rabc0-9]+)\s*', line)
            if match:
                name, ver = match.groups()
                reqdict[name] = ver
    return reqdict  


def normalize_name(name):
    return str(name).strip().replace('_', '-').replace(' ', '-').lower()


def pin_versions(pyproject='pyproject.toml', reqdict=None, overwrite=False):
    if not reqdict or isinstance(reqdict, (str, Path)):
        reqdict = get_requirement_versions(path=reqdict)
    reqdict = {
        normalize_name(k): v for (k, v) in 
        reqdict.items()
        }
    
    pyproj = toml.load(pyproject)
    depdict = pyproj.get('tool', {}).get('poetry', {}).get('dependencies', {})
    depdict = {
        normalize_name(k): v for (k, v) in 
        depdict.items()
        }
    
    for name, spec in reqdict.items():
        if name in depdict:
            ver = depdict[name]
            if isinstance(ver, str) and (overwrite or ver == '*'):
                depdict[name] = spec

    pyproj['tool']['poetry']['dependencies'] = depdict
    overwrite = overwrite or (input(f'Overwrite {pyproject}?')[0].lower() == 'y')
    if overwrite:
        with open(pyproject, 'w') as stream:
            toml.dump(pyproj, stream)
    return pyproj


if __name__ == '__main__':
    path = 'requirements.txt'
    if sys.argv[1:]:
        path = sys.argv[1]
    pyproj = pin_versions(reqdict=path)
    print(toml.dumps(pyproj))