I had a few days off work this week. It was very enjoyable to spend a bit more time with the family, doing some jobs around the house, going for walks, and generally nothing else, thanks to The Event
.
However, in the quiet moments I still find myself browsing around, stumbling on new software I know will be enjoyed by my friends on Linux, and feel compelled to package it up, as a snap. This time around I found a post on /r/gnome about “Spot” a Gtk/Rust Spotify client.
It ticks some boxes for me:
- Rust apps are easy to snap ✅
- GNOME applications fit with my desktop ✅
- Not Electron (nothing against electron, but y’know) ✅
- Spotify ✅
- Leaner than the official client ✅
- Not currently snapped ✅
So obviously I took a look at snapping it. It wasn’t super challenging, having snapped a bunch of Rust and GNOME applications already. I won’t go through the full snapcraft.yaml
in detail because I’ve gone through them before, and there’s only a few interesting differences here. Here’s the full yaml
though.
name: spot
base: core20 # the base snap is the execution environment for this snap
adopt-info: spot
summary: Gtk/Rust native Spotify client for the Gnome desktop.
description: |
Gtk/Rust native Spotify client for the Gnome desktop.
architectures:
- build-on: amd64
- build-on: arm64
grade: stable
confinement: strict
parts:
spot:
plugin: rust
source: https://github.com/xou816/spot.git
override-pull: |
snapcraftctl pull
snapcraftctl set-version "$(git describe --tag)"
build-packages:
- build-essential
- pkg-config
- meson
- cargo
- libssl-dev
- libglib2.0-dev-bin
- libgtk-3-dev
- libasound2-dev
- libpulse-dev
override-build: |
meson target -Dbuildtype=release -Doffline=false
ninja -C target
mkdir $SNAPCRAFT_PART_INSTALL/bin
mkdir -p $SNAPCRAFT_PART_INSTALL/share/spot
cp target/target/debug/spot $SNAPCRAFT_PART_INSTALL/bin
cp target/src/spot.gresource $SNAPCRAFT_PART_INSTALL/share/spot
layout:
/usr/local/share/spot/spot.gresource:
symlink: $SNAP/share/spot/spot.gresource
slots:
spot:
interface: dbus
bus: session
name: dev.alextren.Spot
spot-mpris:
interface: mpris
name: Spot
apps:
spot:
command: bin/spot
extensions: [gnome-3-38]
common-id: dev.alextren.Spot
plugs:
- audio-playback
- network
- x11
- opengl
- desktop
- desktop-legacy
- password-manager-service
A couple of interesting things to note though. I’m using the gnome-3-38
extension which is currently experimental which means I can’t use the automated build service right now. So I’m building this in an empty container on my laptop and publishing directly to the store. Once Launchpad is able to handle this extension, it’ll build there. So that means the application isn’t updated in lock step with the upstream repo, currently.
Also maybe of interest is the layout
section I am using. Thanks to Ken from the Ubuntu Desktop Team for suggesting this. I’m using this because Spot looks for a gresource
file in a location outside the scope of the contained snap. Layouts do some magic voodoo to remap at runtime to make the application think files are where they aren’t.
Once the snap was built, I requested the name spot
from the store. Typically as a publisher I would just snapcraft register spot
but on this occasion the name had already been taken by someone who had never published a snap. So I filed a dispute with the store team, who ‘ruled’ in my favour and handed me the snap name. It doesn’t always go like that, so sometimes you need to contact the original registrant and have a conversation to cleanly hand over the name, or work to collaborate on the application, if applicable.
I filed the dispute at 17:32 on Tuesday 16th and was granted the name by the security team by 17:33, which is quick by any measure. After playing with the application for about 20 minutes or so, I decided to mention the snap online.
Having a play with Spot, a GTK spotify client. Early days, so it's a bit unstable, but pretty well done so far. https://t.co/Rp8zrO1aim pic.twitter.com/ObslcfOUDN
— Alan Pope 🍺🐧🐱🇬🇧🇪🇺 (@popey) February 16, 2021
By this point the snap was still on my hard disk and not uploaded to the store. I fiddled with the snap a little and on Wednesday I tried uploading to the store, knowing it would fail. It uses a couple of features which require an initial manual review. Specifically the use of the dbus name dev.alextren.Spot
and access to the mpris
interface to enable media controls.
I knew this because I run the same review-tools
against the snap before uploading. So I filed a request on the snapcraft forum around lunchtime, asking the security team to allow my snap to use those features.
Pretty soon after the requests were granted. While this was happening Joey at OMGUbuntu wrote about the application after seeing my tweet above. I do like packaging zeitgeisty applications!
The security team allowed my use of the dbus name and mpris, which enabled my uploads to be published. So I released a build to the edge
channel and continued iterating and testing. I kept the build in the edge
channel for now, until the upstream does a stable release.
The Spotify developers don’t have an arm build of the official application, so Raspberry Pi users can either use the web or ncspot. While ncspot is awesome, some people prefer a graphical interface to their music. So I figured I’d try building an arm64 version of Spot. I did this directly on my Raspberry Pi 400, and then uploaded to the store, again to the edge
channel. The tweet below shows the application running on my Pi.
Added an arm64 build of Spot (Open Source Gtk Spotify app) to the Snap Store. Runs okay on my Raspberry Pi here. https://t.co/NXq7xqlKo2 https://t.co/0VrYOJsnI1 pic.twitter.com/7yIEwQ2gD2
— Alan Pope 🍺🐧🐱🇬🇧🇪🇺 (@popey) February 18, 2021
I’ll likely automate these builds. They’re Rust, so they take a while to run on any platform. I want to make sure the snap is kept up to date with the upstream development as much as possible. It’s really great to see someone working on a native way to access Spotify on the GNOME desktop. So I’m really happy to help shine a light on this application.
Grab a copy for your desktop, laptop or Raspberry Pi at the link below. It’s only 6MB!