Last active
June 20, 2025 15:05
-
-
Save Guiorgy/c3a38ddb9b6f0e6284891388065b971f to your computer and use it in GitHub Desktop.
Download the latest, or a specified, Fastfetch release source and build a DEB package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Copyright © 2024 Guiorgy | |
# | |
# 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. | |
# | |
# You can see the full GNU General Public License at | |
# <https://www.gnu.org/licenses/> for more details. | |
# usage examples: | |
# $ ./build.sh | |
# $ ./build.sh 2.7.0 | |
set -Eeo pipefail # exit on error | |
handle_error() { | |
error_code=$? | |
echo -e "${RED}Script failed on line #${1} with error code ${error_code}!${NOCOLOR}" 1>&2 | |
cleanup | |
exit $error_code | |
} | |
trap 'handle_error $LINENO' ERR | |
# colors for colored output | |
NOCOLOR='\033[0m' | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[0;33m' | |
BLUE='\033[0;34m' | |
PURPLE='\033[0;35m' | |
CYAN='\033[0;36m' | |
WHITE='\033[0;37m' | |
error() { | |
echo -e "${RED}Error${NOCOLOR}: ${1}" 1>&2 | |
cleanup | |
if [[ -n "$2" ]]; then | |
exit "$2" | |
else | |
exit 1 | |
fi | |
} | |
information() { | |
COLOR="$YELLOW" | |
if [ $# -gt 1 ]; then | |
case "$1" in | |
--*) | |
case "$1" in | |
--no-color) COLOR="$NOCOLOR" ;; | |
--red) COLOR="$RED" ;; | |
--green) COLOR="$GREEN" ;; | |
--yellow) COLOR="$YELLOW" ;; | |
--blue) COLOR="$BLUE" ;; | |
--purple) COLOR="$PURPLE" ;; | |
--cyan) COLOR="$CYAN" ;; | |
--white) COLOR="$WHITE" ;; | |
*) error 'Unrecognized color' ;; | |
esac | |
shift | |
;; | |
*) ;; | |
esac | |
fi | |
if [[ $# -gt 1 ]]; then | |
if [[ -n "$1" ]]; then | |
echo -e -n "${COLOR}${1}${NOCOLOR}: " | |
fi | |
shift | |
else | |
echo -e -n "${COLOR}Information${NOCOLOR}: " | |
fi | |
echo -e "$1" | |
} | |
cleanupAttempted=0 | |
cleanup() { | |
if [[ $cleanupAttempted -eq 1 ]]; then | |
return | |
fi | |
cleanupAttempted=1 | |
# return to the initial working directory | |
cd "$workingDirectory" | |
if [[ -f "${releaseTag}.tar.gz" ]]; then | |
information 'Cleanup' "Removing the downloaded source archive '${BLUE}${releaseTag}.tar.gz${NOCOLOR}'" | |
rm "${releaseTag}.tar.gz" | |
fi | |
if [[ -d "fastfetch-${releaseTag}" ]]; then | |
information 'Cleanup' "Removing the extracted source directory '${BLUE}fastfetch-${releaseTag}${NOCOLOR}'" | |
rm -rf "fastfetch-${releaseTag}" | |
fi | |
} | |
# remember the current working directory for cleanup | |
workingDirectory=$(pwd) | |
# check if cmake is available | |
if ! command -v cmake &>/dev/null; then | |
error "CMake is not installed. Run '${BLUE}sudo apt install cmake${NOCOLOR}' to install" | |
fi | |
# check if curl is available | |
if ! command -v curl &>/dev/null; then | |
error "Curl is not installed. Run '${BLUE}sudo apt install curl${NOCOLOR}' to install" | |
fi | |
# check if a specific release tag was passed as the first argument | |
releaseTag="$1" | |
if [[ -z "$releaseTag" ]]; then | |
information '' 'Getting the latest release tag from github' | |
response=$(curl --silent --show-error 'https://api.github.com/repos/fastfetch-cli/fastfetch/releases/latest') | |
releaseTag=$(grep -m 1 '"tag_name"' <<< "$response" | cut -d : -d '"' -f 4) \ | |
|| error "Failed to grep the release tag. Response: ${BLUE}${response}${NOCOLOR}" | |
information '' "Latest release tag: ${BLUE}${releaseTag}${NOCOLOR}" | |
fi | |
# validate that the release tag is in the format "x.y.z" | |
if ! [[ "$releaseTag" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
error "The specified release tag '${BLUE}${releaseTag}${NOCOLOR}' is not in the correct format" | |
fi | |
# get the list of already built tags | |
builtTags=$(find . -mindepth 1 -maxdepth 1 -type f -name '*.deb') | |
if [[ -n "$builtTags" ]]; then | |
builtTags=$( \ | |
echo "$builtTags" \ | |
| grep -o 'fastfetch-[0-9]\+\.[0-9]\+\.[0-9]\+-Linux.deb' \ | |
| cut -d - -f 2 \ | |
) | |
# check if the specified release tag is already built | |
if [[ "$builtTags" =~ "$releaseTag" ]]; then | |
information --yellow "Already Built" "Release tag '${BLUE}${releaseTag}${NOCOLOR}' already built" | |
exit 0 | |
fi | |
fi | |
# download source archive | |
# - s: don't show progress | |
# - S: show errors | |
# - L: follow redirects | |
# - O: keep same file name | |
curl -sSLO "https://github.com/fastfetch-cli/fastfetch/archive/refs/tags/${releaseTag}.tar.gz" || error "Failed to download release '${BLUE}${releaseTag}${NOCOLOR}'" | |
# extract the tar.gz archive | |
# - x: extract | |
# - v: verbose output | |
# - z: use gzip | |
# - f: archive file path | |
tar -xvzf "${releaseTag}.tar.gz" || error 'Failed to unpack the source archive' | |
# cd into the extracted directory | |
cd "fastfetch-${releaseTag}" | |
# # modify the package target of CMakeLists.txt to only build a DEB package | |
# sed -i \ | |
# -e 's/set(CPACK_GENERATOR ".*")/set(CPACK_GENERATOR "DEB")/g' \ | |
# CMakeLists.txt \ | |
# || error 'Failed to modify CMakeList.txt' | |
# create a build directory and cd into it | |
mkdir -p build | |
cd build | |
# build the package | |
cmake .. \ | |
-DENABLE_SYSTEM_YYJSON=OFF \ | |
-DENABLE_ASAN=OFF \ | |
-DENABLE_LTO=ON \ | |
-DBUILD_FLASHFETCH=OFF \ | |
-DBUILD_TESTS=OFF \ | |
-DSET_TWEAK=OFF \ | |
-DIS_MUSL=OFF \ | |
-DINSTALL_LICENSE=ON \ | |
-DENABLE_EMBEDDED_PCIIDS=OFF \ | |
|| error 'Failed to generate a CMake project build system' | |
# cmake --build . --target package || error 'Failed to build package using CMake' | |
cpack --verbose -G DEB || error 'Failed to build package using CMake' | |
# find the built package for the current platform | |
package=$(find . -maxdepth 1 -type f -name 'fastfetch-*.deb') \ | |
|| error "Failed to find the built package in -e$(ls | sed -e $'s/^/\t/')" | |
# move the built package to the initial working directory | |
mv "$package" ../../"fastfetch-${releaseTag}-Linux.deb" \ | |
|| error "Failed to move the built package '$package' from:\n$(ls | sed -e $'s/^/\t/')\nto:\n$(ls | sed -e $'s/^/\t/')" | |
# remove downloaded source files and build artifacts | |
cleanup | |
# print the done message and instructions to install | |
information --green 'Done' "Successfully built ${BLUE}fastfetch-${releaseTag}-Linux.deb${NOCOLOR}" | |
information '' "Run '${BLUE}sudo apt install ./fastfetch-${releaseTag}-Linux.deb${NOCOLOR}' to install" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The script dumps the built packages in the working directory and expects the user to manually install the package.
You may modify the script to automatically run
apt install ./fastfetch-[TAG]-Linux.deb
, but instead you may prefer to crate a local package repository and add it to the apt sources:dpkg-dev
if you don't have it/etc/apt/sources.list.d/
deb [trusted=yes] file:/[PATH_TO_THE_DIRECTORY_WITH_THE_BUILD_SCRIPT] ./
dpkg-scanpackages
warnings on missing override file/dev/null
After doing the above and updating apt (
apt update
) you may simply install/upgrade fastfetch as if it were a normal packageapt list -a fastfetch
apt install fastfetch
apt install --only-upgrade fastfetch