diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27a961e4..91d91a86 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: run: pip install -r docs/source/requirements.txt - name: Build Assets - run: python setup.py qtlrelease sample manual + run: python pkgutils.py qtlrelease sample manual - name: Upload Artifacts uses: actions/upload-artifact@v3 @@ -64,7 +64,7 @@ jobs: path: novelwriter/assets - name: Build AppImage - run: python setup.py build-appimage --linux-tag ${{ matrix.linux-tag }} --python-version ${{ matrix.python-version }} + run: python pkgutils.py build-appimage --linux-tag ${{ matrix.linux-tag }} --python-version ${{ matrix.python-version }} - name: Upload Artifacts uses: actions/upload-artifact@v3 diff --git a/.github/workflows/test_linux.yml b/.github/workflows/test_linux.yml index 6a778d2f..23cd2c57 100644 --- a/.github/workflows/test_linux.yml +++ b/.github/workflows/test_linux.yml @@ -30,9 +30,9 @@ jobs: uses: actions/checkout@v3 - name: Install Dependencies (pip) run: | - pip install -U -r requirements.txt -r requirements-dev.txt + pip install -U -r requirements.txt -r tests/requirements.txt - name: Run Build Commands - run: python setup.py qtlrelease sample + run: python pkgutils.py qtlrelease sample - name: Run Tests run: | export QT_QPA_PLATFORM=offscreen diff --git a/.github/workflows/test_mac.yml b/.github/workflows/test_mac.yml index e4ef9cc4..e8f2816d 100644 --- a/.github/workflows/test_mac.yml +++ b/.github/workflows/test_mac.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v3 - name: Install Dependencies (pip) run: | - pip install -U pyobjc -r requirements.txt -r requirements-dev.txt + pip install -U pyobjc -r requirements.txt -r tests/requirements.txt - name: Run Tests run: | export QT_QPA_PLATFORM=offscreen diff --git a/.github/workflows/test_win.yml b/.github/workflows/test_win.yml index f3197a41..781f00f6 100644 --- a/.github/workflows/test_win.yml +++ b/.github/workflows/test_win.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v3 - name: Install Dependencies (pip) run: | - pip install -U -r requirements.txt -r requirements-dev.txt + pip install -U -r requirements.txt -r tests/requirements.txt - name: Run Tests run: | pytest -v --cov=novelwriter --timeout=60 diff --git a/MANIFEST.in b/MANIFEST.in index 0c89f7ca..1f2e5741 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,6 @@ -include setup.py +include pkgutils.py include LICENSE.md include CREDITS.md include CHANGELOG.md -recursive-include setup * recursive-include novelwriter/assets * -recursive-include sample *.nwx *.nwd +recursive-include setup * diff --git a/docs/source/int_source.rst b/docs/source/int_source.rst index 3630b537..e9ae6cec 100644 --- a/docs/source/int_source.rst +++ b/docs/source/int_source.rst @@ -18,21 +18,18 @@ to build the various components like the translation files and documentation. ``python3`` may be needed instead. Likewise, ``pip`` may need to be replaced with ``pip3``. Most of the custom commands for building packages of novelWriter, or building assets, are contained -in the ``setup.py`` script in the root of the source code. You can list the available commands by -running: +in the ``pkgutils.py`` script in the root of the source code. You can list the available commands +by running: .. code-block:: bash - python setup.py help + python pkgutils.py help .. warning:: Calling ``setup.py install`` has been deprecated for a while, and this approach is no longer actively supported in novelWriter either. - In a future version, the packaging and asset build tools part of the current ``setup.py`` file - will be moved to another script and the ``setup.py`` file removed entirely. - .. _a_source_depend: @@ -116,7 +113,7 @@ You can build the ``.qm`` files with: .. code-block:: bash - python setup.py qtlrelease + python pkgutils.py qtlrelease This requires that the Qt Linguist tool is installed on your system. On Ubuntu and Debian, the needed package is called ``qttools5-dev-tools``. @@ -137,7 +134,7 @@ the ``assets`` folder of the source. This file can be built from setup script by .. code-block:: bash - python setup.py sample + python pkgutils.py sample .. _a_source_docs: @@ -165,7 +162,7 @@ You can also build a PDF manual from the documentation using the setup script: .. code-block:: bash - python setup.py manual + python pkgutils.py manual This will build the documentation as a PDF using LaTeX. The file will then be copied into the assets folder and made available in the :guilabel:`Help` menu in novelWriter. The Sphinx build diff --git a/docs/source/tech_tests.rst b/docs/source/tech_tests.rst index 9d252a59..ae40e4d4 100644 --- a/docs/source/tech_tests.rst +++ b/docs/source/tech_tests.rst @@ -15,7 +15,7 @@ The dependencies for running the tests can be installed with: .. code-block:: bash - pip install -r requirements-dev.txt + pip install -r tests/requirements.txt This will install a couple of extra packages for coverage and test management. The minimum requirement is ``pytest`` and ``pytest-qt``. diff --git a/i18n/README.md b/i18n/README.md index b2dd8cc9..159eee73 100644 --- a/i18n/README.md +++ b/i18n/README.md @@ -76,7 +76,7 @@ The `i18n` folder at the root of the repository contains the `nw_XX.ts` translat Whether to add a new language to the translation framework, or to update the file against the current source code, you must first run the `qtlupdate` command: ```bash -python3 setup.py qtlupdate i18n/nw_XX.ts +python3 pkgutils.py qtlupdate i18n/nw_XX.ts ``` The file name must be in the correct format. All translation files must be located in the `i18n` @@ -101,7 +101,7 @@ The application does not use `.ts` files directly. The `novelwriter/assets/i18n/ the actual files used to translate the GUI into another language other than the default British English. These files are not generated by default, but they can be built with: ```bash -python3 setup.py qtlrelease +python3 pkgutils.py qtlrelease ``` You can now test the translation in novelWriter. The Preferences dialog should list the newly added diff --git a/setup.py b/pkgutils.py similarity index 96% rename from setup.py rename to pkgutils.py index 6d3b8c79..27831060 100755 --- a/setup.py +++ b/pkgutils.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 """ -novelWriter – Main Setup Script -=============================== -The main setup and install script for all operating systems +novelWriter – Packaging Utils +============================= File History: Created: 2019-05-16 [0.5.1] +Renamed: 2023-07-26 [2.1b1] This file is a part of novelWriter Copyright 2018–2023, Veronica Berglyd Olsen @@ -74,14 +74,12 @@ def extractVersion(beQuiet=False): def compactVersion(version): - """Make the version number more compact. - """ + """Make the version number more compact.""" return version.replace("-alpha", "a").replace("-beta", "b").replace("-rc", "rc") def sysCall(callArgs, cwd=None): - """Wrapper function for system calls. - """ + """Wrapper function for system calls.""" sysP = subprocess.Popen( callArgs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=cwd @@ -91,21 +89,19 @@ def sysCall(callArgs, cwd=None): def readFile(fileName): - """Read an entire file and return as a string. - """ + """Read an entire file and return as a string.""" with open(fileName, mode="r", encoding="utf-8") as inFile: return inFile.read() def writeFile(fileName, writeText): - """Write string to file. - """ + """Write string to file.""" with open(fileName, mode="w+", encoding="utf-8") as outFile: outFile.write(writeText) def toUpload(srcPath, dstName=None): - """Copy a file produced by one of the build functions to the uplaod + """Copy a file produced by one of the build functions to the upload directory. The file can optionally be given a new name. """ uplDir = "dist_upload" @@ -118,8 +114,7 @@ def toUpload(srcPath, dstName=None): def makeCheckSum(sumFile, cwd=None): - """Create a SHA256 checkcusm file. - """ + """Create a SHA256 checksum file.""" try: if cwd is None: shaFile = sumFile+".sha256" @@ -178,8 +173,7 @@ def installPackages(hostOS): ## def cleanBuildDirs(): - """Recursively delete the 'build' and 'dist' folders. - """ + """Recursively delete the 'build' and 'dist' folders.""" print("") print("Cleaning up build environment ...") print("") @@ -207,7 +201,7 @@ def cleanBuildDirs(): # =============================================================================================== # -# Additional Buiilds +# Additional Builds # =============================================================================================== # ## @@ -215,8 +209,7 @@ def cleanBuildDirs(): ## def buildPdfManual(): - """This function will build the documentation as manual.pdf. - """ + """This function will build the documentation as manual.pdf.""" print("") print("Building PDF Manual") print("===================") @@ -270,8 +263,7 @@ def buildPdfManual(): ## def buildQtI18n(): - """Build the lang.qm files for Qt Linguist. - """ + """Build the lang.qm files for Qt Linguist.""" print("") print("Building Qt Localisation Files") print("==============================") @@ -324,8 +316,7 @@ def buildQtI18n(): ## def buildQtI18nTS(sysArgs): - """Build the lang.ts files for Qt Linguist. - """ + """Build the lang.ts files for Qt Linguist.""" print("") print("Building Qt Translation Files") print("=============================") @@ -404,8 +395,7 @@ def buildQtI18nTS(sysArgs): ## def genMacOSPlist(): - """Set necessary values for .plist file for MacOS build. - """ + """Set necessary values for .plist file for MacOS build.""" numVers, _, _ = extractVersion() pkgVers = compactVersion(numVers) outDir = "setup/macos" @@ -471,8 +461,7 @@ def buildSampleZip(): def cleanBuiltAssets(): - """Remove assets built by this script. - """ + """Remove assets built by this script.""" print("") print("Removing Built Assets") print("=====================") @@ -536,8 +525,7 @@ def checkAssetsExist(): ## def importI18nUpdates(sysArgs): - """Import new translation files from a zip file. - """ + """Import new translation files from a zip file.""" print("") print("Import Updated Translations") print("===========================") @@ -577,8 +565,7 @@ def importI18nUpdates(sysArgs): ## def makeMinimalPackage(targetOS): - """Pack the core source file in a single zip file. - """ + """Pack the core source file in a single zip file.""" from zipfile import ZipFile, ZIP_DEFLATED print("") @@ -626,7 +613,7 @@ def makeMinimalPackage(targetOS): "CREDITS.md", "CHANGELOG.md", "requirements.txt", - "setup.py", + "pkgutils.py", "setup.cfg", "pyproject.toml", ] @@ -694,12 +681,12 @@ def makeMinimalPackage(targetOS): ## def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buildName=""): - """Build a Debian package. - """ + """Build a Debian package.""" print("") print("Build Debian Package") print("====================") - print("On Debian/Ubuntu install: dh-python python3-all debhelper devscripts") + print("On Debian/Ubuntu install: dh-python python3-all debhelper devscripts ") + print(" pybuild-plugin-pyproject") print("") # Version Info @@ -868,8 +855,7 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil ## def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False): - """Wrapper for building debian packages for launchpad. - """ + """Wrapper for building Debian packages for Launchpad.""" print("") print("Launchpad Packages") print("==================") @@ -885,8 +871,8 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False): distLoop = [ ("20.04", "focal"), ("22.04", "jammy"), - ("22.10", "kinetic"), ("23.04", "lunar"), + ("23.10", "mantic"), ] tStamp = datetime.datetime.now().strftime("%Y%m%d~%H%M%S") @@ -938,8 +924,7 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False): ## def makeAppImage(sysArgs): - """Build an AppImage. - """ + """Build an AppImage.""" import glob import argparse @@ -1388,8 +1373,7 @@ def makeWindowsEmbedded(sysArgs): ## def xdgInstall(): - """Will attempt to install icons and make a launcher. - """ + """Will attempt to install icons and make a launcher.""" print("") print("XDG Install") print("===========") @@ -1525,8 +1509,7 @@ def xdgInstall(): ## def xdgUninstall(): - """Will attempt to uninstall icons and make a launcher. - """ + """Will attempt to uninstall icons and the launcher.""" print("") print("XDG Uninstall") print("=============") @@ -1596,15 +1579,14 @@ def xdgUninstall(): ## def winInstall(): - """Will attempt to install icons and make a launcher for Windows. - """ + """Will attempt to install icons and make a launcher for Windows.""" import winreg try: import win32com.client except ImportError: print( "ERROR: Package 'pywin32' is missing on this system.\n" - " Please run 'setup.py pip' to automatically install\n" + " Please run 'pkgutils.py pip' to automatically install\n" " dependecies, or run 'pip install --user pywin32'." ) sys.exit(1) @@ -1724,8 +1706,7 @@ def winInstall(): ## def winUninstall(): - """Will attempt to uninstall icons previously installed. - """ + """Will attempt to uninstall icons previously installed.""" import winreg try: import win32com.client @@ -1812,8 +1793,7 @@ def winUninstall(): # =============================================================================================== # if __name__ == "__main__": - """Parse command line options and run the commands. - """ + """Parse command line options and run the commands.""" # Detect OS if sys.platform.startswith("linux"): hostOS = OS_LINUX @@ -2053,23 +2033,4 @@ if __name__ == "__main__": print("ERROR: Command 'win-uninstall' can only be used on Windows") sys.exit(1) - # Actions - # ======= - - if len(sys.argv) <= 1: - # Nothing more to do - sys.exit(0) - - # Run the standard setup - import setuptools # noqa: F401 - import warnings # noqa: F401 - warnings.warn( - "The setuptools section of setup.py is deprecated and will be removed " - "in a future release and the setup.py file will be renamed to avoid " - "conflicts with build tools. Please don't use the 'setup.py install' " - "command, and instead use the pip and build commands.", - DeprecationWarning - ) - setuptools.setup() - # END Main diff --git a/setup.cfg b/setup.cfg index b9572076..497f444a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -38,7 +38,7 @@ install_requires = pyenchant>=3.0.0 [options.packages.find] -exclude = docs, tests, sample +include = novelwriter* [options.entry_points] console_script = diff --git a/setup/README.md b/setup/README.md deleted file mode 100644 index 4aaa123f..00000000 --- a/setup/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Build and Install novelWriter - -The root folder of the repository contains a standard `setup.py` script. The `setup` folder -contains necessary files for the setup process, like icons and other files, and it also contains -additional scripts that are included in the minimal zip packages. - -## Setup Script - -The `setup.py` script in the root folder has all the necessary commands for generating packages, -installing icons, launcher, and file associations on Linux and Windows (no macOS support yet). - -In addition, it is a wrapper for `setuptools` and accept all commands associated with this tool. - -To list all custom package and install options in this script, run: -``` -./setup.py help -``` -## Windows Scripts - -The `windows_install.bat` and `windows_uninstall.bat` are provided as convenience scripts for -Windows users who aren't used to running commands from command line. They are both located in the -`setup` folder in the source package, but in the minimal zip package for Windows, they can be -found in the root folder. - -These scripts are designed to be double-clicked by the user, but can also be run from the command -line tool. In either case, they will check if Python is properly installed, and then run the -commands to install or uninstall the core dependencies of novelWriter, and then setup or remove the -desktop icon, start menu icon and registry entries. diff --git a/setup/macos/build.sh b/setup/macos/build.sh index b9192b42..2915730c 100755 --- a/setup/macos/build.sh +++ b/setup/macos/build.sh @@ -24,13 +24,13 @@ echo "Build Dir: $BUILD_DIR" pushd "$SRC_DIR" || exit 1 -VERSION="$(python3 setup.py version)" +VERSION="$(python3 pkgutils.py version)" echo "novelWriter Version: $VERSION" # --- Prepare Files ----------------------------------------------------------------------------- # echo "Generating Info.plist" -python3 setup.py gen-plist +python3 pkgutils.py gen-plist if [ -f $SRC_DIR/setup/macos/Info.plist ]; then echo "Found: setup/macos/Info.plist" else diff --git a/setup/make_clean.sh b/setup/make_clean.sh index 0f8cd300..61f9304f 100755 --- a/setup/make_clean.sh +++ b/setup/make_clean.sh @@ -1,10 +1,10 @@ #!/bin/bash set -e -if [ ! -f setup.py ]; then +if [ ! -f pkgutils.py ]; then echo "Must be called from the root folder of the source" exit 1 fi rm -rfv dist_upload -python3 setup.py build-clean +python3 pkgutils.py build-clean diff --git a/setup/make_pip.sh b/setup/make_pip.sh index f26e591e..3c1fdc54 100755 --- a/setup/make_pip.sh +++ b/setup/make_pip.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -if [ ! -f setup.py ]; then +if [ ! -f pkgutils.py ]; then echo "Must be called from the root folder of the source" exit 1 fi @@ -10,7 +10,7 @@ echo "" echo " Building Packages" echo "================================================================================" echo "" -python3 setup.py qtlrelease manual sample +python3 pkgutils.py qtlrelease manual sample python3 -m build mkdir -pv dist_upload cp -v dist/novelWriter-*.whl dist_upload/ diff --git a/setup/make_release.sh b/setup/make_release.sh index 98b142e6..bdbb2426 100755 --- a/setup/make_release.sh +++ b/setup/make_release.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -if [ ! -f setup.py ]; then +if [ ! -f pkgutils.py ]; then echo "Must be called from the root folder of the source" exit 1 fi @@ -10,20 +10,20 @@ echo "" echo " Building Dependencies" echo "================================================================================" echo "" -python3 setup.py clean-assets -python3 setup.py qtlrelease manual sample +python3 pkgutils.py clean-assets +python3 pkgutils.py qtlrelease manual sample echo "" echo " Building Minimal Packages" echo "================================================================================" echo "" -python3 setup.py minimal-zip --target-win -python3 setup.py minimal-zip --target-linux -python3 setup.py minimal-zip --target-darwin +python3 pkgutils.py minimal-zip --target-win +python3 pkgutils.py minimal-zip --target-linux +python3 pkgutils.py minimal-zip --target-darwin echo "" echo " Building Linux Packages" echo "================================================================================" echo "" -python3 setup.py build-deb --sign -python3 setup.py build-ubuntu --sign --first +python3 pkgutils.py build-deb --sign +python3 pkgutils.py build-ubuntu --sign --first diff --git a/setup/make_snapshot.sh b/setup/make_snapshot.sh index 371996a0..8ad797be 100755 --- a/setup/make_snapshot.sh +++ b/setup/make_snapshot.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -if [ ! -f setup.py ]; then +if [ ! -f pkgutils.py ]; then echo "Must be called from the root folder of the source" exit 1 fi @@ -10,11 +10,11 @@ echo "" echo " Building Dependencies" echo "================================================================================" echo "" -python3 setup.py clean-assets -python3 setup.py qtlrelease manual sample +python3 pkgutils.py clean-assets +python3 pkgutils.py qtlrelease manual sample echo "" echo " Building Linux Snapshots" echo "================================================================================" echo "" -python3 setup.py build-ubuntu --sign --snapshot +python3 pkgutils.py build-ubuntu --sign --snapshot diff --git a/setup/windows_install.bat b/setup/windows_install.bat index 4b2c80d6..b27d6640 100644 --- a/setup/windows_install.bat +++ b/setup/windows_install.bat @@ -7,12 +7,12 @@ python --version 2>NUL if errorlevel 1 goto errorNoPython echo Python found. OK. -if exist setup.py ( - echo setup.py found. OK. +if exist pkgutils.py ( + echo pkgutils.py found. OK. ) else ( cd .. - if exist setup.py ( - echo setup.py found. OK. + if exist pkgutils.py ( + echo pkgutils.py found. OK. ) else ( goto errorNoSetup ) @@ -23,7 +23,7 @@ echo. pip install --user pywin32 -r requirements.txt :: Create the desktop and start menu icons -python setup.py win-install +python pkgutils.py win-install pause goto:eof @@ -41,9 +41,9 @@ goto:eof :errorNoSetup echo. -echo ERROR^: Could not find the setup.py script. +echo ERROR^: Could not find the pkgutils.py script. echo. -echo Make sure you run setup.py from the novelWriter root folder. +echo Make sure you run pkgutils.py from the novelWriter root folder. echo. pause diff --git a/setup/windows_uninstall.bat b/setup/windows_uninstall.bat index 18523176..d96b7863 100644 --- a/setup/windows_uninstall.bat +++ b/setup/windows_uninstall.bat @@ -7,12 +7,12 @@ python --version 2>NUL if errorlevel 1 goto errorNoPython echo Python found. OK. -if exist setup.py ( - echo setup.py found. OK. +if exist pkgutils.py ( + echo pkgutils.py found. OK. ) else ( cd .. - if exist setup.py ( - echo setup.py found. OK. + if exist pkgutils.py ( + echo pkgutils.py found. OK. ) else ( goto errorNoSetup ) @@ -27,7 +27,7 @@ goto afterUninst :doUninst :: Remove the desktop and start menu icons -python setup.py win-uninstall +python pkgutils.py win-uninstall :: Remove the PyQt5 and pyenchant dependencies pip uninstall --yes -r requirements.txt @@ -51,9 +51,9 @@ goto:eof :errorNoSetup echo. -echo ERROR^: Could not find the setup.py script. +echo ERROR^: Could not find the pkgutils.py script. echo. -echo Make sure you run setup.py from the novelWriter root folder. +echo Make sure you run pkgutils.py from the novelWriter root folder. echo. pause diff --git a/requirements-dev.txt b/tests/requirements.txt similarity index 100% rename from requirements-dev.txt rename to tests/requirements.txt