219 lines
6.1 KiB
Python
219 lines
6.1 KiB
Python
"""
|
||
novelWriter – Debian Build
|
||
==========================
|
||
|
||
This file is a part of novelWriter
|
||
Copyright (C) 2025 Veronica Berglyd Olsen and novelWriter contributors
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful, but
|
||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
""" # noqa
|
||
from __future__ import annotations
|
||
|
||
import argparse
|
||
import datetime
|
||
import email.utils
|
||
import shutil
|
||
import sys
|
||
|
||
from utils.common import (
|
||
ROOT_DIR, SETUP_DIR, checkAssetsExist, copyPackageFiles, copySourceCode,
|
||
extractVersion, makeCheckSum, systemCall, toUpload, writeFile
|
||
)
|
||
|
||
SIGN_KEY = "D6A9F6B8F227CF7C6F6D1EE84DBBE4B734B0BD08"
|
||
|
||
|
||
def makeDebianPackage(
|
||
signKey: str | None = None, sourceBuild: bool = False, distName: str = "unstable",
|
||
buildName: str = "", forLaunchpad: bool = False, oldLicense: bool = False,
|
||
) -> str:
|
||
"""Build a Debian package."""
|
||
print("")
|
||
print("Build Debian Package")
|
||
print("====================")
|
||
print("On Debian/Ubuntu install: dh-python python3-all debhelper devscripts ")
|
||
print(" pybuild-plugin-pyproject")
|
||
print("")
|
||
|
||
# Version Info
|
||
# ============
|
||
|
||
numVers, hexVers, relDate = extractVersion()
|
||
relDate = datetime.datetime.strptime(relDate, "%Y-%m-%d")
|
||
pkgDate = email.utils.format_datetime(relDate.replace(hour=12, tzinfo=None))
|
||
print("")
|
||
|
||
if forLaunchpad:
|
||
pkgVers = numVers.replace("a", "~a").replace("b", "~b").replace("rc", "~rc")
|
||
else:
|
||
pkgVers = numVers
|
||
pkgVers = f"{pkgVers}+{buildName}" if buildName else pkgVers
|
||
|
||
# Set Up Folder
|
||
# =============
|
||
|
||
bldDir = ROOT_DIR / "dist_deb"
|
||
bldPkg = f"novelwriter_{pkgVers}"
|
||
outDir = bldDir / bldPkg
|
||
debDir = outDir / "debian"
|
||
datDir = outDir / "data"
|
||
|
||
bldDir.mkdir(exist_ok=True)
|
||
if outDir.exists():
|
||
print("Removing old build files ...")
|
||
print("")
|
||
shutil.rmtree(outDir)
|
||
|
||
outDir.mkdir(exist_ok=False)
|
||
|
||
# Check Additional Assets
|
||
# =======================
|
||
|
||
if not checkAssetsExist():
|
||
print("ERROR: Missing build assets")
|
||
sys.exit(1)
|
||
|
||
# Copy novelWriter Source
|
||
# =======================
|
||
|
||
print("Copying novelWriter source ...")
|
||
print("")
|
||
|
||
copySourceCode(outDir)
|
||
|
||
print("")
|
||
print("Copying or generating additional files ...")
|
||
print("")
|
||
|
||
copyPackageFiles(outDir, oldLicense=oldLicense)
|
||
|
||
# Copy/Write Debian Files
|
||
# =======================
|
||
|
||
shutil.copytree(SETUP_DIR / "debian", debDir)
|
||
print("Copied: debian/*")
|
||
|
||
writeFile(debDir / "changelog", (
|
||
f"novelwriter ({pkgVers}) {distName}; urgency=low\n\n"
|
||
f" * Update to version {pkgVers}\n\n"
|
||
f" -- Veronica Berglyd Olsen <code@vkbo.net> {pkgDate}\n"
|
||
))
|
||
print("Wrote: debian/changelog")
|
||
|
||
# Copy/Write Data Files
|
||
# =====================
|
||
|
||
shutil.copytree(SETUP_DIR / "data", datDir)
|
||
print("Copied: data/*")
|
||
|
||
shutil.copyfile(SETUP_DIR / "description_short.txt", outDir / "data" / "description_short.txt")
|
||
print("Copied: data/description_short.txt")
|
||
|
||
# Build Package
|
||
# =============
|
||
|
||
print("")
|
||
print("Running dpkg-buildpackage ...")
|
||
print("")
|
||
|
||
if signKey is None:
|
||
signArgs = ["-us", "-uc"]
|
||
else:
|
||
signArgs = [f"-k{signKey}"]
|
||
|
||
if sourceBuild:
|
||
systemCall(["debuild", "-S", *signArgs], cwd=outDir)
|
||
toUpload(bldDir / f"{bldPkg}.tar.xz")
|
||
else:
|
||
systemCall(["dpkg-buildpackage", *signArgs], cwd=outDir)
|
||
shutil.copyfile(bldDir / f"{bldPkg}.tar.xz", bldDir / f"{bldPkg}.debian.tar.xz")
|
||
toUpload(bldDir / f"{bldPkg}.debian.tar.xz")
|
||
toUpload(bldDir / f"{bldPkg}_all.deb")
|
||
toUpload(makeCheckSum(f"{bldPkg}.debian.tar.xz", cwd=bldDir))
|
||
toUpload(makeCheckSum(f"{bldPkg}_all.deb", cwd=bldDir))
|
||
|
||
print("")
|
||
print("Done!")
|
||
print("")
|
||
|
||
if sourceBuild:
|
||
ppaName = "novelwriter" if hexVers[-2] == "f" else "novelwriter-pre"
|
||
return f"dput {ppaName}/{distName} {bldDir}/{bldPkg}_source.changes"
|
||
|
||
return ""
|
||
|
||
|
||
def debian(args: argparse.Namespace) -> None:
|
||
"""Build a .deb package."""
|
||
if sys.platform != "linux":
|
||
print("ERROR: Command 'build-deb' can only be used on Linux")
|
||
sys.exit(1)
|
||
signKey = SIGN_KEY if args.sign else None
|
||
makeDebianPackage(signKey)
|
||
|
||
|
||
def launchpad(args: argparse.Namespace) -> None:
|
||
"""Build Debian packages for Launchpad."""
|
||
if sys.platform != "linux":
|
||
print("ERROR: Command 'build-ubuntu' can only be used on Linux")
|
||
sys.exit(1)
|
||
|
||
print("")
|
||
print("Launchpad Packages")
|
||
print("==================")
|
||
print("")
|
||
|
||
if args.build:
|
||
bldNum = str(args.build)
|
||
else:
|
||
bldNum = "0"
|
||
|
||
distLoop = [
|
||
("24.04", "noble", True),
|
||
("25.04", "plucky", True),
|
||
("25.10", "questing", False),
|
||
("26.04", "resolute", False),
|
||
]
|
||
|
||
print("Building Ubuntu packages for:")
|
||
print("")
|
||
for distNum, codeName, _ in distLoop:
|
||
print(f" * Ubuntu {distNum} {codeName.title()}")
|
||
print("")
|
||
|
||
signKey = SIGN_KEY if args.sign else None
|
||
|
||
print(f"Sign Key: {signKey!s}")
|
||
print("")
|
||
|
||
dputCmd = []
|
||
for distNum, codeName, oldLicense in distLoop:
|
||
buildName = f"ubuntu{distNum}.{bldNum}"
|
||
dCmd = makeDebianPackage(
|
||
signKey=signKey,
|
||
sourceBuild=True,
|
||
distName=codeName,
|
||
buildName=buildName,
|
||
forLaunchpad=True,
|
||
oldLicense=oldLicense,
|
||
)
|
||
dputCmd.append(dCmd)
|
||
|
||
print("Packages Built")
|
||
print("==============")
|
||
print("")
|
||
for dCmd in dputCmd:
|
||
print(f" > {dCmd}")
|
||
print("")
|