k-holyのPHPとか諸々メモ

Webで働くk-holyがPHP(スクリプト言語)とか諸々のことをメモしていきます。ソースコードはだいたいWindowsで動かしてます。

SparkleShareをWindows7に入れてみたメモ

SparkleShareWindows7に入れて使ってみたメモです。

SparkleShareが何なのかは、ちょっと古いですがこちらの記事が分かりやすかったです。

SparkleShareは、バージョン管理システムGitを利用したリアルタイムファイル共有システムです。 誤解を恐れず書くと オープンソース版オレオレDropboxが作れるツール というとわかりやすいでしょう。

SparkleShareを利用するにはクライアントソフトのSparkleShareのほかに、ファイルを中継して共有するための共有Gitリポジトリが必要になります。 そう書くと、とても面倒なように聞こえますがGitを利用したWebサービスgithubやGitorious、Bitbucketなどに対応しており、アカウントがあればすぐにSparkleShareを利用できます。

また、SparkleShare自体は 特定のディレクトリに置いたファイルを自動的にコミット・プッシュするGitクライアント ですので、Gitに抵抗のある人向けのGitクライアントとしても利用できます。

ちょっと、何か社内でGitを普及促進するのに良さそうじゃないですか?(今更とか言わないで…)というわけで、試してみました。

インストールと初期状態

クライアントのパッケージダウンロードは公式サイト http://sparkleshare.org から sparkleshare-windows-1.4.msi を入れました。

GitHubhbons/SparkleShare にあるものは古いので要注意…。)

インストーラに従ってユーザー名とメールアドレスを入力すると、以下のファイルが生成されます。

%HOMEPATH%\SparkleShare\ユーザー名's link code.txt

中身はOpenSSHの公開鍵なんですが、SSHとか知らなくてもこの「リンクコード」をGitサーバの管理者に送って設置してもらえばいいというわけですね。

実際に利用されると思われる秘密鍵と公開鍵、アプリケーションの設定らしきファイルやログファイルは、以下の場所に生成されていました。

%HOMEPATH%\AppData\Roaming\sparkleshare\2014-06-05_10h08.key
%HOMEPATH%\AppData\Roaming\sparkleshare\2014-06-05_10h08.key.pub
%HOMEPATH%\AppData\Roaming\sparkleshare\config.xml
%HOMEPATH%\AppData\Roaming\sparkleshare\logs\debug_log_2014-06-05.1.txt

SparkleShare.exe を起動するとタスクバーに入ります。

まずは公開鍵をGitサーバ側に登録しておく必要があるので、とりあえずGitHub上にshare-testプロジェクトを作成して、SparkleShare用の公開鍵を追加します。

タスクバーのアイコンをクリック → SparkleShare → Client ID → Copy to Clipboard でインストール時に作成されたOpenSSH形式の公開鍵をクリップボードにコピーします。

GitHubのプロジェクト k-holy/share-test から Settings → Deploy keys → Add deploy key でフォームが開くので、適当な名前付けてペーストして「Add key」。

タスクバーのアイコンをクリック → SparkleShare → Add hosted project... でGitリポジトリを追加します。

うまくいけば「Your shared project is ready!」というメッセージが表示されるので「Show files」をクリックすると、プロジェクトルート %HOMEPATH%\SparkleShare\share-test が開きます。

初期状態ではこんな構成

%HOMEPATH%\SparkleShare\share-test\.git
%HOMEPATH%\SparkleShare\share-test\.sparkleshare
%HOMEPATH%\SparkleShare\share-test\SparkleShare.txt

SparkleShare.txtを覗いてみると…

Congratulations, you've successfully created a SparkleShare repository!

Any files you add or change in this folder will be automatically synced to 
ssh://git@github.com/k-holy/share-test and everyone connected to it.

SparkleShare is an Open Source software program that helps people collaborate and 
share files. If you like what we do, consider buying us a beer: http://www.sparkleshare.org/

Have fun! :)

おっと思いつつGitHubリポジトリを確認してみると、すでに上記のファイルが commit & push されている状態でした。

.sparkleshare には何かのハッシュ値らしきものが書かれていました。

コミットの内容はこんな感じ。

コミットログには、変更のあったファイル名を列挙した内容が自動的にセットされるようです。なるほど。

SparkleShareは自動でリポジトリと同期してくれるGitクライアント

今度はローカルで新規フォルダ test を作成してみます。Gitでは空のフォルダは無視されるはずですが、どうでしょうか…。

