Skip to content

Commit

Permalink
ported #7022 : Fix #279707: Command line option to update AppImage
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkorsukov authored and vpereverzev committed Feb 19, 2021
1 parent 3e7f851 commit b93b05b
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 31 deletions.
5 changes: 5 additions & 0 deletions build/Linux+BSD/mscore.1.in
Expand Up @@ -115,6 +115,11 @@ GNU General Public Licence (GPLv2).
@MAN_PORTABLE@.Ar prefix
@MAN_PORTABLE@to install into a custom location.
@MAN_PORTABLE@Installation is not required to run the program.
@MAN_PORTABLE@.It Cm update , Cm upgrade Oo Fl i Oc Op Ar prefix
@MAN_PORTABLE@Updates MuseScore to the latest version. This uses your internet
@MAN_PORTABLE@connection to check for an update and download it if one is
@MAN_PORTABLE@available. A delta update mechanism is used to minimise the
@MAN_PORTABLE@amount of data that is downloaded.
@MAN_PORTABLE@.It Cm remove , Cm uninstall Op Ar prefix
@MAN_PORTABLE@Removes icons and resources, and asks whether you would
@MAN_PORTABLE@like to remove the program as well.
Expand Down
4 changes: 2 additions & 2 deletions build/Linux+BSD/mscore.desktop.in
@@ -1,6 +1,6 @@
[Desktop Entry]
[Desktop Entry]@Variables_substituted_by_CMAKE_on_installation@
Version=1.0@This_is_version_of_Desktop_Entry_Specification@@It_is_NOT_MuseScore_version@
Name=@MUSESCORE_NAME_VERSION@@Variables_substituted_by_CMAKE_on_installation@
Name=@MUSESCORE_NAME@ @MUSESCORE_VERSION@@MSCORE_INSTALL_SUFFIX@
GenericName=Music notation
GenericName[de]=Notensatz
GenericName[fr]=Notation musicale
Expand Down
2 changes: 1 addition & 1 deletion build/Linux+BSD/portable/AppRun.in
Expand Up @@ -24,7 +24,7 @@ export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}${fallback_libs}"

