-
Notifications
You must be signed in to change notification settings - Fork 0
/
pypiupdate.py
executable file
·110 lines (93 loc) · 3.29 KB
/
pypiupdate.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import logging
LOGGING_FORMAT = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'
logging.basicConfig(format=LOGGING_FORMAT, level=logging.INFO)
from pkgtools.pypi import PyPIJson
import pip
import progressbar
import traceback
import click
from threading import Thread
import pip.commands.install
def install_distributions(distributions, args=None):
"""From http://threebean.org/blog/2011/06/06/installing-from-pip-inside-python-or-a-simple-pip-api/
"""
command = pip.commands.install.InstallCommand()
opts, args = command.parser.parse_args(args)
# TBD, why do we have to run the next part here twice before actual install
requirement_set = command.run(opts, distributions)
requirement_set = command.run(opts, distributions)
requirement_set.install(opts)
try:
# Python 2
from Queue import Queue
except ImportError:
# Python 3
from queue import Queue
def worker():
while True:
pkg = q.get()
try:
remote = PyPIJson(pkg.project_name).retrieve()
remote_version = remote['info']['version']
if remote_version != pkg.version:
outdated.append((pkg,remote_version))
except Exception as e:
print("""Error occurred while checking package "{0}":""".format(pkg))
print(traceback.format_exc())
try:
attrs = vars(e)
print('\n'.join(".{0} == {1}".format(key,val) for key,val in attrs.items()))
except: pass
done.append(pkg)
progress.update(len(done))
q.task_done()
def get_outdated():
global progress
global q
global done
global outdated
outdated = []
progress = None
done = []
# Start up worker pool
q = Queue()
# Ten concurrent connections are alright, I think.
num_worker_threads = 10
for i in range(num_worker_threads):
t = Thread(target=worker)
t.daemon = True
t.start()
only_local_packages = False
pkg_list = pip.get_installed_distributions(local_only=only_local_packages)
progress = progressbar.ProgressBar(widgets=[progressbar.SimpleProgress(), ' ', progressbar.Bar(), ' ', progressbar.ETA()], maxval=len(pkg_list)).start()
for pkg in pkg_list:
q.put(pkg)
q.join()
progress.finish()
return outdated
def update_packages(pkg_list):
for pkg in pkg_list:
try:
print("Updating {0}".format(pkg))
install_distributions([pkg], ['-U','-v'])
print("OK: Updated {0}".format(pkg))
except Exception as e:
print("""Error occurred while updating package "{0}":""".format(pkg))
print(traceback.format_exc())
@click.command()
@click.option('--update/--no-update', default=False, help='Update or list only')
def main(update):
outdated = get_outdated()
if outdated:
if update:
update_packages(sorted(pkg.project_name for (pkg,version) in outdated))
else:
print("Run the following command to update all outdated packages:")
print("pip install -U " + " ".join(sorted(pkg.project_name for (pkg,version) in outdated)))
else:
print("Everything is up to date.")
if __name__=='__main__':
main()