boxenのPuppetfileを一発更新するスクリプトを書いた

 · 5 min read

こんにちは。
今使っているMacBook Airの容量がほぼ一杯になってしまったので、
クリーンインストールをしようと思っています。

Time machineから復旧してしまうと何も変わらないので、
boxenというGithub社が提供しているセットアップツールを使おうと思います。 詳しい使い方は上記リンクをご参照ください。

BoxenではPuppetfileという設定ファイルで色々とアプリを読み込んだり出来るのですが、
このバージョンをいちいち更新するのがひどく面倒くさい。 でも、出来れば常にメンテされた最新版でありたい。

そんな悩みを解消するため、
Pupeetfileで読み込んでいるResourcesのバージョンを全て更新するスクリプトを書きました。

とてもピンポイントですが、
同じ悩みを抱える方には需要のある内容だと思います。

boxenとは、基本的な使い方

繰り返しになりますが、
boxenとは、Github社が提供しているMacのセットアップツールです。

基本的な知識や導入方法についてはこちらのリンクを御覧ください。
先に下記リンクを読んでboxenについて軽く抑えておくといいと思います。

Puppetfileとは

Puppetfileとは、

外部のresourceを使う場合はここで指定する。現在主に仕えるのはboxenにある boxen-* という名前のリポジトリに入っているもの。設定自体は~/src/my-boxenにあるPuppetfileに書く。
Puppetfileには初期状態で何個か設定がある。こいつらはBoxen自体が使ったりするので消さないこと。
Boxen使わなくても許されるのは2012年までだよね

とあるように、外部のresources(アプリやツールなど)を読み込むための設定ファイルです。
4行くらい例を出してみます。

github "dropbox",     "1.0.0"
github "mysql",       "1.0.0"
github "iterm2",      "1.0.0"
github "chrome",      "1.0.0"

このように、dropboxchrome、他にもimagemagickなどがあって、
自分の作りたい環境に合わせて組み合わせることができます。

resource名の後ろにある数字は、バージョンです。

このバージョンはどこから取得するかというと、
例えばdropboxの場合なら、

  1. https://github.com/boxen/puppet-dropboxにアクセスして
  2. Releasesをクリック、表示されたページにあるTagsをクリックして、
  3. 表示されたバージョンのいずれかを指定

結構めんどい手順

という結構めんどい手順が必要です。

読み込むファイルが10個くらいならまだ良いのですが、
色々欲しがってしまう僕は30個以上読み込んでいます。

これらのresource全てを最新版に保つのはあまりにめんどい!
面倒なのもあるけど、見間違え、打ち間違えが出そう!

と思ったので、このバージョンを自動更新するスクリプトを書きました。

Github APIについて

resourceはGithubで公開されているなら、
GithubのAPIを使えばタグも取れんじゃない?

と思ったので、調べてみたらありました。 とあるリポジトリのタグ一覧を取得するには、

GET /repos/:owner/:repo/tags
Repos | GitHub API

とアクセスすればいいようです。

これなら、別途設定ファイルを作らずに、
Puppetfileを読み込んで更新かけられそうです。

自動更新するスクリプト

ということでphpで実装してみました。
ソースコードは最後に載せます。

このスクリプトを動かす前に少しだけ準備があります。

boxenが必須としている部分を書き換えてしまうのは怖いので、
自動アップデートをかける範囲を指定できるようにしました。

Puppetfileの中にこんな感じで指定します。

# ---auto update---
github "osx",            "1.3.2"
github "alfred",         "1.1.1"
github "wunderlist",     "1.0.0"
…
# ---/auto update---

この# ---auto update---という部分はphpの中で定数化しているので、
ダウンロードして各自お好みにカスタマイズして下さい。

そして自動更新のphpファイルを、自分のboxenリポジトリ直下に配置します。
phpファイルを設置したら、ターミナルでそのリポジトリを開いて、

$ cd /path/to/my-boxen/
$ php autoUpdate.php

と実行すると、
Puppetfileのコメントで指定した範囲内がアップデートされます。

ちなみに、アップデートしたresourceは、標準出力で通知します。

標準出力で通知

こんな感じ

まとめ

ソースコードはこちらになります。

<?php
define("READ_START_SYMBOL", "# ---auto update---");
define("READ_END_SYMBOL", "# ---/auto update---");
//
function notify_update($name, $from, $to) {
echo "updated '".$name."' from ".$from." to ".$to."\n";
}
function fetch_new_version($resource) {
$url = "https://api.github.com/repos/boxen/puppet-".$resource."/tags";
$res = file_get_contents($url);
$json = json_decode($res);
return $json[0]->name;
}
function update_version($line) {
// 空行、コメントの行、githubで始まらない行は対象外
if ( strlen($line) === 0 || $line[0] === "#" || strpos($line, "github") === false ) {
return $line;
}
// 現在Puppetfileに書かれているResourcesとバージョンを取得
preg_match("/^github \"(\w+)\",\s*\"(\d+\.\d+\.\d+)\"/", $line, $match);
$name = $match[1];
$version = $match[2];
// Github APIを利用して最新バージョンを取得
$new_version = fetch_new_version($name);
// 500等でバージョンの取得に失敗した場合更新をかけない
if ( $new_version == null ) return $line;
// アップデートがあれば標準出力にて通知
if ( $new_version !== $version ) notify_update($name, $version, $new_version);
// バージョンの部分を最新バージョンに置き換え
return str_replace($version, $new_version, $line);
}
$Puppetfile = file_get_contents("./Puppetfile");
$Puppetfile = explode("\n", $Puppetfile);
// 自動更新する範囲を取得
$read_flg = false;
$Puppetfile = array_map(function($line) {
global $read_flg;
// 読み取り開始/終了
if ( strpos($line, READ_START_SYMBOL) !== false ) $read_flg = true;
if ( strpos($line, READ_END_SYMBOL) !== false ) $read_flg = false;
if ( $read_flg ) {
// 自動更新の範囲内なら更新を行う
return update_version($line);
} else {
return $line; // 何もしない
}
}, $Puppetfile);
// 変更した内容でPuppetfileを上書き
file_put_contents("./Puppetfile", implode("\n", $Puppetfile));
view raw autoUpdate.php hosted with ❤ by GitHub
BoxenPHP
© 2012-2025 Leko