mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
updater: Add custom update message depending on package manager (#1287)
* updater: Add custom update message depending on package manager Close #938 Close #1031 * Reduce cognitive complexity and avoid too many return functions * Use a dictionary instead of if/else * Take into account pkg installation with OSX * updater: add platform detection Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
committed by
Ruslan Kuprieiev
parent
2afe950a27
commit
b6842fb089
+7
-5
@@ -221,8 +221,10 @@ class Logger(object):
|
||||
) for line in lines
|
||||
]
|
||||
|
||||
return "{margin}{padding}{content}{padding}{margin}".format(
|
||||
margin=cls.colorize(margin, border_color),
|
||||
padding=''.join(padding_lines),
|
||||
content=''.join(content_lines),
|
||||
)
|
||||
box = "{margin}{padding}{content}{padding}{margin}".format(
|
||||
margin=cls.colorize(margin, border_color),
|
||||
padding=''.join(padding_lines),
|
||||
content=''.join(content_lines),
|
||||
)
|
||||
|
||||
print(box)
|
||||
|
||||
+111
-30
@@ -1,3 +1,4 @@
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import requests
|
||||
@@ -17,14 +18,9 @@ class Updater(object): # pragma: no cover
|
||||
def __init__(self, dvc_dir):
|
||||
self.dvc_dir = dvc_dir
|
||||
self.updater_file = os.path.join(dvc_dir, self.UPDATER_FILE)
|
||||
|
||||
@staticmethod
|
||||
def init(dvc_dir):
|
||||
return Updater(dvc_dir)
|
||||
self.current = VERSION_BASE
|
||||
|
||||
def check(self):
|
||||
current = VERSION_BASE
|
||||
|
||||
if os.getenv('CI'):
|
||||
return
|
||||
|
||||
@@ -40,36 +36,121 @@ class Updater(object): # pragma: no cover
|
||||
Logger.info('Checking for updates...')
|
||||
|
||||
try:
|
||||
r = requests.get(self.URL, timeout=self.TIMEOUT_GET)
|
||||
j = r.json()
|
||||
latest = j['version']
|
||||
open(self.updater_file, 'w+').close()
|
||||
self._get_latest_version()
|
||||
except Exception as exc:
|
||||
msg = 'Failed to obtain latest version: {}'.format(str(exc))
|
||||
Logger.debug(msg)
|
||||
return
|
||||
|
||||
l_major, l_minor, l_patch = [int(x) for x in latest.split('.')]
|
||||
c_major, c_minor, c_patch = [int(x) for x in current.split('.')]
|
||||
if self._is_outdated():
|
||||
self._notify()
|
||||
|
||||
if l_major <= c_major and \
|
||||
l_minor <= c_minor and \
|
||||
l_patch <= c_patch:
|
||||
return
|
||||
def _get_latest_version(self):
|
||||
r = requests.get(self.URL, timeout=self.TIMEOUT_GET)
|
||||
j = r.json()
|
||||
self.latest = j['version']
|
||||
open(self.updater_file, 'w+').close()
|
||||
|
||||
msg = (
|
||||
def _is_outdated(self):
|
||||
l_major, l_minor, l_patch = [int(x) for x in self.latest.split('.')]
|
||||
c_major, c_minor, c_patch = [int(x) for x in self.current.split('.')]
|
||||
|
||||
return (l_major > c_major or
|
||||
l_minor > c_minor or
|
||||
l_patch > c_patch)
|
||||
|
||||
def _notify(self):
|
||||
message = (
|
||||
'Update available {red}{current}{reset} -> {green}{latest}{reset}'
|
||||
'\n'
|
||||
'Run {yellow}pip{reset} install dvc {blue}--upgrade{reset}'
|
||||
.format(
|
||||
red=colorama.Fore.RED,
|
||||
reset=colorama.Fore.RESET,
|
||||
green=colorama.Fore.GREEN,
|
||||
yellow=colorama.Fore.YELLOW,
|
||||
blue=colorama.Fore.BLUE,
|
||||
current=current,
|
||||
latest=latest,
|
||||
)
|
||||
)
|
||||
+ '\n'
|
||||
+ self._get_update_instructions()
|
||||
).format(red=colorama.Fore.RED,
|
||||
reset=colorama.Fore.RESET,
|
||||
green=colorama.Fore.GREEN,
|
||||
yellow=colorama.Fore.YELLOW,
|
||||
blue=colorama.Fore.BLUE,
|
||||
current=self.current,
|
||||
latest=self.latest)
|
||||
|
||||
Logger.box(msg, border_color='yellow')
|
||||
if sys.stdout.isatty():
|
||||
Logger.box(message, border_color='yellow')
|
||||
|
||||
def _get_update_instructions(self):
|
||||
instructions = {
|
||||
'pip': 'Run {yellow}pip{reset} install dvc {blue}--upgrade{reset}',
|
||||
'yum': 'Run {yellow}yum{reset} update dvc',
|
||||
'yay': 'Run {yellow}yay{reset} {blue}-S{reset} dvc',
|
||||
'formula': 'Run {yellow}brew{reset} upgrade dvc',
|
||||
'cask': 'Run {yellow}brew cask{reset} upgrade dvc',
|
||||
'apt': ('Run {yellow}apt-get{reset} install'
|
||||
' {blue}--only-upgrade{reset} dvc'),
|
||||
'binary': ('To upgrade follow this steps:\n'
|
||||
'1. Uninstall dvc binary\n'
|
||||
'2. Go to {blue}https://dvc.org{reset}\n'
|
||||
'3. Download and install new binary'),
|
||||
None: ('Find the latest release at\n{blue}'
|
||||
'https://github.com/iterative/dvc/releases/latest'
|
||||
'{reset}'),
|
||||
}
|
||||
|
||||
package_manager = self._get_package_manager()
|
||||
|
||||
return instructions[package_manager]
|
||||
|
||||
@staticmethod
|
||||
def _is_binary():
|
||||
return getattr(sys, 'frozen', False)
|
||||
|
||||
def _get_linux(self):
|
||||
import distro
|
||||
|
||||
if not self._is_binary():
|
||||
return 'pip'
|
||||
|
||||
package_managers = {
|
||||
'rhel': 'yum',
|
||||
'centos': 'yum',
|
||||
'fedora': 'yum',
|
||||
'amazon': 'yum',
|
||||
'opensuse': 'yum',
|
||||
'ubuntu': 'apt',
|
||||
'debian': 'apt',
|
||||
}
|
||||
|
||||
return package_managers.get(distro.id())
|
||||
|
||||
def _get_darwin(self):
|
||||
if not self._is_binary():
|
||||
if __file__.startswith('/usr/local/Cellar'):
|
||||
return 'formula'
|
||||
else:
|
||||
return 'pip'
|
||||
|
||||
# NOTE: both pkg and cask put dvc binary into /usr/local/bin,
|
||||
# so in order to know which method of installation was used,
|
||||
# we need to actually call `brew cask`
|
||||
ret = os.system('brew cask ls dvc')
|
||||
if ret == 0:
|
||||
return 'cask'
|
||||
|
||||
return None
|
||||
|
||||
def _get_windows(self):
|
||||
return None if self._is_binary() else 'pip'
|
||||
|
||||
def _get_package_manager(self):
|
||||
import platform
|
||||
from dvc.exceptions import DvcException
|
||||
|
||||
m = {
|
||||
'Windows': self._get_windows,
|
||||
'Darwin': self._get_darwin,
|
||||
'Linux': self._get_linux,
|
||||
}
|
||||
|
||||
system = platform.system()
|
||||
func = m.get(system)
|
||||
if func is None:
|
||||
raise DvcException("Not supported system '{}'".format(system))
|
||||
|
||||
return func()
|
||||
|
||||
@@ -23,3 +23,4 @@ futures>=3.2.0; python_version == "2.7"
|
||||
grandalf==0.6
|
||||
pydot>=1.2.4
|
||||
asciimatics>=1.10.0
|
||||
distro>=1.3.0
|
||||
|
||||
Reference in New Issue
Block a user