11 Commits
24.04 ... 24.06

7 changed files with 470 additions and 25 deletions

View File

@ -1,5 +1,5 @@
SUBDIRS := $(wildcard */.) SUBDIRS := $(wildcard */.)
VERSION = 24.04 VERSION = 24.06
install: install:
@for dir in $(SUBDIRS) ; do \ @for dir in $(SUBDIRS) ; do \

View File

@ -8,12 +8,13 @@ Following dependencies are required for these scripts and tools:
- bash - bash
- coreutils - coreutils
- gcc
- make - make
- grep
- GRUB (please see matter-iso warning) - GRUB (please see matter-iso warning)
- gnupg - gnupg
- fakeroot - fakeroot
- (GNU) tar - (GNU) tar
- (GNU) cpio
- [matt](https://git.matterlinux.xyz/Matter/matt) - [matt](https://git.matterlinux.xyz/Matter/matt)
After installing these dependencies, all the tools and scripts After installing these dependencies, all the tools and scripts
@ -31,4 +32,5 @@ All tools/scripts contains usage information in README files:
- [matter-base](matter-base/README.md) - [matter-base](matter-base/README.md)
- [matter-iso](matter-iso/README.md) - [matter-iso](matter-iso/README.md)
- [mp-build](mp-build/README.md) - [mp-build](mp-build/README.md)
- [mp-check](mp-check/README.md)
- [mp-pool](mp-pool/README.md) - [mp-pool](mp-pool/README.md)

View File

@ -65,7 +65,7 @@ check_iso_vars() {
return 1 return 1
elif [ ! -n "$VERSION" ]; then elif [ ! -n "$VERSION" ]; then
return 1 return 1
elif ! type build &>/dev/null; then elif ! type BUILD &>/dev/null; then
return 1 return 1
fi fi
@ -78,8 +78,9 @@ check_iso_vars() {
if ! type "grub-mkrescue" > /dev/null; then if ! type "grub-mkrescue" > /dev/null; then
error "You need to install GRUB to create ISO files with grub-mkrescue" error "You need to install GRUB to create ISO files with grub-mkrescue"
set_indent set_indent
info "If you want to create UEFI ISO files make sure you install x64 GRUB or grub-efi" warn "If you want to create UEFI ISO files make sure you install x64 GRUB or grub-efi"
info "If you want to create BIOS ISO files make sure you install x86 GRUB or grub-bios" warn "If you want to create BIOS ISO files make sure you install x86 GRUB or grub-bios"
warn "After installing GRUB, don't forget to install libisoburn as well"
exit 1 exit 1
fi fi
@ -191,7 +192,7 @@ if [ ! -z "${PKGS1}" ]; then
fi fi
info "Running build script" info "Running build script"
echo "source /iso.sh && build" > "${tmpdir}/stager.sh" echo "source /iso.sh && BUILD" > "${tmpdir}/stager.sh"
matter-chroot "${tmpdir}" chmod +x /stager.sh matter-chroot "${tmpdir}" chmod +x /stager.sh
matter-chroot "${tmpdir}" /stager.sh matter-chroot "${tmpdir}" /stager.sh
check_ret "Build script failed" check_ret "Build script failed"

View File

@ -105,26 +105,32 @@ clean_dist() {
rm -f "${distpath}/files.tar.gz" rm -f "${distpath}/files.tar.gz"
} }
# checks/installs a list of depends # install a list of packages with matt
check_depends() { matt_install(){
local list=("$@")
if [ "${#list[@]}" == "0" ]; then
info "Got zero depends, skipping depend check"
return 0
fi
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
if type doas > /dev/null; then if type doas > /dev/null; then
DOAS="doas" DOAS="doas"
elif type sudo > /dev/null; then elif type sudo > /dev/null; then
DOAS="sudo" DOAS="sudo"
else else
error "Failed to find doas or sudo, skipping depend check" error "Failed to find doas or sudo, cannot run the install command"
return 0 return 1
fi fi
fi fi
$DOAS matt install --yes --skip --ignore-none $@
return $?
}
# checks and installs a list of depends
check_depends() {
local list=("$@")
if [ "${#list[@]}" == "0" ]; then
info "Got zero depends, skipping depend check"
return 0
fi
for dep in "${list[@]}"; do for dep in "${list[@]}"; do
if [ -z "${depends_str}" ]; then if [ -z "${depends_str}" ]; then
depends_str="${dep}" depends_str="${dep}"
@ -133,12 +139,12 @@ check_depends() {
fi fi
done done
depends_uniq=$(echo "${depends_str}" | tr ' ' '\n' | sort | uniq) depends_uniq="$(echo "${depends_str}" | tr ' ' '\n' | sort | uniq)"
depends_count=$(echo "${depends_uniq}" | wc -l) depends_count="$(echo "${depends_uniq}" | wc -l)"
depends_uniq=$(echo "${depends_uniq}" | tr '\n' ' ') depends_uniq="$(echo "${depends_uniq}" | tr '\n' ' ')"
info "Installing ${depends_count} depends" info "Installing ${depends_count} depends"
$DOAS matt install --yes --skip --ignore-none $depends_uniq matt_install $depends_uniq
return $? return $?
} }
@ -202,10 +208,12 @@ if [ ! -d "${TARGET}" ]; then
fi fi
if [ $OPT_NO_DEPEND -eq 0 ] && ! command -v matt &> /dev/null; then if [ $OPT_NO_DEPEND -eq 0 ] && ! command -v matt &> /dev/null; then
error "!!! BUILD ON MATTERLINUX !!!" error "BUILD ON MATTERLINUX!"
error "matt is not installed, please build on a MatterLinux system" set_indent
error "Do NOT create bug reports if build fails on non-MatterLinux systems" warn "matt is not installed, please build on a MatterLinux system"
warn "Do NOT create bug reports if build fails on non-MatterLinux systems"
info "Auto enabling NO_DEPEND as depend check will fail without matt" info "Auto enabling NO_DEPEND as depend check will fail without matt"
unset_indent
OPT_NO_DEPEND=1 OPT_NO_DEPEND=1
fi fi
@ -277,8 +285,21 @@ all_depends+=("${DEPENDS[@]}")
all_depends+=("${BUILD[@]}") all_depends+=("${BUILD[@]}")
if [ $OPT_NO_DEPEND -eq 0 ]; then if [ $OPT_NO_DEPEND -eq 0 ]; then
info "Checking all the dependencies"
set_indent
is_essential_installed="$(matt info build-essential --grep | grep INSTALLED)"
is_essential_installed="$(echo "${is_essential_installed}" | cut -d: -f2)"
if [ "${is_essential_installed}" == "0" ]; then
info "Installing build-essential (required for every build)"
matt_install build-essential
check_ret "Failed to install build-essential package"
fi
check_depends "${all_depends[@]}" check_depends "${all_depends[@]}"
check_ret "Failed to check all the dependencies" check_ret "Failed to check all the dependencies"
unset_indent
fi fi
# make sure file count and the hash count is the same # make sure file count and the hash count is the same
@ -417,7 +438,7 @@ success "(3/6) Created the changes file (CHANGES)"
# create the install script # create the install script
if type INSTALL &>/dev/null; then if type INSTALL &>/dev/null; then
echo "$(type INSTALL | head -n-1 | tail -n-2 | sed 's/ //')" > "${distpath}/INSTALL" echo "$(type INSTALL | head -n-1 | sed '1,3d' | sed 's/ //')" > "${distpath}/INSTALL"
check_ret "(4/6) Failed to create the install script (INSTALL)" check_ret "(4/6) Failed to create the install script (INSTALL)"
fi fi
success "(4/6) Created the install script (INSTALL)" success "(4/6) Created the install script (INSTALL)"

9
mp-check/Makefile Normal file
View File

@ -0,0 +1,9 @@
PREFIX = /usr
install:
install -Dm755 "mp-check.sh" $(DESTDIR)/$(PREFIX)/bin/mp-check
uninstall:
rm $(DESTDIR)/$(PREFIX)/bin/mp-check
.PHONY: install uninstall

15
mp-check/README.md Normal file
View File

@ -0,0 +1,15 @@
# mp-check | MatterLinux package check script
A simple script to check MatterLinux package archives and sources
for common errors and mistakes.
### Usage
To check a package archive, specify the path for the archive:
script:
```bash
mp-check /path/to/package_version.mpf
```
You can also check for package sources files by specifying the
path for the package source directory:
```bash
mp-check /path/to/package/source
```

397
mp-check/mp-check.sh Executable file
View File

@ -0,0 +1,397 @@
#!/bin/bash
# mp-check | MatterLinux package check script
# MatterLinux 2023-2024 (https://matterlinux.xyz)
# 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/>.
#############################
## import common functions ##
#############################
location=$(dirname "${0}")
location=$(realpath "${location}")
commonsh="$(echo "${location}" | sed 's/\/bin/\/lib/g')/mtsc-common.sh"
source "${commonsh}" > /dev/null
if [ "${?}" != "0" ]; then
echo "Failed to import mtsc-common"
exit 1
fi
#################
## global vars ##
#################
warnc=0
tmpdir="/tmp/.mp-clean"
required_files=(
"DATA"
"HASHES"
"CHANGES"
"files.tar.gz"
)
required_keys=(
"version"
"desc"
"size"
)
root_dirs=(
"boot"
"etc"
"mnt"
"srv"
"usr"
"var"
"opt"
)
bad_vars=(
'$VERSION'
'$ROOTDIR'
'$NAME'
'$DESC'
)
####################
## util functions ##
####################
# prints the help info
help_cmd() {
info "MatterLinux package check script (mtsc ${MTSC_VERSION})" # sourced from mtsc-common
info "Usage: ${0} <options> [archive file/source dir]"
info "Options:"
echo_color " $BOLD--checkpoint$RESET: specify a starting point for the check"
echo_color " $BOLD--fail-warn$RESET: fail on a warning"
echo_color " $BOLD--no-warn$RESET: ignore warnings"
echo
info "Licensed under GPLv3, see <https://www.gnu.org/licenses/> for more information"
}
# adds a new warning to the counter
add_warning(){
[ $OPT_NO_WARN -eq 1 ] && return
warn "${1}"
warnc=$((warnc+1))
[ $OPT_FAIL_WARN -eq 1 ] && fail_check
}
# cleans up the temp directoru
clean_tempdir(){
rm -rf "${tmpdir}"
}
# recreates the temp directory
make_tempdir(){
clean_tempdir
mkdir "${tmpdir}"
}
# returns check status fail
fail_check(){
clean_tempdir
unset_indent
error "${BOLD}Check ${RED}FAILED${RESET}"
exit 1
}
# returns check status fail
success_check(){
clean_tempdir
unset_indent
if [ "${warnc}" == "0" ]; then
success "Check ${GREEN}SUCCESS${RESET}"
elif [ "${warnc}" == "1" ]; then
success "Check ${GREEN}SUCCESS${RESET}${BOLD} with ${YELLOW}${warnc}${RESET}${BOLD} warning${RESET}"
else
success "Check ${GREEN}SUCCESS${RESET}${BOLD} with ${YELLOW}${warnc}${RESET}${BOLD} warnings${RESET}"
fi
exit 0
}
# if the last command failed, print error and fail
check_ret_fail(){
if [ $? -ne 0 ]; then
if [ ! -z "$1" ]; then
error "$1"
fi
fail_check
fi
}
check_archive(){
make_tempdir
info "Extracting the archive"
tar xf "${archivepath}" -C "${tmpdir}"
check_ret_fail "Failed to extract the archive"
info "Checking archive files"
for f in "${required_files[@]}"; do
if [ ! -f "${tmpdir}/${f}" ]; then
error "Archive does not contain required file: ${BOLD}${f}${RESET}"
fail_check
fi
done
info "Checking DATA file"
for k in "${required_keys[@]}"; do
local line_1="$(grep "^${k}=" "${tmpdir}/DATA")"
local line_2="$(grep "^${k} =" "${tmpdir}/DATA")"
if [ -z "${line_1}" ] && [ -z "${line_2}" ]; then
error "File does not contain the required key: ${BOLD}${k}${RESET}"
fail_check
fi
if [ "${k}" == "version" ]; then
if [ ! -z "${line_1}" ]; then
version="$(echo "${line_1}" | sed 's/version= //g')"
version="$(echo "${version}" | sed 's/version=//g')"
else
version="$(echo "${line_2}" | sed 's/version = //g')"
version="$(echo "${version}" | sed 's/version =//g')"
fi
if [ -z "${version}" ]; then
error "Failed to obtain package version information"
fail_check
fi
fi
done
name="$(head -n1 "${tmpdir}/DATA" | sed 's/\[//g')"
name="$(echo "${name}" | sed 's/]//g')"
if [ -z "${name}" ]; then
error "Failed to obtain package name information"
fail_check
fi
filename="${name}_${version}.mpf"
info "Checking HASHES file"
while read l; do
if [ -z "${l}" ]; then
continue
fi
local hash_line="$(echo "${l}" | cut -d' ' -f1)"
local file_line="$(echo "${l}" | cut -d' ' -f3)"
if [ -z "${hash_line}" ] || [ -z "${file_line}" ]; then
error "File contains an invalid formatted line"
fail_check
fi
if [ "${#hash_line}" != "32" ]; then
error "File contains an invalid MD5 hash"
fail_check
fi
done < "${tmpdir}/HASHES"
info "Checking files.tar.gz archive"
while read p; do
if [ "${p:0:1}" == "." ] || [ "${p:0:1}" == "/" ]; then
error "Root file location is invalid (${p:0:1})"
fail_check
fi
local path_root="$(echo "${p}" | cut -d/ -f1)"
local found=0
for d in "${root_dirs[@]}"; do
if [ "${path_root}" == "${d}" ]; then
found=1
break
fi
done
if [ "${found}" == "0" ]; then
error "Package files contains an unknown root directory: ${path_root}"
fail_check
fi
done < <(tar tf "${tmpdir}/files.tar.gz")
info "Checking INSTALL file"
if [ -f "${tmpdir}/INSTALL" ] && ! grep -q . "${tmpdir}/INSTALL"; then
add_warning "Package contains an empty install script"
fi
info "Checking CHANGES file"
if ! grep -q . "${tmpdir}/CHANGES"; then
add_warning "Changes file is empty"
fi
info "Checking archive name"
archivefile="$(basename "${archivepath}")"
if [ "${archivefile}" != "${filename}" ]; then
add_warning "Package archive name is not ideal (${archivefile} -> ${filename})"
fi
clean_tempdir
}
check_source(){
info "Checking the package script"
if [ ! -f "${sourcepath}/pkg.sh" ]; then
error "Package script does not exist"
fail_check
fi
source "${sourcepath}/pkg.sh"
check_ret_fail "Failed to source the package script"
check_pkg_vars
check_ret_fail
if [ ${#DESC} -gt 200 ]; then
error "Package description is too long (>200)"
fail_check
fi
local desc_lower="${DESC,,}"
local line_num=0
if [[ "${DESC}" == *"contains"* ]] || [[ "${DESC}" == *"provides"* ]]; then
add_warning "Avoid using words such as \"contains\" or \"provides\" in the package description"
fi
if type INSTALL &>/dev/null; then
for v in "${bad_vars[@]}"; do
if type INSTALL | grep "${v}" &> /dev/null; then
error "${v} used in the install script"
fail_check
fi
done
fi
while read l; do
line_num=$((line_num+1))
for v in "${bad_vars[@]}"; do
if echo "${l}" | grep "${v}" &> /dev/null; then
add_warning "${v} used without parenthesis on line ${line_num}"
fi
done
if echo "${l}" | grep '&&' | grep -v 'cd ..' &> /dev/null; then
add_warning "Unreliable use of \"&&\" on line ${line_num}"
fi
done < "${sourcepath}/pkg.sh"
info "Checking the changes file"
if [ ! -f "${sourcepath}/changes.md" ]; then
error "Package does not contain a changes file"
fail_check
fi
if ! grep -q . "${sourcepath}/changes.md"; then
add_warning "Changes file is empty"
fi
}
#################
## main script ##
#################
OPT_CHECKPOINT=""
OPT_FAIL_WARN=0
OPT_NO_WARN=0
OPT_TARGET=()
for arg in "$@"; do
case $arg in
"--help")
help_cmd
exit 0 ;;
"--checkpoint"*)
OPT_CHECKPOINT="$(echo "${arg}" | cut -d '=' -f2)" ;;
"--fail-warn")
OPT_FAIL_WARN=1 ;;
"--no-warn")
OPT_NO_WARN=1 ;;
--*)
error "Unknown option: ${arg}"
exit 1 ;;
*)
OPT_TARGET+=("${arg}") ;;
esac
done
if [ -z "${OPT_TARGET}" ]; then
error "Please specify at least one package archive or a source directory, run --help for more info"
exit 1
fi
if [ $OPT_FAIL_WARN -eq 1 ] && [ $OPT_NO_WARN -eq 1 ]; then
error "Cannot use both of the --fail-warn and --no-warn options"
exit 1
fi
info "Running mp-check with the options:"
if [ -z "${OPT_CHECKPOINT}" ]; then
print " $BOLD CHECKPOINT = NONE"
else
print " $BOLD CHECKPOINT = ${OPT_CHECKPOINT}"
fi
print " $BOLD FAIL_WARN = $(itoyn $OPT_FAIL_WARN)"
print " $BOLD NO_WARN = $(itoyn $OPT_NO_WARN)"
for target in "${OPT_TARGET[@]}"; do
if [ ! -f "${target}" ] && [ ! -d "${target}" ]; then
error "Specified path is invalid: ${target}"
exit 1
fi
done
tc="${#OPT_TARGET[@]}"
got_checkpoint=0
ti=0
for target in "${OPT_TARGET[@]}"; do
unset_indent
ti=$((ti + 1))
if [ -z "${OPT_CHECKPOINT}" ] || [ "${target}" == "${OPT_CHECKPOINT}" ]; then
got_checkpoint=1
fi
[ $got_checkpoint -eq 0 ] && continue
if [ -f "${target}" ]; then
info "(${ti}/${tc}) Checking the archive: ${target}"
set_indent
archivepath="$(realpath "${target}")"
check_archive
elif [ -d "${target}" ]; then
info "(${ti}/${tc}) Checking the source directory: ${target}"
set_indent
sourcepath="$(realpath "${target}")"
check_source
fi
done
success_check