live-build/functions/stagefile.sh

112 lines
2.4 KiB
Bash
Raw Normal View History

2007-09-23 08:04:46 +00:00
#!/bin/sh
## live-build(7) - System Build Scripts
## Copyright (C) 2016-2020 The Debian Live team
## Copyright (C) 2006-2015 Daniel Baumann <mail@daniel-baumann.ch>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.
2007-09-23 08:04:46 +00:00
# Get the default filename for a script's stagefile (the name of the script
# file itself). A suffix can be appended via providing as a param.
Stagefile_name ()
{
local SUFFIX="${1}"
local FILENAME
FILENAME="$(basename $0)"
echo ${FILENAME}${SUFFIX:+.$SUFFIX}
}
2007-09-23 08:04:46 +00:00
Check_stagefile ()
{
local FILE
local NAME
FILE=".build/${1:-$(Stagefile_name)}"
NAME="$(basename ${FILE})"
2007-09-23 08:04:46 +00:00
# Checking stage file
if [ -f "${FILE}" ]; then
if [ "${_FORCE}" != "true" ]; then
# Skip execution
Echo_warning "Skipping %s, already done" "${NAME}"
2007-09-23 08:04:48 +00:00
exit 0
2007-09-23 08:04:51 +00:00
else
# Force execution
Echo_message "Forcing %s" "${NAME}"
2007-09-23 08:04:51 +00:00
rm -f "${FILE}"
2007-09-23 08:04:48 +00:00
fi
2007-09-23 08:04:46 +00:00
fi
}
# Used by chroot preperation scripts in removal mode
Ensure_stagefile_exists ()
{
local FILE
local NAME
FILE=".build/${1:-$(Stagefile_name)}"
NAME="$(basename ${FILE})"
# Checking stage file
if [ ! -f "${FILE}" ]; then
if [ "${_FORCE}" != "true" ]; then
# Skip execution
Echo_warning "Skipping removal of %s, it is not applied" "${NAME}"
exit 0
else
# Force execution
Echo_message "Forcing %s" "${NAME}"
fi
fi
}
2007-09-23 08:04:46 +00:00
Create_stagefile ()
{
local FILE
local DIRECTORY
FILE=".build/${1:-$(Stagefile_name)}"
DIRECTORY="$(dirname ${FILE})"
2007-09-23 08:04:46 +00:00
# Creating stage directory
2007-09-23 08:05:11 +00:00
mkdir -p "${DIRECTORY}"
2007-09-23 08:04:46 +00:00
# Creating stage file
2007-09-23 08:04:49 +00:00
touch "${FILE}"
2007-09-23 08:04:46 +00:00
}
Remove_stagefile ()
{
local FILE
FILE=".build/${1:-$(Stagefile_name)}"
rm -f "${FILE}"
}
stagefiles: fix completely wrong require-stages logic now having investigated my suspicions of the functionality and use of Require_stagefile(), i conclude that it has been fundamentally broken all the way back to v1.0~a8-1 (or at least usage of it since v1.0.1-2). gah. (╯°□°)╯︵ ┻━┻ ---- very early on in the history of live-build this function took the name of a _single_ stage file only and did `exit 1` should the file not be found. this was simple and clearly accomplished "what was on the tin", so to speak. in bd1a5ddc8203907eb40135303bea5488397ec5d0 (2007, 1.0~a8-1) things got weird. it was modified to support a list of multiple files. but instead of being written to cause failure if _any_ of the listed files were missing as perhaps one might expect, it was instead written to fail only if all files were missing! if you jump to the conclusion that i'm talking about a simple flipped logic from a lack or otherwise of a `!` here, you'd be mistaken; there is a comment inside the function that could not be more clear about what was intended by the author - "Find at least one of the required stages"! this makes me thoroughly confused about what they were thinking. as we'll get to, this was fundamentally flawed (or at least its later use was), but furthermore there were other notable issues introduced at this point (but don't worry too much about these, they've all been addressed): - `NAME` was modified in the loop, using the existing value, but nothing initially set it... - the setting of `NAME` seems related to its use in the subsequent error output, yet they are logically separated; it is only set if a file exists, while the error is only printed if none exist. - it is pointlessly using a messy `CONTINUE="true"` based mechanism, when it could just `return 0`. - it did not handle correctly the bad use case of no params having been supplied. it doesn't seem to have been entirely thought through, despite its pervasive use throughout the build system. note that no change was made in that commit to make actual use of the new multi-param support. it would not be used until about a year later. the function has remained largely untouched since then. in c68c0a270832ca340429878ce6a0ab606d435b06 a notable change was made to add an initial setting of `NAME`, which partially addressed one of the above issues. but it did not really address the issue the change was meant to solve, since the `NAME` as printed in the error was now the name of the script when what was really wanted was the name of the stagefile. this was finally fixed properly in d54990695f334d205fa846c42b6e0f2afd3c47f5. however the weirdly pointless setting of `NAME` persisted in the loop. finally i personally just refactored the function in the commit prior to this one, retaining the same functionality but addressing the remaining of the above minor implementation issues. looking at usage of the new functionality introduced in bd1a5ddc8203907eb40135303bea5488397ec5d0, it does not seem to have been until 0cbbde2b9664b9fafb311f1048db25ea69952222 (2008, almost a year after it was made possible) that changes were made to finally start making use of the ability to pass more than one filename at a time to the function, and it would appear that perhaps the author forgot what it actually was that the function accomplished when used with multiple params, and failed to double check. in this first use of multiple parameters, this commit went from passing single file names to individual calls to the function to passing the files in one single call, in a commit the purpose of which was described as simply tidying things up. it was most certainly not intended to change stage requirements. unfortunately, a change in requirements did occur as a result since the new usage of the function was not accomplishing the same as before. this change completely broke the stage requirements protection mechanism such that only a single one of the listed stages needed to have completed for the check to pass, rather than all as expected. this flaw made it into release v1.0.1-2 and it has existed every since. in the very next commit from that one, 6204dc0e6db02859a07a978d87f1a5231c0214cf things got even worse. here we see the config stage being specified commonly as the first stage listed, which is still the case today. this means that ever since this commit, if you've already got a config before building (which you inevitably do, especially after some later commits introduced automatically creating it if missing), then all other stage requirements are simply ignored. so it seems pretty damn clear that this function is accomplishing completely the wrong objective. it _should_ be checking that _all_ files given to it exist, not just one or more. ¯\_(ツ)_/¯ this FINALLY addresses this mistake. (not that i wish to berate the author; i've made silly mistakes of my own before)
2020-03-14 02:39:10 -01:00
# Ensure that all specified stagefiles exist (and thus that all associated stages are complete)
Require_stagefiles ()
2007-09-23 08:04:46 +00:00
{
if [ $# -eq 0 ]; then
2020-03-18 07:37:22 -01:00
Echo_warning "Bad 'Require_stagefiles' usage, no params were supplied"
return 0
fi
stagefiles: fix completely wrong require-stages logic now having investigated my suspicions of the functionality and use of Require_stagefile(), i conclude that it has been fundamentally broken all the way back to v1.0~a8-1 (or at least usage of it since v1.0.1-2). gah. (╯°□°)╯︵ ┻━┻ ---- very early on in the history of live-build this function took the name of a _single_ stage file only and did `exit 1` should the file not be found. this was simple and clearly accomplished "what was on the tin", so to speak. in bd1a5ddc8203907eb40135303bea5488397ec5d0 (2007, 1.0~a8-1) things got weird. it was modified to support a list of multiple files. but instead of being written to cause failure if _any_ of the listed files were missing as perhaps one might expect, it was instead written to fail only if all files were missing! if you jump to the conclusion that i'm talking about a simple flipped logic from a lack or otherwise of a `!` here, you'd be mistaken; there is a comment inside the function that could not be more clear about what was intended by the author - "Find at least one of the required stages"! this makes me thoroughly confused about what they were thinking. as we'll get to, this was fundamentally flawed (or at least its later use was), but furthermore there were other notable issues introduced at this point (but don't worry too much about these, they've all been addressed): - `NAME` was modified in the loop, using the existing value, but nothing initially set it... - the setting of `NAME` seems related to its use in the subsequent error output, yet they are logically separated; it is only set if a file exists, while the error is only printed if none exist. - it is pointlessly using a messy `CONTINUE="true"` based mechanism, when it could just `return 0`. - it did not handle correctly the bad use case of no params having been supplied. it doesn't seem to have been entirely thought through, despite its pervasive use throughout the build system. note that no change was made in that commit to make actual use of the new multi-param support. it would not be used until about a year later. the function has remained largely untouched since then. in c68c0a270832ca340429878ce6a0ab606d435b06 a notable change was made to add an initial setting of `NAME`, which partially addressed one of the above issues. but it did not really address the issue the change was meant to solve, since the `NAME` as printed in the error was now the name of the script when what was really wanted was the name of the stagefile. this was finally fixed properly in d54990695f334d205fa846c42b6e0f2afd3c47f5. however the weirdly pointless setting of `NAME` persisted in the loop. finally i personally just refactored the function in the commit prior to this one, retaining the same functionality but addressing the remaining of the above minor implementation issues. looking at usage of the new functionality introduced in bd1a5ddc8203907eb40135303bea5488397ec5d0, it does not seem to have been until 0cbbde2b9664b9fafb311f1048db25ea69952222 (2008, almost a year after it was made possible) that changes were made to finally start making use of the ability to pass more than one filename at a time to the function, and it would appear that perhaps the author forgot what it actually was that the function accomplished when used with multiple params, and failed to double check. in this first use of multiple parameters, this commit went from passing single file names to individual calls to the function to passing the files in one single call, in a commit the purpose of which was described as simply tidying things up. it was most certainly not intended to change stage requirements. unfortunately, a change in requirements did occur as a result since the new usage of the function was not accomplishing the same as before. this change completely broke the stage requirements protection mechanism such that only a single one of the listed stages needed to have completed for the check to pass, rather than all as expected. this flaw made it into release v1.0.1-2 and it has existed every since. in the very next commit from that one, 6204dc0e6db02859a07a978d87f1a5231c0214cf things got even worse. here we see the config stage being specified commonly as the first stage listed, which is still the case today. this means that ever since this commit, if you've already got a config before building (which you inevitably do, especially after some later commits introduced automatically creating it if missing), then all other stage requirements are simply ignored. so it seems pretty damn clear that this function is accomplishing completely the wrong objective. it _should_ be checking that _all_ files given to it exist, not just one or more. ¯\_(ツ)_/¯ this FINALLY addresses this mistake. (not that i wish to berate the author; i've made silly mistakes of my own before)
2020-03-14 02:39:10 -01:00
local FILE
2020-03-14 03:37:56 -01:00
local MISSING=""
2020-03-18 07:37:22 -01:00
local MISSING_COUNT=0
for FILE in "${@}"; do
stagefiles: fix completely wrong require-stages logic now having investigated my suspicions of the functionality and use of Require_stagefile(), i conclude that it has been fundamentally broken all the way back to v1.0~a8-1 (or at least usage of it since v1.0.1-2). gah. (╯°□°)╯︵ ┻━┻ ---- very early on in the history of live-build this function took the name of a _single_ stage file only and did `exit 1` should the file not be found. this was simple and clearly accomplished "what was on the tin", so to speak. in bd1a5ddc8203907eb40135303bea5488397ec5d0 (2007, 1.0~a8-1) things got weird. it was modified to support a list of multiple files. but instead of being written to cause failure if _any_ of the listed files were missing as perhaps one might expect, it was instead written to fail only if all files were missing! if you jump to the conclusion that i'm talking about a simple flipped logic from a lack or otherwise of a `!` here, you'd be mistaken; there is a comment inside the function that could not be more clear about what was intended by the author - "Find at least one of the required stages"! this makes me thoroughly confused about what they were thinking. as we'll get to, this was fundamentally flawed (or at least its later use was), but furthermore there were other notable issues introduced at this point (but don't worry too much about these, they've all been addressed): - `NAME` was modified in the loop, using the existing value, but nothing initially set it... - the setting of `NAME` seems related to its use in the subsequent error output, yet they are logically separated; it is only set if a file exists, while the error is only printed if none exist. - it is pointlessly using a messy `CONTINUE="true"` based mechanism, when it could just `return 0`. - it did not handle correctly the bad use case of no params having been supplied. it doesn't seem to have been entirely thought through, despite its pervasive use throughout the build system. note that no change was made in that commit to make actual use of the new multi-param support. it would not be used until about a year later. the function has remained largely untouched since then. in c68c0a270832ca340429878ce6a0ab606d435b06 a notable change was made to add an initial setting of `NAME`, which partially addressed one of the above issues. but it did not really address the issue the change was meant to solve, since the `NAME` as printed in the error was now the name of the script when what was really wanted was the name of the stagefile. this was finally fixed properly in d54990695f334d205fa846c42b6e0f2afd3c47f5. however the weirdly pointless setting of `NAME` persisted in the loop. finally i personally just refactored the function in the commit prior to this one, retaining the same functionality but addressing the remaining of the above minor implementation issues. looking at usage of the new functionality introduced in bd1a5ddc8203907eb40135303bea5488397ec5d0, it does not seem to have been until 0cbbde2b9664b9fafb311f1048db25ea69952222 (2008, almost a year after it was made possible) that changes were made to finally start making use of the ability to pass more than one filename at a time to the function, and it would appear that perhaps the author forgot what it actually was that the function accomplished when used with multiple params, and failed to double check. in this first use of multiple parameters, this commit went from passing single file names to individual calls to the function to passing the files in one single call, in a commit the purpose of which was described as simply tidying things up. it was most certainly not intended to change stage requirements. unfortunately, a change in requirements did occur as a result since the new usage of the function was not accomplishing the same as before. this change completely broke the stage requirements protection mechanism such that only a single one of the listed stages needed to have completed for the check to pass, rather than all as expected. this flaw made it into release v1.0.1-2 and it has existed every since. in the very next commit from that one, 6204dc0e6db02859a07a978d87f1a5231c0214cf things got even worse. here we see the config stage being specified commonly as the first stage listed, which is still the case today. this means that ever since this commit, if you've already got a config before building (which you inevitably do, especially after some later commits introduced automatically creating it if missing), then all other stage requirements are simply ignored. so it seems pretty damn clear that this function is accomplishing completely the wrong objective. it _should_ be checking that _all_ files given to it exist, not just one or more. ¯\_(ツ)_/¯ this FINALLY addresses this mistake. (not that i wish to berate the author; i've made silly mistakes of my own before)
2020-03-14 02:39:10 -01:00
if [ ! -f ".build/${FILE}" ]; then
2020-03-18 07:37:22 -01:00
MISSING_COUNT=$(( $MISSING_COUNT + 1 ))
2020-03-14 03:37:56 -01:00
MISSING="${MISSING:+$MISSING }${FILE}"
2007-09-23 08:04:52 +00:00
fi
done
2020-03-18 07:37:22 -01:00
if [ $MISSING_COUNT -eq 0 ]; then
stagefiles: fix completely wrong require-stages logic now having investigated my suspicions of the functionality and use of Require_stagefile(), i conclude that it has been fundamentally broken all the way back to v1.0~a8-1 (or at least usage of it since v1.0.1-2). gah. (╯°□°)╯︵ ┻━┻ ---- very early on in the history of live-build this function took the name of a _single_ stage file only and did `exit 1` should the file not be found. this was simple and clearly accomplished "what was on the tin", so to speak. in bd1a5ddc8203907eb40135303bea5488397ec5d0 (2007, 1.0~a8-1) things got weird. it was modified to support a list of multiple files. but instead of being written to cause failure if _any_ of the listed files were missing as perhaps one might expect, it was instead written to fail only if all files were missing! if you jump to the conclusion that i'm talking about a simple flipped logic from a lack or otherwise of a `!` here, you'd be mistaken; there is a comment inside the function that could not be more clear about what was intended by the author - "Find at least one of the required stages"! this makes me thoroughly confused about what they were thinking. as we'll get to, this was fundamentally flawed (or at least its later use was), but furthermore there were other notable issues introduced at this point (but don't worry too much about these, they've all been addressed): - `NAME` was modified in the loop, using the existing value, but nothing initially set it... - the setting of `NAME` seems related to its use in the subsequent error output, yet they are logically separated; it is only set if a file exists, while the error is only printed if none exist. - it is pointlessly using a messy `CONTINUE="true"` based mechanism, when it could just `return 0`. - it did not handle correctly the bad use case of no params having been supplied. it doesn't seem to have been entirely thought through, despite its pervasive use throughout the build system. note that no change was made in that commit to make actual use of the new multi-param support. it would not be used until about a year later. the function has remained largely untouched since then. in c68c0a270832ca340429878ce6a0ab606d435b06 a notable change was made to add an initial setting of `NAME`, which partially addressed one of the above issues. but it did not really address the issue the change was meant to solve, since the `NAME` as printed in the error was now the name of the script when what was really wanted was the name of the stagefile. this was finally fixed properly in d54990695f334d205fa846c42b6e0f2afd3c47f5. however the weirdly pointless setting of `NAME` persisted in the loop. finally i personally just refactored the function in the commit prior to this one, retaining the same functionality but addressing the remaining of the above minor implementation issues. looking at usage of the new functionality introduced in bd1a5ddc8203907eb40135303bea5488397ec5d0, it does not seem to have been until 0cbbde2b9664b9fafb311f1048db25ea69952222 (2008, almost a year after it was made possible) that changes were made to finally start making use of the ability to pass more than one filename at a time to the function, and it would appear that perhaps the author forgot what it actually was that the function accomplished when used with multiple params, and failed to double check. in this first use of multiple parameters, this commit went from passing single file names to individual calls to the function to passing the files in one single call, in a commit the purpose of which was described as simply tidying things up. it was most certainly not intended to change stage requirements. unfortunately, a change in requirements did occur as a result since the new usage of the function was not accomplishing the same as before. this change completely broke the stage requirements protection mechanism such that only a single one of the listed stages needed to have completed for the check to pass, rather than all as expected. this flaw made it into release v1.0.1-2 and it has existed every since. in the very next commit from that one, 6204dc0e6db02859a07a978d87f1a5231c0214cf things got even worse. here we see the config stage being specified commonly as the first stage listed, which is still the case today. this means that ever since this commit, if you've already got a config before building (which you inevitably do, especially after some later commits introduced automatically creating it if missing), then all other stage requirements are simply ignored. so it seems pretty damn clear that this function is accomplishing completely the wrong objective. it _should_ be checking that _all_ files given to it exist, not just one or more. ¯\_(ツ)_/¯ this FINALLY addresses this mistake. (not that i wish to berate the author; i've made silly mistakes of my own before)
2020-03-14 02:39:10 -01:00
return 0
2020-03-18 07:37:22 -01:00
elif [ $MISSING_COUNT -eq 1 ]; then
2020-03-14 03:37:56 -01:00
Echo_error "the following stage is required to be done first: %s" "${MISSING}"
else
2020-03-14 03:37:56 -01:00
Echo_error "the following stages are required to be completed first: %s" "${MISSING}"
2007-09-23 08:04:46 +00:00
fi
exit 1
2007-09-23 08:04:46 +00:00
}