Firefox拡張機能のXPIファイルをシェルスクリプトで作成する

Firefox拡張機能ソースコード作成が終わったら、普通はそれらを圧縮して一つのXPIファイルにまとめる。それを毎回手作業でやっていたらめんどくさいので、一気に作成するbashシェルスクリプトを作成した。なお、これはLinuxの場合だ。Windowsとかはよく知らないので無視する。

筆者の環境

念のため作業環境をメモしておく。

OS
Linux Fedora 8
bashのバージョン
3.2.33
zipのバージョン
2.31

スクリプトの内容

作成したbashスクリプトは以下の通り。

#!/bin/sh

##########################################################
# 拡張機能のソースファイルを圧縮し
# インストール可能なXPIファイルを作成する
##########################################################

#glob展開を無効にする
#除外するファイルの指定などで使用する'*'が展開されるのを防ぐ
set -o noglob

#定数
declare -r EXTENSION_NAME=template
declare -r XPI_FILE_NAME=${EXTENSION_NAME}.xpi

declare -r INCLUDE_FILE_NAME='chrome.manifest install.rdf chrome/'
declare -r EXCLUDE_FILE_NAME='*/.svn/* *.swp'

#古いXPIファイルを削除する
rm -f $XPI_FILE_NAME

#新しいXPIファイルを作成する
zip -q -r $XPI_FILE_NAME $INCLUDE_FILE_NAME -x $EXCLUDE_FILE_NAME

このスクリプトの使い方

このスクリプトの使い方は簡単だ。作成した拡張機能ソースファイルの場所(install.rdfファイルがある場所)に移動して、単に実行すれば良い。

zipコマンドの基本

XPIファイルとは、要するにZIP形式で圧縮したファイルなのでもちろんLinuxでも作成できる。作成できるのだが、ZIPはLinuxではあまり使われない圧縮形式だ。zipコマンドの使い方をよく知らないというLinuxユーザーも多いだろう。なので基本的な書式を確認しておく。

zipコマンドの書式は以下の通り。

% zip オプション ZIPファイル名 対象ファイル名

オプションは、ここでは-qと-rを指定した。

-qはQuiet modeで、余計な出力をしないようにする。-rは再帰的に圧縮するオプションだ。これを指定しないとディレクトリ内のファイルが圧縮されないので必ず指定する。

ZIPファイル名の部分は最終的に出来上がるZIPファイルの名前だ。別にどんな名前でも良いのだが、名前の最後は.xpiにしておく。

対象ファイル名の部分は、圧縮する対象となるファイルやディレクトリ名を書く。ここでは前回作成した「何もしない拡張機能」を前提としているが、作成する拡張機能に応じて変更しなければならない。

対象外とするファイルの指定

ここまでで基本的な解説は終わりなのだが、一つ補足しておく。このシェルスクリプトでは-rを指定して再帰的に圧縮しているので、指定したディレクトリに含まれるすべてのファイルが圧縮対象となる。なので、そのままではエディタのバックアップファイルなど不用なファイルまでXPIファイルに含まれてしまう。

それでは困るので、-xオプションで対象外とするファイルを指定する。この指定にはいくつか注意がある。

まず、-xオプションを指定する場所ははzipコマンドラインの最後でなければならない。これはそういうものなので、素直に従っておく。

そしてもう一つ、対象外とするファイル指定ではシェルスタイルのワイルドカードが使用できるのだが、そのワイルドカードがzipコマンドに渡る前にbashで展開されないようにしなければならない。ここではset -o noglobを使用した。これにより、このシェルスクリプト全体でワイルドカード展開が無効になっている。

別に'\'などでエスケープしても良いのだが、少し読みにくくなるためnoglobを使用した。また、実際に除外するファイル名は作業環境に合わせて各自で変更して欲しい。

終わりに

以上でXPIファイルが作成できるはずだ。必要に応じて定数の部分を変更すること。

作成した圧縮ファイルに含まれるファイル一覧を確認するには、以下のコマンドを実行する。

% unzip -l XPIファイル名

拡張機能のソースファイルが増えてこのスクリプトで対応できなくなった場合はまた改良する。