# Launch MuseScore or an accompanying script
case "$1" in
-h|--help|install|uninstall|remove|man|manual|manpage|check-depends|check-dependencies )
-h|--help|install|update|upgrade|uninstall|remove|man|manual|manpage|check-depends|check-dependencies )
"${APPDIR}/bin/portable-utils" "$@"
;;
* )
Expand Down
119 changes: 97 additions & 22 deletions build/Linux+BSD/portable/portable-utils.in
Expand Up @@ -11,6 +11,9 @@ function main() {
install )
installResources "$2" "$3" || errorMsg "Unable to install to '${prefix}'"
;;
update|upgrade )
update "$2" "$3"
;;
uninstall|remove )
removeResources "$2" "$3" || errorMsg "Unable to remove from '${prefix}'"
;;
Expand Down Expand Up @@ -40,6 +43,7 @@ Special options for MuseScore Portable AppImage:
-h, --help Displays this help and the normal help (below).
man, manual, manpage Displays MuseScore's man page.
install [-i] [PREFIX] Installs resources for desktop integration.
update, upgrade [-i] [PREFIX] Update MuseScore to the latest version.
remove, uninstall [PREFIX] Removes resources from desktop environment.
check-depends [exes-only] Displays system information for developers.
Expand Down Expand Up @@ -123,12 +127,13 @@ cat <<EOF
Step 2 of 3.
MuseScore is at: ${APPIMAGE}
EOF
if [ ! "$interactive" ]; then
echo "Moving it to 'PREFIX/bin'."
mkdir -p "${bin}" && cp -r "${APPIMAGE}" -t "${bin}/" \
&& APPIMAGE="${bin}/$(basename "${APPIMAGE}")" \
|| errorMsg "Couldn't move to '${bin}'"
else
name="$(basename "${APPIMAGE}")"
dest="${bin}/${name}"
if [ ! "$interactive" ] && [ ! "${APPIMAGE}" -ef "${dest}" ]; then
echo "Moving AppImage to 'PREFIX/bin'."
mkdir -p "${bin}"
mv "${APPIMAGE}" "${dest}" && APPIMAGE="${dest}" || errorMsg "Couldn't move to '${bin}'"
elif [ ! "${APPIMAGE}" -ef "${dest}" ]; then
cat <<EOF
You can leave it there, but it is recommended that you move it to 'PREFIX/bin'.
Options: move (m) or copy (c) MuseScore, do nothing (n), or show help (h)?
Expand All @@ -140,10 +145,16 @@ EOF
N|n )
break
;;
M|C|m|c )
mkdir -p "${bin}" && cp -r "${APPIMAGE}" -t "${bin}/" \
&& APPIMAGE="${bin}/$(basename "${APPIMAGE}")" \
|| errorMsg "Couldn't move to '${bin}'"
M|m )
echo "Moving AppImage to 'PREFIX/bin'."
mkdir -p "${bin}"
mv "${APPIMAGE}" "${dest}" && APPIMAGE="${dest}" || errorMsg "Couldn't move to '${bin}'"
break
;;
C|c )
echo "Copying AppImage to 'PREFIX/bin'."
mkdir -p "${bin}"
cp "${APPIMAGE}" "${dest}" && APPIMAGE="${dest}" || errorMsg "Couldn't copy to '${bin}'"
break
;;
H|h )
Expand All @@ -154,7 +165,7 @@ Moving or copying MuseScore to 'PREFIX/bin' has these benefits:
available to the same user(s) as the resources were installed for.)
2) If 'PREFIX/bin' is in your PATH environment variable then you can launch
MuseScore by typing '$(basename ${APPIMAGE})' instead of the full path.
MuseScore by typing '${name}' instead of the full path.
The default locations for PREFIX are in PATH on most systems.
You should move rather than copy unless you want to keep another copy at the
Expand Down Expand Up @@ -182,10 +193,10 @@ EOF
[ "$interactive" ] && printf "Create symlinks 'mscore@MSCORE_INSTALL_SUFFIX@' and 'musescore@MSCORE_INSTALL_SUFFIX@' [Y/n]?"
if [ ! "$interactive" ] || readYes ; then
cd bin
ln -s "$(basename ${APPIMAGE})" mscore@MSCORE_INSTALL_SUFFIX@
ln -s "$(basename ${APPIMAGE})" musescore@MSCORE_INSTALL_SUFFIX@
ln -sf "${name}" "mscore@MSCORE_INSTALL_SUFFIX@"
ln -sf "${name}" "musescore@MSCORE_INSTALL_SUFFIX@"
fi
if [ ! "$(which "$(basename "${APPIMAGE}")")" ]; then
if ! which "${name}" >/dev/null; then
cat <<EOF
INFORMATION: MuseScore is not in PATH. If you want to run MuseScore from
the command line you will have to type the full file path, like this:
Expand All @@ -197,12 +208,68 @@ EOF
fi
}

function update() {
local interactive="" install=true
if [ "$1" == "-i" ]; then
interactive="$1"
prefix="$2"
elif [ "$2" == "-i" ]; then
interactive="$2"
prefix="$1"
fi
checkUpdate
if [ "${interactive}" ]; then
echo -n "Apply the update [Y/n]?"
readYes || exit 0
fi
doUpdate
if "${NEW_APPIMAGE}" --version; then
echo "New version appears to work properly."
else
echo "Error: Could not run new version"
exit 1
fi
echo "Removing old version..." # always interactive
removeResources "${prefix}"
if [ "${interactive}" ]; then
echo -n "Install the new version [Y/n]?"
readYes || install=""
fi
if [ "${install}" ]; then
"${NEW_APPIMAGE}" install "${interactive}" "${prefix}"
fi
}

function checkUpdate() {
echo "Checking for updates..."
"${APPDIR}/bin/appimageupdatetool" --check-for-update -- "${APPIMAGE}"
local -r result=$?
case ${result} in
0) echo "No update is available.";;
1) echo "An update is available."; return 0;; # don't exit
*) echo "Error: Unable to check for updates (status: ${result}).";;
esac
exit ${result} # don't return
}

