Source code for scipion.install.update_manager

#!/usr/bin/env python
# **************************************************************************
# *
# * Authors:    J. Jimenez de la Morena (jjimenez@cnb.csic.es)
# *             Yunior C. Fonseca Reyna (cfonseca@cnb.csic.es)
# *
# *  [1] Unidad de Bioinformatica of Centro Nacional de Biotecnologia, CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************
"""
This module is responsible for updating scipion-em, scipion-pyworkflow and
scipion-app if a higher version of these is released
"""
import subprocess
import argparse

from pyworkflow.utils import redStr, greenStr, os
from scipion.constants import MODE_UPDATE

DRY_COMMAND = '-dry'
SCIPION_NAME = 'Scipion'
PYPI_URL = 'https://pypi.org/pypi/%s/json'


[docs]def updateManagerParser(args): """ Create the parser for the "update" command """ parser = argparse.ArgumentParser(prog=args[1:], formatter_class=argparse.RawTextHelpFormatter) subparsers = parser.add_subparsers() parser_f = subparsers.add_parser(MODE_UPDATE, description='description: update {}.'.format( SCIPION_NAME), formatter_class=argparse.RawTextHelpFormatter, usage="{} [-h/--help] [{}]".format( ' '.join(args[:2]), DRY_COMMAND) ) parser_f.add_argument(DRY_COMMAND, help='only check status {}.'.format(SCIPION_NAME), action="store_true") parsedArgs = parser.parse_args(args[1:]) outdatedPackages = UpdateManager.getPackagesStatus() if not outdatedPackages: print('{} is up to date.'.format(SCIPION_NAME)) elif not parsedArgs.dry: UpdateManager.updateScipion(outdatedPackages)
[docs]class UpdateManager: """ Class responsible for updating scipion-em, scipion-pyworkflow and scipion-app if a higher version of these is released """ import pyworkflow import pwem import scipion packageNames = [('scipion-pyworkflow', pyworkflow.__version__), ('scipion-em', pwem.__version__), ('scipion-app', scipion.__version__)]
[docs] @classmethod def getPackagesStatus(cls, printAll=True): """ Check for scipion-app, scipion-pyworkflow and scipion-em updates return: a list of modules to be updated """ outdatedPackages = [] for package in cls.packageNames: needToUpdate, version = cls.getPackageState(package[0], package[1]) if needToUpdate: outdatedPackages.append((package[0], version)) print( greenStr('The package %s is out of date. Your version is %s, ' 'the latest is %s.' % (package[0], package[1], version))) elif printAll: print(greenStr('The package %s is up to date. Your version ' 'is %s' % (package[0], version))) return outdatedPackages
[docs] @classmethod def getPackageState(cls, packageName, version): """ Check if a package needs to be updated or not :param packageName: the package name :param version: version of the installed package :return (True, version) if the package needs to be updated, otherwise (False, version) """ import requests from packaging.version import Version try: response = requests.get(PYPI_URL % packageName, timeout=10) response.raise_for_status() latest = response.json()['info']['version'] except requests.exceptions.ConnectionError: print("Cannot check update status of %s (%s)" % (packageName, version)) return False, version except Exception as ex: print(redStr('%s :%s' % (packageName, ex))) return False, version # When working in devel mode the local version may be greater than the # latest released one: that is not an update return Version(version) < Version(latest), latest
[docs] @classmethod def updateScipion(cls, outdatedPackages): """ Update a module from which there is released a higher version """ for packageName in outdatedPackages: cmd_args = ['pip', 'install', '--upgrade', packageName[0]] result = subprocess.call(cmd_args) if result == 0: print('%s was correctly updated.' % packageName[0]) else: print('Something went wrong during the update of %s.' % packageName[0])