mirror of
https://github.com/Ralim/IronOS.git
synced 2025-07-23 04:13:01 +02:00
* scripts/deploy.sh: add handmade linter for translation-related json files to check for tabs and odd spaces
308 lines
10 KiB
Bash
Executable File
308 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# little helper for docker deployment to:
|
|
# - start development environment for IronOS ("shell" sub-command)
|
|
# - generate full set of builds ("build" sub-command)
|
|
# - probably doing some other routines (check source briefly before running undocumented commands!)
|
|
|
|
#set -x
|
|
#set -e
|
|
|
|
### helper functions
|
|
|
|
# brief help (some supported commands may be missing!)
|
|
usage()
|
|
{
|
|
echo -e "\nUsage: ${0} [CMD]\n"
|
|
echo "CMD (docker related):"
|
|
echo -e "\tshell - start docker container with shell inside to work on IronOS with all tools needed"
|
|
echo -e "\tbuild - compile builds of IronOS inside docker container for supported hardware"
|
|
echo -e "\tclean - delete created docker image for IronOS & its build cache objects\n"
|
|
echo "CMD (helper routines):"
|
|
echo -e "\tdocs - high level target to run docs_readme and docs_history (see below)\n"
|
|
echo -e "\tdocs_readme - generate & OVERWRITE(!) README.md inside Documentation/ based on nav section from mkdocs.yml if it changed\n"
|
|
echo -e "\tdocs_history - check if History.md has the changelog for the latest stable release\n"
|
|
echo -e "\tcheck_style_file SRC - run code style checks based on clang-format & custom parsers for source code file SRC\n"
|
|
echo -e "\tcheck_style_log - run clang-format using source/Makefile and generate gcc-compatible error log in source/check-style.log\n"
|
|
echo -e "STORAGE NOTICE: for \"shell\" and \"build\" commands extra files will be downloaded so make sure that you have ~5GB of free space.\n"
|
|
}
|
|
|
|
# Documentation/README.md automagical generation routine
|
|
docs_readme()
|
|
{
|
|
# WARNING: ON RUN Documentaion/README.md MAY BE OVERWRITTEN WITHOUT ANY WARNINGS / CONFIRMATIONS !!!
|
|
# Returns:
|
|
## 0 to the environment & silence - if there are no any changes in README.md nor updates in mkdocs.yml
|
|
## 1 to the environment (as error) & note message - if the update of README.md in repo is required
|
|
yml="scripts/IronOS-mkdocs.yml"
|
|
md_old="Documentation/README.md"
|
|
md_new="Documentation/README"
|
|
# ^^^^ hardcoded paths relative to IronOS/ to make this func very trivial
|
|
# file overwritten section looks out of style but hoping to make shellcheck happy
|
|
cat << EOF > "${md_new}"
|
|
|
|
<!-- THIS FILE IS AUTOGENERATED by "scripts/deploy.sh docs_readme" based on nav section in ${yml} config -->
|
|
<!-- THIS FILE IS NOT SUPPOSED TO BE EDITED MANUALLY -->
|
|
|
|
#### This is autogenerated README for brief navigation through github over official documentation for IronOS project
|
|
#### This documentation is also available [here online](https://ralim.github.io/IronOS)
|
|
|
|
EOF
|
|
# it probably will become unexplainable in a few months but so far it works:
|
|
sed '1,/^nav/d; /^ *$/,$d; s,- ,- [,; s,: ,](../Documentation/,; s,.md,.md),; s,:$,],; s,/Pinecil ,/Pinecil%20,; /^ - \[.*\]$/ s,\[,,; s,]$,,' "${yml}" >> "${md_new}"
|
|
ret=0
|
|
if [ -z "$(diff -q "${md_old}" "${md_new}")" ]; then
|
|
rm "${md_new}"
|
|
ret=0
|
|
else
|
|
mv "${md_new}" "${md_old}"
|
|
echo ""
|
|
echo "${yml} seems to be updated..."
|
|
echo "... while ${md_old} is out-of-date!"
|
|
echo ""
|
|
echo "Please, update ${md_old} in your local working copy by command:"
|
|
echo ""
|
|
echo " $ ./scripts/deploy.sh docs_readme"
|
|
echo ""
|
|
echo "And then commit & push changes to update ${md_old} in the repo:"
|
|
echo ""
|
|
echo " $ git commit ${md_old} -m \"${md_old}: update autogenerated file\" && git push"
|
|
echo ""
|
|
ret=1
|
|
fi;
|
|
return "${ret}"
|
|
}
|
|
|
|
# Documentation/History.md automagical changelog routine
|
|
docs_history()
|
|
{
|
|
md="Documentation/History.md"
|
|
ver_md="$(sed -ne 's/^## //1p' "${md}" | head -1)"
|
|
echo "Latest changelog: ${ver_md}"
|
|
ver_git="$(git tag -l | sort | grep -e "^v" | grep -v "rc" | tail -1)"
|
|
echo "Latest release tag: ${ver_git}"
|
|
ret=0
|
|
if [ "${ver_md}" != "${ver_git}" ]; then
|
|
ret=1
|
|
echo "It seems there is no changelog information for ${ver_git} in ${md} yet."
|
|
echo "Please, update changelog information in ${md}."
|
|
fi;
|
|
return "${ret}"
|
|
}
|
|
|
|
# Check for links to release builds in README.md
|
|
docs_links()
|
|
{
|
|
ver_git="$(git tag -l | sort | grep -e "^v" | grep -v "rc" | tail -1)"
|
|
md="README.md"
|
|
test -f "${md}" || (echo "deploy.sh: docs_links: ERROR with the project directory structure!" && exit 1)
|
|
ver_md="$(grep -c "${ver_git}" "${md}")"
|
|
ret=0
|
|
if [ "${ver_md}" -eq 0 ]; then
|
|
ret=1
|
|
echo "Please, update mention & links in ${md} inside Builds section for release builds with version ${ver_git}."
|
|
fi;
|
|
return "${ret}"
|
|
}
|
|
|
|
# source/Makefile:ALL_LANGUAGES & Translations/*.json automagical routine
|
|
build_langs()
|
|
{
|
|
mk="../source/Makefile"
|
|
cd Translations/ || (echo "deploy.sh: build_langs: ERROR with the project directory structure!" && exit 1)
|
|
langs="$(echo "$(find ./*.json | sed -ne 's,^\./translation_,,; s,\.json$,,; /[A-Z]/p' ; sed -ne 's/^ALL_LANGUAGES=//p;' "${mk}")" | sed 's, ,\n,g; s,\r,,g' | sort | uniq -u)"
|
|
if [ -n "${langs}" ]; then
|
|
echo "It seems there is mismatch between supported languages and enabled builds."
|
|
echo "Please, check files in Translations/ and ALL_LANGUAGES variable in source/Makefile for:"
|
|
echo "${langs}"
|
|
return 1
|
|
fi;
|
|
cd ..
|
|
|
|
echo -ne "\n"
|
|
grep -nH $'\11' Translations/translation*.json
|
|
ret="${?}"
|
|
if [ "${ret}" -eq 0 ]; then
|
|
echo -ne "\t^^^^\t^^^^\n"
|
|
echo "Please, remove any tabs as indention from json file(s) in Translations/ directory (see the exact files & lines in the list above)."
|
|
echo "Use spaces only to indent in the future, please."
|
|
echo -ne "\n"
|
|
return 1
|
|
fi;
|
|
|
|
grep -nEH -e "^( {1}| {3}| {5}| {7}| {9}| {11})[^ ]" Translations/translation*.json
|
|
ret="${?}"
|
|
if [ "${ret}" -eq 0 ]; then
|
|
echo -ne "\t^^^^\t^^^^\n"
|
|
echo "Please, remove any odd amount of extra spaces as indention from json file(s) in Translations/ directory (see the exact files & lines in the list above)."
|
|
echo "Use even amount of spaces to indent in the future, please (two actual spaces per one indent, not tab)."
|
|
echo -ne "\n"
|
|
return 1
|
|
fi;
|
|
|
|
return 0
|
|
}
|
|
|
|
# Helper function to check code style using clang-format & grep/sed custom parsers:
|
|
# - basic logic moved from source/Makefile : `check-style` target for better maintainance since a lot of sh script involved;
|
|
# - output goes in gcc-like error compatible format for IDEs/editors.
|
|
check_style_file()
|
|
{
|
|
ret=0
|
|
src="${1}"
|
|
test ! -f "${src}" && echo "ERROR!!! Provided file ${src} is not available to check/read!!!" && exit 1
|
|
# count lines using diff between beauty-fied file & original file to detect format issue
|
|
var="$(clang-format "$src" | diff "$src" - | wc -l)"
|
|
if [ "${var}" -ne 0 ]; then
|
|
# show full log error or, if LIST=anything provided, then show only filename of interest (implemented for debug purposes mainly)
|
|
if [ -z "${LIST}" ]; then
|
|
# sed is here only for pretty logging
|
|
clang-format "${src}" | diff "${src}" - | sed 's/^---/-------------------------------------------------------------------------------/; s/^< /--- /; s/^> /+++ /; /^[0-9].*/ s/[acd,].*$/ERROR1/; /^[0-9].*/ s,^,\n\n\n\n'"${src}"':,; /ERROR1$/ s,ERROR1$,:1: error: clang-format code style mismatch:,; '
|
|
else
|
|
echo "${src}"
|
|
fi;
|
|
ret=1
|
|
fi;
|
|
return "${ret}"
|
|
}
|
|
|
|
# check_style routine for those who too lazy to do it everytime manually
|
|
check_style_log()
|
|
{
|
|
log="source/check-style.log"
|
|
make -C source check-style 2>&1 | tee "${log}"
|
|
chmod 0666 "${log}"
|
|
sed -i -e 's,\r,,g' "${log}"
|
|
return 0
|
|
}
|
|
|
|
### main
|
|
|
|
docker_conf="Env.yml"
|
|
|
|
# get absolute location of project root dir to make docker happy with config(s)
|
|
# (successfully tested on relatively POSIX-compliant Dash shell)
|
|
|
|
# this script
|
|
script_file="/deploy.sh"
|
|
# IronOS/scripts/deploy.sh
|
|
script_path="${PWD}"/"${0}"
|
|
# IronOS/scripts/
|
|
script_dir=${script_path%"${script_file}"}
|
|
# IronOS/
|
|
root_dir="${script_dir}/.."
|
|
# IronOS/Env.yml
|
|
docker_file="-f ${root_dir}/${docker_conf}"
|
|
|
|
# allow providing custom path to docker tool using DOCKER_BIN external env. var.
|
|
# (compose sub-command must be included, i.e. DOCKER_BIN="/usr/local/bin/docker compose" ./deploy.sh)
|
|
|
|
if [ -z "${DOCKER_BIN}" ]; then
|
|
docker_app=""
|
|
else
|
|
docker_app="${DOCKER_BIN}"
|
|
fi;
|
|
|
|
# detect availability of docker
|
|
|
|
docker_compose="$(command -v docker-compose)"
|
|
if [ -n "${docker_compose}" ] && [ -z "${docker_app}" ]; then
|
|
docker_app="${docker_compose}"
|
|
fi;
|
|
|
|
docker_tool="$(command -v docker)"
|
|
if [ -n "${docker_tool}" ] && [ -z "${docker_app}" ]; then
|
|
docker_app="${docker_tool} compose"
|
|
fi;
|
|
|
|
# give function argument a name
|
|
|
|
cmd="${1}"
|
|
|
|
# meta target to verify markdown documents
|
|
|
|
if [ "docs" = "${cmd}" ]; then
|
|
docs_readme
|
|
readme="${?}"
|
|
docs_history
|
|
hist="${?}"
|
|
build_langs
|
|
langs="${?}"
|
|
docs_links
|
|
links="${?}"
|
|
if [ "${readme}" -eq 0 ] && [ "${hist}" -eq 0 ] && [ "${langs}" -eq 0 ] && [ "${links}" -eq 0 ]; then
|
|
ret=0
|
|
else
|
|
ret=1
|
|
fi;
|
|
exit ${ret}
|
|
fi;
|
|
|
|
# if only README.md for Documentation update is required then run it & exit
|
|
|
|
if [ "docs_readme" = "${cmd}" ]; then
|
|
docs_readme
|
|
exit "${?}"
|
|
fi;
|
|
|
|
# if only History.md for Documentation update is required then run it & exit
|
|
|
|
if [ "docs_history" = "${cmd}" ]; then
|
|
docs_history
|
|
exit "${?}"
|
|
fi;
|
|
|
|
if [ "build_langs" = "${cmd}" ]; then
|
|
build_langs
|
|
exit "${?}"
|
|
fi;
|
|
|
|
if [ "docs_links" = "${cmd}" ]; then
|
|
docs_links
|
|
exit "${?}"
|
|
fi;
|
|
|
|
if [ "check_style_file" = "${cmd}" ]; then
|
|
check_style_file "${2}"
|
|
exit "${?}"
|
|
fi;
|
|
|
|
if [ "check_style_log" = "${cmd}" ]; then
|
|
check_style_log
|
|
exit "${?}"
|
|
fi;
|
|
|
|
# if docker is not presented in any way show warning & exit
|
|
|
|
if [ -z "${docker_app}" ]; then
|
|
echo "ERROR: Can't find docker-compose nor docker tool. Please, install docker and try again."
|
|
exit 1
|
|
fi;
|
|
|
|
# construct command to run
|
|
|
|
if [ -z "${cmd}" ] || [ "${cmd}" = "shell" ]; then
|
|
docker_cmd="run --rm builder"
|
|
elif [ "${cmd}" = "build" ]; then
|
|
docker_cmd="run --rm builder make build-all OUT=${OUT}"
|
|
elif [ "${cmd}" = "clean" ]; then
|
|
docker rmi ironos-builder:latest
|
|
docker system prune --filter label=ironos-builder:latest --force
|
|
exit "${?}"
|
|
else
|
|
usage
|
|
exit 1
|
|
fi;
|
|
|
|
# change dir to project root dir & run constructed command
|
|
|
|
cd "${root_dir}" || exit 1
|
|
echo -e "\n====>>>> Firing up & starting container..."
|
|
if [ "${cmd}" = "shell" ]; then
|
|
echo -e "\t* type \"exit\" to end the session when done;"
|
|
fi;
|
|
echo -e "\t* type \"${0} clean\" to delete created container (but not cached data)"
|
|
echo -e "\n====>>>> ${docker_app} ${docker_file} ${docker_cmd}\n"
|
|
eval "${docker_app} ${docker_file} ${docker_cmd}"
|
|
exit "${?}"
|