This commit is contained in:
Vinícius Moreira
2019-09-26 18:42:49 -03:00
committed by GitHub
17 changed files with 281 additions and 48 deletions

View File

@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.6.1] 2019-09-26
### Improvements:
- Better warning presentation when there are several messages
- Better AUR update check handling
- "Show" button available for all information fields
### Fixes:
- Error when retrieving suggestions
- snapd health check when snapd.service is available
- AUR: not showing all optional dependencies ( Info )
## [0.6.0] 2019-09-25 ## [0.6.0] 2019-09-25
### Features ### Features
@@ -33,7 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Environment variable / parameter **BAUH_UPDATE_NOTIFICATION** renamed to **BAUH_SYSTEM_NOTIFICATIONS** and now works for any system notification - Environment variable / parameter **BAUH_UPDATE_NOTIFICATION** renamed to **BAUH_SYSTEM_NOTIFICATIONS** and now works for any system notification
- Environment variable / parameter **BAUH_DOWNLOAD_MULTITHREAD**: if source files should be downloaded using multi-threads (not supported by all **gems**). - Environment variable / parameter **BAUH_DOWNLOAD_MULTITHREAD**: if source files should be downloaded using multi-threads (not supported by all **gems**).
- Environment variables / parameter **BAUH_MAX_DISPLAYED**: controls the maximum number of displayed apps ( default to 50 ) - Environment variables / parameter **BAUH_MAX_DISPLAYED**: controls the maximum number of displayed apps ( default to 50 )
- Environment variables / parameter **BAUH_LOGS**: controls the maximum number of displayed apps ( default to 50 ) - Environment variables / parameter **BAUH_LOGS**: activates console logging.
- small UI improvements - small UI improvements
### UI Changes ### UI Changes

View File

@@ -1,4 +1,4 @@
__version__ = '0.6.0' __version__ = '0.6.1'
__app_name__ = 'bauh' __app_name__ = 'bauh'
import os import os

View File

@@ -1,3 +1,4 @@
import re
from datetime import datetime from datetime import datetime
from bauh.api.abstract.model import PackageStatus from bauh.api.abstract.model import PackageStatus
@@ -5,6 +6,16 @@ from bauh.api.http import HttpClient
from bauh.gems.arch.model import ArchPackage from bauh.gems.arch.model import ArchPackage
URL_PKG_DOWNLOAD = 'https://aur.archlinux.org/{}' URL_PKG_DOWNLOAD = 'https://aur.archlinux.org/{}'
RE_LETTERS = re.compile(r'\.([a-zA-Z]+)-\d+$')
RE_SFX = ('r', 're', 'release')
GA_SFX = ('ga', 'ge')
RC_SFX = ('rc',)
BETA_SFX = ('b', 'beta')
AL_SFX = ('alpha', 'alfa')
DEV_SFX = ('dev', 'devel', 'development')
V_SUFFIX_MAP = {s: {'c': sfxs[0], 'p': idx} for idx, sfxs in enumerate([RE_SFX, GA_SFX, RC_SFX, BETA_SFX, AL_SFX, DEV_SFX]) for s in sfxs}
class ArchDataMapper: class ArchDataMapper:
@@ -36,7 +47,36 @@ class ArchDataMapper:
pkg.url_download = URL_PKG_DOWNLOAD.format(package['URLPath']) if package.get('URLPath') else None pkg.url_download = URL_PKG_DOWNLOAD.format(package['URLPath']) if package.get('URLPath') else None
pkg.first_submitted = datetime.fromtimestamp(package['FirstSubmitted']) if package.get('FirstSubmitted') else None pkg.first_submitted = datetime.fromtimestamp(package['FirstSubmitted']) if package.get('FirstSubmitted') else None
pkg.last_modified = datetime.fromtimestamp(package['LastModified']) if package.get('LastModified') else None pkg.last_modified = datetime.fromtimestamp(package['LastModified']) if package.get('LastModified') else None
pkg.update = pkg.version and pkg.latest_version and pkg.latest_version > pkg.version pkg.update = self.check_update(pkg.version, pkg.latest_version)
@staticmethod
def check_update(version: str, latest_version: str) -> bool:
if version and latest_version:
current_sfx = RE_LETTERS.findall(version)
latest_sf = RE_LETTERS.findall(latest_version)
if latest_sf and current_sfx:
current_sfx = current_sfx[0]
latest_sf = latest_sf[0]
current_sfx_data = V_SUFFIX_MAP.get(current_sfx.lower())
latest_sfx_data = V_SUFFIX_MAP.get(latest_sf.lower())
if current_sfx_data and latest_sfx_data:
nversion = version.split(current_sfx)[0]
nlatest = latest_version.split(latest_sf)[0]
if nversion == nlatest:
if current_sfx_data['c'] != latest_sfx_data['c']:
return latest_sfx_data['p'] < current_sfx_data['p']
else:
return ''.join(latest_version.split(latest_sf)) > ''.join(version.split(current_sfx))
return nlatest > nversion
return latest_version > version
return False
def fill_package_build(self, pkg: ArchPackage): def fill_package_build(self, pkg: ArchPackage):
res = self.http_client.get(pkg.get_pkg_build_url()) res = self.http_client.get(pkg.get_pkg_build_url())

