Merge branch 'main' into patch_to_main
This commit is contained in:
@@ -197,6 +197,7 @@ def cleanBuildDirs():
|
||||
removeFolder("dist")
|
||||
removeFolder("dist_deb")
|
||||
removeFolder("dist_minimal")
|
||||
removeFolder("dist_appimage")
|
||||
removeFolder("novelWriter.egg-info")
|
||||
|
||||
print("")
|
||||
@@ -848,7 +849,6 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
||||
bldNum = "0"
|
||||
|
||||
distLoop = [
|
||||
("18.04", "bionic"),
|
||||
("20.04", "focal"),
|
||||
("22.04", "jammy"),
|
||||
]
|
||||
@@ -897,10 +897,231 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
# Make AppImage (build-appimage)
|
||||
##
|
||||
|
||||
def makeAppImage(sysArgs):
|
||||
"""Build an Appimage
|
||||
"""
|
||||
|
||||
import glob
|
||||
import argparse
|
||||
import platform
|
||||
|
||||
try:
|
||||
import python_appimage # noqa F401
|
||||
except ImportError:
|
||||
print(
|
||||
"ERROR: Package 'python-appimage' is missing on this system.\n"
|
||||
" Please run 'pip install --user python-appimage' to install it.\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
print("")
|
||||
print("Build AppImage")
|
||||
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=f"manylinux2010_{platform.machine()}",
|
||||
help=(
|
||||
"linux compatibility tag (e.g. manylinux1_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.10", help="python version (e.g. 3.10)"
|
||||
)
|
||||
|
||||
args, unparsedArgs = parser.parse_known_args(sysArgs)
|
||||
|
||||
linuxTag = args.linux_tag
|
||||
pythonVer = args.python_version
|
||||
|
||||
# Version Info
|
||||
# ============
|
||||
|
||||
numVers, _, relDate = extractVersion()
|
||||
pkgVers = compactVersion(numVers)
|
||||
relDate = datetime.datetime.strptime(relDate, "%Y-%m-%d")
|
||||
print("")
|
||||
|
||||
# Set Up Folder
|
||||
# =============
|
||||
|
||||
bldDir = "dist_appimage"
|
||||
bldPkg = f"novelwriter_{pkgVers}"
|
||||
outDir = f"{bldDir}/{bldPkg}"
|
||||
imageDir = f"{bldDir}/appimage"
|
||||
|
||||
# Set Up Folders
|
||||
# ==============
|
||||
|
||||
if not os.path.isdir(bldDir):
|
||||
os.mkdir(bldDir)
|
||||
|
||||
if os.path.isdir(outDir):
|
||||
print("Removing old build files ...")
|
||||
print("")
|
||||
shutil.rmtree(outDir)
|
||||
|
||||
os.mkdir(outDir)
|
||||
|
||||
if os.path.isdir(imageDir):
|
||||
print("Removing old build metadata files ...")
|
||||
print("")
|
||||
shutil.rmtree(imageDir)
|
||||
|
||||
os.mkdir(imageDir)
|
||||
|
||||
# Remove old Appimages
|
||||
outFiles = glob.glob(f"{bldDir}/*.AppImage")
|
||||
|
||||
if outFiles:
|
||||
print("Removing old AppImages")
|
||||
print("")
|
||||
for image in outFiles:
|
||||
try:
|
||||
os.remove(image)
|
||||
except OSError:
|
||||
print("Error while deleting file : ", image)
|
||||
|
||||
# Build Additional Assets
|
||||
# =======================
|
||||
|
||||
buildQtI18n()
|
||||
buildSampleZip()
|
||||
buildPdfManual()
|
||||
|
||||
# Copy novelWriter Source
|
||||
# =======================
|
||||
|
||||
print("Copying novelWriter source ...")
|
||||
print("")
|
||||
|
||||
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("Copying or generating additional files ...")
|
||||
print("")
|
||||
|
||||
# Copy/Write Root Files
|
||||
# =====================
|
||||
|
||||
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("setup.cfg").replace(
|
||||
"file: setup/description_pypi.md", "file: data/description_short.txt"
|
||||
)
|
||||
writeFile(f"{outDir}/setup.cfg", setupCfg)
|
||||
print("Wrote: setup.cfg")
|
||||
|
||||
# Write Metadata
|
||||
# ==============
|
||||
|
||||
appDescription = readFile("setup/description_short.txt")
|
||||
appdataXML = readFile("setup/novelwriter.appdata.xml").format(description=appDescription)
|
||||
writeFile(f"{imageDir}/novelwriter.appdata.xml", appdataXML)
|
||||
print("Wrote: novelwriter.appdata.xml")
|
||||
|
||||
writeFile(f"{imageDir}/entrypoint.sh", (
|
||||
'#! /bin/bash \n'
|
||||
'{{ python-executable }} -sE ${APPDIR}/opt/python{{ python-version }}/bin/novelwriter "$@"'
|
||||
))
|
||||
print("Wrote: entrypoint.sh")
|
||||
|
||||
writeFile(f"{imageDir}/requirements.txt", os.path.abspath(outDir))
|
||||
print("Wrote: requirements.txt")
|
||||
|
||||
shutil.copyfile("setup/data/novelwriter.desktop", f"{imageDir}/novelwriter.desktop")
|
||||
print("Copied: setup/data/novelwriter.desktop")
|
||||
|
||||
shutil.copyfile("setup/icons/novelwriter.svg", f"{imageDir}/novelwriter.svg")
|
||||
print("Copied: setup/icons/novelwriter.svg")
|
||||
|
||||
shutil.copyfile("setup/data/hicolor/256x256/apps/novelwriter.png",
|
||||
f"{imageDir}/novelwriter.png")
|
||||
print("Copied: setup/data/hicolor/256x256/apps/novelwriter.png")
|
||||
|
||||
# Build Appimage
|
||||
# ==============
|
||||
|
||||
try:
|
||||
subprocess.call([
|
||||
sys.executable, "-m", "python_appimage", "build", "app",
|
||||
"-l", linuxTag, "-p", pythonVer, "appimage"
|
||||
], cwd=bldDir)
|
||||
except Exception as exc:
|
||||
print("AppImage build: FAILED")
|
||||
print("")
|
||||
print(str(exc))
|
||||
print("")
|
||||
print("Dependencies:")
|
||||
print(" * pip install python-appimage")
|
||||
print("")
|
||||
sys.exit(1)
|
||||
|
||||
outFile = glob.glob(f"{bldDir}/*.AppImage")[0]
|
||||
shaFile = makeCheckSum(os.path.basename(outFile), cwd=bldDir)
|
||||
|
||||
toUpload(outFile)
|
||||
toUpload(shaFile)
|
||||
|
||||
return unparsedArgs
|
||||
|
||||
##
|
||||
# Make Windows Setup EXE (build-win-exe)
|
||||
##
|
||||
|
||||
|
||||
def makeWindowsEmbedded(sysArgs):
|
||||
"""Set up a package with embedded Python and dependencies for
|
||||
Windows installation.
|
||||
@@ -1651,6 +1872,8 @@ if __name__ == "__main__":
|
||||
" Add --snapshot to make a snapshot package.",
|
||||
" build-win-exe Build a setup.exe file with Python embedded for Windows.",
|
||||
" The package must be built from a minimal windows zip file.",
|
||||
" build-appimage Build an AppImage. Argument --linux-tag defaults to",
|
||||
" manylinux1_x86_64 / i386, and --python-version to 3.10.",
|
||||
"",
|
||||
"System Install:",
|
||||
"",
|
||||
@@ -1753,6 +1976,14 @@ if __name__ == "__main__":
|
||||
makeWindowsEmbedded(sys.argv)
|
||||
sys.exit(0) # Don't continue execution
|
||||
|
||||
if "build-appimage" in sys.argv:
|
||||
sys.argv.remove("build-appimage")
|
||||
if hostOS == OS_LINUX:
|
||||
sys.argv = makeAppImage(sys.argv) # Build appimage and prune its args
|
||||
else:
|
||||
print("ERROR: Command 'build-appimage' can only be used on Linux")
|
||||
sys.exit(1)
|
||||
|
||||
# General Installers
|
||||
# ==================
|
||||
|
||||
|
||||
Reference in New Issue
Block a user