From d929336f08f08e0b8c6a054df2367d24af92dd11 Mon Sep 17 00:00:00 2001 From: rejbasket <39080670+rejbasket@users.noreply.github.com> Date: Sat, 10 Feb 2024 20:16:30 +0100 Subject: [PATCH] Rejbasket/pyinstaller fix installer checks (#2718) * netowrkx deps added in build * check for user inkscape config before installing * get os version in exception * update electron app location according to pyinstaller redesign * fixed broken libgeos syslinks * contents-directory added pyinstaller args fix broken linux and win versions * updated inkex * fix print_pdf --------- authored-by: rejbasket --- .github/workflows/build.yml | 23 +++++++++++++++++---- bin/build-distribution-archives | 21 +++++++++++++++---- bin/build-python | 2 ++ installer_scripts/inkstitch.plist | 2 +- installer_scripts/scripts/preinstall | 14 +------------ installer_scripts/template.iss | 14 +++++++++++++ lib/exceptions.py | 30 +++++++++++++++++++++++++++- lib/extensions/print_pdf.py | 2 +- lib/svg/rendering.py | 2 +- requirements.txt | 4 ++-- 10 files changed, 87 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9041d87cf..0e6726b32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,7 +72,11 @@ jobs: python -m pip install https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04/wxPython-4.2.1-cp38-cp38-linux_x86_64.whl python -m pip install -r requirements.txt - python -m pip install pyinstaller==5.13.2 + # for networkx + python -m pip install pandas + python -m pip install pyarrow + + python -m pip install pyinstaller # scipy gives us a ELF error when stripped sudo apt-get install gcc g++ gfortran python3-dev libopenblas-dev liblapack-dev @@ -118,7 +122,10 @@ jobs: python -m pip install scipy==1.9.0 pip install wxPython python -m pip install -r requirements.txt - python -m pip install pyinstaller==5.13.2 + # for networkx + python -m pip install pandas + + python -m pip install pyinstaller echo "${{ env.pythonLocation }}\bin" >> $GITHUB_PATH - shell: bash @@ -166,7 +173,11 @@ jobs: python -m pip install wheel pip install wxPython python -m pip install -r requirements.txt - python -m pip install pyinstaller==5.13.2 + # for networkx + python -m pip install pandas + python -m pip install pyarrow + + python -m pip install pyinstaller echo "${{ env.pythonLocation }}\bin" >> $GITHUB_PATH - shell: bash @@ -225,7 +236,11 @@ jobs: pip install PyGObject pip install wxPython pip install -r requirements.txt - pip install pyinstaller==5.13.2 + # for networkx + pip install pandas + pip install pyarrow + + pip install pyinstaller echo "${{ env.pythonLocation }}/bin" >> $GITHUB_PATH - shell: bash diff --git a/bin/build-distribution-archives b/bin/build-distribution-archives index 021461dfd..285e5ef83 100644 --- a/bin/build-distribution-archives +++ b/bin/build-distribution-archives @@ -8,8 +8,21 @@ if [ "$BUILD" = "osx" ]; then # adding version to Info.plist plutil -replace CFBundleShortVersionString -string ${VERSION} dist/inkstitch.app/Contents/Info.plist rm -rf dist/inkstitch/ - # this removes the extra dylibs that cause notary to fail. - rm -rf dist/inkstitch.app/Contents/MacOS/shapely/.dylibs + # unlinking the libgeos and dot dylib folder syslinks and fix broken syslinks for notary. + # copying libgeos dylibs with ditto preserves information to pass notary. + unlink dist/inkstitch.app/Contents/Resources/shapely/.dylibs + + unlink dist/inkstitch.app/Contents/Resources/libgeos.3.11.2.dylib + unlink dist/inkstitch.app/Contents/Resources/libgeos_c.1.17.2.dylib + + unlink dist/inkstitch.app/Contents/Frameworks/libgeos.3.11.2.dylib + unlink dist/inkstitch.app/Contents/Frameworks/libgeos_c.1.17.2.dylib + + ditto dist/inkstitch.app/Contents/Frameworks/shapely/__dot__dylibs/libgeos.3.11.2.dylib dist/inkstitch.app/Contents/Resources/ + ditto dist/inkstitch.app/Contents/Frameworks/shapely/__dot__dylibs/libgeos_c.1.17.2.dylib dist/inkstitch.app/Contents/Resources/ + + ditto dist/inkstitch.app/Contents/Frameworks/shapely/__dot__dylibs/libgeos.3.11.2.dylib dist/inkstitch.app/Contents/Frameworks/ + ditto dist/inkstitch.app/Contents/Frameworks/shapely/__dot__dylibs/libgeos_c.1.17.2.dylib dist/inkstitch.app/Contents/Frameworks/ # Install location for pkgbuild PKG_INSTALL_PATH="/tmp/inkstitch/" # Checking arch of macos and setting path of electron for arm64 or intel @@ -36,7 +49,7 @@ if [ "$BUILD" = "osx" ]; then DEV_IDENT="Developer ID Application: Lex Neva (929A568N58)" echo "Signing of inkstitch.app" # Coyping inkstitch-gui.app into inkstitch - ditto "${ELECTRON_BUILD_PATH}" dist/inkstitch.app/Contents/MacOS/electron + ditto "${ELECTRON_BUILD_PATH}" dist/inkstitch.app/Contents/Frameworks/electron # signing the binary may fix notary issue /usr/bin/codesign -s "${DEV_IDENT}" \ --deep \ @@ -92,7 +105,7 @@ if [ "$BUILD" = "osx" ]; then fi else # local builds will not be signed or notarized - cp -a "${ELECTRON_BUILD_PATH}" dist/inkstitch.app/Contents/MacOS/electron + cp -a "${ELECTRON_BUILD_PATH}" dist/inkstitch.app/Contents/Frameworks/electron pkgbuild --root dist/inkstitch.app \ --component-plist installer_scripts/inkstitch.plist \ --ownership recommended \ diff --git a/bin/build-python b/bin/build-python index 4c27e5d81..cd3e84a26 100755 --- a/bin/build-python +++ b/bin/build-python @@ -2,6 +2,8 @@ set -e info_year=$( date "+%Y" ) +# PyInstaller v6.x rearranges folder configuration causing broken builds, This re-enables old onedir layout. +pyinstaller_args+="--contents-directory . " # We need to use the precompiled bootloader linked with graphical Mac OS X # libraries if we develop a GUI application for Mac: diff --git a/installer_scripts/inkstitch.plist b/installer_scripts/inkstitch.plist index 8d102d1f4..4d85c7a53 100644 --- a/installer_scripts/inkstitch.plist +++ b/installer_scripts/inkstitch.plist @@ -12,7 +12,7 @@ BundleOverwriteAction install RootRelativeBundlePath - Contents/MacOS/electron/inkstitch-gui.app + Contents/Frameworks/electron/inkstitch-gui.app diff --git a/installer_scripts/scripts/preinstall b/installer_scripts/scripts/preinstall index 165128a7f..01427651f 100755 --- a/installer_scripts/scripts/preinstall +++ b/installer_scripts/scripts/preinstall @@ -1,25 +1,13 @@ #!/bin/bash set -e inkstitch_folder=($HOME/Library/Application\ Support/org.inkscape.Inkscape/config/inkscape/extensions/inkstitch) -location_inkscape=(/Applications/Inkscape.app) - -# Checking if Inkscape is installed -if [[ -d "${location_inkscape}" ]]; then - echo "Inkscape is found and installed "${location_Inkscape}"." -else - osascript <<-AppleScript - set theDialogText to "Ink/Stich is an Inkscape plugin. Please install and run Inkscape before installing Ink/Stitch." - display dialog theDialogText buttons {"Okay"} default button "Okay" - AppleScript - exit 1 -fi # Checking if Inkscape configuration folders are created if [[ -d "${inkstitch_folder%config*}" ]]; then echo "Inkscape configs are found and installed "${inkstitch_folder%config*}"." else osascript <<-AppleScript - set theDialogText to "Please run Inkscape before installing Ink/Stitch." + set theDialogText to "Ink/Stich is an Inkscape plugin. Please install and run Inkscape before installing Ink/Stitch." display dialog theDialogText buttons {"Okay"} default button "Okay" AppleScript exit 1 diff --git a/installer_scripts/template.iss b/installer_scripts/template.iss index 99ae6d33d..8dd269766 100755 --- a/installer_scripts/template.iss +++ b/installer_scripts/template.iss @@ -118,6 +118,20 @@ begin Result := 1; end; +{ ///////////////////////////////////////////////////////////////////// } +function InitializeSetup(): Boolean; +begin + Result := True; + + if DirExists(ExpandConstant('{userappdata}\inkscape\extensions\')) then + Log('Found Inks') + else + begin + MsgBox('Error: Inkscape Extensions folder not found! Install and then run Inkscape to create the extension folder.', mbInformation, MB_OK); + Result := False; + end; +end; + { ///////////////////////////////////////////////////////////////////// } procedure CurStepChanged(CurStep: TSetupStep); begin diff --git a/lib/exceptions.py b/lib/exceptions.py index 3a6b456c6..8bef185ff 100644 --- a/lib/exceptions.py +++ b/lib/exceptions.py @@ -3,12 +3,38 @@ # Copyright (c) 2010 Authors # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. import traceback +import sys +import platform +import subprocess +from glob import glob class InkstitchException(Exception): pass +def get_os_version(): + if sys.platform == "win32": + # To get the windows version, python functions are used + # Using python subprocess with cmd.exe in windows is currently a security risk + os_ver = "Windows " + platform.release() + " version: " + platform.version() + if sys.platform == "darwin": + # macOS command line progam provides accurate info than python functions + mac_v = subprocess.run(["sw_vers"], capture_output=True, text=True) + os_ver = str(mac_v.stdout.strip()) + if sys.platform == "linux": + # Getting linux version method used here is for systemd and nonsystemd linux. + try: + ltmp = subprocess.run(["cat"] + glob("/etc/*-release"), capture_output=True, text=True) + lnx_ver = ltmp.stdout.splitlines() + lnx_ver = str(list(filter(lambda x: "PRETTY_NAME" in x, lnx_ver))) + os_ver = lnx_ver[15:][:-3] + except FileNotFoundError: + os_ver = "Cannot get Linux distro version" + + return os_ver + + def format_uncaught_exception(): """Format the current exception as a request for a bug report. @@ -30,7 +56,9 @@ def format_uncaught_exception(): "- create a new issue at") message += " https://github.com/inkstitch/inkstitch/issues/new\n\n" message += _("Include the error description and also (if possible) the svg file.") - message += '\n\n\n' + message += '\n\n' + message += get_os_version() + message += '\n\n' message += version.get_inkstitch_version() + '\n' message += traceback.format_exc() diff --git a/lib/extensions/print_pdf.py b/lib/extensions/print_pdf.py index 4e6671302..ddfdc3a30 100644 --- a/lib/extensions/print_pdf.py +++ b/lib/extensions/print_pdf.py @@ -231,7 +231,7 @@ class Print(InkstitchExtension): # for all color blocks together. layers = svg.findall("./g[@%s='layer']" % INKSCAPE_GROUPMODE) - stitch_plan_layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']") + stitch_plan_layer = svg.findone(".//*[@id='__inkstitch_stitch_plan__']") # Make sure there is no leftover translation from stitch plan preview stitch_plan_layer.pop('transform') diff --git a/lib/svg/rendering.py b/lib/svg/rendering.py index 1f74e2df8..b96fe9b7b 100644 --- a/lib/svg/rendering.py +++ b/lib/svg/rendering.py @@ -222,7 +222,7 @@ def color_block_to_paths(color_block, svg, destination, visual_commands): def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True): - layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']") + layer = svg.findone(".//*[@id='__inkstitch_stitch_plan__']") if layer is None: layer = inkex.Group(attrib={ 'id': '__inkstitch_stitch_plan__', diff --git a/requirements.txt b/requirements.txt index ea63db739..855c9bc32 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ ./pyembroidery -# get up to date inkex version (October 23 2023) -inkex @ git+https://gitlab.com/inkscape/extensions.git@b38c022b0394c7eb665c4a0927b226d2f5840fad +# get up to date inkex version (Febuary 10, 2024) +inkex @ git+https://gitlab.com/inkscape/extensions.git@99db88135c3e557b343dd3d878eea8de2676d2ab wxPython>=4.1.1