function doUpdate() {
echo "Updating to the latest version..."
local -r output="$(stdouterr "${APPDIR}/bin/appimageupdatetool" -- "${APPIMAGE}")"
local -r result=$?
NEW_APPIMAGE="$(sed -n "s|^Update successful. New file created: ||p" <<<"${output}")"
case ${result} in
0) return 0;; # don't exit
*) echo "Error: Unable to apply update (status: ${result}).";;
esac
exit ${result} # don't return
}

function removeResources() {
[ "$1" == "-i" ] && shift # ignore option. Remove is always interactive
if [ "$1" != "" ]; then
# User specified a directory
prefix="$1"
echo -n "Remove resources from ${prefix} [Y/n]?"
echo -n "Remove MuseScore resources from ${prefix} [Y/n]?"
elif [ "${EUID}" == "0" ]; then
prefix=/usr/local
echo -n "Running as root. Remove MuseScore resources from '$prefix' for all users [Y/n]?"
Expand All @@ -212,14 +279,15 @@ function removeResources() {
fi
readYes || return 0
cd "$prefix" && <"${APPDIR}/install_manifest.txt" xargs rm || return 1
rm "$(dirname "${APPIMAGE}")/mscore@MSCORE_INSTALL_SUFFIX@"
rm "$(dirname "${APPIMAGE}")/musescore@MSCORE_INSTALL_SUFFIX@"
actual_location="$(readlink -f "${APPIMAGE}")" # get before deleting symlinks
rm "bin/mscore@MSCORE_INSTALL_SUFFIX@"
rm "bin/musescore@MSCORE_INSTALL_SUFFIX@"
<"${APPDIR}/install_manifest.txt" xargs "${APPDIR}/bin/rm-empty-dirs"
updateCache $prefix
echo -ne "Resources removed from ${PWD}.\nRemove MuseScore itself (delete ${APPIMAGE}) [Y/n]?"
readYes || { echo -e "MuseScore remains at ${APPIMAGE}.\nYou may delete it yourself or install again at any time." && return 0 ; }
rm "${APPIMAGE}" && echo "Successfully removed MuseScore from $prefix"
rmdir "$(dirname "${APPIMAGE}")"
updateCache "${prefix}"
echo -ne "Resources removed from ${PWD}.\nRemove MuseScore itself (delete ${actual_location}) [Y/n]?"
readYes || { echo -e "MuseScore remains at ${actual_location}.\nYou may delete it yourself or install again at any time." && return 0 ; }
rm "${actual_location}" && echo "Successfully removed MuseScore from $prefix"
"${APPDIR}/bin/rm-empty-dirs" bin "${APPIMAGE}" "${actual_location}"
return 0
}

Expand Down Expand Up @@ -311,6 +379,13 @@ function updateCache() {
return $ret
}

function stdouterr() {
# Run command & pipe output to both stdout and stderr, enabling you to
# capture the output while simultaneously printing it in the terminal.
set -o pipefail # preserve command exit status
"$@" 2>&1 | tee >(cat >&2) # duplicate output on stdout and stderr
}

function errorMsg() {
cat <<EOF
$1. Things to check:
Expand Down
19 changes: 14 additions & 5 deletions build/ci/linux/build.sh
Expand Up @@ -11,6 +11,7 @@ ARTIFACTS_DIR=build.artifacts
TELEMETRY_TRACK_ID=""
CRASH_REPORT_URL=""
BUILD_MODE=""
SUFFIX="" # appended to `mscore` command name to avoid conflicts (e.g. `mscore-dev`)

while [[ "$#" -gt 0 ]]; do
case $1 in
Expand All @@ -29,10 +30,17 @@ if [ -z "$BUILD_MODE" ]; then BUILD_MODE=$(cat $ARTIFACTS_DIR/env/build_mode.env

MUSESCORE_BUILD_CONFIG=dev
BUILD_UNIT_TESTS=OFF
if [ "$BUILD_MODE" == "devel_build" ]; then MUSESCORE_BUILD_CONFIG=dev; fi
if [ "$BUILD_MODE" == "nightly_build" ]; then MUSESCORE_BUILD_CONFIG=dev; fi
if [ "$BUILD_MODE" == "testing_build" ]; then MUSESCORE_BUILD_CONFIG=testing; fi
if [ "$BUILD_MODE" == "stable_build" ]; then MUSESCORE_BUILD_CONFIG=release; fi
case "${BUILD_MODE}" in
"devel_build") MUSESCORE_BUILD_CONFIG=dev; SUFFIX=-dev;;
"nightly_build") MUSESCORE_BUILD_CONFIG=dev; SUFFIX=-nightly;;
"testing_build") MUSESCORE_BUILD_CONFIG=testing; SUFFIX=-testing;;
"stable_build") MUSESCORE_BUILD_CONFIG=release; SUFFIX="";;
"mtests") MUSESCORE_BUILD_CONFIG=dev; BUILDTYPE=installdebug; OPTIONS="USE_SYSTEM_FREETYPE=ON UPDATE_CACHE=FALSE PREFIX=$ARTIFACTS_DIR/software";;
esac

