Updated AppImage packaging code
This commit is contained in:
+153
-199
@@ -37,6 +37,7 @@ import zipfile
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
CURR_DIR = Path(__file__).parent
|
CURR_DIR = Path(__file__).parent
|
||||||
|
SETUP_DIR = CURR_DIR / "setup"
|
||||||
SIGN_KEY = "D6A9F6B8F227CF7C6F6D1EE84DBBE4B734B0BD08"
|
SIGN_KEY = "D6A9F6B8F227CF7C6F6D1EE84DBBE4B734B0BD08"
|
||||||
|
|
||||||
OS_LINUX = sys.platform.startswith("linux")
|
OS_LINUX = sys.platform.startswith("linux")
|
||||||
@@ -90,27 +91,6 @@ def stripVersion(version: str) -> str:
|
|||||||
return version
|
return version
|
||||||
|
|
||||||
|
|
||||||
def copySourceCode(dst: Path) -> None:
|
|
||||||
"""Copy the novelwriter source tree to path."""
|
|
||||||
src = CURR_DIR / "novelwriter"
|
|
||||||
for item in src.glob("**/*"):
|
|
||||||
relSrc = item.relative_to(CURR_DIR)
|
|
||||||
if item.suffix in (".pyc", ".pyo"):
|
|
||||||
print(f"Ignore: {relSrc}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if item.parent.is_dir() and item.parent.name != "__pycache__":
|
|
||||||
dstDir = dst / relSrc.parent
|
|
||||||
if not dstDir.exists():
|
|
||||||
dstDir.mkdir(parents=True)
|
|
||||||
print(f"Folder: {dstDir}")
|
|
||||||
|
|
||||||
if item.is_file():
|
|
||||||
shutil.copyfile(item, dst / relSrc)
|
|
||||||
print(f"Copied: {dst / relSrc}")
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def readFile(fileName: str) -> str:
|
def readFile(fileName: str) -> str:
|
||||||
"""Read an entire file and return as a string."""
|
"""Read an entire file and return as a string."""
|
||||||
return Path(fileName).read_text(encoding="utf-8")
|
return Path(fileName).read_text(encoding="utf-8")
|
||||||
@@ -347,6 +327,42 @@ def buildSampleZip(args: argparse.Namespace | None = None) -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Import Translations (import-i18n)
|
||||||
|
##
|
||||||
|
|
||||||
|
def importI18nUpdates(args: argparse.Namespace) -> None:
|
||||||
|
"""Import new translation files from a zip file."""
|
||||||
|
print("")
|
||||||
|
print("Import Updated Translations")
|
||||||
|
print("===========================")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
fileName = Path(args.file).absolute()
|
||||||
|
if not fileName.is_file():
|
||||||
|
print("File not found ...")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
dstPath = CURR_DIR / "novelwriter" / "assets" / "i18n"
|
||||||
|
srcPath = CURR_DIR / "i18n"
|
||||||
|
|
||||||
|
print(f"Loading file: {fileName}")
|
||||||
|
with zipfile.ZipFile(fileName) as zipObj:
|
||||||
|
for item in zipObj.namelist():
|
||||||
|
if item.startswith("nw_") and item.endswith(".ts"):
|
||||||
|
zipObj.extract(item, srcPath)
|
||||||
|
print(f"Extracted: {item} > {srcPath / item}")
|
||||||
|
elif item.startswith("project_") and item.endswith(".json"):
|
||||||
|
zipObj.extract(item, dstPath)
|
||||||
|
print(f"Extracted: {item} > {dstPath / item}")
|
||||||
|
else:
|
||||||
|
print(f"Skipped: {item}")
|
||||||
|
|
||||||
|
print("")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Qt Linguist TS Builder (qtlupdate)
|
# Qt Linguist TS Builder (qtlupdate)
|
||||||
##
|
##
|
||||||
@@ -536,37 +552,66 @@ def genMacOSPlist() -> None:
|
|||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
|
||||||
##
|
##
|
||||||
# Import Translations (import-i18n)
|
# Copy Source
|
||||||
##
|
##
|
||||||
|
|
||||||
def importI18nUpdates(args: argparse.Namespace) -> None:
|
def copySourceCode(dst: Path) -> None:
|
||||||
"""Import new translation files from a zip file."""
|
"""Copy the novelwriter source tree to path."""
|
||||||
print("")
|
src = CURR_DIR / "novelwriter"
|
||||||
print("Import Updated Translations")
|
for item in src.glob("**/*"):
|
||||||
print("===========================")
|
relSrc = item.relative_to(CURR_DIR)
|
||||||
print("")
|
if item.suffix in (".pyc", ".pyo"):
|
||||||
|
print(f"Ignore: {relSrc}")
|
||||||
|
continue
|
||||||
|
if item.parent.is_dir() and item.parent.name != "__pycache__":
|
||||||
|
dstDir = dst / relSrc.parent
|
||||||
|
if not dstDir.exists():
|
||||||
|
dstDir.mkdir(parents=True)
|
||||||
|
print(f"Folder: {dstDir}")
|
||||||
|
if item.is_file():
|
||||||
|
shutil.copyfile(item, dst / relSrc)
|
||||||
|
print(f"Copied: {dst / relSrc}")
|
||||||
|
return
|
||||||
|
|
||||||
fileName = Path(args.file).absolute()
|
|
||||||
if not fileName.is_file():
|
|
||||||
print("File not found ...")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
dstPath = CURR_DIR / "novelwriter" / "assets" / "i18n"
|
##
|
||||||
srcPath = CURR_DIR / "i18n"
|
# Copy Package Files
|
||||||
|
##
|
||||||
|
|
||||||
print(f"Loading file: {fileName}")
|
def copyPackageFiles(dst: Path, useCfg: bool = False) -> None:
|
||||||
with zipfile.ZipFile(fileName) as zipObj:
|
"""Copy files needed for packaging."""
|
||||||
for item in zipObj.namelist():
|
|
||||||
if item.startswith("nw_") and item.endswith(".ts"):
|
|
||||||
zipObj.extract(item, srcPath)
|
|
||||||
print(f"Extracted: {item} > {srcPath / item}")
|
|
||||||
elif item.startswith("project_") and item.endswith(".json"):
|
|
||||||
zipObj.extract(item, dstPath)
|
|
||||||
print(f"Extracted: {item} > {dstPath / item}")
|
|
||||||
else:
|
|
||||||
print(f"Skipped: {item}")
|
|
||||||
|
|
||||||
print("")
|
copyFiles = ["LICENSE.md", "CREDITS.md", "pyproject.toml"]
|
||||||
|
for copyFile in copyFiles:
|
||||||
|
shutil.copyfile(copyFile, dst / copyFile)
|
||||||
|
print("Copied: %s" % copyFile)
|
||||||
|
|
||||||
|
(dst / "MANIFEST.in").write_text(
|
||||||
|
"include LICENSE.md\n"
|
||||||
|
"include CREDITS.md\n"
|
||||||
|
# "include data/*\n"
|
||||||
|
"recursive-include novelwriter/assets *\n"
|
||||||
|
)
|
||||||
|
print("Wrote: MANIFEST.in")
|
||||||
|
|
||||||
|
if useCfg:
|
||||||
|
# This is needed for Ubuntu up to 22.04
|
||||||
|
text = (SETUP_DIR / "launchpad_setup.cfg").read_text()
|
||||||
|
text = text.replace("setup/description_pypi.md", "data/description_short.txt")
|
||||||
|
(dst / "setup.cfg").write_text(text)
|
||||||
|
print("Wrote: setup.cfg")
|
||||||
|
|
||||||
|
(dst / "pyproject.toml").write_text(
|
||||||
|
"[build-system]\n"
|
||||||
|
"requires = [\"setuptools\"]\n"
|
||||||
|
"build-backend = \"setuptools.build_meta\"\n"
|
||||||
|
)
|
||||||
|
print("Wrote: pyproject.toml")
|
||||||
|
else:
|
||||||
|
text = (CURR_DIR / "pyproject.toml").read_text()
|
||||||
|
text = text.replace("setup/description_pypi.md", "data/description_short.txt")
|
||||||
|
(dst / "pyproject.toml").write_text(text)
|
||||||
|
print("Wrote: pyproject.toml")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -676,7 +721,6 @@ def makeDebianPackage(
|
|||||||
# Set Up Folder
|
# Set Up Folder
|
||||||
# =============
|
# =============
|
||||||
|
|
||||||
refDir = CURR_DIR / "setup"
|
|
||||||
bldDir = CURR_DIR / "dist_deb"
|
bldDir = CURR_DIR / "dist_deb"
|
||||||
bldPkg = f"novelwriter_{pkgVers}"
|
bldPkg = f"novelwriter_{pkgVers}"
|
||||||
outDir = bldDir / bldPkg
|
outDir = bldDir / bldPkg
|
||||||
@@ -703,58 +747,19 @@ def makeDebianPackage(
|
|||||||
|
|
||||||
print("Copying novelWriter source ...")
|
print("Copying novelWriter source ...")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
copySourceCode(outDir)
|
copySourceCode(outDir)
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
print("Copying or generating additional files ...")
|
print("Copying or generating additional files ...")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
# Copy/Write Root Files
|
copyPackageFiles(outDir, oldSetuptools)
|
||||||
# =====================
|
|
||||||
|
|
||||||
copyFiles = ["LICENSE.md", "CREDITS.md", "CHANGELOG.md", "pyproject.toml"]
|
|
||||||
for copyFile in copyFiles:
|
|
||||||
shutil.copyfile(copyFile, f"{outDir}/{copyFile}")
|
|
||||||
print("Copied: %s" % copyFile)
|
|
||||||
|
|
||||||
(outDir / "MANIFEST.in").write_text(
|
|
||||||
"include LICENSE.md\n"
|
|
||||||
"include CREDITS.md\n"
|
|
||||||
"include CHANGELOG.md\n"
|
|
||||||
"include data/*\n"
|
|
||||||
"recursive-include novelwriter/assets *\n"
|
|
||||||
)
|
|
||||||
print("Wrote: MANIFEST.in")
|
|
||||||
|
|
||||||
(outDir / "setup.py").write_text(
|
|
||||||
"import setuptools\n"
|
|
||||||
"setuptools.setup()\n"
|
|
||||||
)
|
|
||||||
print("Wrote: setup.py")
|
|
||||||
|
|
||||||
if oldSetuptools:
|
|
||||||
# This is needed for Ubuntu up to 22.04
|
|
||||||
text = (CURR_DIR / "setup" / "launchpad_setup.cfg").read_text()
|
|
||||||
text.replace("setup/description_pypi.md", "data/description_short.txt")
|
|
||||||
(outDir / "setup.cfg").write_text(text)
|
|
||||||
print("Wrote: setup.cfg")
|
|
||||||
|
|
||||||
(outDir / "pyproject.toml").write_text(
|
|
||||||
"[build-system]\n"
|
|
||||||
"requires = [\"setuptools\"]\n"
|
|
||||||
"build-backend = \"setuptools.build_meta\"\n"
|
|
||||||
)
|
|
||||||
print("Wrote: pyproject.toml")
|
|
||||||
else:
|
|
||||||
text = (CURR_DIR / "pyproject.toml").read_text()
|
|
||||||
text.replace("setup/description_pypi.md", "data/description_short.txt")
|
|
||||||
(outDir / "pyproject.toml").write_text(text)
|
|
||||||
print("Wrote: pyproject.toml")
|
|
||||||
|
|
||||||
# Copy/Write Debian Files
|
# Copy/Write Debian Files
|
||||||
# =======================
|
# =======================
|
||||||
|
|
||||||
shutil.copytree(refDir / "debian", debDir)
|
shutil.copytree(SETUP_DIR / "debian", debDir)
|
||||||
print("Copied: debian/*")
|
print("Copied: debian/*")
|
||||||
|
|
||||||
(debDir / "changelog").write_text(
|
(debDir / "changelog").write_text(
|
||||||
@@ -767,10 +772,10 @@ def makeDebianPackage(
|
|||||||
# Copy/Write Data Files
|
# Copy/Write Data Files
|
||||||
# =====================
|
# =====================
|
||||||
|
|
||||||
shutil.copytree(refDir / "data", datDir)
|
shutil.copytree(SETUP_DIR / "data", datDir)
|
||||||
print("Copied: data/*")
|
print("Copied: data/*")
|
||||||
|
|
||||||
shutil.copyfile(refDir / "description_short.txt", outDir / "data" / "description_short.txt")
|
shutil.copyfile(SETUP_DIR / "description_short.txt", outDir / "data" / "description_short.txt")
|
||||||
print("Copied: data/description_short.txt")
|
print("Copied: data/description_short.txt")
|
||||||
|
|
||||||
# Build Package
|
# Build Package
|
||||||
@@ -884,14 +889,11 @@ def buildForLaunchpad(args: argparse.Namespace) -> None:
|
|||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Make AppImage (build-appimage)
|
# Build AppImage (build-appimage)
|
||||||
##
|
##
|
||||||
|
|
||||||
def makeAppImage(sysArgs: list[str]) -> list[str]:
|
def buildAppImage(args: argparse.Namespace) -> None:
|
||||||
"""Build an AppImage."""
|
"""Build an AppImage."""
|
||||||
import argparse
|
|
||||||
import glob
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import python_appimage # noqa: F401 # type: ignore
|
import python_appimage # noqa: F401 # type: ignore
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -901,32 +903,15 @@ def makeAppImage(sysArgs: list[str]) -> list[str]:
|
|||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not OS_LINUX:
|
||||||
|
print("ERROR: Command 'build-ubuntu' can only be used on Linux")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
print("Build AppImage")
|
print("Build AppImage")
|
||||||
print("==============")
|
print("==============")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
prog="build_appimage",
|
|
||||||
description="Build an AppImage",
|
|
||||||
epilog="see https://appimage.org/ for more details",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--linux-tag",
|
|
||||||
nargs="?",
|
|
||||||
default="manylinux_2_28_x86_64",
|
|
||||||
help=(
|
|
||||||
"Linux compatibility tag (e.g. manylinux_2_28_x86_64)\n"
|
|
||||||
"see https://python-appimage.readthedocs.io/en/latest/#available-python-appimages \n"
|
|
||||||
"and https://github.com/pypa/manylinux for a list of valid tags"
|
|
||||||
),
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--python-version", nargs="?", default="3.11", help="Python version (e.g. 3.11)"
|
|
||||||
)
|
|
||||||
|
|
||||||
args, unparsedArgs = parser.parse_known_args(sysArgs)
|
|
||||||
|
|
||||||
linuxTag = args.linux_tag
|
linuxTag = args.linux_tag
|
||||||
pythonVer = args.python_version
|
pythonVer = args.python_version
|
||||||
|
|
||||||
@@ -940,129 +925,77 @@ def makeAppImage(sysArgs: list[str]) -> list[str]:
|
|||||||
# Set Up Folder
|
# Set Up Folder
|
||||||
# =============
|
# =============
|
||||||
|
|
||||||
bldDir = "dist_appimage"
|
bldDir = CURR_DIR / "dist_appimage"
|
||||||
bldPkg = f"novelwriter_{pkgVers}"
|
bldPkg = f"novelwriter_{pkgVers}"
|
||||||
outDir = f"{bldDir}/{bldPkg}"
|
outDir = bldDir / bldPkg
|
||||||
imageDir = f"{bldDir}/appimage"
|
imgDir = bldDir / "appimage"
|
||||||
|
|
||||||
# Set Up Folders
|
# Set Up Folders
|
||||||
# ==============
|
# ==============
|
||||||
|
|
||||||
if not os.path.isdir(bldDir):
|
bldDir.mkdir(exist_ok=True)
|
||||||
os.mkdir(bldDir)
|
|
||||||
|
|
||||||
if os.path.isdir(outDir):
|
if outDir.exists():
|
||||||
print("Removing old build files ...")
|
print("Removing old build files ...")
|
||||||
print("")
|
print("")
|
||||||
shutil.rmtree(outDir)
|
shutil.rmtree(outDir)
|
||||||
|
|
||||||
os.mkdir(outDir)
|
outDir.mkdir()
|
||||||
|
|
||||||
if os.path.isdir(imageDir):
|
if imgDir.exists():
|
||||||
print("Removing old build metadata files ...")
|
print("Removing old build metadata files ...")
|
||||||
print("")
|
print("")
|
||||||
shutil.rmtree(imageDir)
|
shutil.rmtree(imgDir)
|
||||||
|
|
||||||
os.mkdir(imageDir)
|
imgDir.mkdir()
|
||||||
|
|
||||||
# Remove old AppImages
|
# Remove old AppImages
|
||||||
outFiles = glob.glob(f"{bldDir}/*.AppImage")
|
if images := bldDir.glob("*.AppImage"):
|
||||||
if outFiles:
|
|
||||||
print("Removing old AppImages")
|
print("Removing old AppImages")
|
||||||
print("")
|
print("")
|
||||||
for image in outFiles:
|
for image in images:
|
||||||
try:
|
image.unlink()
|
||||||
os.remove(image)
|
|
||||||
except OSError:
|
|
||||||
print("Error while deleting file : ", image)
|
|
||||||
|
|
||||||
# Copy novelWriter Source
|
# Copy novelWriter Source
|
||||||
# =======================
|
# =======================
|
||||||
|
|
||||||
print("Copying novelWriter source ...")
|
print("Copying novelWriter source ...")
|
||||||
print("")
|
print("")
|
||||||
|
copySourceCode(outDir)
|
||||||
for nPath, _, nFiles in os.walk("novelwriter"):
|
|
||||||
if nPath.endswith("__pycache__"):
|
|
||||||
print("Skipped: %s" % nPath)
|
|
||||||
continue
|
|
||||||
|
|
||||||
pPath = f"{outDir}/{nPath}"
|
|
||||||
if not os.path.isdir(pPath):
|
|
||||||
os.mkdir(pPath)
|
|
||||||
|
|
||||||
fCount = 0
|
|
||||||
for fFile in nFiles:
|
|
||||||
nFile = f"{nPath}/{fFile}"
|
|
||||||
pFile = f"{pPath}/{fFile}"
|
|
||||||
|
|
||||||
if fFile.endswith(".pyc"):
|
|
||||||
print("Skipped: %s" % nFile)
|
|
||||||
continue
|
|
||||||
|
|
||||||
shutil.copyfile(nFile, pFile)
|
|
||||||
fCount += 1
|
|
||||||
|
|
||||||
print("Copied: %s/* [Files: %d]" % (nPath, fCount))
|
|
||||||
|
|
||||||
print("")
|
print("")
|
||||||
print("Copying or generating additional files ...")
|
print("Copying or generating additional files ...")
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
# Copy/Write Root Files
|
copyPackageFiles(outDir)
|
||||||
# =====================
|
|
||||||
|
|
||||||
copyFiles = ["LICENSE.md", "CREDITS.md", "CHANGELOG.md", "pyproject.toml"]
|
|
||||||
for copyFile in copyFiles:
|
|
||||||
shutil.copyfile(copyFile, f"{outDir}/{copyFile}")
|
|
||||||
print("Copied: %s" % copyFile)
|
|
||||||
|
|
||||||
writeFile(f"{outDir}/MANIFEST.in", (
|
|
||||||
"include LICENSE.md\n"
|
|
||||||
"include CREDITS.md\n"
|
|
||||||
"include CHANGELOG.md\n"
|
|
||||||
"include data/*\n"
|
|
||||||
"recursive-include novelwriter/assets *\n"
|
|
||||||
))
|
|
||||||
print("Wrote: MANIFEST.in")
|
|
||||||
|
|
||||||
writeFile(f"{outDir}/setup.py", (
|
|
||||||
"import setuptools\n"
|
|
||||||
"setuptools.setup()\n"
|
|
||||||
))
|
|
||||||
print("Wrote: setup.py")
|
|
||||||
|
|
||||||
setupCfg = readFile("pyproject.toml").replace(
|
|
||||||
"setup/description_pypi.md", "data/description_short.txt"
|
|
||||||
)
|
|
||||||
writeFile(f"{outDir}/pyproject.toml", setupCfg)
|
|
||||||
print("Wrote: pyproject.toml")
|
|
||||||
|
|
||||||
# Write Metadata
|
# Write Metadata
|
||||||
# ==============
|
# ==============
|
||||||
|
|
||||||
appDescription = readFile("setup/description_short.txt")
|
appDescription = (SETUP_DIR / "description_short.txt").read_text()
|
||||||
appdataXML = readFile("setup/novelwriter.appdata.xml").format(description=appDescription)
|
appdataXML = (SETUP_DIR / "novelwriter.appdata.xml").read_text()
|
||||||
writeFile(f"{imageDir}/novelwriter.appdata.xml", appdataXML)
|
appdataXML = appdataXML.format(description=appDescription)
|
||||||
|
(imgDir / "novelwriter.appdata.xml").write_text(appdataXML)
|
||||||
print("Wrote: novelwriter.appdata.xml")
|
print("Wrote: novelwriter.appdata.xml")
|
||||||
|
|
||||||
writeFile(f"{imageDir}/entrypoint.sh", (
|
(imgDir / "entrypoint.sh").write_text(
|
||||||
'#! /bin/bash \n'
|
'#! /bin/bash \n'
|
||||||
'{{ python-executable }} -sE ${APPDIR}/opt/python{{ python-version }}/bin/novelwriter "$@"'
|
'{{ python-executable }} -sE ${APPDIR}/opt/python{{ python-version }}/bin/novelwriter "$@"'
|
||||||
))
|
)
|
||||||
print("Wrote: entrypoint.sh")
|
print("Wrote: entrypoint.sh")
|
||||||
|
|
||||||
writeFile(f"{imageDir}/requirements.txt", os.path.abspath(outDir))
|
(imgDir / "requirements.txt").write_text(str(outDir))
|
||||||
print("Wrote: requirements.txt")
|
print("Wrote: requirements.txt")
|
||||||
|
|
||||||
shutil.copyfile("setup/data/novelwriter.desktop", f"{imageDir}/novelwriter.desktop")
|
shutil.copyfile(SETUP_DIR / "data" / "novelwriter.desktop", imgDir / "novelwriter.desktop")
|
||||||
print("Copied: novelwriter.desktop")
|
print("Copied: novelwriter.desktop")
|
||||||
|
|
||||||
shutil.copyfile("setup/icons/novelwriter.svg", f"{imageDir}/novelwriter.svg")
|
shutil.copyfile(SETUP_DIR / "icons" / "novelwriter.svg", imgDir / "novelwriter.svg")
|
||||||
print("Copied: novelwriter.svg")
|
print("Copied: novelwriter.svg")
|
||||||
|
|
||||||
shutil.copyfile(
|
shutil.copyfile(
|
||||||
"setup/data/hicolor/256x256/apps/novelwriter.png", f"{imageDir}/novelwriter.png"
|
SETUP_DIR / "data" / "hicolor" / "256x256" / "apps" / "novelwriter.png",
|
||||||
|
imgDir / "novelwriter.png"
|
||||||
)
|
)
|
||||||
print("Copied: novelwriter.png")
|
print("Copied: novelwriter.png")
|
||||||
|
|
||||||
@@ -1081,15 +1014,15 @@ def makeAppImage(sysArgs: list[str]) -> list[str]:
|
|||||||
print("")
|
print("")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
bldFile = glob.glob(f"{bldDir}/*.AppImage")[0]
|
bldFile = list(bldDir.glob("*.AppImage"))[0]
|
||||||
outFile = f"{bldDir}/novelWriter-{pkgVers}.AppImage"
|
outFile = bldDir / f"novelWriter-{pkgVers}.AppImage"
|
||||||
os.rename(bldFile, outFile)
|
bldFile.rename(outFile)
|
||||||
shaFile = makeCheckSum(os.path.basename(outFile), cwd=bldDir)
|
shaFile = makeCheckSum(outFile.name, cwd=bldDir)
|
||||||
|
|
||||||
toUpload(outFile)
|
toUpload(outFile)
|
||||||
toUpload(shaFile)
|
toUpload(shaFile)
|
||||||
|
|
||||||
return unparsedArgs
|
return
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -1690,6 +1623,27 @@ if __name__ == "__main__":
|
|||||||
cmdBuildUbuntu.add_argument("--first", action="store_true", help="Set build number to 0.")
|
cmdBuildUbuntu.add_argument("--first", action="store_true", help="Set build number to 0.")
|
||||||
cmdBuildUbuntu.set_defaults(func=buildForLaunchpad)
|
cmdBuildUbuntu.set_defaults(func=buildForLaunchpad)
|
||||||
|
|
||||||
|
# Build AppImage
|
||||||
|
cmdBuildAppImage = parsers.add_parser(
|
||||||
|
"build-appimage", help=(
|
||||||
|
"Build an AppImage. "
|
||||||
|
"Argument --linux-tag defaults manylinux_2_28_x86_64, and --python-version to 3.11."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
cmdBuildAppImage.add_argument(
|
||||||
|
"--linux-tag",
|
||||||
|
default="manylinux_2_28_x86_64",
|
||||||
|
help=(
|
||||||
|
"Linux compatibility tag (e.g. manylinux_2_28_x86_64) "
|
||||||
|
"see https://python-appimage.readthedocs.io/en/latest/#available-python-appimages "
|
||||||
|
"and https://github.com/pypa/manylinux for a list of valid tags."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
cmdBuildAppImage.add_argument(
|
||||||
|
"--python-version", default="3.11", help="Python version (e.g. 3.11)"
|
||||||
|
)
|
||||||
|
cmdBuildAppImage.set_defaults(func=buildAppImage)
|
||||||
|
|
||||||
# if "gen-plist" in sysArgs:
|
# if "gen-plist" in sysArgs:
|
||||||
# sysArgs.remove("gen-plist")
|
# sysArgs.remove("gen-plist")
|
||||||
# genMacOSPlist()
|
# genMacOSPlist()
|
||||||
|
|||||||
Reference in New Issue
Block a user