Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package spotify-easyrpm for openSUSE:Factory 
checked in at 2026-08-18 16:36:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spotify-easyrpm (Old)
 and      /work/SRC/openSUSE:Factory/.spotify-easyrpm.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "spotify-easyrpm"

Tue Aug 18 16:36:53 2026 rev:12 rq:1371626 version:4.0.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/spotify-easyrpm/spotify-easyrpm.changes  
2025-10-03 15:47:15.050083681 +0200
+++ 
/work/SRC/openSUSE:Factory/.spotify-easyrpm.new.1258/spotify-easyrpm.changes    
    2026-08-18 16:37:34.378270246 +0200
@@ -1,0 +2,31 @@
+Mon Aug 17 21:52:43 UTC 2026 - David Mace <[email protected]>
+
+- Update to 4.0.1
+  * Give the built spotify-client RPM a timestamped release, so rebuilding
+    an unchanged Spotify version produces an installable package instead of
+    colliding with the installed version-release
+  * Verify the downloaded snap against the sha3-384 digest published by
+    snapcraft.io, and query the API over https
+  * Fail with an error when the snapcraft.io lookup fails, instead of
+    reporting the installed version as up to date
+  * Own the local repo as the invoking user at 755/644 rather than making it
+    world writable, which combined with gpgcheck=0 let any local user stage
+    a package for zypper to install as root
+  * Exit the prompts on EOF instead of looping forever, and reject answers
+    that are not understood
+  * --clean-repo keeps the newest build instead of deleting every RPM, and
+    clears out stale debuginfo / debugsource packages
+  * Disable the debug package, so no empty debugsource RPMs reach the local
+    repo and rpmbuild no longer warns
+  * Show a progress bar while downloading, and extract the snap quietly
+  * Validate the --set-channel argument
+  * Do not force X11 in the desktop launcher. Spotify selects it by default
+    again, and forcing it breaks startup on a session without Xwayland
+  * Leave /usr/bin/spotify-easyrpm alone when a package owns it
+  * Check dependencies on scheduled runs, where sudo cannot prompt
+  * Drop the unmaintained Mageia support, the tool is openSUSE / SLE only
+  * zypper ar: disable the package cache for the local repo @stanislav-brabec
+- Drop the obsolete update-desktop-files requirement
+- Require curl, wget and openssl, which the script calls at runtime
+
+-------------------------------------------------------------------

Old:
----
  spotify-easyrpm-3.0.7.obscpio

New:
----
  spotify-easyrpm-4.0.1.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ spotify-easyrpm.spec ++++++
--- /var/tmp/diff_new_pack.t2Ffg9/_old  2026-08-18 16:37:36.408342980 +0200
+++ /var/tmp/diff_new_pack.t2Ffg9/_new  2026-08-18 16:37:36.413343159 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package spotify-easyrpm
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           spotify-easyrpm
-Version:        3.0.7
+Version:        4.0.1
 Release:        0
 Summary:        Tool to download, convert and install the Spotify for Linux 
package
 License:        GPL-3.0-only
@@ -25,11 +25,13 @@
 URL:            https://github.com/megamaced/spotify-easyrpm
 Source0:        %{name}-%{version}.tar.gz
 Requires:       createrepo_c
+Requires:       curl
 Requires:       jq
+Requires:       openssl
 Requires:       rpm-build
 Requires:       rpmdevtools
 Requires:       squashfs
-Requires:       update-desktop-files
+Requires:       wget
 BuildArch:      noarch
 
 %description

++++++ _service ++++++
--- /var/tmp/diff_new_pack.t2Ffg9/_old  2026-08-18 16:37:36.513346742 +0200
+++ /var/tmp/diff_new_pack.t2Ffg9/_new  2026-08-18 16:37:36.523347100 +0200
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="manual">
     <param name="url">https://github.com/megamaced/spotify-easyrpm.git</param>
     <param name="scm">git</param>
-    <param name="revision">3.0.7</param>
+    <param name="revision">4.0.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
   </service>
   <service name="tar" mode="buildtime"/>

++++++ spotify-easyrpm-3.0.7.obscpio -> spotify-easyrpm-4.0.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotify-easyrpm-3.0.7/README.md 
new/spotify-easyrpm-4.0.1/README.md
--- old/spotify-easyrpm-3.0.7/README.md 2025-10-02 16:54:11.000000000 +0200
+++ new/spotify-easyrpm-4.0.1/README.md 2026-08-17 23:47:15.000000000 +0200
@@ -10,7 +10,7 @@
 * Convert the snap package to RPM format
 * Install the Spotify RPM
 * Automated Spotify update check
