404 motivation not found | t_ishidaのブログ

6月/11

23

[誰得]SVNクライアントのラッパが大きくなりました

SVNクライアントのラッパーが使っているうちに大きくなりましたので、晒します。使い方はソース読んでください。

正直、ここまで大きくなるなら、pm にしてhelpとコマンドをセットと略式コマンドに対応出来たほうが良かったんじゃないかって思ってます。

#!/usr/bin/perl
use File::Basename;
use strict;

## 環境設定
sub say { print @_ , "\n" }
my $SVN   = 'svn';
my %HOSTS = (
  host1  => {
    host       => 'http://svn-server.domain/path/to/repostiry',
    local_dir  => '/local/working/copy/dir/home',
    server_host => 'user@domain.com',
    server_key  =>  "/path/to/server-key/id_rsa",
    server_dir  => '/path/to/dir',
    default    => 1,
  },
  host2 => {
    host       => 'http://svn-server.domain/path/to/repostiry',
    local_dir  => '/local/working/copy/dir/home',
    server_host => 'user@domain.com',
    server_key  =>  "/path/to/server-key/id_rsa",
    server_dir  => '/path/to/dir',
    default    => 0,
  },
);

my $SVN_ENV    = {};
## ここからロジック

our %COMMANDS =  (
  ##
  ## 対象リポジトリのブランチのリストを表示
  ##
  ls        => sub {
    `$SVN list '$SVN_ENV->{host}/branches'`
  },

  ##
  ## 対象ブランチのベースリビジョンを取得
  ##
  base_rev  => sub {
    `$SVN log '$SVN_ENV->{host}/branches/$_[0]' --stop-on-copy --quiet`
  },

  ##
  ## update
  ##
  update       => sub {
    if ( $_[0] ) { `$SVN update $SVN_ENV->{local_dir}/branches/$_[0]` }
    else         { `$SVN update` }
  },

  ##
  ##  ブランチの削除
  ##
  del       => sub {
    `$SVN del -m 'del $_[0]' $SVN_ENV->{host}/branches/$_[0]`
  },

  ##
  ##  ブランチの移動
  ##
  mv        => sub {
    `$SVN mv -m 'mv $_[0]' '$SVN_ENV->{host}/branches/$_[0]' '$SVN_ENV->{host}/branches/$_[1]'`
  },

  ##
  ##  ブランチを作成してチェックアウトしてくる
  ##
  create => sub {
    my $branch_name = shift;
    if ( `$SVN log $SVN_ENV->{host}/branches/$branch_name 2>&1` =~ /not +found/ ){
      print 'creating branch ' . $branch_name . '.....' . "\n";
      print `$SVN cp -m 'make $branch_name' $SVN_ENV->{host}/trunk $SVN_ENV->{host}/branches/$branch_name`;
    }

    if ( !-d "$SVN_ENV->{local_dir}/branches/$branch_name" ) {
      print 'checking out branch ' . $branch_name . '.....' . "\n";
      print `$SVN co $SVN_ENV->{host}/branches/$branch_name $SVN_ENV->{local_dir}/branches/$branch_name` ;
    } else {
      print 'updating branch ' . $branch_name . '.....' . "\n";
      print `$SVN update $SVN_ENV->{local_dir}/branches/$branch_name`;
    }

    if (  !-f "$SVN_ENV->{local_dir}/branches/$branch_name/.aurc" ) {
      print 'making dot_aurc_copy ' . $branch_name . '.....' . "\n";
      my $TMPL = "$SVN_ENV->{server_host}\n" .
      "$SVN_ENV->{server_key}\n".
      "$SVN_ENV->{server_dir}\n";
      my $path = "$SVN_ENV->{local_dir}/branches/$branch_name";
      $path =~ s#(?:/$)##;
      if ( $path ) { -d $path or die 'ディレクトリが無いような気がしますよ' . $path; }
      else       { $path = '.' }
      open F, '> ' . $path . '/.aurc'; print F $TMPL; close F;
      print $path . 'に.aurcを作りました'. "\n";
    }
    'created';
  },

  ##
  ## mergeコマンド(対象の作業ディレクトリで実行してください)
  ##
  merge => sub {
    our %COMMANDS;
    my ( $path, $dry_run ) = @_;
    my $rev = undef;
    print $COMMANDS{update}->() . "\n";
    $path or die 'パスの指定がありません' ;
    my $stat = `$SVN stat $SVN_ENV->{local_dir}/branches/$path`;
    if ( $stat ) {
      my @adds    = map { /(\S+)$/ } grep { /^\?/ } split /\n/, $stat;
      my @changes = map { /(\S+)$/ } grep { /^m/i } split /\n/, $stat;
      say 'コミット漏れ、追加漏れあったけどどうする? 追加漏れ:' .@adds . ' コミット漏れ:' . @changes . ' [y/n]';
      my $answer = <STDIN>;
      chomp $answer;
      say;
      if ( $answer ne 'n' ){
        say `$SVN update $SVN_ENV->{local_dir}/branches/$path`;
        for ( @adds ) {
          say '追加する?[y/n]:' . $_ ;
          my $answer = <STDIN>;
          chomp $answer;
          say;
          say `$SVN add $_` if $answer ne 'n';
        }
        say `$SVN ci -m 'prepared for merging by svn_branch.pl' $SVN_ENV->{local_dir}/branches/$path`;
      }
    }
    my @log =  map  { /(\d+)/ } grep { /\S/ }
      split /^\s*-+$/m, $COMMANDS{base_rev}->( $path );
    $rev = pop @log or die 'ブランチ間違ってない?';
    my $MERGE_COMMAND = "$SVN merge -x -w ";
    $dry_run and $MERGE_COMMAND .= ' --dry-run ';
    `$MERGE_COMMAND -r $rev:HEAD $SVN_ENV->{host}/branches/$path`;
  },

  ##
  ## ひとつ前のリビジョンに戻す
  ##
  rollback => sub {
    if ( $_[0] ) { `$SVN merge -x -w -r HEAD:PREV $SVN_ENV->{host}/branches/$_[0]` }
    else         { `$SVN merge -x -w -r HEAD:PREV` }
  },
);

## パラメータ処理(一個目はいつでもコマンド)
my $cmd    = shift @ARGV;
$COMMANDS{$cmd} or die '指定のコマンド無いっす';

## 対象ホストの解析とか
my %params = @ARGV;
if ( $params{-h} && $HOSTS{$params{-h}} ) {
  $SVN_ENV    = $HOSTS{$params{-h}};
}
else {
  my ( $key ) = grep { $HOSTS{$_}->{default} } keys %HOSTS;
  $SVN_ENV = $HOSTS{$key};
}
/^-/ and delete $params{$_} for keys %params;

## 実行
say $COMMANDS{$cmd}->( %params );
Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Tumblr
  • email
  • Facebook
  • FriendFeed

RSS Feed

コメントはまだありません。

Leave a comment!

<< create_functionのアレ

[誰得]svnクライアントのラッパ >>

Find it!

Theme Design by devolux.org

Tag Cloud