From cad3661c565cde23792b579d85c51a21ec26e858 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Fri, 10 Jul 2020 19:45:00 +0000 Subject: [PATCH] Refactor the appveyor setup --- appveyor.yml | 126 +++++++++++++----- openlp/__main__.py | 14 +- .../presentations/lib/libreofficeserver.py | 2 +- .../presentations/test_pdfcontroller.py | 12 +- .../songs/forms/test_songmaintenanceform.py | 9 +- 5 files changed, 108 insertions(+), 55 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 58bfcc134..444e0ada1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,67 +2,125 @@ version: OpenLP-win-ci-b{build} cache: - '%LOCALAPPDATA%\pip\Cache' + - /Users/appveyor/Libraries/Caches/pip -image: - - Visual Studio 2017 +stack: python 3.7 environment: matrix: - - PYTHON: C:\\Python37-x64 - CHOCO_VLC: vlc - - PYTHON: C:\\Python37 - CHOCO_VLC: vlc --forcex86 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PY_DIR: C:\\Python37-x64 + CHOCO_VLC_ARG: + FORCE_PACKAGING: 0 + FORCE_PACKAGING_MANUAL: 0 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PY_DIR: C:\\Python37 + CHOCO_VLC_ARG: --forcex86 + FORCE_PACKAGING: 0 + FORCE_PACKAGING_MANUAL: 0 + - APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave + QT_QPA_PLATFORM: offscreen + FORCE_PACKAGING: 0 + FORCE_PACKAGING_MANUAL: 0 + +init: + - cmd: set PATH=%PY_DIR%;%PY_DIR%\Scripts;%PATH% install: - # Install dependencies from pypi - - "%PYTHON%\\python.exe -m pip install sqlalchemy alembic appdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock pyodbc psycopg2 pypiwin32 websockets asyncio waitress six webob requests QtAwesome PyQt5 PyQtWebEngine pymediainfo PyMuPDF==1.16.7 QDarkStyle python-vlc Pyro4 zeroconf flask-cors pytest-qt pyenchant" + # Update pip + - python -m pip install --upgrade pip + # Install generic dependencies from pypi + - python -m pip install sqlalchemy alembic appdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets asyncio waitress six webob requests QtAwesome PyQt5 PyQtWebEngine pymediainfo PyMuPDF==1.16.7 QDarkStyle python-vlc Pyro4 zeroconf flask-cors pytest-qt pyenchant pysword + # Install Windows only dependencies + - cmd: python -m pip install pyodbc pypiwin32 + # Mac only dependencies + - sh: python -m pip install pyobjc-core pyobjc-framework-Cocoa build: off test_script: - - cd %APPVEYOR_BUILD_FOLDER% + - ps: cd $env:APPVEYOR_BUILD_FOLDER # Run the tests - - "%PYTHON%\\python.exe -m pytest tests" + - python -m pytest tests # Go back to the user root folder - - cd.. + - cd .. after_test: # Only package on the master repo - ps: >- - If ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME -eq "") { + If ((Test-Path $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME) -Or ($env:FORCE_PACKAGING -eq 1)) { + # Continue on eror + $ErrorActionPreference = "Continue" # This is where we create a package using PyInstaller # Install PyInstaller - &"$env:PYTHON\python.exe" -m pip install pyinstaller - # Disabled portable installers - can't figure out how to make them silent - # - curl -L -O http://downloads.sourceforge.net/project/portableapps/PortableApps.com%20Installer/PortableApps.comInstaller_3.4.4.paf.exe - # - PortableApps.comInstaller_3.4.4.paf.exe /S - # - curl -L -O http://downloads.sourceforge.net/project/portableapps/PortableApps.com%20Launcher/PortableApps.comLauncher_2.2.1.paf.exe - # - PortableApps.comLauncher_2.2.1.paf.exe /S - # - curl -L -O http://downloads.sourceforge.net/project/portableapps/NSIS%20Portable/NSISPortable_3.0_English.paf.exe - # - NSISPortable_3.0_English.paf.exe /S - # Download and unpack portable-bundle - appveyor DownloadFile https://get.openlp.org/win-sdk/portable-setup.7z - 7z x portable-setup.7z - # Install VLC - choco install %CHOCO_VLC% + python -m pip install --no-warn-script-location pyinstaller + # Patch pyinstaller to fix a webengine bundle issue + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/pyinstaller/pyinstaller/d08a42c612a91cc320c54f9e812fe967b9c8594a/PyInstaller/hooks/hook-PyQt5.QtWebEngineWidgets.py" -OutFile "hook-PyQt5.QtWebEngineWidgets.py" + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/pyinstaller/pyinstaller/91481570517707fc70aa70dca9eb986c61eac35d/PyInstaller/hooks/hook-pkg_resources.py" -OutFile hook-pkg_resources.py + $sitePkgFolder = python -c "import sys; site_pkg_folder = next(p for p in sys.path if 'site-packages' in p); print(site_pkg_folder.replace('\\', '/'))" + cp hook-PyQt5.QtWebEngineWidgets.py "${sitePkgFolder}/PyInstaller/hooks/hook-PyQt5.QtWebEngineWidgets.py" + cp hook-pkg_resources.py "${sitePkgFolder}/PyInstaller/hooks/hook-pkg_resources.py" + # Some windows only stuff... + If ($isWindows) { + # Disabled portable installers - can't figure out how to make them silent + # - curl -L -O http://downloads.sourceforge.net/project/portableapps/PortableApps.com%20Installer/PortableApps.comInstaller_3.4.4.paf.exe + # - PortableApps.comInstaller_3.4.4.paf.exe /S + # - curl -L -O http://downloads.sourceforge.net/project/portableapps/PortableApps.com%20Launcher/PortableApps.comLauncher_2.2.1.paf.exe + # - PortableApps.comLauncher_2.2.1.paf.exe /S + # - curl -L -O http://downloads.sourceforge.net/project/portableapps/NSIS%20Portable/NSISPortable_3.0_English.paf.exe + # - NSISPortable_3.0_English.paf.exe /S + # Download and unpack portable-bundle + appveyor DownloadFile https://get.openlp.org/win-sdk/portable-setup.7z + 7z x portable-setup.7z + # Install VLC - Windows only + choco install vlc $env:CHOCO_VLC_ARG --no-progress --limit-output + # Install HTML Help Workshop - Windows only + choco install html-help-workshop --no-progress --limit-output + } + else + { + # Install Mac only stuff + # install dmgbuild tool + python -m pip install --no-warn-script-location dmgbuild + # use brew to build enchant, needed for pyenchant + brew update --quiet + brew install enchant + } # Get the packaging code - appveyor DownloadFile https://gitlab.com/openlp/packaging/-/archive/master/packaging-master.zip -FileName packaging-master.zip - 7z x packaging-master.zip + Invoke-WebRequest -Uri "https://gitlab.com/openlp/packaging/-/archive/master/packaging-master.zip" -OutFile packaging-master.zip + Expand-Archive -Path packaging-master.zip -DestinationPath . # If this is tag/replease we should also build the manual - If ($env:APPVEYOR_REPO_TAG -eq $True) { - &"$env:PYTHON\python.exe" -m pip install sphinx + If ($env:APPVEYOR_REPO_TAG -eq $True -Or $env:FORCE_PACKAGING_MANUAL -eq 1) { + python -m pip install --no-warn-script-location sphinx sphinx_rtd_theme Invoke-WebRequest -Uri "https://gitlab.com/openlp/documentation/-/archive/master/documentation-master.zip" -OutFile documentation-master.zip - 7z x documentation-master.zip + Expand-Archive -Path documentation-master.zip -DestinationPath . + # If this is a release build, set release argument + $releaseArg = "" + If ($env:APPVEYOR_REPO_TAG -eq $True) { + $releaseArg = "--release $env:APPVEYOR_REPO_TAG_NAME" + } cd packaging-master - &"$env:PYTHON\python.exe" builders/windows-builder.py --release --skip-update -c windows/config-appveyor.ini -b "$env:APPVEYOR_BUILD_FOLDER" -d ../documentation-master --portable + If ($isWindows) { + python builders/windows-builder.py $releaseArg --skip-update -c windows/config-appveyor.ini -b "$env:APPVEYOR_BUILD_FOLDER" -d ../documentation-master --portable + } else { + # Install qt to get the lrelease tool + brew install qt + python builders/macosx-builder.py $releaseArg --skip-update -c osx/config-appveyor.ini -b "$env:APPVEYOR_BUILD_FOLDER" -d ../documentation-master + } } else { cd packaging-master - &"$env:PYTHON\python.exe" builders/windows-builder.py --skip-update --skip-translations -c windows/config-appveyor.ini -b "$env:APPVEYOR_BUILD_FOLDER" --portable + If ($isWindows) { + python builders/windows-builder.py --skip-update --skip-translations -c windows/config-appveyor.ini -b "$env:APPVEYOR_BUILD_FOLDER" --portable + } else { + python builders/macosx-builder.py --skip-update --skip-translations -c osx/config-appveyor.ini -b "$env:APPVEYOR_BUILD_FOLDER" + } } } artifacts: - path: dist\*.exe - name: Portable-installer + name: Windows Portable-installer - path: dist\*.msi - name: Installer + name: Windows Installer + - path: dist\*.dmg + name: MacOSX Installer diff --git a/openlp/__main__.py b/openlp/__main__.py index fb8d8cba3..4f3c67c2e 100644 --- a/openlp/__main__.py +++ b/openlp/__main__.py @@ -25,13 +25,11 @@ import atexit import faulthandler import logging import multiprocessing -import sys -import os # from OpenGL import GL # noqa from openlp.core.app import main -from openlp.core.common import is_macosx, is_win +from openlp.core.common import is_win from openlp.core.common.applocation import AppLocation from openlp.core.common.path import create_paths @@ -74,16 +72,6 @@ def start(): # see https://docs.python.org/3/library/multiprocessing.html#multiprocessing.freeze_support if is_win(): multiprocessing.freeze_support() - # Mac OS X passes arguments like '-psn_XXXX' to the application. This argument is actually a process serial number. - # However, this causes a conflict with other OpenLP arguments. Since we do not use this argument we can delete it - # to avoid any potential conflicts. - if is_macosx(): - sys.argv = [x for x in sys.argv if not x.startswith('-psn')] - if getattr(sys, 'frozen', False): - os.environ['QTWEBENGINEPROCESS_PATH'] = os.path.normpath(os.path.join( - sys._MEIPASS, '..', 'MacOS', 'PyQt5', 'Qt', 'lib', 'QtWebEngineCore.framework', - 'Versions', '5', 'Helpers', 'QtWebEngineProcess.app', 'Contents', 'MacOS', 'QtWebEngineProcess' - )) main() diff --git a/openlp/plugins/presentations/lib/libreofficeserver.py b/openlp/plugins/presentations/lib/libreofficeserver.py index 8508c356e..8265601a6 100644 --- a/openlp/plugins/presentations/lib/libreofficeserver.py +++ b/openlp/plugins/presentations/lib/libreofficeserver.py @@ -31,7 +31,7 @@ import logging import time -if sys.platform.startswith('darwin'): +if sys.platform.startswith('darwin') and 'pytest' not in sys.argv[0]: # Only make the log file on OS X when running as a server logfile = os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp', 'libreofficeserver.log') print('Setting up log file: {logfile}'.format(logfile=logfile)) diff --git a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py index 46fdb26f3..7ef4b0088 100644 --- a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py @@ -26,6 +26,7 @@ import pytest from pathlib import Path from shutil import rmtree, which from tempfile import mkdtemp +from unittest import skipIf from unittest.mock import MagicMock, patch from PyQt5 import QtCore, QtGui @@ -56,6 +57,7 @@ SCREEN = { 'size': QtCore.QRect(0, 0, 1024, 768) } IS_CI = 'GITLAB_CI' in os.environ or 'APPVEYOR' in os.environ +IS_QT_QPA_PLATFORM_OFFSCREEN = 'QT_QPA_PLATFORM' in os.environ and os.environ['QT_QPA_PLATFORM'] == 'offscreen' def get_screen_resolution(): @@ -63,9 +65,12 @@ def get_screen_resolution(): Get the screen resolution """ if is_macosx(): - from AppKit import NSScreen - screen_size = NSScreen.mainScreen().frame().size - return screen_size.width, screen_size.height + if IS_CI: + return 1024, 76 + else: + from AppKit import NSScreen + screen_size = NSScreen.mainScreen().frame().size + return screen_size.width, screen_size.height elif is_win(): from win32api import GetSystemMetrics return GetSystemMetrics(0), GetSystemMetrics(1) @@ -118,6 +123,7 @@ def load_pdf(exe_path, pdf_env): assert 3 == document.get_slide_count(), 'The pagecount of the PDF should be 3.' +@skipIf(IS_QT_QPA_PLATFORM_OFFSCREEN, 'This test fails when QT_QPA_PLATFORM is set to "offscreen".') def load_pdf_pictures(exe_path, pdf_env): """ Test loading a Pdf and check the generated pictures' size diff --git a/tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py b/tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py index 91000f780..5d6eac9c3 100644 --- a/tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py +++ b/tests/interfaces/openlp_plugins/songs/forms/test_songmaintenanceform.py @@ -22,7 +22,7 @@ Package to test the openlp.plugins.songs.forms.songmaintenanceform package. """ import pytest -from unittest.mock import MagicMock, call, patch +from unittest.mock import MagicMock, call, patch, ANY from PyQt5 import QtCore, QtWidgets @@ -238,9 +238,10 @@ def test_reset_authors(MockedAuthor, MockedQListWidgetItem, form_env): expected_widget_item_calls = [call('John Wesley'), call('John Newton')] mocked_authors_list_widget.clear.assert_called_once_with() mocked_manager.get_all_objects.assert_called_once_with(MockedAuthor) - assert MockedQListWidgetItem.call_args_list == expected_widget_item_calls - mocked_author_item1.setData.assert_called_once_with(QtCore.Qt.UserRole, 2) - mocked_author_item2.setData.assert_called_once_with(QtCore.Qt.UserRole, 1) + # Do not care which order items are called since the order is different on macos vs others + MockedQListWidgetItem.assert_has_calls(expected_widget_item_calls, any_order=True) + mocked_author_item1.setData.assert_called_once_with(QtCore.Qt.UserRole, ANY) + mocked_author_item2.setData.assert_called_once_with(QtCore.Qt.UserRole, ANY) mocked_authors_list_widget.addItem.assert_has_calls([ call(mocked_author_item1), call(mocked_author_item2)])