Powershell / slack / vivado > 処理終了時slack通知 (v0.8) > バックグラウンドで実行可能にした  > 別プロジェクトで通知失敗

```txt:動作確認
Windows 8.1 pro (64bit)
Vivado 2015.4
```


処理終了時にslackへ通知する実装。
v0.3 > http://qiita.com/7of9/items/3d1473925fd94e2ca2db
v0.4..v0.6 > http://qiita.com/7of9/items/ef75686bc961dce90566
v0.7 > http://qiita.com/7of9/items/5f5ea430357ecef49f65


## code (v0.8) > バックグラウンドで実行可能にした

スクリプト実行時にスクリプトフォルダを指定することで、バックグラウンドで実行可能にした。

```main.ps1
#
## 前提 > 以下のファイルがそろった環境で実行する
# 1. secret_slack_url.txt - slackのURL (git ignore対象ファイル)
# 2. target_dir.txt - Vivadoのhw/, SDK/ を含むフォルダ
# 3. このスクリプトファイル

<#
v0.8 2016 Jan 30
    - use Param to get script directory
v0.7 2016 Jan 23
    - tweak check files
        + change find_implementationEndFile()
        + change find_synthesisEndFile()
v0.6 2016 Jan 23
    - check Generate Bitstream end
        + check Generate Bitsteram end at main loop
        + add find_generateBitstreamEndFile()
v0.5 2016 Jan 23
    - check Run Implementation end
        + check Run Implementation end at main loop
        + add find_implementationEndFile()
v0.4 2016 Jan 23
    - check Run Synthesis end
        + check Run Synthesis end at main loop
        + add find_synthesisEndFile()
v0.3 2016 Jan 16
    - check [vcs\ps7_init.tcl]
v0.2 2016 Jan 16
    - check [mem_init_files\ps7_init.tcl] instead of [system.hwdef]
    - add find_ps7InitTcl()
v0.1 2016 Jan 15
    - add notifyToSlack()
    - add get_lastWriteTime_hwdef()
    - add find_hwdef()
    - add get_target_dir()
    - add get_slack_url()
    - add main()
#>

Param (
[String]$scriptDir
)

function get_slack_url() 
{
    $slkurl = ( Get-Content $scriptDir\\secret_slack_url.txt )
    return $slkurl
}

function get_target_dir()
{
    $trgDir = ( Get-Content $scriptDir\\target_dir.txt )
    return $trgDir
}

function find_hwdef($targetDir)
{
    $hwdf = ( Get-ChildItem $targetDir -Recurse "system.hwdef" )
    return $hwdf.Fullname
}

function find_ps7InitTcl($targetDir)
{
    # vcs folder is processed lastly among 5 folders (ies / modelsim / questa / vcs / xsim)
    #
    $tcllst = ( Get-ChildItem $targetDir -Recurse "ps7_init.tcl" )
    foreach($tclfile in $tcllst) {
#        echo $tclfile.Fullname
        if ( ($tclfile.Fullname).IndexOf("vcs") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function find_synthesisEndFile($targetDir)
{
#    $tcllst = ( Get-ChildItem $targetDir -Recurse "system_wrapper.vds" )

    $tcllst = ( Get-ChildItem $targetDir -Recurse ".vivado.end.rst" )
    foreach($tclfile in $tcllst) {
        if ( ($tclfile.Fullname).IndexOf("synth_1") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function find_implementationEndFile($targetDir)
{
#    $tcllst = ( Get-ChildItem $targetDir -Recurse "system_wrapper.vdi" )

    $tcllst = ( Get-ChildItem $targetDir -Recurse ".route_design.end.rst" )

    foreach($tclfile in $tcllst) {
        if ( ($tclfile.Fullname).IndexOf("impl_1") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function find_generateBitstreamEndFile($targetDir)
{
#    $tcllst = ( Get-ChildItem $targetDir -Recurse "write_bitstream.pb" )

    $tcllst = ( Get-ChildItem $targetDir -Recurse "system_wrapper.bit" )
    foreach($tclfile in $tcllst) {
        if ( ($tclfile.Fullname).IndexOf("impl_1") -gt 0) {
            return $tclfile.Fullname
        }
    }
    return ""
}

function get_lastDateTime($afile)
{
    if ( $afile.Length -eq 0 ) {
        return (Get-Date)
    }
    return (Get-ChildItem $afile).LastWriteTime
}

function notifyToSlack($msgToSlk, $slkurl) {
  $enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
  $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($msgToSlk)

  $notificationPayload = @{ 
    channel = "#zybo";
    username = "7of9";
    text = $enc.GetString($utf8Bytes);
  }

  Invoke-RestMethod -Uri $slkurl -Method Post -Body (ConvertTo-Json $notificationPayload)
}

function main() 
{

    if ( [string]::IsNullOrEmpty($scriptDir) ) {
        "ERROR: script directory is NULL"
        exit
    }

    $slackUrl = get_slack_url
    $targetDir = get_target_dir

#    $slackUrl
#    $targetDir

    $ps7initTcl = find_ps7InitTcl $targetDir
    $GenBlockDesign_pretime = get_lastDateTime($ps7initTcl)
    echo $GenBlockDesign_pretime

    $synEndFile = find_synthesisEndFile $targetDir
    $RunSynthesis_pretime = get_lastDateTime($synEndFile)
#    echo $RunSynthesis_pretime

    $impEndFile = find_implementationEndFile $targetDir
    $RunImpl_pretime = get_lastDateTime($impEndFile)
#    echo $RunImpl_pretime

    $genBitstrEndFile = find_generateBitstreamEndFile $targetDir
    $GenBitstr_pretime = get_lastDateTime($genBitstrmEndFile)
#    echo $GenBitstr_pretime

    $msg = "Start"
    notifyToSlack $msg $slackUrl

    while ( 1 ) { 
        if (Test-Path $ps7initTcl) { # to avoid error by deletion of files during the process
            $GetBlockDesign_curtime = (Get-ChildItem $ps7initTcl).LastWriteTime
            echo "Block Design File:$GetBlockDesign_curtime"
            if ( $GetBlockDesign_curtime -gt $GenBlockDesign_pretime) {
                $GenBlockDesign_pretime = $GetBlockDesign_curtime            
                echo "Generate Block Design"
                notifyToSlack "Generated Block Design" $slackUrl
            }
        }

        if (Test-Path $synEndFile) { # to avoid error by deletion of files during the process
            $RunSynthesis_curtime = (Get-ChildItem $synEndFile).LastWriteTime
            echo "Run Synthesis File:$RunSynthesis_curtime"
            if ( $RunSynthesis_curtime -gt $RunSynthesis_pretime) {
                $RunSynthesis_pretime = $RunSynthesis_curtime            
                echo "Run Synthesis"
                notifyToSlack "Run Synthesis" $slackUrl
            }
        }

        if (Test-Path $impEndFile) { # to avoid error by deletion of files during the process
            $RunImpl_curtime = (Get-ChildItem $impEndFile).LastWriteTime
            echo "Run Implementation File:$RunImpl_curtime"
            if ( $RunImpl_curtime -gt $RunImpl_pretime) {
                $RunImpl_pretime = $RunImpl_curtime            
                echo "Run Implementation"
                notifyToSlack "Run Implementation" $slackUrl
            }
        }

        if (Test-Path $genBitstrEndFile) { # to avoid error by deletion of files during the process
            $GenBitstr_curtime = (Get-ChildItem $genBitstrEndFile).LastWriteTime
            echo "Generate Bitstream File:$GenBitstr_curtime"
            if ( $GenBitstr_curtime -gt $GenBitstr_pretime) {
                $GenBitstr_pretime = $GenBitstr_curtime            
                echo "Generate Bitstream"
                notifyToSlack "Generate Bitstream" $slackUrl
            }
        }

        sleep 5
    }

}

main
```

