From 24f4d688ba92564e2198128aae8dbbaad4f568f5 Mon Sep 17 00:00:00 2001 From: Sven Sager Date: Sun, 1 Oct 2023 13:45:02 +0200 Subject: [PATCH] build: Upgrade buildsystem with new Makefile and make.bat If a PyInstaller target is called from the Makefile, all libraries installed in the virtual environment are captured with version and license. The file 'bundled-libraries.md' contains a list of libraries with version and license. The file 'open-source-licenses.txt' includes the name, version, author, project URL, description and complete license for each installed library. The files are included in the output of the PyInstaller. --- Makefile | 116 ++++++++++++++++++++++++++++++++--------------- make.bat | 81 ++++++++++++++++++++++++--------- requirements.txt | 7 ++- 3 files changed, 145 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index a9bc2df..2b00ec0 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ endif SYSTEM_PYTHON = python3 PYTHON = $(or $(wildcard $(VENV_PATH)/bin/python), $(SYSTEM_PYTHON)) -APP_VERSION = $(shell $(PYTHON) src/$(PACKAGE) --version) +APP_VERSION = $(shell "$(PYTHON)" src/$(PACKAGE) --version | cut -d ' ' -f 2) all: build_ui build_rc test build @@ -27,55 +27,105 @@ all: build_ui build_rc test build ## Environment venv-info: - echo Using path: "$(VENV_PATH)" + @echo Environment for $(APP_NAME) $(APP_VERSION) + @echo Using path: "$(VENV_PATH)" exit 0 venv: - $(SYSTEM_PYTHON) -m venv --system-site-packages "$(VENV_PATH)" - source $(VENV_PATH)/bin/activate && \ + # Start with empty environment + "$(SYSTEM_PYTHON)" -m venv "$(VENV_PATH)" + source "$(VENV_PATH)/bin/activate" && \ python3 -m pip install --upgrade pip && \ python3 -m pip install -r requirements.txt exit 0 -.PHONY: venv-info venv +venv-ssp: + # Include system installed site-packages and add just missing modules + "$(SYSTEM_PYTHON)" -m venv --system-site-packages "$(VENV_PATH)" + source "$(VENV_PATH)/bin/activate" && \ + python3 -m pip install --upgrade pip && \ + python3 -m pip install -r requirements.txt + exit 0 + +.PHONY: venv-info venv venv-ssp ## Compile Qt UI files to python code -build_ui: +build-ui: cd ui_dev && for ui_file in *.ui; do \ file_name=$${ui_file%.ui}; \ - $(PYTHON) -m PyQt5.uic.pyuic $${ui_file} -o ../src/$(PACKAGE)/ui/$${file_name}_ui.py -x --from-imports; \ + "$(PYTHON)" -m PyQt5.uic.pyuic $${ui_file} -o ../src/$(PACKAGE)/ui/$${file_name}_ui.py -x --from-imports; \ echo $${file_name}; \ done -build_rc: +build-rc: cd ui_dev && for rc_file in *.qrc; do \ file_name=$${rc_file%.qrc}; \ - $(PYTHON) -m PyQt5.pyrcc_main $${rc_file} -o ../src/$(PACKAGE)/ui/$${file_name}_rc.py; \ + "$(PYTHON)" -m PyQt5.pyrcc_main $${rc_file} -o ../src/$(PACKAGE)/ui/$${file_name}_rc.py; \ echo $${file_name}; \ done -update_translation: - $(PYTHON) -m PyQt5.pylupdate_main translate.pro +update-translation: + "$(PYTHON)" -m PyQt5.pylupdate_main translate.pro -.PHONY: build_ui build_rc update_translation +.PHONY: build-ui build-rc update-translation ## Build steps -build: build_ui build_rc - $(PYTHON) -m setup sdist - $(PYTHON) -m setup bdist_wheel +build: + "$(PYTHON)" -m setup sdist + "$(PYTHON)" -m setup bdist_wheel -install: test build - $(PYTHON) -m pip install dist/$(PACKAGE)-*.whl +install: build + "$(PYTHON)" -m pip install dist/$(PACKAGE)-$(APP_VERSION)-*.whl uninstall: - $(PYTHON) -m pip uninstall --yes $(PACKAGE) + "$(PYTHON)" -m pip uninstall --yes $(PACKAGE) .PHONY: test build install uninstall ## PyInstaller -installer_mac: build_ui build_rc - $(PYTHON) -m PyInstaller -n $(APP_NAME) \ +app-licenses: + mkdir -p dist + # Create a list of all installed libraries, their versions and licenses + "$(PYTHON)" -m piplicenses \ + --format=markdown \ + --output-file dist/bundled-libraries.md + # Create a list of installed libraries with complete project information + "$(PYTHON)" -m piplicenses \ + --with-authors \ + --with-urls \ + --with-description \ + --with-license-file \ + --no-license-path \ + --format=json \ + --output-file dist/open-source-licenses.json + "$(PYTHON)" -m piplicenses \ + --with-authors \ + --with-urls \ + --with-description \ + --with-license-file \ + --no-license-path \ + --format=plain-vertical \ + --output-file dist/open-source-licenses.txt + +app: build-ui build-rc app-licenses + "$(PYTHON)" -m PyInstaller -n $(APP_NAME) \ --add-data="src/$(PACKAGE)/locale:./$(PACKAGE)/locale" \ + --add-data="dist/bundled-libraries.md:$(PACKAGE)/open-source-licenses" \ + --add-data="dist/open-source-licenses.*:$(PACKAGE)/open-source-licenses" \ + --add-data="data/$(PACKAGE).ico:." \ + --add-data="data/$(PACKAGE).png:." \ + --icon=data/$(PACKAGE).ico \ + --noconfirm \ + --clean \ + --onedir \ + --windowed \ + src/$(PACKAGE)/__main__.py + +app-mac: build-ui build-rc app-licenses + "$(PYTHON)" -m PyInstaller -n $(APP_NAME) \ + --add-data="src/$(PACKAGE)/locale:./$(PACKAGE)/locale" \ + --add-data="dist/bundled-libraries.md:$(PACKAGE)/open-source-licenses" \ + --add-data="dist/open-source-licenses.*:$(PACKAGE)/open-source-licenses" \ --add-data="data/$(PACKAGE).icns:." \ --icon=data/$(PACKAGE).icns \ --noconfirm \ @@ -86,7 +136,7 @@ installer_mac: build_ui build_rc --codesign-identity $(APPLE_SIG) \ src/$(PACKAGE)/__main__.py -installer_mac_dmg: installer_mac +app-mac-dmg: app-mac mkdir dist/dmg mv dist/$(APP_NAME).app dist/dmg create-dmg \ @@ -104,25 +154,19 @@ installer_mac_dmg: installer_mac dist/$(APP_NAME)\ $(APP_VERSION).dmg \ dist/dmg -installer_linux: build_ui build_rc - $(PYTHON) -m PyInstaller -n $(APP_NAME) \ - --add-data="src/$(PACKAGE)/locale:./$(PACKAGE)/locale" \ - --add-data="data/$(PACKAGE).ico:." \ - --add-data="data/$(PACKAGE).png:." \ - --icon=data/$(PACKAGE).ico \ - --noconfirm \ - --clean \ - --onedir \ - --windowed \ - src/$(PACKAGE)/__main__.py - -.PHONY: installer_mac installer_mac_dmg installer_linux +.PHONY: app-licenses app app-mac app-mac-dmg ## Clean clean: - rm -rf build dist src/*.egg-info *.spec + # PyTest caches + rm -rf .pytest_cache + # Build artifacts + rm -rf build dist src/*.egg-info + # PyInstaller created files + rm -rf *.spec distclean: clean - rm -rf $(VENV_PATH) + # Virtual environment + rm -rf "$(VENV_PATH)" .PHONY: clean distclean diff --git a/make.bat b/make.bat index 36eaaa1..e9c2efa 100644 --- a/make.bat +++ b/make.bat @@ -2,38 +2,77 @@ set PACKAGE=revpicommander set APP_NAME=RevPi Commander +set PYTHON=venv\\Scripts\\python.exe + if "%1" == "venv" goto venv -if "%1" == "installer" goto installer +if "%1" == "test" goto test +if "%1" == "build" goto build +if "%1" == "app" goto app if "%1" == "clean" goto clean +if "%1" == "distclean" goto distclean echo Make script for "%APP_NAME%" on Windows echo. echo Need action: -echo venv Create / update your virtual environment for build process -echo installer Build this application with PyInstaller -echo clean Clean up your environment after build process +echo venv Create your virtual environment for build process +echo test Run defined tests of the project +echo build Build PIP packages as source distribution and Wheel +echo app Build this application with PyInstaller +echo clean Clean up build artifacts after build process +echo distclean Same as clean plus removing virtual environment goto end :venv -python -m venv venv -venv\\Scripts\\pip.exe install --upgrade -r requirements.txt -goto end + python -m venv venv + venv\\Scripts\\pip.exe install -r requirements.txt + goto end -:installer -venv\\Scripts\\pyinstaller -n "%APP_NAME%" ^ - --add-data="src\%PACKAGE%\locale;.\%PACKAGE%\locale" ^ - --add-data="data\%PACKAGE%.ico;." ^ - --icon=data\\%PACKAGE%.ico ^ - --noconfirm ^ - --clean ^ - --onedir ^ - --windowed ^ - src\\%PACKAGE%\\__main__.py -goto end +:test + set PYTHONPATH=src + %PYTHON% -m pytest + goto end + +:build + %PYTHON% -m setup sdist + %PYTHON% -m setup bdist_wheel + goto end + +:app + mkdir dist + %PYTHON% -m piplicenses ^ + --format=markdown ^ + --output-file dist/bundled-libraries.md + %PYTHON% -m piplicenses ^ + --with-authors ^ + --with-urls ^ + --with-description ^ + --with-license-file ^ + --no-license-path ^ + --format=json ^ + --output-file dist/open-source-licenses.json + %PYTHON% -m piplicenses ^ + --with-authors ^ + --with-urls ^ + --with-description ^ + --with-license-file ^ + --no-license-path ^ + --format=plain-vertical ^ + --output-file dist/open-source-licenses.txt + %PYTHON% -m PyInstaller -n "%APP_NAME%" ^ + --add-data="dist/bundled-libraries.md;%PACKAGE%\open-source-licenses" ^ + --add-data="dist/open-source-licenses.*;%PACKAGE%\open-source-licenses" ^ + --noconfirm ^ + --clean ^ + --onefile ^ + src\\%PACKAGE%\\__main__.py + goto end + +:distclean + rmdir /S /Q venv :clean -rmdir /S /Q build dist -rmdir /S /Q src\%PACKAGE%.egg-info -del *.spec + rmdir /S /Q .pytest_cache + rmdir /S /Q build dist src\%PACKAGE%.egg-info + del /Q *.spec :end diff --git a/requirements.txt b/requirements.txt index 6f98a21..383199c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,10 @@ -setuptools>=65.6.3 -wheel +# Build dependencies +pip-licenses Pyinstaller +setuptools +wheel +# Runtime dependencies, must match install_requires in setup.py keyring>=23.13.1 PyQt5>=5.14.1 paramiko>=2.12.0