From 09aa363c399064213768ce28f6c102bb30360683 Mon Sep 17 00:00:00 2001 From: pdelboca Date: Fri, 17 Jan 2025 09:31:13 +0100 Subject: [PATCH] Add deb package creation logic. --- .gitignore | 1 + build.py | 22 +++++++++ create-deb.sh | 45 +++++++++++++++++++ ode/__init__.py | 1 + ode/main.py | 3 ++ packaging/linux/icon.svg | 25 +++++++++++ packaging/linux/opendataeditor.desktop | 19 ++++++++ .../macos/entitlements.mac.plist | 0 8 files changed, 116 insertions(+) create mode 100644 build.py create mode 100755 create-deb.sh create mode 100644 packaging/linux/icon.svg create mode 100644 packaging/linux/opendataeditor.desktop rename entitlements.mac.plist => packaging/macos/entitlements.mac.plist (100%) diff --git a/.gitignore b/.gitignore index 4aed74f48..e8462c7e9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ data/ __pycache__ build/ dist/ +tmp/ # Astro node_modules/ diff --git a/build.py b/build.py new file mode 100644 index 000000000..641754c31 --- /dev/null +++ b/build.py @@ -0,0 +1,22 @@ +import PyInstaller.__main__ +import subprocess + + +def build_application(): + """Build an executable file for the Application.""" + + print("[server] Creating linux executable file for Open Data Editor") + PyInstaller.__main__.run([ + 'ode/main.py', + '--collect-all', 'frictionless', # Frictionless depends on data files + '--collect-all', 'ode', # Collect all assets from Open Data Editor + '--log-level', 'WARN', + '--name', 'opendataeditor', + '--noconfirm', + ]) + # Clean the spec file generated by PyInstaller + subprocess.run(['rm', 'opendataeditor.spec']) + + +if __name__ == "__main__": + build_application() diff --git a/create-deb.sh b/create-deb.sh new file mode 100755 index 000000000..8a9c35dfa --- /dev/null +++ b/create-deb.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Script to create a PyQT deb package using fpm +# +# This script will create a folder structure that will be used as input +# for the fpm command and copy into it all the distributable files generated by +# pyinstaller. +# We will create a folder with the same structure Linux systems expects: +# - /opt for our executable and associated files (a.k.a our dist/ folder) +# - /usr/share/applications (for the .desktop file) +# - /usr/share/icons/hicolor/scalable/apps for our svg icons (only svg in scalable folder) +# +# More info: +# - https://www.pythonguis.com/tutorials/packaging-pyqt5-applications-linux-pyinstaller/ +# - https://fpm.readthedocs.io/en/latest/packages/dir.html#dir-local-files +# +# Create folders +[ -e package ] && rm -r tmp +mkdir -p tmp/opt +mkdir -p tmp/usr/share/applications +mkdir -p tmp/usr/share/icons/hicolor/scalable/apps + +# Build the project +[ -e build ] && rm -r build +[ -e dist ] && rm -r dist +python build.py + +# Copy files +cp -r dist/opendataeditor tmp/opt/opendataeditor +cp ./packaging/linux/icon.svg tmp/usr/share/icons/hicolor/scalable/apps/org.okfn.opendataeditor.svg +cp ./packaging/linux/opendataeditor.desktop tmp/usr/share/applications + +# Change permissions +# Packages retain the permissions of installed files from when they were packaged, +# but will be installed by root. In order for ordinary users to be able to run the +# application, we need to change the permissions. +find tmp/opt/opendataeditor -type f -exec chmod 644 -- {} + +find tmp/opt/opendataeditor -type d -exec chmod 755 -- {} + +find tmp/usr/share -type f -exec chmod 644 -- {} + +chmod +x tmp/opt/opendataeditor/opendataeditor + +# Create the deb package +VERSION=$(python -c "import ode; print(ode.__version__)") +FILENAME=opendataeditor-linux-$VERSION.deb +[ -e $FILENAME ] && rm $FILENAME +fpm -C tmp -s dir -t deb -n "opendataeditor" -v $VERSION -p dist/$FILENAME diff --git a/ode/__init__.py b/ode/__init__.py index 855bd3e97..8efd6ba51 100644 --- a/ode/__init__.py +++ b/ode/__init__.py @@ -1 +1,2 @@ # Required for PyInstaller to collect all assets +__version__ = "1.3.0" diff --git a/ode/main.py b/ode/main.py index c2d851e82..d704a8c80 100644 --- a/ode/main.py +++ b/ode/main.py @@ -1,6 +1,7 @@ import collections import sys import shutil +import ode from PySide6.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, @@ -335,6 +336,8 @@ def open_report_issue(self): if __name__ == "__main__": app = QApplication(sys.argv) + app.setApplicationName("Open Data Editor") + app.setApplicationVersion(ode.__version__) window = MainWindow() window.show() sys.exit(app.exec()) diff --git a/packaging/linux/icon.svg b/packaging/linux/icon.svg new file mode 100644 index 000000000..c8075631f --- /dev/null +++ b/packaging/linux/icon.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/linux/opendataeditor.desktop b/packaging/linux/opendataeditor.desktop new file mode 100644 index 000000000..f05e2b25a --- /dev/null +++ b/packaging/linux/opendataeditor.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] + +# The type of the thing this desktop file refers to +Type=Application + +# The Application Name +Name=Open Data Editor + +# Tooltip comment to show in menus +Comment=Data management for humans. + +# The path (folder) in which the executable is run +Path=/opt/opendataeditor + +# The executable (can include arguments) +Exec=/opt/opendataeditor/opendataeditor + +# The icon we install for the application, use the target filesystem path +Icon=org.okfn.opendataeditor diff --git a/entitlements.mac.plist b/packaging/macos/entitlements.mac.plist similarity index 100% rename from entitlements.mac.plist rename to packaging/macos/entitlements.mac.plist