View File

@@ -6,7 +6,7 @@ from bauh.api.abstract.handler import ProcessWatcher
from bauh.commons.system import run_cmd, new_subprocess, new_root_subprocess, SystemProcess, ProcessHandler from bauh.commons.system import run_cmd, new_subprocess, new_root_subprocess, SystemProcess, ProcessHandler
RE_DEPS = re.compile(r'[\w\-_]+:[\s\w_\-\.]+\s+\[\w+\]') RE_DEPS = re.compile(r'[\w\-_]+:[\s\w_\-\.]+\s+\[\w+\]')
RE_OPTDEPS = re.compile(r'[\w\._\-]+\s*:')
def is_enabled() -> bool: def is_enabled() -> bool:
try: try:
@@ -43,7 +43,7 @@ def get_info(pkg_name) -> str:
def get_info_list(pkg_name: str) -> List[tuple]: def get_info_list(pkg_name: str) -> List[tuple]:
info = get_info(pkg_name) info = get_info(pkg_name)
if info: if info:
return re.findall(r'(\w+\s?\w+)\s+:\s+(.+(\n\s+.+)*)', info) return re.findall(r'(\w+\s?\w+)\s*:\s*(.+(\n\s+.+)*)', info)
def get_info_dict(pkg_name: str) -> dict: def get_info_dict(pkg_name: str) -> dict:
@@ -53,14 +53,13 @@ def get_info_dict(pkg_name: str) -> dict:
info_dict = {} info_dict = {}
for info_data in info_list: for info_data in info_list:
attr = info_data[0].lower().strip() attr = info_data[0].lower().strip()
info_dict[attr] = info_data[1] if '\n' not in info_data[1] else ' '.join( info_dict[attr] = info_data[1]
[l.strip() for l in info_data[1].split('\n')])
if info_dict[attr] == 'None': if info_dict[attr] == 'None':
info_dict[attr] = None info_dict[attr] = None
if attr == 'optional deps' and info_dict[attr]: if attr == 'optional deps' and info_dict[attr]:
info_dict[attr] = RE_DEPS.findall(info_dict[attr]) info_dict[attr] = info_dict[attr].split('\n')
elif attr == 'depends on' and info_dict[attr]: elif attr == 'depends on' and info_dict[attr]:
info_dict[attr] = [d.strip() for d in info_dict[attr].split(' ') if d] info_dict[attr] = [d.strip() for d in info_dict[attr].split(' ') if d]

View File