作成したフォルダの直下に .empty というファイルが自動的に作成された状態で commit & push されています。なるほど。

(「I'm a folder!」とか別に要らないよぉって感じですが…)

もちろん、これらの変更をクライアント側で見ることもできます。

タスクバーのアイコンをクリック → SparkleShare → Recent changes...

ユーザー名@プロジェクト名 のリンクをクリックすると、プロジェクトルートのフォルダをエクスプローラで開きます。

一覧に表示されているファイル名のリンクをクリックすると、そのファイルが拡張子に関連付けられたアプリケーションで開きます。

なるほど。これは「Dropboxクローン」というよりも、管理対象フォルダ以下の変更を検知して自動でリポジトリと同期してくれるGitクライアントですね。

日本語ファイル名は一応使えるけど一部で化ける?

新規フォルダ てすと を作成して、日本語のファイル名が使えるかどうかも確認します。

なんか微妙に文字化けしてますね…それに、フォルダ命名してる間にコミットされてしまったようです。

盛んに紹介されていた2012年頃の記事には、SparkleShareに同梱されているmsysgitの問題で日本語ファイルが使えないという情報がありますが、2014年6月現在のバージョン SparkleShare 1.4 + Git 1.8.0 では大丈夫でした。

次はファイルの中身も日本語にしてみます。

ファイルを作成…

ファイル名を変更…

UTF-8で中身を記述。diffは文字化けしてません。

中身をShift_JISに変更して保存したところ、diffが文字化け。

クライアント側のRecent Changesはこんな感じ。

ちょっと惜しい…クライアント側にとってコミットログはそれほど重要な情報ではないと思いますが、文字化けしたファイルへのリンクが切れちゃってるのが残念。

なお、複数ユーザーで触った場合のRecent Changesはこんな感じでした。

クライアント間の更新通知は notifications.sparkleshare.org を仲介して行われる

複数クライアント間でリアルタイムに同期を取るには、別のクライアントで更新されたことを通知する必要があると思いますが、クライアント間の更新通知については、公式リポジトリWikiにそれらしい情報がありました。

SparkleShare uses a small script that handles update notifications between clients.

By default it uses the one running on notifications.sparkleshare.org.

The only information sent to this service is a hash of a folder identifier and a hash of the current revision.

The service then tells the other connected clients that are subscribed to a folder that they can pull new changes from wherever your repository is hosted.

This allows SparkleShare clients to sync new changes instantly, instead of polling with potentially long delays (up to 10 minutes).

英語はよく分かりませんが、notifications.sparkleshare.org を介して、フォルダID(設定ファイルの <identifier>544d01eae5adc8ea5f8765f84f3d6ae5fdd9846e</identifier> の値)とリビジョンIDをやり取りすることで、クライアント間の同期を取る仕組みのようです?

ただ、前述のログファイル %HOMEPATH%\AppData\Roaming\sparkleshare\logs\debug_log_2014-06-05.1.txt を見たところ、1分間隔で notifications.sparkleshare.org へ接続を試みているものの、失敗しているようでした。

23:43:43 | Listener | Trying to reconnect to tcp://notifications.sparkleshare.org:443/
23:43:45 | Listener | Disconnected from tcp://notifications.sparkleshare.org:443/: 対象のコンピューターによって拒否されたため、接続できませんでした。 204.62.14.135:443
23:43:45 | share-test | Falling back to regular polling

対象のコンピューターによって拒否されたため、接続できませんでした。 というメッセージは相手から拒否されたように読めますが、これはクライアント側の問題でしょうか。

該当メッセージでGoogle検索してみると、様々なWindowsアプリケーションでTCP通信時にこのエラーが発生することがあるようですが、ちょっと自分ではすぐに解決できなさそうなので保留…。

リポジトリへの反映は即時、リポジトリからの取り込みは定期的に行われる

前述の通り、管理対象フォルダへの変更は即時に検知され、リポジトリに反映されます。

これもログファイルを見ると、何となく動きが分かりました。

23:41:08 | Cmd | share-test | git status --porcelain
23:41:08 | Local | share-test | Activity detected, waiting for it to settle...
23:41:10 | Local | share-test | Activity has settled
23:41:10 | Cmd | share-test | git status --porcelain
23:41:10 | SyncUp | share-test | Initiated
23:41:10 | Cmd | share-test | git add --all
23:41:10 | Cmd | share-test | git status --porcelain
23:41:10 | Cmd | share-test | git config user.name "k-holy"
23:41:10 | Cmd | share-test | git config user.email "k.holy74@gmail.com"

リポジトリへのコミットで使用される user.name と user.email が、前述の設定ファイル %HOMEPATH%\AppData\Roaming\sparkleshare\config.xml の内容になっています。

<?xml version="1.0" encoding="UTF-8"?>
<sparkleshare>
  <user>
    <name>k-holy</name>
    <email>k.holy74@gmail.com</email>
  </user>
  <notifications>False</notifications>
  <folder>
    <name>share-test</name>
    <identifier>544d01eae5adc8ea5f8765f84f3d6ae5fdd9846e</identifier>
    <url>ssh://git@github.com/k-holy/share-test</url>
    <backend>Git</backend>
  </folder>
</sparkleshare>

git config の後 git commit コマンドを発行しており、コミットログの文字化けはこの時点で発生しているようです。

自動生成されるコミットメッセージへのファイル名の受け渡しでマルチバイトが考慮されていないのでしょうけど、どうすればいいのやら…。

23:41:10 | Cmd | share-test | git commit --all --message="+ ‘test/譁ー縺励>繝・く繧ケ繝・繝峨く繝・繝。繝ウ繝・txt’
" --author="k-holy <k.holy74@gmail.com>"
23:41:10 | Cmd | share-test | git push --progress "ssh://git@github.com/k-holy/share-test" master
23:41:13 | Git | share-test | Counting objects: 6, done.
23:41:13 | Git | share-test | Delta compression using up to 4 threads.
23:41:13 | Git | share-test | Total 4 (delta 1), reused 0 (delta 0)
23:41:14 | Git | share-test | To ssh://git@github.com/k-holy/share-test
23:41:14 | Git | share-test |    41b5b0b..da151e2  master -> master
23:41:14 | SyncUp | share-test | Done
23:41:14 | Cmd | share-test | git log --since=1.month --raw --find-renames --date=iso --format=medium --no-color -m --first-parent
23:41:14 | Cmd | share-test | git rev-parse HEAD
23:41:14 | Listener | Can't send message to tcp://notifications.sparkleshare.org:443/. Queuing message

最後に Listener が Can't send message to tcp://notifications.sparkleshare.org:443/. Queuing message と言ってるのは、更新通知を送ろうとして接続に失敗しているようです。

(表には一切何も表示されませんが、裏側では結構エラーが出てたりするようで、この辺は要注意ですね…。)

また、クライアント間の更新通知とは別に、リモートのGitリポジトリへの更新チェックが5分間隔で行われるようです。

23:45:47 | Git | share-test | Checking for remote changes...
23:45:47 | Cmd | share-test | git rev-parse HEAD
23:45:47 | Cmd | share-test | git ls-remote --heads --exit-code "ssh://git@github.com/k-holy/share-test" master
23:45:51 | Git | share-test | No remote changes, local+remote: 9ecb3784403aa484bd08b618dee765927ab04bda

こちらは問題なく完了していますし、そこまでリアルタイム同期にこだわらないのであれば、これでも充分という気がします。

SparkleShareはテキストコンテンツ管理に向いてるかも

似たような趣旨で紹介される ownCloud が完全なWeb + DBアプリケーションであるのに対して、中身は全く異なることが分かりました。

SparkleShareはGitとおんぶだっこ。だがそれがいい

ディレクトリの状態が変更されるたびに自動コミットされてコミットの粒度が最小になってしまうため、通常のソフトウェア開発には不向きでしょう。

いわゆる静的サイトジェネレータのような、リポジトリを一種のデータストアとして扱う仕組みと相性が良いんじゃないでしょうか。

クライアント側のUIにはSSHやGitコマンドはもちろんリビジョンIDすら登場せず、バージョン管理の概念すら知らなくてもファイルの共有と同期、そして履歴管理の恩恵を受けられるというのは、なかなか凄いことだと思います。

応用例として、RedmineやGitoliteを組み合わせて、フラットODFという単一のXMLファイルに文書とメタ情報とBase64エンコードされた画像などを詰め込んだ文書の管理システムを構築したという方も。

クライアント側ではLibreOffice WriterでフラットODFファイルを出力、SparkleShareでリポジトリに反映、Gitoliteを使うことでユーザーの権限制御を実現しつつ、Redmineを管理者によるタスク管理とリポジトリビューアとして利用する仕組みのようです。

Gitに乗っかることで、こういう組み合わせの可能性が広がるのもいいですね。