チケットの情報を取得するスクリプト

PowerShellからTracのチケット情報を取得するスクリプトを作ってみた。

TracにはオプションでXML-RPCインターフェースが用意されているので、このインターフェース経由で情報を取得することになる。

そのためにまず、以前作ったXmlRpc用のPowerShellスクリプトをちょっと変更した。具体的には認証情報を渡せるようにした(ファイル名のリンクをクリックするとソースをダウンロードできます)。

Download Invoke-XmlRpc.ps1

param([string]$url, [string]$methodName, [object[]]$arguments=@(), [Net.ICredentials]$credential)

if($url.Length -eq 0 -or $methodName.Length -eq 0 -or $args[0] -eq "-?") {
    $commandName = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)
    Write-Host -foregroundColor Yellow @"

Name:
    $commandName

Description:
    指定したURLに対してXML-RPCリクエストを行います。

Usage:
    $commandName [[-url] <string>] [[-methodName] <string>] [[-arguments] <object[]>] [[-credential] <Net.ICredentials>]

    -url <string>
        リクエスト先のURL
    
    -methodName <string>
        メソッド名
        
    -arguments <object[]>
        引数
    
    -credential <Net.ICredentials>
        認証オブジェクト(必要な場合)

"@
    exit 1
}

$XmlRpcTypes = @{
    [string]="string";
    [int]="int"; [long]="int";
    [double]="double"; [float]="double";
    [bool]="boolean";
    [DateTime]="dateTime.iso8601";
}

# 指定した値をXML-RPCで表現される値に変換します。
function toXmlRpcValue([object]$value) {
    if($value -is [Hashtable]) {
        [string](&{ @"
<struct>
"@
$value.GetEnumerator() | % { $name=$_.Key; $value=(toXmlRpcValue $_.Value); @"
  <member>
    <name>$name</name>
    <value>$value</value>
  </member>
"@ }
@"
</struct>
"@
})
    } elseif($value -is [Array]) {
        [string](&{ @"
<array>
  <data>
"@
$value | % { $value=(toXmlRpcValue $_); @"
    <value>$value</value>
"@ }
@"
  </data>
</array>
"@
})
    } else {
        "<{0}>{1}</{0}>" -f $XmlRpcTypes[$value.GetType()], (& {
            if($value -is [DateTime]) { $value.ToString("yyyyMMddTHH:mm:ss") }
            else {
                $value
            }
        })
    }
}

$reqXml = [string](&{ @"
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
  <methodName>$methodName</methodName>
  <params>
"@
$arguments | % { $value=(toXmlRpcValue $_); @"
    <param>
      <value>
        $value
      </value>
    </param>
"@ }
@"
  </params>
</methodCall>
"@
}); Write-Debug [string]$reqXml

$data = [Text.Encoding]::UTF8.GetBytes($reqXml)

$webReq = [Net.HttpWebRequest]::Create($url)
$webReq.Method = "POST"
$webReq.Credentials = $credential
$webReq.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows XP)"
$webReq.ContentType = "text/xml"
$webReq.ContentLength = $data.Length

$reqStream = $webReq.GetRequestStream()
$reqStream.Write($data, 0, $data.Length)
$reqStream.Close()

$webRes = $webReq.GetResponse()
$sr = New-Object IO.StreamReader($webRes.GetResponseStream())
$resXml = $sr.ReadToEnd()
$sr.Close()
$webRes.Close()

$resXml

trap { throw $_ }

そして、これを使ってTracにアクセスするスクリプトが以下。

Download Get-Ticket.ps1

param([string]$url, [int]$ticketId, [string]$userName, [string]$password)

if($url.Length -eq 0 -or $methodName.Length -eq 0 -or $args[0] -eq "-?") {
    $commandName = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)
    Write-Host -foregroundColor Yellow @"

Name:
    $commandName

Description:
    指定したURLのTracサイトから指定したIdのチケット情報を取得します。

Usage:
    $commandName [[-url] <string>] [[-ticketId] <int>] [[-userName] <string>] [[-password] <string>]

    -url <string>
        リクエスト先のTracのURL
    
    -ticketId <int>
        チケットのId
        
    -userName <string>
        ユーザ名
    
    -password <string>
        パスワード

"@
    exit 1
}

if($userName.Length -gt 0 -and $password.Length -gt 0) {
    $credential = New-Object Net.NetworkCredential($userName, $password)
}
$resXml = [xml](Invoke-XmlRpc "$url/login/xmlrpc" "ticket.get" $ticketId -credential $credential)

$data = $resXml.methodResponse.params.param.value.array.data
$id = $data.value[0].int
$createdTime = $data.value[1].int
$changedTime = $data.value[2].int

[string]::Join([Environment]::NewLine, (&{ @"
<?xml version="1.0" encoding="utf-8"?>
<ticket>
    <id>$id</id>
    <createdTime>$createdTime</createdTime>
    <changedTime>$changedTime</changedTime>
"@
$data.value[3].struct.member | % {
    $name = $_.name; $value = $_.value.string; 
@"
    <$name>$value</$name>
"@
}
@"
</ticket>
"@ })
)

引数で渡したIdのチケット情報を取得して、XML形式で返してくれる。

使い方

PS > Get-Ticket http://localhost/trac/SampleProject 1 admin ******

出力
<?xml version="1.0" encoding="utf-8"?>
<ticket>
    <id>1</id>
    <createdTime>1212410936</createdTime>
    <changedTime>1212414652</changedTime>
    <status>closed</status>
    <description>チケットのテストです。</description>
    <reporter>admin</reporter>
    <cc>Hoge</cc>
    <resolution>対応済</resolution>
    <component>その他</component>
    <due_assign>2008/06/11</due_assign>
    <summary>チケット1</summary>
    <priority></priority>
    <keywords></keywords>
    <version>1.0β</version>
    <milestone>1.0αリリース</milestone>
    <owner>somebody</owner>
    <type>タスク</type>
    <due_close>2008/06/27</due_close>
    <complete></complete>
</ticket>

しかし、XML-RPCってかったるいね。