Friday, September 12, 2014

Auto-Update of Dart on Linux


Updating Dart packages as part of an automated test suite is easy (pub upgrade). But what about updating Dart itself?

As a coder, my instinct is a curl script to check the dartlang.org page for the latest release, then a Bash script to compare that value with the current install, then download, unzip and install. I am almost tempted to head down that rabbit hole—like all rabbit holes, it sounds fun from the outside. But, <deep breath>, maybe there is a better way.

The DartEditor has an auto-update feature, but if that is easily accessed from the command-line or code, I cannot find it. Shame. That too sounds like a fun rabbit hole.

So instead, I note that there are Debian packages for the SDK. I could add my CI server's user to the sudoers list for updating the package list and upgrading the SDK. I will not easily be able to trigger a new build when new versions of Dart are available, but I probably want to run the test suite every night regardless. Also, I like my grapes sour, dammit.

But that won't work either. My CI server is still 32-bit. Bleh.

So rabbit hole #1 it is. I will write a Bash script that will compare the currently installed version of Dart with the latest—installing the latest as needed.

First up, determining the latest version. Instead of scraping the dartlang.org site, I find that the VERSION resource at https://storage.googleapis.com/dart-archive/channels/stable/release/latest/VERSION is a better bet:
$ curl https://storage.googleapis.com/dart-archive/channels/stable/release/latest/VERSION 2>/dev/null                      ~/Downloads
{
  "revision": "39553",
  "version" : "1.6.0",
  "date"    : "201408270039"
}
Thanks to curl, I can grab that JSON and run it through grep and sed to find what I need:
VERSION_URL='https://storage.googleapis.com/dart-archive/channels/stable/release/latest/VERSION'

latest=`curl $VERSION_URL 2>/dev/null |
  grep version |
  sed -e 's/\s*"version"\s*:\s*"//' \
      -e 's/".*//'`
Checking the currently installed version is easy enough, though I do set +e to prevent the script from halting if the dart executable is not already installed:
set +e
current=`drt --version 2>&1 |
  sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
set -e
I am fairly proficient at what comes next. I remove the “old” Dart (a backup of the currently installed Dart), then move the currently installed Dart to dart.old. Last, I download and unzip Dart:
rm -rf $ROOT_DIR/dart.old
mv $ROOT_DIR/dart $ROOT_DIR/dart.old

rm -f /tmp/dart.zip
wget -O /tmp/dart.zip $DOWNLOAD_URL

cd $ROOT_DIR
unzip /tmp/dart.zip
I am using the DartEditor as the DOWNLOAD_URL as I need the content_shell associated with it for testing. The DartEditor zip extracts into the dart directory so I have my replacement for the old $ROOT_DIR/dart install.

Last, I need to download content_shell for testing. The DartEditor zip includes a download script, but not the actual executable as it is somewhat largish. This should do the trick:
cd $ROOT_DIR/dart

./chromium/download_contentshell.sh
unzip content_shell-linux-*-release.zip
mv drt-lucid*-full-stable-* content_shell
The whole script is then:
#!/bin/sh

ROOT_DIR='/home/chris/local'

VERSION_URL='https://storage.googleapis.com/dart-archive/channels/stable/release/latest/VERSION'
DOWNLOAD_URL='https://storage.googleapis.com/dart-archive/channels/stable/release/latest/editor/darteditor-linux-ia32.zip'

latest=`curl $VERSION_URL 2>/dev/null |
  grep version |
  sed -e 's/\s*"version"\s*:\s*"//' \
      -e 's/".*//'`

set +e
current=`dart --version 2>&1 |
  sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
set -e

echo "Latest: $latest"
echo "Current: $current"
echo ""

if [ "$current" = "$latest" ]; then
    echo "Up to date."
    exit 0
fi

echo "Downloading the latest version of Dart!"
echo ""

rm -rf $ROOT_DIR/dart.old
set +e
mv $ROOT_DIR/dart $ROOT_DIR/dart.old
set -e

rm -f /tmp/dart.zip
wget -nv -O /tmp/dart.zip $DOWNLOAD_URL

cd $ROOT_DIR
unzip -q /tmp/dart.zip

cd $ROOT_DIR/dart

./chromium/download_contentshell.sh
unzip content_shell-linux-*-release.zip
mv drt-lucid*-full-stable-* content_shell
Which does the trick. Even on my Debian 32 bit CI server:



Sometime the first rabbit hole really is the best option.


Day #181

2 comments:

  1. I use this script to check for updates and download/install it when there is one
    https://gist.github.com/zoechi/d240f56a32ed5649797f

    ReplyDelete
    Replies
    1. Nice. Yours seems a little more sophisticated than mine, so I may very well switch over. I'm glad to see that I wasn't missing a more obvious way to accomplish this :)

      Delete