image

  • フォト Amazonギフト券
    ※この時計の時刻は、閲覧しているパソコンのものであり、必ずしも正確な時間とは限りません

検索

最近のトラックバック

無料ブログはココログ

« ピックアップ:Macで打つ特殊文字ショートカット集, Windows XPのPCメーカーへの出荷は来年1月で終了, etc... | トップページ | ピックアップ:ブラウザだけで遊べる『World of Solitaire』,歩いていけばお台場は近い, etc... »

2007-08-25

ruby で subversion を扱う実験

subversion-rubybindings というのがあるのを知った。

インストールは macport で。

  $ sudo port install subversion-rubybindings

インストールできたことの確認。

  $ ruby -rsvn/client -e 'p Svn::Client::Context.new.methods'
  ["log_message", "prop_list", "revprop_set", "pd", "methods", "method", "rm", "praise", "taint", "rpl", "instance_variable_defined?", "plist", "cleanup", "status", "commit", "rpset", "propget", "add_ssl_server_trust_prompt_provider", "__id__", "singleton_methods", "add", "rm_f", "add_simple_provider", "mkdir", "annotate", "object_id", "mv", "add_simple_prompt_provider", "respond_to?", "export", "nil?", "update", "pl", "blame", "lock", "add_username_provider", "rps", "__send__", "switch", "protected_methods", "merge_peg", "tainted?", "mv_f", "list", "ann", "prop_set", "untaint", "st", "instance_of?", "diff_summarize", "equal?", "copy", "set_notify_func", "relocate", "revprop_del", "display", "prop_get", "add_ssl_client_cert_prompt_provider", "private_methods", "hash", "diff", "send", "revprop", "url_from_path", "pset", "kind_of?", "freeze", "eql?", "merge", "add_ssl_client_cert_file_provider", "id", "rpdel", "pget", "public_methods", "instance_eval", "revprop_get", "ps", "uuid_from_path", "is_a?", "diff_summarize_peg", "ls", "unlock", "type", "ci", "rpd", "pg", "add_ssl_client_cert_pw_prompt_provider", "cat", "instance_variables", "up", "co", "rp", "progress_func", "frozen?", "log_msg_func2", "log", "propdel", "to_a", "progress_func=", "log_msg_func2=", "set_cancel_func", "revert", "add_ssl_client_cert_pw_file_provider", "class", "revprop_list", "delete", "config", "proplist", "_auth_baton", "instance_variable_get", "import", "==", "rpget", "progress_baton", "log_msg_baton2", "===", "uuid_from_url", "config=", "prop_del", "to_s", "extend", "del", "progress_baton=", "cp", "log_msg_baton2=", "info", "resolved", "diff_peg", "clone", "set_log_msg_func", "auth_baton", "instance_variable_set", "=~", "rpg", "open_ra_session", "auth_baton=", "pdel", "add_username_prompt_provider", "remove", "inspect", "move", "checkout", "propset", "add_ssl_server_trust_file_provider", "dup", "rplist"]

インストールされたバージョンはこれだ。

$ port installed | grep subversion
  subversion @1.4.4_0 (active)
  subversion-rubybindings @1.4.4_0 (active)

参照:
  http://svn.collab.net/viewvc/svn/trunk/subversion/bindings/swig/ruby/?sortby=file#dirlist

svn の cimmit, diff, status などすべての操作が出来るようだ。
(java-binding もある。
ruby, java のどちらをつかうにせよ、xfy/xvcd で subversion を扱うことができそうだ。
svn の gui クライアントをつくるとか、
xfy 作成したファイルや xvcd ファイルの 保存先を subversion にして履歴管理をできるようにする
とかが実現できるかも知れない。
リモートファイルシステムとして subversion を使うことで、共同編集が可能になるなどソーシャルな
ものができると考えている。
)

ruby-binding を利用したプログラム例を以下で見つけた。
- http://blog.wolfman.com/articles/2006/09/04/using-ruby-svn-bindings-to-get-file-status
> > Using Ruby SVN bindings to get file status

しかし ここの記事中コードのままでは、次のようなエラーがでてしまう。

