forked from tubearchivist/tubearchivist
-
Notifications
You must be signed in to change notification settings - Fork 0
/
version_check.py
executable file
·115 lines (83 loc) · 3.27 KB
/
version_check.py
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python
""" check requirements.txt for outdated packages """
import pathlib
import requests
class Requirements:
"""handle requirements.txt"""
FILE_PATH = "tubearchivist/requirements.txt"
LOCK = "/tmp/tubearchivist-requirements.lock"
def __init__(self):
self.exists = self.checked_today()
self.all_requirements = False
self.all_updates = False
def checked_today(self):
"""skip requirements check when lock file exists"""
exists = pathlib.Path(self.LOCK).exists()
return exists
def look_for_updates(self):
"""look through requirements and check for updates"""
self.all_requirements = self.get_dependencies()
self.all_updates = self.check_packages()
def get_dependencies(self):
"""read out requirements.txt"""
all_requirements = []
with open(self.FILE_PATH, "r", encoding="utf-8") as f:
dependencies = f.readlines()
for dependency in dependencies:
package, version = dependency.split("==")
all_requirements.append((package, version.strip()))
all_requirements.sort(key=lambda x: x[0].lower())
return all_requirements
def check_packages(self):
"""compare installed with remote version"""
total = len(self.all_requirements)
print(f"checking versions for {total} packages...")
all_updates = {}
for dependency in self.all_requirements:
package, version_installed = dependency
url = f"https://pypi.org/pypi/{package}/json"
response = requests.get(url).json()
version_remote = response["info"]["version"]
homepage = response["info"]["home_page"]
if version_remote != version_installed:
to_update = {
package: {"from": version_installed, "to": version_remote}
}
all_updates.update(to_update)
message = (
f"update {package} {version_installed}"
+ f"==> {version_remote}\n {homepage}"
)
print(message)
if not all_updates:
print("no updates found")
# remember that
pathlib.Path(self.LOCK).touch()
return all_updates
def apply_updates(self):
"""update requirements.txt file with new versions"""
to_write = []
for requirement in self.all_requirements:
package, old_version = requirement
if package in self.all_updates.keys():
package_version = self.all_updates[package]["to"]
else:
package_version = old_version
to_write.append(f"{package}=={package_version}\n")
with open(self.FILE_PATH, "w", encoding="utf-8") as f:
f.writelines(to_write)
print("requirements.txt updates")
def main():
"""main to check for updates"""
handler = Requirements()
if handler.exists:
return
handler.look_for_updates()
if handler.all_updates:
input_response = input("\nupdate requirements.txt? [y/n] ")
if input_response == "y":
handler.apply_updates()
else:
print("skip update...")
if __name__ == "__main__":
main()