@@ -8,7 +8,7 @@ from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \ from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \
SuggestionPriority SuggestionPriority
from bauh.commons import internet from bauh.commons.html import bold
from bauh.commons.system import SystemProcess, ProcessHandler from bauh.commons.system import SystemProcess, ProcessHandler
from bauh.gems.snap import snap, suggestions from bauh.gems.snap import snap, suggestions
from bauh.gems.snap.constants import SNAP_API_URL from bauh.gems.snap.constants import SNAP_API_URL
@@ -83,7 +83,6 @@ class SnapManager(SoftwareManager):
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult: def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
if snap.is_snapd_running(): if snap.is_snapd_running():
internet_available = internet.is_available(self.http_client, self.logger)
installed = [self.map_json(app_json, installed=True, disk_loader=disk_loader, internet=internet_available) for app_json in snap.read_installed()] installed = [self.map_json(app_json, installed=True, disk_loader=disk_loader, internet=internet_available) for app_json in snap.read_installed()]
return SearchResult(installed, None, len(installed)) return SearchResult(installed, None, len(installed))
else: else:
@@ -145,8 +144,10 @@ class SnapManager(SoftwareManager):
pass pass
def list_warnings(self) -> List[str]: def list_warnings(self) -> List[str]:
if not snap.is_snapd_running(): if snap.is_installed() and not snap.is_snapd_running():
return [self.i18n['snap.notification.snapd_unavailable']] snap_bold = bold('Snap')
return [self.i18n['snap.notification.snapd_unavailable'].format(bold('snapd'), snap_bold),
self.i18n['snap.notification.snap.disable'].format(snap_bold, bold(self.i18n['manage_window.settings.gems']))]
def _fill_suggestion(self, pkg_name: str, priority: SuggestionPriority, out: List[PackageSuggestion]): def _fill_suggestion(self, pkg_name: str, priority: SuggestionPriority, out: List[PackageSuggestion]):
res = self.http_client.get_json(SNAP_API_URL + '/search?q=package_name:{}'.format(pkg_name)) res = self.http_client.get_json(SNAP_API_URL + '/search?q=package_name:{}'.format(pkg_name))
@@ -163,24 +164,25 @@ class SnapManager(SoftwareManager):
def list_suggestions(self, limit: int) -> List[PackageSuggestion]: def list_suggestions(self, limit: int) -> List[PackageSuggestion]:
res = [] res = []
sugs = [(i, p) for i, p in suggestions.ALL.items()] if snap.is_snapd_running():
sugs.sort(key=lambda t: t[1].value, reverse=True) sugs = [(i, p) for i, p in suggestions.ALL.items()]
sugs.sort(key=lambda t: t[1].value, reverse=True)
threads = [] threads = []
for sug in sugs: for sug in sugs:
if limit <= 0 or len(res) < limit: if limit <= 0 or len(res) < limit:
t = Thread(target=self._fill_suggestion, args=(sug[0], sug[1], res)) t = Thread(target=self._fill_suggestion, args=(sug[0], sug[1], res))
t.start() t.start()
threads.append(t) threads.append(t)
time.sleep(0.001) # to avoid being blocked time.sleep(0.001) # to avoid being blocked
else: else:
break break
for t in threads: for t in threads:
t.join() t.join()
res.sort(key=lambda s: s.priority.value, reverse=True) res.sort(key=lambda s: s.priority.value, reverse=True)
return res return res
def is_default_enabled(self) -> bool: def is_default_enabled(self) -> bool:

View File

@@ -1,3 +1,4 @@
snap.notification.snapd_unavailable=snapd seems not to be installed or enabled. snap packages will not be available. snap.notification.snapd_unavailable={} seems not to be installed or enabled. {} packages will not be available.
snap.notification.snap.disable=If you do not want to use Snap applications, uncheck {} in {}
snap.action.refresh.status=Refreshing snap.action.refresh.status=Refreshing
snap.action.refresh.label=Refresh snap.action.refresh.label=Refresh

View File

@@ -7,6 +7,7 @@ snap.info.revision=revisión
snap.info.tracking=tracking snap.info.tracking=tracking
snap.info.installed=instalado snap.info.installed=instalado
snap.info.publisher=publicador snap.info.publisher=publicador
snap.notification.snapd_unavailable=snapd no parece estar instalado o habilitado. los paquetes snap estarán indisponibles. snap.notification.snapd_unavailable={} no parece estar instalado o habilitado. Los paquetes {} estarán indisponibles.
snap.notification.snap.disable=Si no desea usar aplicativos Snap, desmarque {} en {}
snap.action.refresh.status=Actualizando snap.action.refresh.status=Actualizando
snap.action.refresh.label=Actualizar snap.action.refresh.label=Actualizar

View File

@@ -7,6 +7,7 @@ snap.info.revision=revisão
snap.info.tracking=tracking snap.info.tracking=tracking
snap.info.installed=instalado snap.info.installed=instalado
snap.info.publisher=publicador snap.info.publisher=publicador
snap.notification.snapd_unavailable=snapd não parece estar instalado ou habilitado. os pacotes snap estarão indisponíveis. snap.notification.snapd_unavailable={} não parece estar instalado ou habilitado. Os pacotes {} estarão indisponíveis.
snap.notification.snap.disable=Se não deseja usar aplicativos Snap, desmarque {} em {}
snap.action.refresh.status=Atualizando snap.action.refresh.status=Atualizando
snap.action.refresh.label=Atualizar snap.action.refresh.label=Atualizar

