Skip to content

Commit 6026735

Browse files
committed
Merge branch 'feat/linux-builds'
2 parents 13b371d + 56a8b87 commit 6026735

File tree

2 files changed

+87
-126
lines changed

2 files changed

+87
-126
lines changed

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: |
66
practice area on the right. Lessons are stored in JSON and can be extended.
77
88
publish_to: 'none'
9-
version: 0.1.0
9+
version: 0.2.0
1010

1111
environment:
1212
sdk: ">=3.0.0 <4.0.0"

scripts/package_deb.sh

Lines changed: 86 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,90 @@
11
#!/usr/bin/env bash
2-
set -euo pipefail
3-
4-
VERSION="${1:-0.0.0}"
5-
APP_NAME="Asante Typing"
6-
APP_BIN_NAME="asante-typing" # launcher name
2+
# package_deb.sh — Build a Linux Release, system-install for testing,
3+
# stage files into pkgroot, and produce a Debian .deb with fpm.
4+
# This script encodes the exact working sequence you confirmed.
5+
6+
set -Eeuo pipefail
7+
8+
# ---- Config you may tweak ----------------------------------------------------
9+
APP_NAME="asante-typing" # Debian package name
10+
BINARY_NAME="asante_typing" # Installed binary name
11+
INSTALL_PREFIX="/usr" # FHS system install prefix
12+
BUILD_TYPE="Release"
13+
PKG_BUILD_DIR="build/linux/x64/release/pkg/cmake"
714
BUNDLE_DIR="build/linux/x64/release/bundle"
8-
ICON_SRC="assets/icon/app_icon.png" # Path to the icon in the repository
9-
10-
# Check if icon exists
11-
if [[ ! -f "$ICON_SRC" ]]; then
12-
echo "Icon file not found: $ICON_SRC" >&2
13-
exit 1
14-
fi
15-
16-
if [[ ! -d "$BUNDLE_DIR" ]]; then
17-
echo "Bundle not found: $BUNDLE_DIR" >&2
18-
exit 1
19-
fi
20-
21-
WORK="dist/linux/pkg"
22-
DEB_OUT="dist/linux"
23-
mkdir -p "$WORK/DEBIAN" "$WORK/usr/bin" "$WORK/opt/$APP_BIN_NAME" "$WORK/usr/share/applications" "$WORK/usr/share/pixmaps"
24-
25-
if [[ ! -d "$WORK/DEBIAN" ]]; then
26-
echo "Failed to create directory: $WORK/DEBIAN" >&2
27-
exit 1
28-
fi
29-
30-
# Copy built files
31-
cp -a "$BUNDLE_DIR/." "$WORK/opt/$APP_BIN_NAME/"
32-
33-
if [[ ! -f "$WORK/opt/$APP_BIN_NAME/asante_typing" ]]; then
34-
echo "Main binary not found in $WORK/opt/$APP_BIN_NAME/asante_typing" >&2
35-
exit 1
36-
fi
37-
38-
# Copy icon
39-
cp "$ICON_SRC" "$WORK/usr/share/pixmaps/$APP_BIN_NAME.png"
40-
chmod 0644 "$WORK/usr/share/pixmaps/$APP_BIN_NAME.png"
41-
42-
# Simple launcher wrapper
43-
cat > "$WORK/usr/bin/$APP_BIN_NAME" <<'EOF'
44-
#!/usr/bin/env bash
45-
DIR="/opt/asante-typing"
46-
exec "$DIR/asante_typing" "$@"
47-
EOF
48-
chmod +x "$WORK/usr/bin/$APP_BIN_NAME"
49-
50-
# .desktop entry
51-
cat > "$WORK/usr/share/applications/${APP_BIN_NAME}.desktop" <<EOF
52-
[Desktop Entry]
53-
Name=$APP_NAME
54-
Exec=$APP_BIN_NAME
55-
Icon=$APP_BIN_NAME
56-
Type=Application
57-
Categories=Utility;Education;
58-
Terminal=false
59-
EOF
60-
61-
# Control file
62-
cat > "$WORK/DEBIAN/control" <<EOF
63-
Package: ${APP_BIN_NAME}
64-
Version: ${VERSION}
65-
Section: utils
66-
Priority: optional
67-
Architecture: amd64
68-
Maintainer: John Francis Mukulu SJ <john.f.mukulu@gmail.com>
69-
Homepage: https://mukulu.org/asante-typing
70-
Vcs-Git: https://github.com/mukulu/asante-typing.git
71-
Description: $APP_NAME - typing tutor
72-
Asante Typing is an open-source typing tutor designed to help users improve
73-
their typing speed and accuracy. Featuring interactive lessons and customizable
74-
settings, it supports multiple keyboard layouts and provides real-time feedback
75-
to enhance touch-typing skills. Ideal for beginners and advanced users alike.
76-
EOF
77-
78-
# Copyright file
79-
cat > "$WORK/DEBIAN/copyright" <<EOF
80-
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
81-
Upstream-Name: $APP_NAME
82-
Upstream-Contact: John Francis Mukulu SJ <john.f.mukulu@gmail.com>
83-
Source: https://github.com/mukulu/asante-typing
84-
85-
Files: *
86-
Copyright: 2025 John Francis Mukulu SJ
87-
License: GPL-3.0
88-
This program is free software: you can redistribute it and/or modify
89-
it under the terms of the GNU General Public License as published by
90-
the Free Software Foundation, version 3.
91-
.
92-
This program is distributed in the hope that it will be useful,
93-
but WITHOUT ANY WARRANTY; without even the implied warranty of
94-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
95-
GNU General Public License for more details.
96-
.
97-
You should have received a copy of the GNU General Public License
98-
along with this program. If not, see <https://www.gnu.org/licenses/>.
99-
100-
License: GPL-3.0
101-
On Debian systems, the complete text of the GNU General Public
102-
License version 3 can be found in "/usr/share/common-licenses/GPL-3".
103-
EOF
104-
105-
mkdir -p "$DEB_OUT"
106-
107-
# --- FIX: normalise DEBIAN/ perms to satisfy dpkg-deb ---
108-
# Some filesystems create dirs with g+s (2775). dpkg-deb requires 0755–0775.
109-
chmod -R ug-s "$WORK/DEBIAN"
110-
find "$WORK/DEBIAN" -type d -exec chmod 0755 {} \;
111-
# control, copyright, conffiles, etc. must be readable (0644)
112-
find "$WORK/DEBIAN" -maxdepth 1 -type f -not -name 'preinst' -not -name 'postinst' -not -name 'prerm' -not -name 'postrm' -exec chmod 0644 {} \;
113-
# Maintainer scripts must be executable (0755) if present
114-
for f in preinst postinst prerm postrm; do
115-
[ -f "$WORK/DEBIAN/$f" ] && chmod 0755 "$WORK/DEBIAN/$f"
116-
done
117-
# --- END FIX ---
118-
119-
# Debug: List permissions
120-
ls -lR "$WORK/DEBIAN"
121-
122-
# Check for dpkg-deb
123-
if ! command -v dpkg-deb >/dev/null; then
124-
echo "dpkg-deb is not installed. Please install it (e.g., sudo apt install dpkg)." >&2
125-
exit 1
15+
PKGROOT="$(pwd)/pkgroot"
16+
17+
# Version: use env APPVER if set, else read pubspec.yaml, else fallback.
18+
APPVER="${APPVER:-$(awk -F': *' '/^version:/{print $2; exit}' pubspec.yaml 2>/dev/null || echo '0.1.0')}"
19+
ARCH="amd64"
20+
21+
VENDOR="John Francis Mukulu <john.f.mukulu@gmail.com>"
22+
HOMEPAGE="https://mukulu.org"
23+
LICENSE="MIT"
24+
DESCRIPTION="Asante Typing – learn touch-typing with interactive lessons."
25+
# -----------------------------------------------------------------------------
26+
27+
echo "==> Cleaning workspace"
28+
git clean -xfd || true
29+
flutter clean
30+
flutter pub get
31+
32+
echo "==> Flutter Release build (bundle)"
33+
flutter build linux --release
34+
35+
echo "==> Configure CMake (packaging/FHS mode)"
36+
rm -rf "${PKG_BUILD_DIR}"
37+
cmake -S linux -B "${PKG_BUILD_DIR}" \
38+
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
39+
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
40+
-DASANTE_SYSTEM_INSTALL=ON
41+
42+
echo "==> Build native runner"
43+
cmake --build "${PKG_BUILD_DIR}" --config "${BUILD_TYPE}"
44+
45+
echo "==> System install for local test (needs sudo)"
46+
sudo cmake --install "${PKG_BUILD_DIR}"
47+
48+
echo "==> Refresh desktop/icon caches (needs sudo)"
49+
sudo update-desktop-database || true
50+
sudo gtk-update-icon-cache -f /usr/share/icons/hicolor || true
51+
52+
echo "==> Stage files into pkgroot exactly as they'd be installed"
53+
sudo rm -rf "${PKGROOT}"
54+
sudo mkdir -p "${PKGROOT}"
55+
# NOTE: using sudo here mirrors your working sequence and avoids permission hiccups
56+
sudo DESTDIR="${PKGROOT}" cmake --install "${PKG_BUILD_DIR}"
57+
58+
echo "==> Remove any existing ${APP_NAME}*.deb (per your workflow)"
59+
sudo rm -f ${APP_NAME}*.deb || true
60+
61+
echo "==> Ensure fpm is available (ruby-dev, rubygems, build-essential required)"
62+
if ! command -v fpm >/dev/null 2>&1; then
63+
echo "!! fpm not found. Installing (needs sudo) ..."
64+
sudo apt-get update
65+
sudo apt-get install -y ruby-dev rubygems build-essential
66+
sudo gem install --no-document fpm
12667
fi
12768