in `svn_client_status2': subversion/libsvn_subr/auth.c:176 No provider registered for 'svn.username' credentials (Svn::Error::AUTHN_NO_PROVIDER)

そこで

  ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = ''
  ctx.add_username_provider
  ctx.add_simple_provider

といったコードを追加して、エラーを回避することができた。

最終的なプログラムと 実行例を示す。

$ cat status.rb
# See http://blog.wolfman.com/articles/2006/09/04/using-ruby-svn-bindings-to-get-file-status
#     http://www.nabble.com/Ruby-bindings'-excessive-memory-usage-t726131.html

require "svn/core"
require "svn/client"
require "svn/wc"
require "svn/repos"
require 'pp'

# define Consts for all the numeric status values
NONE = 1
UNVERSIONED = 2
NORMAL = 3
ADDED = 4
MISSING = 5
DELETED = 6
REPLACED = 7
MODIFIED = 8
MERGED = 9
CONFLICTED = 10
IGNORED = 11
OBSTRUCTED = 12
EXTERNAL = 13
INCOMPLETE = 14
# I added these so I can amalgamate repo and local status
UPDATED = 15
MODIFIED_NEWER = 16
NEWFILE = 17

$modes= { # Map status to English
    NONE => "None",
    UNVERSIONED => "unversioned",
    NORMAL => "normal",
    ADDED => "file added",
    MISSING => "missing",
    DELETED => "file removed",
    REPLACED => "deleted and then re-added",
    MODIFIED => "modified",
    MERGED => "received repos mods",
    CONFLICTED => "file modified and in conflict",
    IGNORED => "ignored",
    OBSTRUCTED =>  "unversioned resource is in the way of the versioned resource",
    EXTERNAL => "unversioned path populated by an svn:external property",
    INCOMPLETE => "directory doesn't contain a complete entries list",
    UPDATED => "newer version in repository",
    MODIFIED_NEWER => "modified and newer version in repository",
    NEWFILE => "new file in repository",
    nil => "Unknown status"
}

# this amalgamates the most common status between local and repository
def compute_status(status)
  # if modified in repo and localy
  return MODIFIED_NEWER if status.repos_text_status == MODIFIED && status.text_status != NORMAL
  # if added in repo and does not exist locally
  return NEWFILE if status.repos_text_status == ADDED && status.text_status == NONE
  # if repo is none then use local status
  return status.text_status if status.text_status != NORMAL
  # if normal locally but changed in repo
  return UPDATED if status.repos_text_status == MODIFIED
  # otherwise it must be normal
  NORMAL
end

def showDate(time)
  if (time == nil)
    "nil"
  elsif (time == 0)
     "0"
  else
     Time.at(time/1000000).strftime('%Y/%m/%d %H:%M:%S %Z')
  end
end

ctx = Svn::Client::Context.new()

ctx.auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = ''
ctx.add_username_provider
ctx.add_simple_provider

project = "/Users/kato/zzz/test2/svn-reps"
rev = ctx.status(project) do |path, status|
  astat= compute_status(status)
  puts "#{path}: #{status.text_status},#{status.repos_text_status} = #{$modes[astat]}"

  unless status.entry.nil?
    puts("    name: #{status.entry.name}")
    puts("    url: #{status.entry.url}")
    puts("    repos: #{status.entry.repos }")
    puts("    revision: #{status.entry.revision}")
    puts("    kind: #{status.entry.kind}")
    puts("    schedule: #{status.entry.schedule}")
    puts("    deleted: #{status.entry.deleted}")
    puts("    absent: #{status.entry.absent}")
    puts("    incomplete: #{status.entry.incomplete}")
    puts("    cmt_date: #{showDate(status.entry.cmt_date)}")
    puts("    cmt_rev: #{status.entry.cmt_rev}")
    puts("    cmt_author: #{status.entry.cmt_author}")
    puts("    prop_time: #{status.entry.prop_time}")
    puts("    text_time: #{showDate(status.entry.text_time)}")
  end
end

実行させてみよう。まずは svn で状態を確認する。

$ svn status
?      status.rb
!      test02.txt
A      status2.rb

作成した ruby プログラムで得られる状態がこれ。

$ ruby status.rb
/Users/kato/zzz/test2/svn-reps/test/status2.rb: 4,1 = file added
    name: status2.rb
    url: file:///usr/local/svn-reps/test/status2.rb
    repos: file:///usr/local/svn-reps
    revision: 0
    kind: 1
    schedule: 1
    deleted: false
    absent: false
    incomplete: false
    cmt_date: 0
    cmt_rev: -1
    cmt_author:
    prop_time: 0
    text_time: 0
/Users/kato/zzz/test2/svn-reps/test/test02.txt: 5,1 = missing
    name: test02.txt
    url: file:///usr/local/svn-reps/test/test02.txt
    repos: file:///usr/local/svn-reps
    revision: 47
    kind: 1
    schedule: 0
    deleted: false
    absent: false
    incomplete: false
    cmt_date: 2007/08/25 15:21:32 JST
    cmt_rev: 47
    cmt_author:
    prop_time: 0
    text_time: 2007/08/25 15:20:26 JST
/Users/kato/zzz/test2/svn-reps/test/status.rb: 2,1 = unversioned

3 ファイルの add, missing, unversioned の状態が svn コマンドと同様の取得できていることが判る。

他の参照記事:
  - http://www.oneofthewolves.com/2007/03/06/ruby-subversion-bindings-finally-some-documentation/
  > > One of the Wolves » Ruby Subversion Bindings. Finally Some Documentation.

  - http://alcove.onlyconnect.jp/node/33
  > > Ruby Subversion Binding : リポジトリの作成 | alcove

« ピックアップ:Macで打つ特殊文字ショートカット集, Windows XPのPCメーカーへの出荷は来年1月で終了, etc... | トップページ | ピックアップ:ブラウザだけで遊べる『World of Solitaire』,歩いていけばお台場は近い, etc... »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: ruby で subversion を扱う実験:

« ピックアップ:Macで打つ特殊文字ショートカット集, Windows XPのPCメーカーへの出荷は来年1月で終了, etc... | トップページ | ピックアップ:ブラウザだけで遊べる『World of Solitaire』,歩いていけばお台場は近い, etc... »

mokuji

2013年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

google

  • twitter
  • __
  • _
    Googleボットチェッカー

合わせて読む

  • 合わせて読む
    フィードメーター - katoy: cocolog あわせて読みたい

リンク