-* Update Spofity alongside your regular system updates
+* Update Spotify alongside your regular system updates
 * Create a local filesystem repo
 * Fully unattended quiet mode
 
@@ -64,7 +64,7 @@
 ## Auto Updates
 
 spotify-easyrpm can create a systemd user timer job which will run daily and 5 
minutes after user login.
-This will call the script to do a light check against the Spotify debian repo 
for a new release.
+This will call the script to do a light check against snapcraft.io for a new 
release.
 If a new release is found, a build process is kicked off in the background and 
the final RPM will
 be placed on your machine in a local filesystem repo 
(/var/cache/spotify-easyrpm).
 The next time you run the system updater or zypper up you will see 
spotify-client appear as an
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spotify-easyrpm-3.0.7/spotify-easyrpm 
new/spotify-easyrpm-4.0.1/spotify-easyrpm
--- old/spotify-easyrpm-3.0.7/spotify-easyrpm   2025-10-02 16:54:11.000000000 
+0200
+++ new/spotify-easyrpm-4.0.1/spotify-easyrpm   2026-08-17 23:47:15.000000000 
+0200
@@ -2,6 +2,8 @@
 #
 #set -x
 
+# The config file path is only known at runtime
+# shellcheck disable=SC1090
 
 V_PRG_NAME="spotify-easyrpm"
 V_CONFIG_FILE="${HOME}/.${V_PRG_NAME}"
@@ -18,6 +20,10 @@
 
 V_SNAP_EXTRACT_DIR="${V_SOURCES_DIR}/spotify-snap"
 
+# Packages we need installed, and tools we need on PATH
+V_DEP_PKGS=(rpm-build squashfs jq rpmdevtools hicolor-icon-theme)
+V_DEP_CMDS=(curl wget openssl)
+
 SYSTEMD_UNIT_DIR="${HOME}/.local/share/systemd/user"
 SYSTEMD_UNIT="${SYSTEMD_UNIT_DIR}/${V_PRG_NAME}.service"
 SYSTEMD_TIMER="${SYSTEMD_UNIT_DIR}/${V_PRG_NAME}.timer"
@@ -31,7 +37,7 @@
 ┌─┐┌─┐┌─┐┌┬┐┬┌─┐┬ ┬   ┌─┐┌─┐┌─┐┬ ┬┬─┐┌─┐┌┬┐
 └─┐├─┘│ │ │ │├┤ └┬┘───├┤ ├─┤└─┐└┬┘├┬┘├─┘│││
 └─┘┴  └─┘ ┴ ┴└   ┴    └─┘┴ ┴└─┘ ┴ ┴└─┴  ┴ ┴
-Version: 3.0.7
+Version: 4.0.1
 EOF
 sleep 2
 cat <<EOF
@@ -93,6 +99,35 @@
 }
 
 
