Skip to content

Commit

Permalink
Major refactor using gh-pages to store a debian repo
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcooper committed Jul 7, 2017
1 parent a498e7e commit b08b869
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 102 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
apt-repo/
librespot/
raspotify*.deb
raspotify/usr/bin/librespot
Expand Down
15 changes: 8 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
FROM debian:stretch

# Install git and compilers
RUN apt-get update && apt-get install -y \
build-essential \
curl \
git \
# Install git and compilers, let's toss gnupg and reprepro in there so we can
# use this container to make the apt repo as well
RUN apt-get update && apt-get -y upgrade && apt-get install -y \
build-essential \
curl \
git \
gnupg \
reprepro \
&& rm -rf /var/lib/apt/lists/*

RUN mkdir /toolchain
Expand All @@ -31,5 +34,3 @@ RUN curl -O ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.29.tar.bz2 \
&& cd .. && rm -rf alsa-lib-1.0.29.tar.bz2 alsa-lib-1.0.29

RUN mkdir /build

CMD /mnt/build.sh in_docker_container
62 changes: 59 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
.PHONY: all clean container apt apt-deploy apt-repo-warning apt-deploy-warning

# You'll need my GPG_KEY for signing, which I'm pretty sure you don't have :P
APT_GPG_KEY?=2CC9B80F5AE2B7ACEFF2BA3209146F2F7953A455
APT_GH_PAGES_REPO?[email protected]:dtcooper/raspotify.git

raspotify_*.deb:
./build.sh
docker build -t raspotify .
docker run \
--rm \
--volume "$(CURDIR):/mnt/raspotify" \
--env PERMFIX_UID="$$(id -u)" \
--env PERMFIX_GID="$$(id -g)" \
raspotify /mnt/raspotify/build.sh

clean:
rm -rf *.deb librespot raspotify/usr raspotify/DEBIAN/control
rm -rf *.deb librespot raspotify/usr raspotify/DEBIAN/control apt-repo

distclean: clean
docker rmi raspotify

apt: apt-repo

apt-repo-warning:
@printf '\n >> This will overwrite the apt-repo directory. Are you sure? (y/N) '
@read YESNO; \
if echo "$$YESNO" | grep -vq '^[yY]'; then \
exit 1; \
fi;

apt-repo: raspotify_*.deb apt-repo-warning
# # Shallow clone of github pages for overwrite
rm -rf apt-repo
git clone -b gh-pages --single-branch "$(APT_GH_PAGES_REPO)" apt-repo
docker build -t raspotify .
# # Needs an interactive terminal to get gpg passphrase
docker run \
--interactive \
--tty \
--rm \
--volume "$(CURDIR):/mnt/raspotify" \
--volume "$(HOME)/.gnupg:/root/.gnupg" \
--env GPG_KEY="$(APT_GPG_KEY)" \
--env PERMFIX_UID="$$(id -u)" \
--env PERMFIX_GID="$$(id -g)" \
raspotify /mnt/raspotify/make-apt-repo.sh

apt-deploy-warning:
@printf '\n >> This will amend and overwrite the last commit to the gh-pages branch, and\n'
@printf ' >> *FORCE PUSH* the branch to $(APT_GH_PAGES_REPO). Are you sure? (y/N) '
@read YESNO; \
if echo "$$YESNO" | grep -vq '^[yY]'; then \
exit 1; \
fi;

apt-deploy: apt apt-deploy-warning
gpg --armor --export "$(APT_GPG_KEY)" > apt-repo/key.asc
cp -v README.md LICENSE install.sh apt-repo
cd apt-repo && git add -A
cd apt-repo && git commit --amend -C HEAD --reset-author
# # Force push, overwriting gh-pages branch chomping previous versions.
cd apt-repo && git push -f origin gh-pages

.PHONY: all
all: raspotify_*.deb
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ _**Spotify Connect client for the Raspberry Pi that Just Works™.**_
Install the Spotify Connect client on your Raspberry Pi,

```
curl -sL https://raw.github.com/dtcooper/raspotify/master/install.sh | sh
curl -sL https://dtcooper.github.io/raspotify/install.sh | sh
```

## Introduction

Raspotify is a Spotify Connect client for [Raspbian](https://www.raspberrypi.org/downloads/raspbian/)
on the Raspberry Pi that Just Works™. Raspotify is a Debian package which thinly
wraps the awesome [librespot](https://github.com/plietar/librespot) library by
[Paul Lietar]([https://github.com/plietar) that works out of the box on all three
versions of the Pi, immediately after installation.
Raspotify is a [Spotify Connect](https://www.spotify.com/connect/) client for
[Raspbian](https://www.raspberrypi.org/downloads/raspbian/) on the Raspberry Pi
that Just Works™. Raspotify is a
[Debian package and associated repository](https://en.wikipedia.org/wiki/Deb_\(file_format\))
which thinly wraps the awesome
[librespot](https://github.com/plietar/librespot) library by
[Paul Lietar](https://github.com/plietar) that works out of the box on all three
revisions of the Pi, immediately after installation.

## Download Latest Version

Expand All @@ -27,7 +30,8 @@ the [directions below](#easy-installation).
### Requirements

Raspotify works on a Raspberry Pi running [Raspbian](https://www.raspberrypi.org/downloads/raspbian/).
You'll need a Spotify Premium account in order to use Connect.
You'll need a [Spotify Premium](https://www.spotify.com/premium/) account in order
to use Connect.

Raspotify should work on _any_ Pi but it has been tested on,

Expand All @@ -41,7 +45,7 @@ Download the Debian package and install it. Run the following at the command
line on your Pi to install the latest version.

```
curl -sL https://raw.github.com/dtcooper/raspotify/master/install.sh | sh
curl -sL https://dtcooper.github.io/raspotify/install.sh | sh
```

That's it! Plug a speaker into your Pi on your local network, select the device
Expand All @@ -55,6 +59,12 @@ To uninstall, remove the package,
sudo apt-get remove -y raspotify
```

To completely remove the Raspotify and its Debian repo, try
```
sudo apt-get remove -y --purge raspotify
sudo rm -v /etc/apt/sources.list.d/raspotify.list
```

## Configuration

Raspotify works out of the box and should be discoverable on Spotify Connect on
Expand Down Expand Up @@ -85,16 +95,16 @@ which passes arguments to [librespot](https://github.com/plietar/librespot).
# Uncomment to use a cache for downloaded audio files. It's best to leave this
# as-is since permissions are properly set on directory `/var/cache/raspotify'.
#CACHE_ARGS="--cache /var/cache/raspotify"
```

After editing restart the daemon by running `sudo systemctl restart raspotify`.

## Building the Package Yourself

All that's required is [Docker](https://www.docker.com/) on a \*nix system with git
and Make. It can built on any amd64 platform that runs docker using Raspberry Pi's
cross-compiler (tested on Ubuntu 16.04 LTS and macOS El Capitan).
All that's required is [Docker](https://www.docker.com/) on a \*nix system with
[git](https://git-scm.com/) and [Make](https://www.gnu.org/software/make/). It
can built on any amd64 platform that runs docker using Raspberry Pi's cross-compiler
(tested on Ubuntu 16.04 LTS and macOS El Capitan).

```
git clone https://github.com/dtcooper/raspotify
Expand All @@ -111,5 +121,7 @@ file for details.

## Acknowledgments

Special thanks to [Paul Lietar]([https://github.com/plietar) for
Special thanks to [Paul Lietar](https://github.com/plietar) for
[librespot](https://github.com/plietar/librespot), which Raspotify packages.
Without [librespot](https://github.com/plietar/librespot), Raspotify would simply
not exist.
82 changes: 44 additions & 38 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,53 +1,59 @@
#!/bin/sh

echo 'Building in docker container'

set -e
cd /mnt/raspotify

# Install most recent version of rust
curl https://sh.rustup.rs -sSf | sh -s -- -y
export PATH="/root/.cargo/bin/:$PATH"
export CARGO_TARGET_DIR="/build"
export CARGO_HOME="/build/cache"

# We're NOT in the docker container, so let's build it and enter
if [ "$1" != 'in_docker_container' ]; then
cd "$(dirname "$0")"
# Install the gcc wrapper in container into cargo
mkdir /.cargo
echo '[target.arm-unknown-linux-gnueabihf]\nlinker = "gcc-wrapper"' > /.cargo/config
rustup target add arm-unknown-linux-gnueabihf

if [ ! -d librespot ]; then
echo "No directory named librespot exists! Cloning..."
git clone git://github.com/plietar/librespot.git
fi
# Get the git rev of raspotify for .deb versioning
RASPOTIFY_GIT_VER="$(git describe --tags --always --dirty 2>/dev/null || echo unknown)"

# Build Docker container and run script
docker build -t raspotify .
docker run --rm -v "$(pwd):/mnt" raspotify
else
echo 'Building in docker container'
if [ ! -d librespot ]; then
echo "No directory named librespot exists! Cloning..."
git clone git://github.com/plietar/librespot.git
fi

# Install most recent version of rust
curl https://sh.rustup.rs -sSf | sh -s -- -y
export PATH="/root/.cargo/bin/:$PATH"
export CARGO_TARGET_DIR="/build"
export CARGO_HOME="/build/cache"
# Get the git rev of librespot for .deb versioning
cd librespot
LIBRESPOT_GIT_REV="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
LIBRESPOT_DEB_VER="$(TZ=UTC git show --quiet --date='format-local:%Y%m%dT%H%M%SZ' --format="%cd.%h" "$LIBRESPOT_GIT_REV" 2>/dev/null || echo "unknown")"

mkdir /.cargo
echo '[target.arm-unknown-linux-gnueabihf]\nlinker = "gcc-wrapper"' > /.cargo/config
rustup target add arm-unknown-linux-gnueabihf
# Build librespot
cargo build --release --target arm-unknown-linux-gnueabihf --no-default-features --features alsa-backend

cd /mnt
RASPOTIFY_GIT_VER="$(git describe --tags --always --dirty=-modified 2>/dev/null || echo unknown)"
# Copy librespot to pkg root
cd /mnt/raspotify
mkdir -p raspotify/usr/bin
cp -v /build/arm-unknown-linux-gnueabihf/release/librespot raspotify/usr/bin

cd librespot
LIBRESPOT_GIT_REV="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
cargo build --release --target arm-unknown-linux-gnueabihf --no-default-features --features alsa-backend
# Strip dramatically decreases the size
arm-linux-gnueabihf-strip raspotify/usr/bin/librespot

cd /mnt
mkdir -p raspotify/usr/bin
cp -v /build/arm-unknown-linux-gnueabihf/release/librespot raspotify/usr/bin
# Compute final package version + filename
DEB_PKG_VER="${RASPOTIFY_GIT_VER}~librespot.${LIBRESPOT_DEB_VER}"
DEB_PKG_NAME="raspotify_${DEB_PKG_VER}_armhf.deb"
echo "$DEB_PKG_NAME"
sed "s/<<<VERSION>>>/$DEB_PKG_VER/g" control.debian.tmpl > raspotify/DEBIAN/control

# Strip dramatically decreases the size
arm-linux-gnueabihf-strip raspotify/usr/bin/librespot
# Copy over copyright
mkdir -p raspotify/usr/share/doc/raspotify
cp -v LICENSE raspotify/usr/share/doc/raspotify/copyright

DEB_PKG_VER="${RASPOTIFY_GIT_VER}~librespot-${LIBRESPOT_GIT_REV}-1"
DEB_PKG_NAME="raspotify_${DEB_PKG_VER}_armhf.deb"
sed "s/<<<VERSION>>>/$DEB_PKG_VER/g" control.debian.tmpl > raspotify/DEBIAN/control
# Finally, build debian package
dpkg-deb -b raspotify "$DEB_PKG_NAME"

mkdir -p raspotify/usr/share/doc/raspotify
cp -v LICENSE raspotify/usr/share/doc/raspotify/copyright
# Perm fixup. Not needed on macOS, but is on Linux
chown -R "$PERMFIX_UID:$PERMFIX_GID" /mnt/raspotify 2> /dev/null

fakeroot dpkg-deb -b raspotify "$DEB_PKG_NAME"
echo "Package built as $DEB_PKG_NAME"
fi
echo "Package built as $DEB_PKG_NAME"
60 changes: 19 additions & 41 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,62 +1,40 @@
#!/bin/sh

REQUIRED_PACKAGES="libasound2 adduser"
SOURCE_REPO="deb https://dtcooper.github.io/raspotify jessie main"

# Install script for Raspotify. Downloads and installs Debian package.
# Install script for Raspotify. Adds the Debian repo and installs.
set -e

run_on_pi_only() {
echo "Raspotify installer only runs on a Raspberry Pi"
exit 1
}

if ! which apt-get > /dev/null; then
if ! which apt-get apt-key > /dev/null; then
run_on_pi_only
fi

DID_APT_GET_UPDATE=

do_apt_get_update() {
if [ -z "$DID_APT_GET_UPDATE" ]; then
sudo apt-get update
DID_APT_GET_UPDATE=1
# You probably have these
PREREQ_PACKAGES="curl apt-transport-https lsb-release"
PREREQ_PACKAGES_TO_INSTALL=
for package in $PREREQ_PACKAGES; do
if ! dpkg-query --show --showformat='${db:Status-Status}\n' "$package" 2> /dev/null | grep -q '^installed$'; then
PREREQ_PACKAGES_TO_INSTALL="$package $PREREQ_PACKAGES_TO_INSTALL"
fi
}
done

if ! which lsb_release > /dev/null; then
do_apt_get_update
sudo apt-get install -y lsb-release
if [ "$PREREQ_PACKAGES_TO_INSTALL" ]; then
sudo apt-get update
sudo apt-get -y install $PREREQ_PACKAGES_TO_INSTALL
fi

if lsb_release -si | fgrep -ivq raspbian; then
run_on_pi_only
fi

# Add public key to apt
curl -sSL https://dtcooper.github.io/raspotify/key.asc | sudo apt-key add -v -
echo "$SOURCE_REPO" | sudo tee /etc/apt/sources.list.d/raspotify.list

if ! which curl > /dev/null; then
do_apt_get_update
sudo apt-get install -y curl
fi


LATEST_RELEASE="$(curl -Ls https://api.github.com/repos/dtcooper/raspotify/releases/latest | fgrep browser_download_url | head -n 1 | cut -d '"' -f 4)"
if [ -z "$LATEST_RELEASE" ]; then
echo "Can't find latest Raspotify release on GitHub"
exit 1
fi

PACKAGES_TO_INSTALL=
for package in $REQUIRED_PACKAGES; do
if ! dpkg-query --show --showformat='${db:Status-Status}\n' "$package" 2> /dev/null | grep -q '^installed$'; then
PACKAGES_TO_INSTALL="$package $PACKAGES_TO_INSTALL"
fi
done

if [ "$PACKAGES_TO_INSTALL" ]; then
do_apt_get_update
sudo apt-get -y install $PACKAGES_TO_INSTALL
fi

cd /tmp
curl -Lo raspotify-latest.deb "$LATEST_RELEASE"
sudo dpkg -i --force-confold raspotify-latest.deb
rm raspotify-latest.deb
sudo apt-get update
sudo apt-get -y install raspotify
Loading

0 comments on commit b08b869

Please sign in to comment.