2021年5月から6月までの記事
Redmineでステータスと連動して進捗率と担当者を変更する(View customize plugin)
View customize pluginで、(個人的に)一番便利だと思っているスクリプトです。
チケットの担当者を切り替えながら進めていくような場合には、ほんんんんとに便利なので、ぜひ試して欲しいです。
View customize pluginで、(個人的に)一番便利だと思っているスクリプトです。
チケットの担当者を切り替えながら進めていくような場合には、ほんんんんとに便利なので、ぜひ試して欲しいです。
CSVファイルを処理するcsvt
というCLIのツールをGoで作りました。
作り始める時点で用意しようと思っていた機能が揃ったので紹介します。
(2021-12-07追記) その後欲しい機能が増えて、サブコマンドが倍増したので、現在の情報で更新します。
csvtはCSVファイルを処理するCLIのツールです。
Goで実装しています。
Goの勉強のために個人で作ったものですが、今所属するプロジェクト内でも利用してもらっています。
下記のようなサブコマンドを用意しており、CSVを編集するうえでたいていのことは、これらコマンドで事足りるようになりました。
add
列を追加します。choose
列を選択して新しいCSVファイルを作成します。concat
2つのCSVファイルを結合します。count
レコード数をカウントします。exclude
他のCSVファイルに存在する行を除外します。filter
条件に一致する行に絞り込みます。head
先頭の数行を表示します。header
CSVファイルのヘッダを表示します。include
他のCSVファイルに存在する行に絞り込みます。join
指定した列をキーとして、CSVファイルのレコードを結合します。remove
列を削除します。rename
列名(ヘッダ)を変更します。replace
CSVファイルの値を正規表現を使って置換します。slice
指定した範囲の行を切り出します。sort
指定した列の値でソートします。split
指定された行数毎に分割します。transform
CSVファイルのフォーマットを変更します。unique
指定した列の値を利用して重複するレコードを取り除きます。一番大変だった気に入っているコマンドはjoin
です。
ExcelのVOOKUP的なことができます。
$ csvt join -1 INPUT1 -2 INPUT2 -c COLUMN -o OUTPUT
Usage: csvt join [flags] Flags: -1, --first string First CSV file path. -2, --second string Second CSV file path. -c, --column string Name of the column to use for joining. --column2 string (optional) Name of the column to use for joining in the second CSV file. Specify if different from the first CSV file. -o, --output string Output CSV file path. --usingfile (optional) Use temporary files for joining. Use this when joining large files that will not fit in memory. --norecord (optional) No error even if there is no record corresponding to sencod CSV. -h, --help help for join
例えば、input1.csv
として下記内容のCSVファイルと、
UserID,Name,Age,CompanyID 1,"Taro, Yamada",10,2 2,Hanako,21,1 3,Smith,30,2 4,Jun,22,4
input2.csv
として下記内容のCSVファイルを用意して、
CompanyID,CompanyName 1,CompanyA 2,CompanyB 3,CompanyC 4,"AAA Inc"
CompanyID
の値を使って結合します。
$ csvt join -1 input1.csv -2 input2.csv -c CompanyID -o output.csv
できあがったoutput.csv
は下記のような内容になります。
input1.csv
を基準として、input2.csv
の内容を足していくようなイメージです。
UserID,Name,Age,CompanyID,CompanyName 1,"Taro, Yamada",10,2,CompanyB 2,Hanako,21,1,CompanyA 3,Smith,30,2,CompanyB 4,Jun,22,4,AAA Inc
--usingfile
というオプションを利用すると、メモリにファイル全体を載せることなく結合するので、どんな大きなファイルでも問題なく処理できます。(数GBのCSVファイルでも使用メモリは数十MB)
他のコマンドも含め、詳しい利用方法はREADMEをご参照ください。
csvt の特徴的なところとして、柔軟にフォーマットが指定できるというところがあります。
CSV、TSVといった良くあるフォーマットだけでなく、マイナーなフォーマットにも対応するために、フォーマットとして下記が指定できるようになっています。
全てのサブコマンド共通のフラグです。
Global Flags: --delim string (optional) CSV delimiter. The default is ',' --quote string (optional) CSV quote. The default is '"' --sep string (optional) CSV record separator. The default is CRLF. --allquote (optional) Always quote CSV fields. The default is to quote only the necessary fields. --encoding string (optional) CSV encoding. The default is utf-8. Supported encodings: utf-8, shift_jis, euc-jp --bom (optional) CSV with BOM. When reading, the BOM will be automatically removed without this flag.
Cobra を利用することで、CLIでのサブコマンドの実装が簡単にできました。
cobra add
で追加される雛形だと、サブコマンド毎のテストが書きずらかったので変えています。
root側にサブコマンドに関する処理を追加しなければならないのが煩雑ですが、テスト毎にサブコマンドを生成したかったのでやもえずです。
(ほんとはもっと良い方法があるのかもしれない、、)
フラグをソートしたくなかったり、エラーメッセージの表示タイミング変えたりとか、、いろいろ調べることもありましたが、Cobraに関する情報はたくさんあったので、やり方が見つからないといったようなことはありませんでした。
join
やsort
コマンドでは、CSVのレコードを全部読み込んだうえで処理しなければならず、それをメモリに載せてしまうと、巨大なCSVファイルを処理するときにメモリが足りなくなりかねません。
キーバリューストアのBoltを使うことで、map
をメモリの外(ファイル)に追い出すような実装も用意し、オプションで切り替えられるようにしました。
BoltはAPIがシンプルなのもあってか、迷うことなく簡単に利用することができました。
head
コマンドでCSVの先頭数行を表形式で表示したかったので、何か良いライブラリが無いかなと調べたところ、ASCII Table Writerというライブラリを見つけました。
全角文字にもちゃんと対応しているので、日本語で崩れるといったようなこともなく、簡単に表形式での表示が実現できました。
細かいフォーマットのカスタマイズが encoding/csv
だと出来ないので、別途CSVパーサを書いてそれを利用するようにしました。
他のCSVライブラリもいくつか確認しましたが、要件満たしている&良く使われてそうでこれなら安心そう、、ってのが見当たらなかったので、Goの勉強も兼ねてということで、、
第20回 redmine.tokyo にて、『Redmine issue assign notice plugin の紹介』というタイトルでLTさせていただきました。
資料はこちら。
Redmine issue assign notice pluginは、チケットの担当者を切り替えて進めていくようなプロジェクトでは、とても有用なプラグインだと思っていますので、今回このLTを見て試してみようという方がいたらうれしいです。
今回の勉強会は、ところどころ抜けながらの参加(リモートだから家のことを途中で出来るので助かる)でしたが、聴いた発表はどれも良いものでした。
その中でも特に skys さんの「新型コロナウイルス感染者情報管理」は、Redmineをカスタマイズすることで、コロナウイルス感染者情報管理するという、とても面白い事例でした。
Redmineのカスタマイズ性の高さからか、開発以外の用途でも活用できる事例は多いですね。
愛用しているShortcutKey2URLというChrome/Firefox用の拡張機能の紹介記事です。
個人的にはとても便利だと思っているので、もっといろんな人に使ってもらえたらなぁと思っています。
Gradle Shadow Pluginで、デフォルトだとMETA-INF/services
配下が上書きされてしまい、ハマった際の記事です。
忘れたころにまた嵌りそうです、、
社内勉強会で最近作ったものってタイトルで、Goで作ったツールやRedmine issue assign notice pluginについて発表しました。
www.slideshare.net
在宅勤務で通勤時間&肉体的な負荷が無くなったことで、趣味でコード書ける時間が今までより増えたなーって思います。
あと、Goはちょっとしたツールを作って配布するためのものが全て揃っていて素晴らしいです。
Goの勉強も兼ねて、適当な課題見つけてCLIツールをちょこちょこ作っているのですが、他の人が使っても便利かもしれないものが出来たので紹介します。
指定したディレクトリ配下のファイル一覧を再帰的に表示するツールです。
$ filist -s -M . a.txt 24 3d3a42d900823afcfdfeb6de338bcec1 b/1.txt 81 ae23e0b40e773ac132f477f661e89b86 b/2.txt 163 494ba81d0d828ff9a244da627b5ece47
ファイルパス以外にも、サイズ、更新日時、MD5、SHA1などといった情報も一緒に出力できます。
オプションは下記の通りです。
Usage: filist [options] directory ... options -r, --rel Print relative path (If neither 'rel' nor 'abs' is specified, 'rel' will be printed first column.) -a, --abs Print absolute path -s, --size Print file size -m, --mtime Print modification time -M, --md5 Print MD5 hash -S, --sha1 Print SHA-1 hash --sha256 Print SHA-256 hash -h, --help Help
オプションの指定順に情報が並ぶので、例えば先頭にMD5で、その後にファイル名、、といった指定もできます。
$ filist -M -r . 3d3a42d900823afcfdfeb6de338bcec1 a.txt ae23e0b40e773ac132f477f661e89b86 b/1.txt 494ba81d0d828ff9a244da627b5ece47 b/2.txt
全てのファイルにmd5sumかけたい、、っていうようなときに、コマンド組み合わせてワンライナーで書けなくないですが、こういったツール用意しておくと便利かなーって思って作りました。
Goだと各OS用の実行ファイルをシングルバイナリで簡単に提供できるってのがほんと素晴らしいです。
チケットの担当者が変わったときに、SlackやRocket.Chat、Teamsなどに通知するプラグイン、Redmine issue assign notice pluginのv1.2.0をリリースしました。
Google Chatのメンションに対応しました。
Google ChatのIncoming Webhookの設定などは、下記をご参照ください。
また、下記の2つの問題を修正しています。
\[KaTeX\]
表示となってしまう。