if [ "${BUILDTYPE}" == "portable" ]; then
SUFFIX="-portable${SUFFIX}" # special value needed for CMakeLists.txt
fi

echo "MUSESCORE_BUILD_CONFIG: $MUSESCORE_BUILD_CONFIG"
echo "BUILD_NUMBER: $BUILD_NUMBER"
Expand All @@ -46,7 +54,7 @@ cat ./../musescore_environment.sh
source ./../musescore_environment.sh

echo " "
${CXX} --version
${CXX} --version
${CC} --version
echo " "
cmake --version
Expand All @@ -65,6 +73,7 @@ MUSESCORE_REVISION=$(git rev-parse --short=7 HEAD)

# Build portable AppImage
MUSESCORE_BUILD_CONFIG=$MUSESCORE_BUILD_CONFIG \
MUSESCORE_INSTALL_SUFFIX=$SUFFIX \
MUSESCORE_BUILD_NUMBER=$BUILD_NUMBER \
MUSESCORE_REVISION=$MUSESCORE_REVISION \
MUSESCORE_TELEMETRY_ID=$TELEMETRY_TRACK_ID \
Expand Down
30 changes: 29 additions & 1 deletion build/ci/linux/tools/make_appimage.sh
Expand Up @@ -43,6 +43,15 @@ fi
export PATH="${PWD%/}/appimagetool:${PATH}"
appimagetool --version

if [[ ! -d "appimageupdatetool" ]]; then
mkdir appimageupdatetool
cd appimageupdatetool
download_appimage_release AppImage/AppImageUpdate appimageupdatetool continuous
cd ..
fi
export PATH="${PWD%/}/appimageupdatetool:${PATH}"
appimageupdatetool --version

function download_linuxdeploy_component()
{
download_appimage_release "linuxdeploy/$1" "$1" continuous
Expand All @@ -58,7 +67,6 @@ fi
export PATH="${PWD%/}/linuxdeploy:${PATH}"
linuxdeploy --list-plugins


##########################################################################
# BUNDLE DEPENDENCIES INTO APPDIR
##########################################################################
Expand Down Expand Up @@ -157,6 +165,13 @@ fallback_libraries=(
libjack.so.0 # https://github.com/LMMS/lmms/pull/3958
)

# PREVIOUSLY EXTRACTED APPIMAGES
# These include their own dependencies. We bundle them uncompressed to avoid
# creating a double layer of compression (AppImage inside AppImage).
extracted_appimages=(
appimageupdatetool
)

for file in "${unwanted_files[@]}"; do
rm -rf "${appdir}/${file}"
done
Expand All @@ -175,6 +190,19 @@ for fb_lib in "${fallback_libraries[@]}"; do
fallback_library "${fb_lib}"
done

for name in "${extracted_appimages[@]}"; do
symlink="$(which "${name}")"
apprun="$(dirname "${symlink}")/$(readlink "${symlink}")"
if [[ ! -L "${symlink}" || ! -f "${apprun}" ]]; then
echo "$0: Warning: Unable to find AppImage for '${name}'. Will not bundle." >&2
continue
fi
extracted_appdir_path="$(dirname "${apprun}")"
extracted_appdir_name="$(basename "${extracted_appdir_path}")"
cp -r "${extracted_appdir_path}" "${appdir}/"
ln -s "../${extracted_appdir_name}/AppRun" "${appdir}/bin/${name}"
done

# METHOD OF LAST RESORT
# Special treatment for some dependencies when all other methods fail

Expand Down

0 comments on commit b93b05b

Please sign in to comment.