View File

@@ -7,6 +7,8 @@ from bauh.commons.system import new_root_subprocess, run_cmd, new_subprocess
from bauh.gems.snap.model import SnapApplication from bauh.gems.snap.model import SnapApplication
BASE_CMD = 'snap' BASE_CMD = 'snap'
RE_SNAPD_STATUS = re.compile('\s+')
SNAPD_RUNNING_STATUS = {'listening', 'running'}
def is_installed(): def is_installed():
@@ -17,12 +19,24 @@ def is_installed():
def is_snapd_running() -> bool: def is_snapd_running() -> bool:
services = new_subprocess(['systemctl', 'list-units']) services = new_subprocess(['systemctl', 'list-units'])
for o in new_subprocess(['grep', '-oP', 'snapd.socket.+\K(listening|running)'], stdin=services.stdout).stdout: service, service_running = False, False
socket, socket_running = False, False
for o in new_subprocess(['grep', '-Eo', 'snapd.+'], stdin=services.stdout).stdout:
if o: if o:
line = o.decode().strip() line = o.decode().strip()
return bool(line)
return False if line:
line_split = RE_SNAPD_STATUS.split(line)
running = line_split[3] in SNAPD_RUNNING_STATUS
if line_split[0] == 'snapd.service':
service = True
service_running = running
elif line_split[0] == 'snapd.socket':
socket = True
socket_running = running
return socket and socket_running and (not service or (service and service_running))
def app_str_to_json(app: str) -> dict: def app_str_to_json(app: str) -> dict:

View File

@@ -3,7 +3,6 @@ from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QGroupBox, \ from PyQt5.QtWidgets import QDialog, QVBoxLayout, QGroupBox, \
QLineEdit, QLabel, QGridLayout, QPushButton, QPlainTextEdit, QToolBar QLineEdit, QLabel, QGridLayout, QPushButton, QPlainTextEdit, QToolBar
from bauh.api.abstract.cache import MemoryCache from bauh.api.abstract.cache import MemoryCache
from bauh.commons.html import strip_html
IGNORED_ATTRS = {'name', '__app__'} IGNORED_ATTRS = {'name', '__app__'}
@@ -54,8 +53,6 @@ class InfoDialog(QDialog):
else: else:
val = str(app[attr]).strip() val = str(app[attr]).strip()
full_val = None
i18n_val = locale_keys.get('{}.{}'.format(i18n_key, val.lower())) i18n_val = locale_keys.get('{}.{}'.format(i18n_key, val.lower()))
if i18n_val: if i18n_val:
@@ -63,13 +60,6 @@ class InfoDialog(QDialog):
text = QLineEdit() text = QLineEdit()
text.setToolTip(val) text.setToolTip(val)
if len(val) > 80:
full_val = val
self.full_vals.append(full_val)
val = strip_html(val)
val = val[0:80] + '...'
text.setText(val) text.setText(val)
text.setCursorPosition(0) text.setCursorPosition(0)
text.setStyleSheet("width: 400px") text.setStyleSheet("width: 400px")
@@ -80,9 +70,7 @@ class InfoDialog(QDialog):
self.gbox_info_layout.addWidget(label, idx, 0) self.gbox_info_layout.addWidget(label, idx, 0)
self.gbox_info_layout.addWidget(text, idx, 1) self.gbox_info_layout.addWidget(text, idx, 1)
self._gen_show_button(idx, val)
if full_val is not None:
self._gen_show_button(idx, full_val)
self.adjustSize() self.adjustSize()

View File

@@ -389,7 +389,7 @@ class FindSuggestions(AsyncAction):
def run(self): def run(self):
sugs = self.man.list_suggestions(limit=-1) sugs = self.man.list_suggestions(limit=-1)
self.notify_finished([s.package for s in sugs] if sugs is not None else []) self.notify_finished({'pkgs_found': [s.package for s in sugs] if sugs is not None else [], 'error': None})
class ListWarnings(QThread): class ListWarnings(QThread):