+f_abort() {
+echo "$1" 1>&2
+f_cleanup
+exit 1
+}
+
+
+f_abort_no_input() {
+f_abort "No input received. Use --quiet to run unattended"
+}
+
+
+f_ver_gt() {
+# True when version $1 is higher than version $2. rpmdev-vercmp exits
+# 11 for greater than, 12 for less than and 0 for equal
+V_VERCMP_RC=0
+rpmdev-vercmp "$1" "$2" > /dev/null 2>&1 || V_VERCMP_RC="$?"
+[[ "${V_VERCMP_RC}" == "11" ]]
+}
+
+
+f_rpm_version() {
+# Read the version field out of an RPM file name we created ourselves
+V_RPM_VERSION="$(basename "$1")"
+V_RPM_VERSION="${V_RPM_VERSION#"${V_PKGNAME}"-}"
+echo "${V_RPM_VERSION%%-*}"
+}
+
+
 f_cleanup() {
 rm "${V_SOURCES_DIR:?}"/*.snap > /dev/null 2>&1
 rm -rf "${V_SNAP_EXTRACT_DIR:?}" > /dev/null 2>&1
@@ -148,14 +183,24 @@
 
 
 f_check_metered() {
-  test -n "`(LC_ALL=C.UTF-8 ; export LC_ALL ; nmcli -t -f active,name 
connection show 2>/dev/null | sed -n 's/^yes://p' | while read ; do nmcli 
connection show "$REPLY" | grep '^connection\.metered:[[:space:]]*yes' ; done 
)`"
+# True when any active NetworkManager connection is marked as metered
+if ! command -v nmcli > /dev/null 2>&1; then
+ return 1
+fi
+while IFS= read -r V_ACTIVE_CONN; do
+ if LC_ALL=C.UTF-8 nmcli connection show "${V_ACTIVE_CONN}" 2>/dev/null | grep 
-q '^connection\.metered:[[:space:]]*yes'; then
+  echo "Active connection ${V_ACTIVE_CONN} is metered. Skipping this run"
+  return 0
+ fi
+done < <(LC_ALL=C.UTF-8 nmcli -t -f active,name connection show 2>/dev/null | 
sed -n 's/^yes://p')
+return 1
 }
 
 f_release_channel() {
 if [[ "${PREF_PROMPT_CHANNEL}" == "YES" ]] && [[ "${V_RUN_MODE}" == "prompt" 
]]; then
   while true
    do
-    read -rp "Do you wish to download the Spotify stable or edge release 
(s/e)?" Q_RELEASE_CHANNEL
+    read -rp "Do you wish to download the Spotify stable or edge release 
(s/e)?" Q_RELEASE_CHANNEL || f_abort_no_input
 
   case $Q_RELEASE_CHANNEL in
   s )  sed -i "s/\(PREF_PROMPT_CHANNEL=\)\(.*\)/\1NO/" "${V_CONFIG_FILE}"
@@ -172,16 +217,36 @@
        sleep 3
    break;;
 
+  * )  echo "Please answer s or e";;
+
   esac
  done
- fi 
+ fi
 }
 
 f_download() {
 echo "Downloading the latest Spotify snap"
-if ! wget -q -P "${V_SOURCES_DIR}"/ "${V_HTTP_REPO}"; then
+# Show a progress bar when someone is watching, stay silent for the timer
+V_WGET_OPTS=(-q)
+if [[ -t 1 ]] && wget --help 2>&1 | grep -q -- '--show-progress'; then
+ V_WGET_OPTS+=(--show-progress)
+fi
+if ! wget "${V_WGET_OPTS[@]}" -P "${V_SOURCES_DIR}"/ "${V_HTTP_REPO}"; then
 f_error "Failed to download Spotify. Aborting"
 fi
+f_verify_snap
+}
+
+
+f_verify_snap() {
+if [[ -z "${V_HTTP_SHA3_384}" ]] || [[ "${V_HTTP_SHA3_384}" == "null" ]]; then
+ f_error "snapcraft.io did not provide a checksum for ${V_HTTP_SNAP}. Aborting"
+fi
+echo "Verifying the snap checksum"
+V_LOCAL_SHA3_384="$(openssl dgst -sha3-384 "${V_SOURCES_DIR}"/"${V_HTTP_SNAP}" 
| awk '{print $NF}')"
+if [[ "${V_LOCAL_SHA3_384}" != "${V_HTTP_SHA3_384}" ]]; then
+ f_error "Checksum mismatch on ${V_HTTP_SNAP}. Expected ${V_HTTP_SHA3_384} but 
got ${V_LOCAL_SHA3_384}. Aborting"
+fi
 }
 
 
@@ -190,12 +255,12 @@
 if ! mkdir -p "${V_TOPDIR}"/{BUILD,BUILDROOT,OTHER,RPMS,SOURCES,SPECS,SRPMS}; 
then
 f_error "Failed to create rpmbuild root. Aborting"
 fi
-V_RPMBUILD_OWNER_CHECK="$(find "${V_TOPDIR}" -not -user "$(id -u)")"
+V_RPMBUILD_OWNER_CHECK="$(find "${V_TOPDIR}" -not -user "$(id -u)" -print 
-quit)"
 if [[ -n "${V_RPMBUILD_OWNER_CHECK}" ]]; then
-  echo "Detected some directories / files not owned by you. Fixing 
${V_RPMBUILD_OWNER_CHECK}"
-  for i in ${V_RPMBUILD_OWNER_CHECK}; do
-    sudo chown "$(id -u)" "$i"
-  done
+  echo "Detected some directories / files not owned by you. Fixing ownership 
under ${V_TOPDIR}"
+  if ! sudo find "${V_TOPDIR}" -not -user "$(id -u)" -exec chown "$(id 
-u)":"$(id -g)" {} \+; then
+    f_error "Failed to fix ownership under ${V_TOPDIR}. Aborting"
+  fi
 fi
 if [[ ! -f "${HOME}"/.rpmmacros ]]; then
  echo "Creating ${HOME}/.rpmmacros"
@@ -209,7 +274,18 @@
 
 f_extract_snap() {
 echo "Extracting snap and preparing"
-unsquashfs -d "${V_SNAP_EXTRACT_DIR}"  "${V_SOURCES_DIR}"/"${V_HTTP_SNAP}" || 
f_error "Failed to extract snap"
+# Drop the processor / inode / created file counts and the progress bar.
+# Errors are still printed. The help spells these as -q[uiet] and
+# -n[o-progress], so only pass them when this squashfs advertises them
+V_UNSQUASHFS_HELP="$(unsquashfs -help 2>&1)"
+V_UNSQUASHFS_OPTS=()
+if grep -qE '^[[:space:]]+-q(\[uiet\]|uiet)' <<< "${V_UNSQUASHFS_HELP}"; then
+ V_UNSQUASHFS_OPTS+=(-quiet)
+fi
+if grep -qE '^[[:space:]]+-n(\[o-progress\]|o-progress)' <<< 
"${V_UNSQUASHFS_HELP}"; then
+ V_UNSQUASHFS_OPTS+=(-no-progress)
+fi
+unsquashfs "${V_UNSQUASHFS_OPTS[@]}" -d "${V_SNAP_EXTRACT_DIR}" 
"${V_SOURCES_DIR}"/"${V_HTTP_SNAP}" || f_error "Failed to extract snap"
 mkdir -p "${V_SOURCES_DIR}"/"${V_PKGNAME}"/usr/{share/applications,bin}
 mv "${V_SNAP_EXTRACT_DIR}"/usr/share/spotify 
"${V_SOURCES_DIR}"/"${V_PKGNAME}"/usr/share
 mv "${V_SNAP_EXTRACT_DIR}"/usr/bin/spotify 
"${V_SOURCES_DIR}"/"${V_PKGNAME}"/usr/bin
@@ -217,10 +293,19 @@
 
 
 f_script_location_check() {
-if [[ ! -f /usr/bin/"${V_PRG_NAME}" ]] || ! diff "${0}" 
/usr/bin/"${V_PRG_NAME}" > /dev/null 2>&1; then
- echo "Copying ${V_PRG_NAME} to /usr/bin/${V_PRG_NAME} for the schedule to 
work"
- sudo cp "${0}" /usr/bin/"${V_PRG_NAME}"
+if [[ "$(readlink -f "${0}")" == /usr/bin/"${V_PRG_NAME}" ]]; then
+ return 0
 fi
+if [[ -f /usr/bin/"${V_PRG_NAME}" ]] && diff "${0}" /usr/bin/"${V_PRG_NAME}" > 
/dev/null 2>&1; then
+ return 0
+fi
+if rpm -qf /usr/bin/"${V_PRG_NAME}" > /dev/null 2>&1; then
+ echo "/usr/bin/${V_PRG_NAME} is owned by an installed package and differs 
from this copy"
+ echo "Leaving it alone. The schedule will run the packaged version"
+ return 0
+fi
+echo "Copying ${V_PRG_NAME} to /usr/bin/${V_PRG_NAME} for the schedule to work"
+sudo cp "${0}" /usr/bin/"${V_PRG_NAME}"
 }
 
 
@@ -230,7 +315,7 @@
   if [[ "${V_RUN_MODE}" == "create-schedule" ]] || [[ 
"${PREF_PROMPT_SCHEDULE}" != "NO" ]]; then
   while true
   do
-   read -rp "Do you wish to set up an automated update schedule (y/n)?" 
Q_SCHEDULE_ANSWER
+   read -rp "Do you wish to set up an automated update schedule (y/n)?" 
Q_SCHEDULE_ANSWER || f_abort_no_input
 
   case $Q_SCHEDULE_ANSWER in
   y ) f_create_repo
@@ -242,6 +327,8 @@
       sed -i "s/\(PREF_PROMPT_SCHEDULE=\)\(.*\)/\1NO/" "${V_CONFIG_FILE}"
       break;;
 
+  * ) echo "Please answer y or n";;
+
   esac
  done
 else
@@ -249,24 +336,32 @@
  fi
 else
   echo "Found existing schedule. Skipping"
-  f_update_local_repo
+  if [[ -d "${V_LOCAL_REPO}" ]]; then
+   f_secure_repo
+   f_update_local_repo
+  else
+   echo "Local repo ${V_LOCAL_REPO} is missing. Recreating it"
+   f_create_repo
+  fi
 fi
 }
 
 
 f_remove_schedule() {
- if [[ -f "${SYSTEMD_UNIT}" ]]; then
-  echo "Removing ${V_PRG_NAME} from your systemd unit files"
-  systemctl --user disable spotify-easyrpm
-  rm "${SYSTEMD_UNIT}"
-  systemctl --user daemon-reload
- fi
  if [[ -f "${SYSTEMD_TIMER}" ]]; then
   echo "Removing ${V_PRG_NAME} from your systemd timers"
-  systemctl --user disable spotify-easyrpm.timer
+  systemctl --user stop "${V_PRG_NAME}.timer"
+  systemctl --user disable "${V_PRG_NAME}.timer"
   rm "${SYSTEMD_TIMER}"
   systemctl --user daemon-reload
  fi
+ if [[ -f "${SYSTEMD_UNIT}" ]]; then
+  echo "Removing ${V_PRG_NAME} from your systemd unit files"
+  systemctl --user stop "${V_PRG_NAME}"
+  systemctl --user disable "${V_PRG_NAME}"
+  rm "${SYSTEMD_UNIT}"
+  systemctl --user daemon-reload
+ fi
 }
 
 f_remove_repo() {
@@ -280,15 +375,43 @@
  fi
 }
 
-f_install_build_deps() {
-for pkg in rpm-build squashfs jq rpmdevtools hicolor-icon-theme; do
+f_missing_build_deps() {
+# Fills V_MISSING_DEPS with whatever we need but do not have. Packages are
+# checked with rpm, tools with command -v so a rename upstream cannot hide them
+V_MISSING_DEPS=()
+for pkg in "${V_DEP_PKGS[@]}"; do
   if ! rpm -q "${pkg}" > /dev/null 2>&1; then
-    echo "Installing build dependencies (${pkg})"
-    if ! sudo zypper --non-interactive in "${pkg}"; then
-      f_error "Failed to install build dependencies (${pkg}). Aborting"
-    fi
+    V_MISSING_DEPS+=("${pkg}")
+  fi
+done
+for cmd in "${V_DEP_CMDS[@]}"; do
+  if ! command -v "${cmd}" > /dev/null 2>&1; then
+    V_MISSING_DEPS+=("${cmd}")
+  fi
+done
+}
+
+f_install_build_deps() {
+f_missing_build_deps
+for dep in "${V_MISSING_DEPS[@]}"; do
+  echo "Installing build dependencies (${dep})"
+  if ! sudo zypper --non-interactive in "${dep}"; then
+    f_error "Failed to install build dependencies (${dep}). Aborting"
   fi
 done
+f_check_build_deps
+}
+
+f_check_build_deps() {
+# A scheduled run has no terminal for sudo to prompt on, so report what is
+# missing instead of trying to install it
+f_missing_build_deps
+if [[ "${#V_MISSING_DEPS[@]}" -gt 0 ]]; then
+ if [[ "${V_RUN_MODE}" == "scheduled" ]]; then
+  f_abort "Missing dependencies: ${V_MISSING_DEPS[*]}. Run ${V_PRG_NAME} 
--quiet to install them. Aborting"
+ fi
+ f_abort "Dependencies still missing after install: ${V_MISSING_DEPS[*]}. 
Aborting"
+fi
 }
 
 f_prepare_src() {
@@ -309,39 +432,67 @@
 TryExec=spotify
 Terminal=false
 Type=Application
-Categories=Audio;Music;Player;AudioVideo;Qt;
+Categories=Audio;Music;Player;AudioVideo;
 MimeType=x-scheme-handler/spotify
+StartupWMClass=spotify
 EOF
 }
 
 
 f_ver_compare() {
-V_HTTP_REPO="$(curl -s -H 'Snap-Device-Series: 16' 
http://api.snapcraft.io/v2/snaps/info/spotify | jq -r '."channel-map"[] | 
select(.channel.name=='\"$PREF_CHANNEL\"') | .download.url')"
-V_HTTP_VERSION="$(curl -s -H 'Snap-Device-Series: 16' 
http://api.snapcraft.io/v2/snaps/info/spotify | jq -r '."channel-map"[] | 
select(.channel.name=='\"$PREF_CHANNEL\"') | .version')"
+echo "Asking snapcraft.io for the latest ${PREF_CHANNEL} Spotify release"
+if ! V_SNAP_INFO="$(curl -sfL -H 'Snap-Device-Series: 16' 
https://api.snapcraft.io/v2/snaps/info/spotify)"; then
+  f_error "Failed to query snapcraft.io for the latest Spotify release. 
Aborting"
+fi
+
+V_SNAP_ENTRY="$(jq -c --arg channel "${PREF_CHANNEL}" 'first(."channel-map"[] 
| select(.channel.name==$channel and .channel.architecture=="amd64"))' <<< 
"${V_SNAP_INFO}")"
+if [[ -z "${V_SNAP_ENTRY}" ]] || [[ "${V_SNAP_ENTRY}" == "null" ]]; then
+  f_error "snapcraft.io has no ${PREF_CHANNEL} release for Spotify. Aborting"
+fi
+
+V_HTTP_REPO="$(jq -r '.download.url' <<< "${V_SNAP_ENTRY}")"
+V_HTTP_VERSION="$(jq -r '.version' <<< "${V_SNAP_ENTRY}")"
+V_HTTP_SHA3_384="$(jq -r '.download."sha3-384"' <<< "${V_SNAP_ENTRY}")"
+
+if [[ -z "${V_HTTP_REPO}" ]] || [[ "${V_HTTP_REPO}" == "null" ]]; then
+  f_error "snapcraft.io did not return a download URL for Spotify. Aborting"
+fi
+
 V_HTTP_SNAP="$(basename "${V_HTTP_REPO}")"
 
+# RPM does not allow "-" in the version field
+V_HTTP_VERSION="${V_HTTP_VERSION//-/.}"
+if [[ ! "${V_HTTP_VERSION}" =~ ^[A-Za-z0-9._+~^]+$ ]]; then
+  f_error "snapcraft.io returned an unusable version string 
(${V_HTTP_VERSION}). Aborting"
+fi
+
 # Read repo versions
-readarray -t V_REPO_VERSION_NUMS < <( find "${V_LOCAL_REPO}" -type f -name 
"*.rpm" | sort | cut -f4 -d"-")
+V_REPO_VERSION_NUMS=()
+if [[ -d "${V_LOCAL_REPO}" ]]; then
+  while IFS= read -r V_REPO_RPM; do
+    V_REPO_VERSION_NUMS+=("$(f_rpm_version "${V_REPO_RPM}")")
+  done < <(find "${V_LOCAL_REPO}" -type f -name "${V_PKGNAME}-[0-9]*.rpm")
+fi
 
 # Add installed version if available
 if rpm -q "${V_PKGNAME}" > /dev/null 2>&1; then
-  V_REPO_VERSION_NUMS+=("$(rpm -q "${V_PKGNAME}" | cut -f3 -d"-")")
+  V_REPO_VERSION_NUMS+=("$(rpm -q --queryformat '%{VERSION}' "${V_PKGNAME}")")
 fi
 
 echo "Comparing snapcraft.io repo version to installed or local machine repo 
version (if any)"
 
-# Default to TRUE
-V_SNAPISNEWER=TRUE
-
 # Compare versions
 V_HIGHEST_VERSION="0"
 for V_REPO_VERSION_NUM in "${V_REPO_VERSION_NUMS[@]}"; do
-  if rpmdev-vercmp "$V_REPO_VERSION_NUM" "$V_HIGHEST_VERSION" | grep -q " > "; 
then
-    V_HIGHEST_VERSION="$V_REPO_VERSION_NUM"
+  if [[ -z "${V_REPO_VERSION_NUM}" ]]; then
+    continue
+  fi
+  if f_ver_gt "${V_REPO_VERSION_NUM}" "${V_HIGHEST_VERSION}"; then
+    V_HIGHEST_VERSION="${V_REPO_VERSION_NUM}"
   fi
 done
 
-if rpmdev-vercmp "$V_HTTP_VERSION" "$V_HIGHEST_VERSION" | grep -q " > "; then
+if f_ver_gt "${V_HTTP_VERSION}" "${V_HIGHEST_VERSION}"; then
   V_SNAPISNEWER=TRUE
 else
   V_SNAPISNEWER=FALSE
@@ -356,7 +507,7 @@
  while true
   do
    echo "The latest $PREF_CHANNEL version at snapcraft.io is ${V_HTTP_VERSION} 
which is already installed or available from local machine repo. "
-   read -rp "Continue anyway? (y/n)" Q_SAME_VER_CONTINUE
+   read -rp "Continue anyway? (y/n)" Q_SAME_VER_CONTINUE || f_abort_no_input
     case $Q_SAME_VER_CONTINUE in
 
       y ) echo "ok"
@@ -367,6 +518,8 @@
           echo "bye"
       exit;;
 
+      * ) echo "Please answer y or n";;
+
    esac
  done
  fi
@@ -377,6 +530,10 @@
 f_rpm_spec() {
 echo "Writing new build file"
 
+# A timestamped release keeps rebuilds of an unchanged Spotify version
+# installable, so packaging changes are not stuck behind an upstream bump
+V_RPM_RELEASE="$(date -u +%Y%m%d%H%M)"
+
 cat << EOF > "${V_SPECS_DIR}"/spotify.spec
 #
 # spec file for package ${V_PKGNAME}
@@ -395,9 +552,16 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
+# Repackaging a prebuilt binary, so there is nothing to extract debuginfo from
+%global debug_package %{nil}
+
+# Avoids "warning: Could not canonicalize hostname" on hosts that do not
+# resolve their own name
+%define _buildhost localhost
+
 Name:   ${V_PKGNAME}
 Version:  ${V_HTTP_VERSION}
-Release:  0
+Release:  ${V_RPM_RELEASE}
 License:  https://www.spotify.com/legal/end-user-agreement
 Summary:  Spotify streaming music client
 Vendor:   Spotify AB
@@ -497,7 +661,7 @@
 else
  while true
   do
-   read -rp "Do you wish to install the Spotify RPM (y/n)?" Q_RPM_INSTALL
+   read -rp "Do you wish to install the Spotify RPM (y/n)?" Q_RPM_INSTALL || 
f_abort_no_input
 
   case $Q_RPM_INSTALL in
   y ) f_rpm_install
@@ -506,6 +670,8 @@
   n ) echo "OK not installing now"
    break;;
 
+  * ) echo "Please answer y or n";;
+
   esac
  done
 fi
@@ -520,6 +686,28 @@
 }
 
 
+f_secure_repo() {
+# Only the invoking user needs write access here. A world writable repo
+# combined with gpgcheck=0 would let any local user stage a package that
+# zypper then installs as root
+if [[ ! -d "${V_LOCAL_REPO}" ]]; then
+ return 0
+fi
+if [[ "$(stat -c '%U %a' "${V_LOCAL_REPO}" 2>/dev/null)" == "$(id -un) 755" 
]]; then
+ return 0
+fi
+echo "Restricting ${V_LOCAL_REPO} to your user"
+if ! sudo chown -R "$(id -u)":"$(id -g)" "${V_LOCAL_REPO}"; then
+ f_error "Failed to set ownership on ${V_LOCAL_REPO}. Aborting"
+fi
+if ! sudo find "${V_LOCAL_REPO}" -type d -exec chmod 755 {} \+; then
+ f_error "Failed to chmod ${V_LOCAL_REPO}"
+fi
+if ! sudo find "${V_LOCAL_REPO}" -type f -exec chmod 644 {} \+; then
+ f_error "Failed to chmod ${V_LOCAL_REPO}"
+fi
+}
+
 f_create_repo() {
 if ! rpm -q createrepo_c > /dev/null 2>&1; then
  echo "Installing CreateRepo for local filesystem repo"
@@ -529,20 +717,15 @@
 fi
 if [[ ! -d "${V_LOCAL_REPO}" ]]; then
  echo "Creating local filesystem repo at ${V_LOCAL_REPO}"
- if ! sudo mkdir -p ${V_LOCAL_REPO}; then
+ if ! sudo mkdir -p "${V_LOCAL_REPO}"; then
   f_error "Failed to create local filesystem repo at ${V_LOCAL_REPO}. Aborting"
  fi
 fi
-if ! sudo find ${V_LOCAL_REPO} -type d -exec chmod 777 {} \+; then
- f_error "Failed to chmod ${V_LOCAL_REPO}"
-fi
-if ! sudo find ${V_LOCAL_REPO} -type f -exec chmod 666 {} \+; then
- f_error "Failed to chmod ${V_LOCAL_REPO}"
-fi
+f_secure_repo
 f_update_local_repo
 if [[ ! -f /etc/zypp/repos.d/${V_PRG_NAME}.repo ]]; then
  echo "Adding local file system repository to zypper"
- if ! sudo zypper ar -G --refresh "${V_LOCAL_REPO}" "${V_PRG_NAME}"; then
+ if ! sudo zypper ar -G --refresh -K "${V_LOCAL_REPO}" "${V_PRG_NAME}"; then
   f_error "Failed to add local repo to zypper. Aborting"
  fi
 fi
@@ -581,9 +764,12 @@
 
 
 f_update_local_repo() {
+if [[ ! -d "${V_LOCAL_REPO}" ]]; then
+ f_error "Local repo ${V_LOCAL_REPO} does not exist. Run ${V_PRG_NAME} 
--create-schedule to recreate it. Aborting"
+fi
 if [[ "${V_RUN_MODE}" != "clean-repo" ]]; then
 echo "Moving any Spotify RPMs from your rpmbuild ${V_RPMS_DIR} to your local 
repo ${V_LOCAL_REPO}"
-find "${V_RPMS_DIR}"/"${V_RPM_ARCH}"/ -name "${V_PKGNAME}-*${V_RPM_ARCH}.rpm" 
-type f -exec mv -t "${V_LOCAL_REPO}" {} \+
+find "${V_RPMS_DIR}"/"${V_RPM_ARCH}"/ -name 
"${V_PKGNAME}-[0-9]*${V_RPM_ARCH}.rpm" -type f -exec mv -t "${V_LOCAL_REPO}" {} 
\+
 fi
 if ! createrepo -q "${V_LOCAL_REPO}"; then
  f_error "Failed to create / update local repo. Aborting"
@@ -591,19 +777,43 @@
 }
 
 f_clean_repo() {
-sudo find "${V_LOCAL_REPO}" -type f -name "*.rpm" -exec rm {} \;
+if [[ ! -d "${V_LOCAL_REPO}" ]]; then
+ echo "No local repo at ${V_LOCAL_REPO}. Nothing to clean"
+ exit 0
+fi
+f_secure_repo
+
+# Work out which RPM to keep - the highest version, and for equal
+# versions the most recently built one
+V_KEEP_RPM=""
+V_KEEP_VERSION="0"
+while IFS= read -r V_REPO_RPM; do
+  V_REPO_VERSION="$(f_rpm_version "${V_REPO_RPM}")"
+  if [[ -z "${V_KEEP_RPM}" ]] || f_ver_gt "${V_REPO_VERSION}" 
"${V_KEEP_VERSION}" ||
+     { [[ "${V_REPO_VERSION}" == "${V_KEEP_VERSION}" ]] && [[ "${V_REPO_RPM}" 
-nt "${V_KEEP_RPM}" ]]; }; then
+    V_KEEP_RPM="${V_REPO_RPM}"
+    V_KEEP_VERSION="${V_REPO_VERSION}"
+  fi
+done < <(find "${V_LOCAL_REPO}" -type f -name "${V_PKGNAME}-[0-9]*.rpm")
+
+if [[ -z "${V_KEEP_RPM}" ]]; then
+ echo "No ${V_PKGNAME} RPMs found in ${V_LOCAL_REPO}"
+else
+ # Sweeps out any debuginfo / debugsource left by older versions of this script
+ echo "Keeping ${V_KEEP_RPM##*/} and removing everything older"
+ find "${V_LOCAL_REPO}" -type f -name "${V_PKGNAME}-*.rpm" ! -path 
"${V_KEEP_RPM}" -print -delete
+fi
 f_update_local_repo
 echo "done!"
 }
 
 f_set_channel() {
-if [[ -z $PREF_CHANNEL ]]; then
- f_error "Please specify either 'stable' or 'edge'"
-else
- sed -i "s/\(PREF_CHANNEL=\)\(.*\)/\1$PREF_CHANNEL/" "${V_CONFIG_FILE}"
- sed -i "s/\(PREF_PROMPT_CHANNEL=\)\(.*\)/\1NO/" "${V_CONFIG_FILE}"
- echo "done!"
+if [[ ! "${PREF_CHANNEL}" == "stable" ]] && [[ ! "${PREF_CHANNEL}" == "edge" 
]]; then
+ f_abort "Please specify either 'stable' or 'edge'"
 fi
+sed -i "s/\(PREF_CHANNEL=\)\(.*\)/\1${PREF_CHANNEL}/" "${V_CONFIG_FILE}"
+sed -i "s/\(PREF_PROMPT_CHANNEL=\)\(.*\)/\1NO/" "${V_CONFIG_FILE}"
+echo "done!"
 }
 
 f_main() {
@@ -632,6 +842,7 @@
                         ;;
     --scheduled | -scheduled )  V_RUN_MODE="scheduled"
                         if f_check_metered ; then break ; fi
+                        f_check_build_deps
                         f_release_channel
                         f_ver_compare
                         f_download

++++++ spotify-easyrpm.obsinfo ++++++
--- /var/tmp/diff_new_pack.t2Ffg9/_old  2026-08-18 16:37:36.909360930 +0200
+++ /var/tmp/diff_new_pack.t2Ffg9/_new  2026-08-18 16:37:36.925361504 +0200
@@ -1,5 +1,5 @@
 name: spotify-easyrpm
-version: 3.0.7
-mtime: 1759416851
-commit: 286b2a3db967405935bba6d59be2a00f804d5d42
+version: 4.0.1
+mtime: 1787003235
+commit: 34d77d964fb239be8b21989fe798167d77a9c41e
 

Reply via email to