### 設定ファイル

以下のファイルを用意しておく。

1. secret_slack_url.txt - slackのincoming webhookのURL (<font color=red>git ignore対象ファイル</font>)
2. target_dir.txt - Vivadoのhw/, SDK/ を含む作業フォルダ

```secret_slack_url.txt
https://hooks.slack.com/services/xxxxx/xxxxx/xxxx
```

上記URLは本来のIncoming Webhookのアドレスから改変している(security対策)

```target_dir.txt
C:\ZyboDev\zybo_160112_baseDesign
```


### 実行方法

C:\ZyboDev\powershell\powershell_160115_notifyGenerateBlockDesign
にスクリプトと上記設定ファイルがあるとする。

powershellのウィンドウで以下のように実行する。
Tab補完が使えるので、どんどん使う。

```
> Start-Job -ScriptBlock { C:\ZyboDev\powershell\powershell_160115_notifyGenerateB
lockDesign\main.ps1 -scriptDir C:\ZyboDev\powershell\powershell_160115_notifyGenerateBlockDesign }
```

以下のような画面で動いていることが確認できる。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b74f99c7-b68f-08fb-77bb-8c8319cb8f1e.png)

このジョブはPowershellウィンドウを閉じると終了してしまう。powershellウィンドウを最小化して運用となりそうだ。

### ジョブの確認

powershellウィンドウにて`Get-Job`で動いているJobのリストを表示できる

### ジョブの終了

powershellウィンドウにて`Remove-Job -id 2`のように該当jobのidを指定してジョブを終了できる。

### 失敗しそうな点

target_dir.txtを書き変え忘れて、違うフォルダをチェックしてslack通知が来ない、とか失敗しそう。

現在のチェック中のフォルダ名を表示するとかしたほうがいいかもしれない。


## 動作失敗

他のプロジェクトで動かしたら以下の点で失敗した

- ps7initTcl の取得
- genBitstrEndFile の取得

まだ改善しないといけないようだ。