From 13ccc4e03208a97e4b72ef6ff068c7f17943874d Mon Sep 17 00:00:00 2001 From: Aiden Schembri Date: Fri, 27 Feb 2026 08:27:03 +0100 Subject: [PATCH] openmotor: init at 0.6.1 --- pkgs/by-name/op/openmotor/Info.plist | 24 +++ pkgs/by-name/op/openmotor/fix-setup.patch | 32 ++++ .../op/openmotor/main-entrypoint.patch | 17 ++ pkgs/by-name/op/openmotor/package.nix | 159 ++++++++++++++++++ 4 files changed, 232 insertions(+) create mode 100644 pkgs/by-name/op/openmotor/Info.plist create mode 100644 pkgs/by-name/op/openmotor/fix-setup.patch create mode 100644 pkgs/by-name/op/openmotor/main-entrypoint.patch create mode 100644 pkgs/by-name/op/openmotor/package.nix diff --git a/pkgs/by-name/op/openmotor/Info.plist b/pkgs/by-name/op/openmotor/Info.plist new file mode 100644 index 000000000000..66c8ecc81bfb --- /dev/null +++ b/pkgs/by-name/op/openmotor/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleExecutable + openMotor + CFBundleName + openMotor + CFBundleDisplayName + openMotor + CFBundleIdentifier + com.reilleya.openmotor + CFBundleVersion + @version@ + CFBundleShortVersionString + @version@ + CFBundlePackageType + APPL + CFBundleIconFile + openMotor + NSHighResolutionCapable + + + diff --git a/pkgs/by-name/op/openmotor/fix-setup.patch b/pkgs/by-name/op/openmotor/fix-setup.patch new file mode 100644 index 000000000000..63f60ed5ecd4 --- /dev/null +++ b/pkgs/by-name/op/openmotor/fix-setup.patch @@ -0,0 +1,32 @@ +diff --git a/setup.py b/setup.py +index 460c7d7..77e7a7a 100644 +--- a/setup.py ++++ b/setup.py +@@ -11,11 +11,7 @@ except ImportError: + build_ui = None # user won't have pyqt_distutils when deploying + cmdclass = {} + +-try: +- from uilib.fileIO import appVersionStr +-except ImportError: +- print('App version not available, defaulting to 0.0.0') +- appVersionStr = '0.0.0' ++appVersionStr = '@version@' + + extensions = [ + Extension( +@@ -34,9 +30,11 @@ setup( + nthreads = multiprocessing.cpu_count(), + compiler_directives={'language_level': 3} + ), ++ py_modules=['main', 'app'], + packages=find_packages(), + url='https://github.com/reilleya/openMotor', + description='An open-source internal ballistics simulator for rocket motor experimenters', + long_description=open('README.md').read(), +- cmdclass=cmdclass +-) +\ No newline at end of file ++ cmdclass=cmdclass, ++ entry_points={'console_scripts': ['openMotor=main:main']} ++) diff --git a/pkgs/by-name/op/openmotor/main-entrypoint.patch b/pkgs/by-name/op/openmotor/main-entrypoint.patch new file mode 100644 index 000000000000..a993d2fb97f6 --- /dev/null +++ b/pkgs/by-name/op/openmotor/main-entrypoint.patch @@ -0,0 +1,17 @@ +diff --git a/main.py b/main.py +index 1ecf103..fb4e8fe 100644 +--- a/main.py ++++ b/main.py +@@ -1,6 +1,9 @@ + import sys + from app import App +-from PyQt6.QtCore import Qt + +-app = App(sys.argv) +-sys.exit(app.exec()) ++def main(): ++ app = App(sys.argv) ++ sys.exit(app.exec()) ++ ++if __name__ == '__main__': ++ main() diff --git a/pkgs/by-name/op/openmotor/package.nix b/pkgs/by-name/op/openmotor/package.nix new file mode 100644 index 000000000000..e06ef932f2c1 --- /dev/null +++ b/pkgs/by-name/op/openmotor/package.nix @@ -0,0 +1,159 @@ +{ + lib, + stdenv, + python3Packages, + fetchFromGitHub, + qt6, + writableTmpDirAsHomeHook, + copyDesktopItems, + makeDesktopItem, + replaceVars, + nix-update-script, +}: + +python3Packages.buildPythonApplication rec { + pname = "openmotor"; + version = "0.6.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "reilleya"; + repo = "openMotor"; + tag = "v${version}"; + hash = "sha256-5b/Q/qjd2EH+OG6pAZhPTnEnFy0e/reBH8sIH0DZORo="; + }; + + patches = [ + ./main-entrypoint.patch + ./fix-setup.patch + ]; + + nativeBuildInputs = [ + qt6.wrapQtAppsHook + writableTmpDirAsHomeHook + ] + ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [ + copyDesktopItems + ]; + + buildInputs = [ + qt6.qtbase + ] + ++ lib.optionals stdenv.hostPlatform.isLinux [ + qt6.qtwayland + ]; + + build-system = with python3Packages; [ + setuptools + cython + pyqt6 + ]; + + dependencies = with python3Packages; [ + cycler + decorator + ezdxf + imageio + matplotlib + networkx + numpy + pillow + platformdirs + pyparsing + pyqt6 + pyqt6-sip + python-dateutil + pyyaml + scikit-fmm + scikit-image + scipy + six + ]; + + postPatch = '' + # Substitute version placeholder in patched setup.py + substituteInPlace setup.py --replace-fail '@version@' '${version}' + ''; + + preBuild = '' + # Compile Qt Designer .ui files to Python modules + find uilib/views/forms -name "*.ui" 2>/dev/null | while read ui_file; do + py_file="uilib/views/$(basename "$ui_file" .ui)_ui.py" + echo "Compiling $ui_file -> $py_file" + pyuic6 "$ui_file" -o "$py_file" + done + + # Ensure views directory has __init__.py + touch uilib/views/__init__.py + ''; + + postInstall = lib.optionalString (!stdenv.hostPlatform.isDarwin) '' + # Install icons on Linux + install -Dm644 resources/oMIconCycles.png $out/share/icons/hicolor/256x256/apps/openmotor.png + install -Dm644 resources/oMIconCyclesSmall.png $out/share/icons/hicolor/128x128/apps/openmotor.png + ''; + + postFixup = lib.optionalString stdenv.hostPlatform.isDarwin '' + # Create macOS app bundle + mkdir -p $out/Applications/openMotor.app/Contents/{MacOS,Resources} + + # Install Info.plist + install -Dm644 ${ + replaceVars ./Info.plist { inherit version; } + } $out/Applications/openMotor.app/Contents/Info.plist + + # Use upstream's .icns icon + install -Dm644 resources/oMIconCycles.icns $out/Applications/openMotor.app/Contents/Resources/openMotor.icns + + # Move the wrapped binary into the app bundle + mv $out/bin/openMotor $out/Applications/openMotor.app/Contents/MacOS/ + + # Create symlink back to bin for CLI access + ln -s $out/Applications/openMotor.app/Contents/MacOS/openMotor $out/bin/openMotor + ''; + + preFixup = '' + makeWrapperArgs+=("''${qtWrapperArgs[@]}") + ''; + + # Tests require additional setup and data files + doCheck = false; + + pythonImportsCheck = [ + "motorlib" + "uilib" + ]; + + desktopItems = lib.optionals (!stdenv.hostPlatform.isDarwin) [ + (makeDesktopItem { + name = "openmotor"; + exec = "openMotor"; + icon = "openmotor"; + desktopName = "openMotor"; + comment = meta.description; + categories = [ + "Science" + "Engineering" + ]; + }) + ]; + + passthru.updateScript = nix-update-script { }; + + meta = { + description = "Open-source internal ballistics simulator for rocket motor experimenters"; + longDescription = '' + openMotor is an open-source internal ballistics simulator for rocket motor + experimenters. The software estimates a rocket motor's chamber pressure and + thrust based on propellant properties, grain geometry, and nozzle specifications. + It uses the Fast Marching Method to determine how a propellant grain regresses, + which allows the use of arbitrary core geometries. + ''; + homepage = "https://github.com/reilleya/openMotor"; + changelog = "https://github.com/reilleya/openMotor/releases/tag/v${version}"; + license = lib.licenses.gpl3Only; + maintainers = with lib.maintainers; [ schembriaiden ]; + platforms = lib.platforms.unix; + mainProgram = "openMotor"; + }; +}