Change in-app version format and .deb package names (#1659)
This commit is contained in:
@@ -42,9 +42,9 @@ __license__ = "GPLv3"
|
|||||||
__author__ = "Veronica Berglyd Olsen"
|
__author__ = "Veronica Berglyd Olsen"
|
||||||
__maintainer__ = "Veronica Berglyd Olsen"
|
__maintainer__ = "Veronica Berglyd Olsen"
|
||||||
__email__ = "code@vkbo.net"
|
__email__ = "code@vkbo.net"
|
||||||
__version__ = "2.3-alpha1"
|
__version__ = "2.3a1"
|
||||||
__hexversion__ = "0x020300a1"
|
__hexversion__ = "0x020300a1"
|
||||||
__date__ = "2023-12-17"
|
__date__ = "2024-01-23"
|
||||||
__status__ = "Stable"
|
__status__ = "Stable"
|
||||||
__domain__ = "novelwriter.io"
|
__domain__ = "novelwriter.io"
|
||||||
|
|
||||||
|
|||||||
@@ -250,6 +250,11 @@ def formatTime(t: int) -> str:
|
|||||||
return "ERROR"
|
return "ERROR"
|
||||||
|
|
||||||
|
|
||||||
|
def formatVersion(value: str) -> str:
|
||||||
|
"""Format a version number into a more human readable form."""
|
||||||
|
return value.lower().replace("a", " Alpha ").replace("b", " Beta ").replace("rc", " RC ")
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
# String Functions
|
# String Functions
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ from PyQt5.QtWidgets import (
|
|||||||
|
|
||||||
from novelwriter import CONFIG, SHARED, __version__, __date__
|
from novelwriter import CONFIG, SHARED, __version__, __date__
|
||||||
from novelwriter.enum import nwItemClass
|
from novelwriter.enum import nwItemClass
|
||||||
from novelwriter.common import formatInt, makeFileNameSafe
|
from novelwriter.common import formatInt, formatVersion, makeFileNameSafe
|
||||||
from novelwriter.constants import nwUnicode
|
from novelwriter.constants import nwUnicode
|
||||||
from novelwriter.core.coretools import ProjectBuilder
|
from novelwriter.core.coretools import ProjectBuilder
|
||||||
from novelwriter.extensions.switch import NSwitch
|
from novelwriter.extensions.switch import NSwitch
|
||||||
@@ -91,7 +91,8 @@ class GuiWelcome(QDialog):
|
|||||||
self.nwLabel.setPixmap(self.nwImage)
|
self.nwLabel.setPixmap(self.nwImage)
|
||||||
|
|
||||||
self.nwInfo = QLabel(self.tr("Version {0} {1} Released on {2}").format(
|
self.nwInfo = QLabel(self.tr("Version {0} {1} Released on {2}").format(
|
||||||
__version__, nwUnicode.U_ENDASH, datetime.strptime(__date__, "%Y-%m-%d").strftime("%x")
|
formatVersion(__version__), nwUnicode.U_ENDASH,
|
||||||
|
datetime.strptime(__date__, "%Y-%m-%d").strftime("%x")
|
||||||
))
|
))
|
||||||
|
|
||||||
self.tabOpen = _OpenProjectPage(self)
|
self.tabOpen = _OpenProjectPage(self)
|
||||||
|
|||||||
+107
-135
@@ -23,6 +23,7 @@ General Public License for more details.
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -42,7 +43,7 @@ OS_DARWIN = 3
|
|||||||
# Utilities
|
# Utilities
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
|
||||||
def extractVersion(beQuiet=False):
|
def extractVersion(beQuiet: bool = False) -> tuple[str, str, str]:
|
||||||
"""Extract the novelWriter version number without having to import
|
"""Extract the novelWriter version number without having to import
|
||||||
anything else from the main package.
|
anything else from the main package.
|
||||||
"""
|
"""
|
||||||
@@ -73,34 +74,31 @@ def extractVersion(beQuiet=False):
|
|||||||
return numVers, hexVers, relDate
|
return numVers, hexVers, relDate
|
||||||
|
|
||||||
|
|
||||||
def compactVersion(version):
|
def stripVersion(version: str) -> str:
|
||||||
"""Make the version number more compact."""
|
"""Strip the pre-release part from a version number."""
|
||||||
return version.replace("-alpha", "a").replace("-beta", "b").replace("-rc", "rc")
|
if "a" in version:
|
||||||
|
return version.partition("a")[0]
|
||||||
|
elif "b" in version:
|
||||||
|
return version.partition("b")[0]
|
||||||
|
elif "rc" in version:
|
||||||
|
return version.partition("rc")[0]
|
||||||
|
else:
|
||||||
|
return version
|
||||||
|
|
||||||
|
|
||||||
def sysCall(callArgs, cwd=None):
|
def readFile(fileName: str) -> str:
|
||||||
"""Wrapper function for system calls."""
|
|
||||||
sysP = subprocess.Popen(
|
|
||||||
callArgs, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
||||||
shell=True, cwd=cwd
|
|
||||||
)
|
|
||||||
stdOut, stdErr = sysP.communicate()
|
|
||||||
return stdOut.decode("utf-8"), stdErr.decode("utf-8"), sysP.returncode
|
|
||||||
|
|
||||||
|
|
||||||
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:
|
with open(fileName, mode="r", encoding="utf-8") as inFile:
|
||||||
return inFile.read()
|
return inFile.read()
|
||||||
|
|
||||||
|
|
||||||
def writeFile(fileName, writeText):
|
def writeFile(fileName: str, writeText: str) -> None:
|
||||||
"""Write string to file."""
|
"""Write string to file."""
|
||||||
with open(fileName, mode="w+", encoding="utf-8") as outFile:
|
with open(fileName, mode="w+", encoding="utf-8") as outFile:
|
||||||
outFile.write(writeText)
|
outFile.write(writeText)
|
||||||
|
|
||||||
|
|
||||||
def toUpload(srcPath, dstName=None):
|
def toUpload(srcPath: str, dstName: str | None = None) -> None:
|
||||||
"""Copy a file produced by one of the build functions to the upload
|
"""Copy a file produced by one of the build functions to the upload
|
||||||
directory. The file can optionally be given a new name.
|
directory. The file can optionally be given a new name.
|
||||||
"""
|
"""
|
||||||
@@ -113,7 +111,7 @@ def toUpload(srcPath, dstName=None):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def makeCheckSum(sumFile, cwd=None):
|
def makeCheckSum(sumFile: str, cwd: str | None = None) -> str:
|
||||||
"""Create a SHA256 checksum file."""
|
"""Create a SHA256 checksum file."""
|
||||||
try:
|
try:
|
||||||
if cwd is None:
|
if cwd is None:
|
||||||
@@ -139,7 +137,7 @@ def makeCheckSum(sumFile, cwd=None):
|
|||||||
# Package Installer (pip)
|
# Package Installer (pip)
|
||||||
##
|
##
|
||||||
|
|
||||||
def installPackages(hostOS):
|
def installPackages(hostOS: int) -> None:
|
||||||
"""Install package dependencies both for this script and for running
|
"""Install package dependencies both for this script and for running
|
||||||
novelWriter itself.
|
novelWriter itself.
|
||||||
"""
|
"""
|
||||||
@@ -172,7 +170,7 @@ def installPackages(hostOS):
|
|||||||
# Clean Build and Dist Folders (build-clean)
|
# Clean Build and Dist Folders (build-clean)
|
||||||
##
|
##
|
||||||
|
|
||||||
def cleanBuildDirs():
|
def cleanBuildDirs() -> None:
|
||||||
"""Recursively delete the 'build' and 'dist' folders."""
|
"""Recursively delete the 'build' and 'dist' folders."""
|
||||||
print("")
|
print("")
|
||||||
print("Cleaning up build environment ...")
|
print("Cleaning up build environment ...")
|
||||||
@@ -208,7 +206,7 @@ def cleanBuildDirs():
|
|||||||
# Build PDF Manual (manual)
|
# Build PDF Manual (manual)
|
||||||
##
|
##
|
||||||
|
|
||||||
def buildPdfManual():
|
def buildPdfManual() -> None:
|
||||||
"""This function will build the documentation as manual.pdf."""
|
"""This function will build the documentation as manual.pdf."""
|
||||||
print("")
|
print("")
|
||||||
print("Building PDF Manual")
|
print("Building PDF Manual")
|
||||||
@@ -262,7 +260,7 @@ def buildPdfManual():
|
|||||||
# Qt Linguist QM Builder (qtlrelease)
|
# Qt Linguist QM Builder (qtlrelease)
|
||||||
##
|
##
|
||||||
|
|
||||||
def buildQtI18n():
|
def buildQtI18n() -> None:
|
||||||
"""Build the lang.qm files for Qt Linguist."""
|
"""Build the lang.qm files for Qt Linguist."""
|
||||||
print("")
|
print("")
|
||||||
print("Building Qt Localisation Files")
|
print("Building Qt Localisation Files")
|
||||||
@@ -315,7 +313,7 @@ def buildQtI18n():
|
|||||||
# Qt Linguist TS Builder (qtlupdate)
|
# Qt Linguist TS Builder (qtlupdate)
|
||||||
##
|
##
|
||||||
|
|
||||||
def buildQtI18nTS(sysArgs):
|
def buildQtI18nTS(sysArgs: list[str]) -> None:
|
||||||
"""Build the lang.ts files for Qt Linguist."""
|
"""Build the lang.ts files for Qt Linguist."""
|
||||||
print("")
|
print("")
|
||||||
print("Building Qt Translation Files")
|
print("Building Qt Translation Files")
|
||||||
@@ -392,16 +390,16 @@ def buildQtI18nTS(sysArgs):
|
|||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Generage MacOS PList
|
# Generate MacOS PList
|
||||||
##
|
##
|
||||||
|
|
||||||
def genMacOSPlist():
|
def genMacOSPlist() -> None:
|
||||||
"""Set necessary values for .plist file for MacOS build."""
|
"""Set necessary values for .plist file for MacOS build."""
|
||||||
outDir = "setup/macos"
|
outDir = "setup/macos"
|
||||||
numVers = extractVersion()[0].partition("-")[0]
|
numVers = stripVersion(extractVersion()[0])
|
||||||
copyrightYear = datetime.datetime.now().year
|
copyrightYear = datetime.datetime.now().year
|
||||||
|
|
||||||
# These keys are no longer used but are present for compatability
|
# These keys are no longer used but are present for compatibility
|
||||||
pkgVersMaj, pkgVersMin = numVers.split(".")[:2]
|
pkgVersMaj, pkgVersMin = numVers.split(".")[:2]
|
||||||
|
|
||||||
plistXML = readFile(f"{outDir}/Info.plist.template").format(
|
plistXML = readFile(f"{outDir}/Info.plist.template").format(
|
||||||
@@ -422,7 +420,7 @@ def genMacOSPlist():
|
|||||||
# Sample Project ZIP File Builder (sample)
|
# Sample Project ZIP File Builder (sample)
|
||||||
##
|
##
|
||||||
|
|
||||||
def buildSampleZip():
|
def buildSampleZip() -> None:
|
||||||
"""Bundle the sample project into a single zip file to be saved into
|
"""Bundle the sample project into a single zip file to be saved into
|
||||||
the novelwriter/assets folder for further bundling into builds.
|
the novelwriter/assets folder for further bundling into builds.
|
||||||
"""
|
"""
|
||||||
@@ -459,7 +457,7 @@ def buildSampleZip():
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def cleanBuiltAssets():
|
def cleanBuiltAssets() -> None:
|
||||||
"""Remove assets built by this script."""
|
"""Remove assets built by this script."""
|
||||||
print("")
|
print("")
|
||||||
print("Removing Built Assets")
|
print("Removing Built Assets")
|
||||||
@@ -488,7 +486,7 @@ def cleanBuiltAssets():
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def checkAssetsExist():
|
def checkAssetsExist() -> bool:
|
||||||
"""Check that the necessary compiled assets exist ahead of a build.
|
"""Check that the necessary compiled assets exist ahead of a build.
|
||||||
"""
|
"""
|
||||||
hasSample = False
|
hasSample = False
|
||||||
@@ -523,7 +521,7 @@ def checkAssetsExist():
|
|||||||
# Import Translations (import-i18n)
|
# Import Translations (import-i18n)
|
||||||
##
|
##
|
||||||
|
|
||||||
def importI18nUpdates(sysArgs):
|
def importI18nUpdates(sysArgs: list[str]) -> None:
|
||||||
"""Import new translation files from a zip file."""
|
"""Import new translation files from a zip file."""
|
||||||
print("")
|
print("")
|
||||||
print("Import Updated Translations")
|
print("Import Updated Translations")
|
||||||
@@ -563,7 +561,7 @@ def importI18nUpdates(sysArgs):
|
|||||||
# Make Minimal Package (minimal-zip)
|
# Make Minimal Package (minimal-zip)
|
||||||
##
|
##
|
||||||
|
|
||||||
def makeMinimalPackage(targetOS):
|
def makeMinimalPackage(targetOS: int) -> None:
|
||||||
"""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
|
from zipfile import ZipFile, ZIP_DEFLATED
|
||||||
|
|
||||||
@@ -598,8 +596,7 @@ def makeMinimalPackage(targetOS):
|
|||||||
# Build Minimal Zip
|
# Build Minimal Zip
|
||||||
# =================
|
# =================
|
||||||
|
|
||||||
numVers, _, _ = extractVersion()
|
pkgVers, _, _ = extractVersion()
|
||||||
pkgVers = compactVersion(numVers)
|
|
||||||
zipFile = f"novelwriter-{pkgVers}-minimal{targName}.zip"
|
zipFile = f"novelwriter-{pkgVers}-minimal{targName}.zip"
|
||||||
outFile = os.path.join(bldDir, zipFile)
|
outFile = os.path.join(bldDir, zipFile)
|
||||||
if os.path.isfile(outFile):
|
if os.path.isfile(outFile):
|
||||||
@@ -679,7 +676,8 @@ def makeMinimalPackage(targetOS):
|
|||||||
# Make Debian Package (build-deb)
|
# Make Debian Package (build-deb)
|
||||||
##
|
##
|
||||||
|
|
||||||
def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buildName=""):
|
def makeDebianPackage(signKey: str | None = None, sourceBuild: bool = False,
|
||||||
|
distName: str = "unstable", buildName: str = "") -> str:
|
||||||
"""Build a Debian package."""
|
"""Build a Debian package."""
|
||||||
print("")
|
print("")
|
||||||
print("Build Debian Package")
|
print("Build Debian Package")
|
||||||
@@ -692,13 +690,12 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil
|
|||||||
# ============
|
# ============
|
||||||
|
|
||||||
numVers, hexVers, relDate = extractVersion()
|
numVers, hexVers, relDate = extractVersion()
|
||||||
pkgVers = compactVersion(numVers)
|
|
||||||
relDate = datetime.datetime.strptime(relDate, "%Y-%m-%d")
|
relDate = datetime.datetime.strptime(relDate, "%Y-%m-%d")
|
||||||
pkgDate = email.utils.format_datetime(relDate.replace(hour=12, tzinfo=None))
|
pkgDate = email.utils.format_datetime(relDate.replace(hour=12, tzinfo=None))
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
if buildName:
|
pkgVers = numVers.replace("a", "~a").replace("b", "~b").replace("rc", "~rc")
|
||||||
pkgVers = f"{pkgVers}{buildName}"
|
pkgVers = f"{pkgVers}+{buildName}" if buildName else pkgVers
|
||||||
|
|
||||||
# Set Up Folder
|
# Set Up Folder
|
||||||
# =============
|
# =============
|
||||||
@@ -839,11 +836,7 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil
|
|||||||
print("")
|
print("")
|
||||||
|
|
||||||
if sourceBuild:
|
if sourceBuild:
|
||||||
if hexVers[-2] == "f":
|
ppaName = "novelwriter" if hexVers[-2] == "f" else "novelwriter-pre"
|
||||||
ppaName = "novelwriter"
|
|
||||||
else:
|
|
||||||
ppaName = "novelwriter-pre"
|
|
||||||
|
|
||||||
return f"dput {ppaName}/{distName} {bldDir}/{bldPkg}_source.changes"
|
return f"dput {ppaName}/{distName} {bldDir}/{bldPkg}_source.changes"
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
@@ -853,14 +846,14 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil
|
|||||||
# Make Launchpad Package (build-ubuntu)
|
# Make Launchpad Package (build-ubuntu)
|
||||||
##
|
##
|
||||||
|
|
||||||
def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
def makeForLaunchpad(doSign: bool = False, isFirst: bool = False) -> None:
|
||||||
"""Wrapper for building Debian packages for Launchpad."""
|
"""Wrapper for building Debian packages for Launchpad."""
|
||||||
print("")
|
print("")
|
||||||
print("Launchpad Packages")
|
print("Launchpad Packages")
|
||||||
print("==================")
|
print("==================")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
if isFirst or isSnapshot:
|
if isFirst:
|
||||||
bldNum = "0"
|
bldNum = "0"
|
||||||
else:
|
else:
|
||||||
bldNum = input("Build number [0]: ")
|
bldNum = input("Build number [0]: ")
|
||||||
@@ -874,13 +867,8 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
|||||||
("23.10", "mantic"),
|
("23.10", "mantic"),
|
||||||
]
|
]
|
||||||
|
|
||||||
tStamp = datetime.datetime.now().strftime("%Y%m%d~%H%M%S")
|
print("Building Ubuntu packages for:")
|
||||||
if isSnapshot:
|
print("")
|
||||||
print(f"Building Ununtu SNAPSHOT~{tStamp} for:")
|
|
||||||
print("")
|
|
||||||
else:
|
|
||||||
print("Building Ubuntu packages for:")
|
|
||||||
print("")
|
|
||||||
for distNum, codeName in distLoop:
|
for distNum, codeName in distLoop:
|
||||||
print(f" * Ubuntu {distNum} {codeName.title()}")
|
print(f" * Ubuntu {distNum} {codeName.title()}")
|
||||||
print("")
|
print("")
|
||||||
@@ -895,11 +883,7 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
|||||||
|
|
||||||
dputCmd = []
|
dputCmd = []
|
||||||
for distNum, codeName in distLoop:
|
for distNum, codeName in distLoop:
|
||||||
if isSnapshot:
|
buildName = f"ubuntu{distNum}.{bldNum}"
|
||||||
buildName = f"+SNAPSHOT~{tStamp}~ubuntu{distNum}.0"
|
|
||||||
else:
|
|
||||||
buildName = f"~ubuntu{distNum}.{bldNum}"
|
|
||||||
|
|
||||||
dCmd = makeDebianPackage(
|
dCmd = makeDebianPackage(
|
||||||
signKey=signKey,
|
signKey=signKey,
|
||||||
sourceBuild=True,
|
sourceBuild=True,
|
||||||
@@ -922,7 +906,7 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
|||||||
# Make AppImage (build-appimage)
|
# Make AppImage (build-appimage)
|
||||||
##
|
##
|
||||||
|
|
||||||
def makeAppImage(sysArgs):
|
def makeAppImage(sysArgs: list[str]) -> list[str]:
|
||||||
"""Build an AppImage."""
|
"""Build an AppImage."""
|
||||||
import glob
|
import glob
|
||||||
import argparse
|
import argparse
|
||||||
@@ -968,8 +952,7 @@ def makeAppImage(sysArgs):
|
|||||||
# Version Info
|
# Version Info
|
||||||
# ============
|
# ============
|
||||||
|
|
||||||
numVers, _, relDate = extractVersion()
|
pkgVers, _, relDate = extractVersion()
|
||||||
pkgVers = compactVersion(numVers)
|
|
||||||
relDate = datetime.datetime.strptime(relDate, "%Y-%m-%d")
|
relDate = datetime.datetime.strptime(relDate, "%Y-%m-%d")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
@@ -1139,7 +1122,7 @@ def makeAppImage(sysArgs):
|
|||||||
# Make Windows Setup EXE (build-win-exe)
|
# Make Windows Setup EXE (build-win-exe)
|
||||||
##
|
##
|
||||||
|
|
||||||
def makeWindowsEmbedded(sysArgs):
|
def makeWindowsEmbedded(sysArgs: list[str]) -> None:
|
||||||
"""Set up a package with embedded Python and dependencies for
|
"""Set up a package with embedded Python and dependencies for
|
||||||
Windows installation.
|
Windows installation.
|
||||||
"""
|
"""
|
||||||
@@ -1371,7 +1354,7 @@ def makeWindowsEmbedded(sysArgs):
|
|||||||
# XDG Installation (xdg-install)
|
# XDG Installation (xdg-install)
|
||||||
##
|
##
|
||||||
|
|
||||||
def xdgInstall():
|
def xdgInstall() -> None:
|
||||||
"""Will attempt to install icons and make a launcher."""
|
"""Will attempt to install icons and make a launcher."""
|
||||||
print("")
|
print("")
|
||||||
print("XDG Install")
|
print("XDG Install")
|
||||||
@@ -1507,7 +1490,7 @@ def xdgInstall():
|
|||||||
# XDG Uninstallation (xdg-uninstall)
|
# XDG Uninstallation (xdg-uninstall)
|
||||||
##
|
##
|
||||||
|
|
||||||
def xdgUninstall():
|
def xdgUninstall() -> None:
|
||||||
"""Will attempt to uninstall icons and the launcher."""
|
"""Will attempt to uninstall icons and the launcher."""
|
||||||
print("")
|
print("")
|
||||||
print("XDG Uninstall")
|
print("XDG Uninstall")
|
||||||
@@ -1577,7 +1560,7 @@ def xdgUninstall():
|
|||||||
# WIN Installation (win-install)
|
# WIN Installation (win-install)
|
||||||
##
|
##
|
||||||
|
|
||||||
def winInstall():
|
def winInstall() -> None:
|
||||||
"""Will attempt to install icons and make a launcher for Windows."""
|
"""Will attempt to install icons and make a launcher for Windows."""
|
||||||
import winreg
|
import winreg
|
||||||
try:
|
try:
|
||||||
@@ -1704,7 +1687,7 @@ def winInstall():
|
|||||||
# WIN Uninstallation (win-uninstall)
|
# WIN Uninstallation (win-uninstall)
|
||||||
##
|
##
|
||||||
|
|
||||||
def winUninstall():
|
def winUninstall() -> None:
|
||||||
"""Will attempt to uninstall icons previously installed."""
|
"""Will attempt to uninstall icons previously installed."""
|
||||||
import winreg
|
import winreg
|
||||||
try:
|
try:
|
||||||
@@ -1805,40 +1788,35 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
hostOS = OS_NONE
|
hostOS = OS_NONE
|
||||||
|
|
||||||
|
sysArgs = sys.argv.copy()
|
||||||
|
|
||||||
# Set Target OS
|
# Set Target OS
|
||||||
if "--target-linux" in sys.argv:
|
if "--target-linux" in sysArgs:
|
||||||
sys.argv.remove("--target-linux")
|
sysArgs.remove("--target-linux")
|
||||||
targetOS = OS_LINUX
|
targetOS = OS_LINUX
|
||||||
elif "--target-darwin" in sys.argv:
|
elif "--target-darwin" in sysArgs:
|
||||||
sys.argv.remove("--target-darwin")
|
sysArgs.remove("--target-darwin")
|
||||||
targetOS = OS_DARWIN
|
targetOS = OS_DARWIN
|
||||||
elif "--target-win" in sys.argv:
|
elif "--target-win" in sysArgs:
|
||||||
sys.argv.remove("--target-win")
|
sysArgs.remove("--target-win")
|
||||||
targetOS = OS_WIN
|
targetOS = OS_WIN
|
||||||
else:
|
else:
|
||||||
targetOS = hostOS
|
targetOS = hostOS
|
||||||
|
|
||||||
# Sign package
|
# Sign package
|
||||||
if "--sign" in sys.argv:
|
if "--sign" in sysArgs:
|
||||||
sys.argv.remove("--sign")
|
sysArgs.remove("--sign")
|
||||||
doSign = True
|
doSign = True
|
||||||
else:
|
else:
|
||||||
doSign = False
|
doSign = False
|
||||||
|
|
||||||
# First build
|
# First build
|
||||||
if "--first" in sys.argv:
|
if "--first" in sysArgs:
|
||||||
sys.argv.remove("--first")
|
sysArgs.remove("--first")
|
||||||
isFirstBuild = True
|
isFirstBuild = True
|
||||||
else:
|
else:
|
||||||
isFirstBuild = False
|
isFirstBuild = False
|
||||||
|
|
||||||
# Build snapshot
|
|
||||||
if "--snapshot" in sys.argv:
|
|
||||||
sys.argv.remove("--snapshot")
|
|
||||||
isSnapshot = True
|
|
||||||
else:
|
|
||||||
isSnapshot = False
|
|
||||||
|
|
||||||
helpMsg = [
|
helpMsg = [
|
||||||
"",
|
"",
|
||||||
"novelWriter Setup Tool",
|
"novelWriter Setup Tool",
|
||||||
@@ -1856,7 +1834,7 @@ if __name__ == "__main__":
|
|||||||
"",
|
"",
|
||||||
" help Print the help message.",
|
" help Print the help message.",
|
||||||
" pip Install all package dependencies for novelWriter using pip.",
|
" pip Install all package dependencies for novelWriter using pip.",
|
||||||
" version Print the novelWriter version. Add -c for short version.",
|
" version Print the novelWriter version.",
|
||||||
" build-clean Will attempt to delete 'build' and 'dist' folders.",
|
" build-clean Will attempt to delete 'build' and 'dist' folders.",
|
||||||
"",
|
"",
|
||||||
"Additional Builds:",
|
"Additional Builds:",
|
||||||
@@ -1880,7 +1858,6 @@ if __name__ == "__main__":
|
|||||||
" sign package.",
|
" sign package.",
|
||||||
" build-ubuntu Build a .deb packages Launchpad. Add --sign to ",
|
" build-ubuntu Build a .deb packages Launchpad. Add --sign to ",
|
||||||
" sign package. Add --first to set build number to 0.",
|
" sign package. Add --first to set build number to 0.",
|
||||||
" Add --snapshot to make a snapshot package.",
|
|
||||||
" build-win-exe Build a setup.exe file with Python embedded for Windows.",
|
" build-win-exe Build a setup.exe file with Python embedded for Windows.",
|
||||||
" The package must be built from a minimal windows zip file.",
|
" The package must be built from a minimal windows zip file.",
|
||||||
" build-appimage Build an AppImage. Argument --linux-tag defaults to",
|
" build-appimage Build an AppImage. Argument --linux-tag defaults to",
|
||||||
@@ -1905,71 +1882,66 @@ if __name__ == "__main__":
|
|||||||
# General
|
# General
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
if "help" in sys.argv:
|
if "help" in sysArgs:
|
||||||
sys.argv.remove("help")
|
sysArgs.remove("help")
|
||||||
print("\n".join(helpMsg))
|
print("\n".join(helpMsg))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if "version" in sys.argv:
|
if "version" in sysArgs:
|
||||||
sys.argv.remove("version")
|
sysArgs.remove("version")
|
||||||
numVers, _, _ = extractVersion(beQuiet=True)
|
print(extractVersion(beQuiet=True)[0], end=None)
|
||||||
if "-c" in sys.argv:
|
|
||||||
sys.argv.remove("-c")
|
|
||||||
print(compactVersion(numVers), end=None)
|
|
||||||
else:
|
|
||||||
print(numVers, end=None)
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if "pip" in sys.argv:
|
if "pip" in sysArgs:
|
||||||
sys.argv.remove("pip")
|
sysArgs.remove("pip")
|
||||||
installPackages(hostOS)
|
installPackages(hostOS)
|
||||||
|
|
||||||
if "build-clean" in sys.argv:
|
if "build-clean" in sysArgs:
|
||||||
sys.argv.remove("build-clean")
|
sysArgs.remove("build-clean")
|
||||||
cleanBuildDirs()
|
cleanBuildDirs()
|
||||||
|
|
||||||
# Additional Builds
|
# Additional Builds
|
||||||
# =================
|
# =================
|
||||||
|
|
||||||
if "manual" in sys.argv:
|
if "manual" in sysArgs:
|
||||||
sys.argv.remove("manual")
|
sysArgs.remove("manual")
|
||||||
buildPdfManual()
|
buildPdfManual()
|
||||||
|
|
||||||
if "qtlrelease" in sys.argv:
|
if "qtlrelease" in sysArgs:
|
||||||
sys.argv.remove("qtlrelease")
|
sysArgs.remove("qtlrelease")
|
||||||
buildQtI18n()
|
buildQtI18n()
|
||||||
|
|
||||||
if "qtlupdate" in sys.argv:
|
if "qtlupdate" in sysArgs:
|
||||||
sys.argv.remove("qtlupdate")
|
sysArgs.remove("qtlupdate")
|
||||||
buildQtI18nTS(sys.argv)
|
buildQtI18nTS(sysArgs)
|
||||||
sys.exit(0) # Don't continue execution
|
sys.exit(0) # Don't continue execution
|
||||||
|
|
||||||
if "sample" in sys.argv:
|
if "sample" in sysArgs:
|
||||||
sys.argv.remove("sample")
|
sysArgs.remove("sample")
|
||||||
buildSampleZip()
|
buildSampleZip()
|
||||||
|
|
||||||
if "clean-assets" in sys.argv:
|
if "clean-assets" in sysArgs:
|
||||||
sys.argv.remove("clean-assets")
|
sysArgs.remove("clean-assets")
|
||||||
cleanBuiltAssets()
|
cleanBuiltAssets()
|
||||||
|
|
||||||
if "gen-plist" in sys.argv:
|
if "gen-plist" in sysArgs:
|
||||||
sys.argv.remove("gen-plist")
|
sysArgs.remove("gen-plist")
|
||||||
genMacOSPlist()
|
genMacOSPlist()
|
||||||
|
|
||||||
# Python Packaging
|
# Python Packaging
|
||||||
# ================
|
# ================
|
||||||
|
|
||||||
if "import-i18n" in sys.argv:
|
if "import-i18n" in sysArgs:
|
||||||
sys.argv.remove("import-i18n")
|
sysArgs.remove("import-i18n")
|
||||||
importI18nUpdates(sys.argv)
|
importI18nUpdates(sysArgs)
|
||||||
sys.exit(0) # Don't continue execution
|
sys.exit(0) # Don't continue execution
|
||||||
|
|
||||||
if "minimal-zip" in sys.argv:
|
if "minimal-zip" in sysArgs:
|
||||||
sys.argv.remove("minimal-zip")
|
sysArgs.remove("minimal-zip")
|
||||||
makeMinimalPackage(targetOS)
|
makeMinimalPackage(targetOS)
|
||||||
|
|
||||||
if "build-deb" in sys.argv:
|
if "build-deb" in sysArgs:
|
||||||
sys.argv.remove("build-deb")
|
sysArgs.remove("build-deb")
|
||||||
if hostOS == OS_LINUX:
|
if hostOS == OS_LINUX:
|
||||||
if doSign:
|
if doSign:
|
||||||
signKey = "D6A9F6B8F227CF7C6F6D1EE84DBBE4B734B0BD08"
|
signKey = "D6A9F6B8F227CF7C6F6D1EE84DBBE4B734B0BD08"
|
||||||
@@ -1980,23 +1952,23 @@ if __name__ == "__main__":
|
|||||||
print("ERROR: Command 'build-deb' can only be used on Linux")
|
print("ERROR: Command 'build-deb' can only be used on Linux")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if "build-ubuntu" in sys.argv:
|
if "build-ubuntu" in sysArgs:
|
||||||
sys.argv.remove("build-ubuntu")
|
sysArgs.remove("build-ubuntu")
|
||||||
if hostOS == OS_LINUX:
|
if hostOS == OS_LINUX:
|
||||||
makeForLaunchpad(doSign=doSign, isFirst=isFirstBuild, isSnapshot=isSnapshot)
|
makeForLaunchpad(doSign=doSign, isFirst=isFirstBuild)
|
||||||
else:
|
else:
|
||||||
print("ERROR: Command 'build-ubuntu' can only be used on Linux")
|
print("ERROR: Command 'build-ubuntu' can only be used on Linux")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if "build-win-exe" in sys.argv:
|
if "build-win-exe" in sysArgs:
|
||||||
sys.argv.remove("build-win-exe")
|
sysArgs.remove("build-win-exe")
|
||||||
makeWindowsEmbedded(sys.argv)
|
makeWindowsEmbedded(sysArgs)
|
||||||
sys.exit(0) # Don't continue execution
|
sys.exit(0) # Don't continue execution
|
||||||
|
|
||||||
if "build-appimage" in sys.argv:
|
if "build-appimage" in sysArgs:
|
||||||
sys.argv.remove("build-appimage")
|
sysArgs.remove("build-appimage")
|
||||||
if hostOS == OS_LINUX:
|
if hostOS == OS_LINUX:
|
||||||
sys.argv = makeAppImage(sys.argv) # Build appimage and prune its args
|
sysArgs = makeAppImage(sysArgs)
|
||||||
else:
|
else:
|
||||||
print("ERROR: Command 'build-appimage' can only be used on Linux")
|
print("ERROR: Command 'build-appimage' can only be used on Linux")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -2004,32 +1976,32 @@ if __name__ == "__main__":
|
|||||||
# General Installers
|
# General Installers
|
||||||
# ==================
|
# ==================
|
||||||
|
|
||||||
if "xdg-install" in sys.argv:
|
if "xdg-install" in sysArgs:
|
||||||
sys.argv.remove("xdg-install")
|
sysArgs.remove("xdg-install")
|
||||||
if hostOS == OS_WIN:
|
if hostOS == OS_WIN:
|
||||||
print("ERROR: Command 'xdg-install' cannot be used on Windows")
|
print("ERROR: Command 'xdg-install' cannot be used on Windows")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
xdgInstall()
|
xdgInstall()
|
||||||
|
|
||||||
if "xdg-uninstall" in sys.argv:
|
if "xdg-uninstall" in sysArgs:
|
||||||
sys.argv.remove("xdg-uninstall")
|
sysArgs.remove("xdg-uninstall")
|
||||||
if hostOS == OS_WIN:
|
if hostOS == OS_WIN:
|
||||||
print("ERROR: Command 'xdg-uninstall' cannot be used on Windows")
|
print("ERROR: Command 'xdg-uninstall' cannot be used on Windows")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
xdgUninstall()
|
xdgUninstall()
|
||||||
|
|
||||||
if "win-install" in sys.argv:
|
if "win-install" in sysArgs:
|
||||||
sys.argv.remove("win-install")
|
sysArgs.remove("win-install")
|
||||||
if hostOS == OS_WIN:
|
if hostOS == OS_WIN:
|
||||||
winInstall()
|
winInstall()
|
||||||
else:
|
else:
|
||||||
print("ERROR: Command 'win-install' can only be used on Windows")
|
print("ERROR: Command 'win-install' can only be used on Windows")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if "win-uninstall" in sys.argv:
|
if "win-uninstall" in sysArgs:
|
||||||
sys.argv.remove("win-uninstall")
|
sysArgs.remove("win-uninstall")
|
||||||
if hostOS == OS_WIN:
|
if hostOS == OS_WIN:
|
||||||
winUninstall()
|
winUninstall()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="2.3-alpha1" hexVersion="0x020300a1" fileVersion="1.5" fileRevision="1" timeStamp="2023-12-17 17:48:43">
|
<novelWriterXML appVersion="2.3a1" hexVersion="0x020300a1" fileVersion="1.5" fileRevision="1" timeStamp="2024-01-23 13:06:53">
|
||||||
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1617" autoCount="255" editTime="81245">
|
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1619" autoCount="255" editTime="81251">
|
||||||
<name>Sample Project</name>
|
<name>Sample Project</name>
|
||||||
<title>Sample Project</title>
|
<title>Sample Project</title>
|
||||||
<author>Jane Smith</author>
|
<author>Jane Smith</author>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ echo "Build Dir: $BUILD_DIR"
|
|||||||
|
|
||||||
pushd "$SRC_DIR" || exit 1
|
pushd "$SRC_DIR" || exit 1
|
||||||
|
|
||||||
VERSION="$(python3 pkgutils.py version -c)"
|
VERSION="$(python3 pkgutils.py version)"
|
||||||
echo "novelWriter Version: $VERSION"
|
echo "novelWriter Version: $VERSION"
|
||||||
|
|
||||||
# --- Prepare Files ----------------------------------------------------------------------------- #
|
# --- Prepare Files ----------------------------------------------------------------------------- #
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
ENVPATH=/tmp/nwBuild
|
|
||||||
|
|
||||||
if [ ! -f pkgutils.py ]; then
|
|
||||||
echo "Must be called from the root folder of the source"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo " Building Dependencies"
|
|
||||||
echo "================================================================================"
|
|
||||||
echo ""
|
|
||||||
if [ ! -d $ENVPATH ]; then
|
|
||||||
python3 -m venv $ENVPATH
|
|
||||||
fi
|
|
||||||
source $ENVPATH/bin/activate
|
|
||||||
pip3 install -r docs/source/requirements.txt
|
|
||||||
python3 pkgutils.py clean-assets
|
|
||||||
python3 pkgutils.py qtlrelease manual sample
|
|
||||||
deactivate
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo " Building Linux Snapshots"
|
|
||||||
echo "================================================================================"
|
|
||||||
echo ""
|
|
||||||
python3 pkgutils.py build-ubuntu --sign --snapshot
|
|
||||||
@@ -35,7 +35,7 @@ from PyQt5.QtCore import QUrl
|
|||||||
from novelwriter.common import (
|
from novelwriter.common import (
|
||||||
checkBool, checkFloat, checkHandle, checkInt, checkIntTuple, checkPath,
|
checkBool, checkFloat, checkHandle, checkInt, checkIntTuple, checkPath,
|
||||||
checkString, checkStringNone, checkUuid, formatInt, formatTime,
|
checkString, checkStringNone, checkUuid, formatInt, formatTime,
|
||||||
formatTimeStamp, fuzzyTime, getFileSize, hexToInt, isHandle, isItemClass,
|
formatTimeStamp, formatVersion, fuzzyTime, getFileSize, hexToInt, isHandle, isItemClass,
|
||||||
isItemLayout, isItemType, isTitleTag, jsonEncode, makeFileNameSafe, minmax,
|
isItemLayout, isItemType, isTitleTag, jsonEncode, makeFileNameSafe, minmax,
|
||||||
numberToRoman, NWConfigParser, openExternalPath, readTextFile, simplified,
|
numberToRoman, NWConfigParser, openExternalPath, readTextFile, simplified,
|
||||||
transferCase, xmlIndent, yesNo
|
transferCase, xmlIndent, yesNo
|
||||||
@@ -348,6 +348,17 @@ def testBaseCommon_formatTime():
|
|||||||
# END Test testBaseCommon_formatTime
|
# END Test testBaseCommon_formatTime
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.base
|
||||||
|
def testBaseCommon_formatVersion():
|
||||||
|
"""Test the formatVersion function."""
|
||||||
|
assert formatVersion("1.2") == "1.2"
|
||||||
|
assert formatVersion("1.2a1") == "1.2 Alpha 1"
|
||||||
|
assert formatVersion("1.2b2") == "1.2 Beta 2"
|
||||||
|
assert formatVersion("1.2rc3") == "1.2 RC 3"
|
||||||
|
|
||||||
|
# END Test testBaseCommon_formatVersion
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.base
|
@pytest.mark.base
|
||||||
def testBaseCommon_simplified():
|
def testBaseCommon_simplified():
|
||||||
"""Test the simplified function."""
|
"""Test the simplified function."""
|
||||||
|
|||||||
Reference in New Issue
Block a user