View File

@@ -333,7 +333,7 @@ class ManageWindow(QWidget):
def _show_warnings(self, warnings: List[str]): def _show_warnings(self, warnings: List[str]):
if warnings: if warnings:
dialog.show_message(title=self.i18n['warning'].capitalize(), body='<p>{}</p>'.format('<br/>'.join(warnings)), type_=MessageType.WARNING) dialog.show_message(title=self.i18n['warning'].capitalize(), body='<p>{}</p>'.format('<br/><br/>'.join(warnings)), type_=MessageType.WARNING)
def show(self): def show(self):
super(ManageWindow, self).show() super(ManageWindow, self).show()

View File

@@ -30,9 +30,10 @@ setup(
author_email=AUTHOR_EMAIL, author_email=AUTHOR_EMAIL,
python_requires=">=3.5", python_requires=">=3.5",
url=URL, url=URL,
packages=find_packages(), packages=find_packages(exclude=["tests.*", "tests"]),
package_data={NAME: ["view/resources/locale/*", "view/resources/img/*", "gems/*/resources/img/*", "gems/*/resources/locale/*"]}, package_data={NAME: ["view/resources/locale/*", "view/resources/img/*", "gems/*/resources/img/*", "gems/*/resources/locale/*"]},
install_requires=requirements, install_requires=requirements,
test_suite="tests",
entry_points={ entry_points={
"console_scripts": [ "console_scripts": [
"{name}={name}.app:main".format(name=NAME) "{name}={name}.app:main".format(name=NAME)

0
tests/__init__.py Normal file
View File

0
tests/gems/__init__.py Normal file
View File

View File

View File

@@ -0,0 +1,175 @@
from unittest import TestCase
from bauh.gems.arch.mapper import ArchDataMapper
class ArchDataMapperTest(TestCase):
def test_check_update_no_suffix(self):
self.assertTrue(ArchDataMapper.check_update('1.0.0-1', '1.0.0-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0-2', '1.0.0-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0-5', '1.0.1-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.1-1', '1.0.0-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.5-5', '1.1.0-2'))
self.assertFalse(ArchDataMapper.check_update('1.1.0-2', '1.0.5-5'))
self.assertTrue(ArchDataMapper.check_update('1.5.0-2', '1.5.1-1'))
self.assertFalse(ArchDataMapper.check_update('1.5.1-1', '1.5.0-2'))
self.assertTrue(ArchDataMapper.check_update('1.5.1-1', '1.5.1-2'))
self.assertTrue(ArchDataMapper.check_update('1.5.1-1', '2.0.0-1'))
self.assertFalse(ArchDataMapper.check_update('2.0.0-1', '1.5.1-1'))
def test_check_update_release(self):
# RE
self.assertTrue(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.R-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-2', '1.0.0.R-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.1.R-1', '1.0.0.R-5'))
self.assertTrue(ArchDataMapper.check_update('1.0.1.R-1', '1.0.1.R-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.2.R-1', '1.0.1.R-7'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.R-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RELEASE-2', '1.0.0.R-5'))
self.assertFalse(ArchDataMapper.check_update('1.0.1.R-1', '1.0.0.RELEASE-5'))
self.assertFalse(ArchDataMapper.check_update('1.0.1.R-1', '1.0.0.RE-1'))
# GA
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.Ge-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.GA-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.Ge-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.GE-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.GE-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.GE-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.GA-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.GA-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.GA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.R-5', '1.0.1.GA-1'))
# RCS
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.RC-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.RC-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.RC-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.R-5', '1.0.1.RC-1'))
# BETA
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.B-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.B-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.B-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.BETA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.BETA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.BETA-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.R-5', '1.0.1.BETA-1'))
# ALPHA
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.Alpha-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.ALPHA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.ALPHA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.ALPHA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.ALPHA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.ALPHA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.ALFA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.ALFA-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.ALFA-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.R-5', '1.0.1.Alfa-1'))
# DEV
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.DeV-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.DEV-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.DEVEL-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.R-1', '1.0.0.DEV-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.DEV-2'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.RELEASE-1', '1.0.0.DEV-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.R-5', '1.0.1.DEV-1'))
def test_check_update_ga(self):
# GA
self.assertFalse(ArchDataMapper.check_update('1.0.0.GA-1', '1.0.0.GE-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.GE-1', '1.0.0.GA-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.GA-2', '1.0.1.GA-1'))
self.assertFalse(ArchDataMapper.check_update('1.1.0.GE-3', '1.0.6.GE-10'))
# RC
self.assertFalse(ArchDataMapper.check_update('1.0.0.GA-1', '1.0.0.RC-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.GE-1', '1.0.0.RC-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.GA-1', '1.0.0.RC-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.GE-1', '1.0.1.RC-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.10.GA-10', '1.1.0.RC-1'))
self.assertFalse(ArchDataMapper.check_update('1.1.0.GE-1', '1.0.1.RC-1'))
# BETA
self.assertFalse(ArchDataMapper.check_update('1.0.0.GA-1', '1.0.0.BETA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.GE-1', '1.0.1.BETA-1'))
# ALPHA
self.assertFalse(ArchDataMapper.check_update('1.0.0.GE-1', '1.0.0.ALPHA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.GA-1', '1.0.1.ALPHA-1'))
# DEV
self.assertFalse(ArchDataMapper.check_update('1.0.0.GA-1', '1.0.0.DEV-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.GE-1', '1.0.1.DEV-1'))
def test_check_update_rc(self):
# RC
self.assertFalse(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.0.RC-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.0.RC-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RC-2', '1.0.1.RC-1'))
self.assertFalse(ArchDataMapper.check_update('1.1.0.RC-3', '1.0.6.RC-10'))
# BETA
self.assertFalse(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.0.BETA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.1.BETA-1'))
# ALPHA
self.assertFalse(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.0.ALPHA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.1.ALPHA-1'))
# DEV
self.assertFalse(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.0.DEV-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.RC-1', '1.0.1.DEV-1'))
def test_check_update_beta(self):
# BETA
self.assertFalse(ArchDataMapper.check_update('1.0.0.BETA-1', '1.0.0.BETA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.BETA-1', '1.0.0.BETA-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.BETA-2', '1.0.1.B-1'))
self.assertFalse(ArchDataMapper.check_update('1.1.0.B-3', '1.0.6.BETA-10'))
# ALPHA
self.assertFalse(ArchDataMapper.check_update('1.0.0.BETA-1', '1.0.0.ALPHA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.B-1', '1.0.1.ALPHA-1'))
# DEV
self.assertFalse(ArchDataMapper.check_update('1.0.0.BETA-1', '1.0.0.DEV-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.B-1', '1.0.1.DEV-1'))
def test_check_update_alpha(self):
# ALPHA
self.assertFalse(ArchDataMapper.check_update('1.0.0.ALPHA-1', '1.0.0.ALPHA-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.ALPHA-1', '1.0.0.ALFA-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.ALFA-1', '1.0.0.ALPHA-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.ALPHA-2', '1.0.1.ALFA-1'))
self.assertFalse(ArchDataMapper.check_update('1.1.0.ALFA-3', '1.0.6.ALFA-10'))
# DEV
self.assertFalse(ArchDataMapper.check_update('1.0.0.ALFA-1', '1.0.0.DEV-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.ALPHA-1', '1.0.1.DEV-1'))
def test_check_update_dev(self):
self.assertFalse(ArchDataMapper.check_update('1.0.0.DEV-1', '1.0.0.DEV-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.DEV-1', '1.0.0.DEVEL-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.DEVEL-1', '1.0.0.DEVELOPMENT-1'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.DEV-1', '1.0.0.DEVEL-2'))
self.assertTrue(ArchDataMapper.check_update('1.0.0.DEVEL-2', '1.0.1.DEV-1'))
self.assertFalse(ArchDataMapper.check_update('1.1.0.DEV-3', '1.0.6.DEVELOPMENT-10'))
def test_check_update_unknown_suffix(self):
self.assertTrue(ArchDataMapper.check_update('1.0.0.BALL-1', '1.0.0.TAR-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.TAR-1', '1.0.0.BALL-1'))
def test_check_update_known_and_unknown_suffix(self):
self.assertTrue(ArchDataMapper.check_update('1.0.0.RE-1', '1.0.0.TAR-1'))
self.assertFalse(ArchDataMapper.check_update('1.0.0.TAR-1', '1.0.0.RE-1'))