128-
dpkg-deb --build "$WORK" "${DEB_OUT}/${APP_BIN_NAME}_${VERSION}_amd64.deb"
129-
echo "Built ${DEB_OUT}/${APP_BIN_NAME}_${VERSION}_amd64.deb"
69+
echo "==> Build .deb with fpm (using sudo as you did)"
70+
sudo fpm -s dir -t deb \
71+
-n "${APP_NAME}" -v "${APPVER}" -a "${ARCH}" \
72+
--description "${DESCRIPTION}" \
73+
--license "${LICENSE}" \
74+
--url "${HOMEPAGE}" \
75+
--vendor "${VENDOR}" \
76+
-C "${PKGROOT}" .
77+
78+
echo "==> Install the freshly built package (needs sudo)"
79+
DEB_FILE="${APP_NAME}_${APPVER}_${ARCH}.deb"
80+
sudo apt install ./"${DEB_FILE}"
81+
82+
echo "==> Make the .deb world-writable (per your convenience workflow)"
83+
sudo chmod a+rwx ${APP_NAME}*.deb || true
84+
85+
echo
86+
echo "✅ Done."
87+
echo "Package: ${DEB_FILE}"
88+
echo "Binary : ${INSTALL_PREFIX}/bin/${BINARY_NAME}"
89+
echo
90+
echo "Tip: Launch via '${BINARY_NAME}' or from your app menu (icon: org.mukulu.asante_typing)."

0 commit comments

Comments
 (0)