Windows用のHyperEstraierのGo言語のラッパーを作りました、途中まで!

qrunch.ioより転記)

これな

実は会社で HyperEstraier を使ったWindows 製品の保守をちょっとだけしているのですが、標準のコマンドラインツール estcmd は UTF8 でして、ANK 文字ならいいんですが、日本語が入るとコマンドラインは CP932 (ShiftJIS+α)なので、つらいことに!

ということで、Go言語でラッパーを作りました。といっても、検索側の機能だけで、インデックスを作成する方はまだ未実装です(そのうち、必要になったら作りますが、とりあえず目下の問題が解消されたので、すぐやる必要がなくなってしまった!)

この手のツールは、"cgo" を使ってC言語ライブラリをスタティックリンクするのが普通なんですが、自分はついつい慣れた「syscall.NewLazyDLL で Windows のバイナリライブラリを呼び出す」という方法の方を使ってしまいます。プロプライエタリなソフトウェアならともかく、オープンソースソフトウェアのライブラリで、それやる必要あんの?という感じですが、ジジイはついつい慣れた方法を使ってしまうものなのです。

ほとんど自分しか使わないツールですが、もし他に使う人がいらっしゃるようであれば、まじめに改善に取り組みますので、コメントください

nyagos の type, more で UTF16 をサポート

(qrunch.io より転記)

これな

当初は「とりあえず書いてみた」という感じの issue で、そのうちニーズがない割に面倒なので、やめようかな…と思っていました。

が、最近、会社で過去に書いたプロダクトに問題があって、その修正をしていのたですが、ワークファイルが UTF16 で保存されていて、vim ではかろうじて開けるものの、more も grep も使えないので、たいへんなことに。

ということでですね、実は別途 ANSI/UTF8 の自動判別読み込みフィルター "github.com/zetamatta/go-texts/mbcs".NewAutoDetectReader別パッケージで作ってまして、それを改善する形で取り込んで、UTF16 もサポートするようにしました。 (※バイナリ版はまだリリースしていません)

これの文字コード判別ルールは極めて簡単で

  • \xFF\xFE で始まっていたら、UTF16LE 確定
  • \xFE\xFF で始まっていたら、UTF16BE 確定
  • 0スタートの偶数バイト目に \0 が存在していたら、UTF16BE 確定
  • 奇数バイト名に \0 が存在していたら、UTF16LE 確定
  • 任意の場所に \xEF\xBB\xBF があれば UTF8 確定
  • 1行単位で読み込んで、Go 言語の "utf8".Valid() が false ならば、非UTF8 のマルチバイト文字列と確定
  • 以上でなければ、暫定的に UTF8 とする

実のところ、こんな判別ルールよりももっとたいへんなのが、 "golang.org/x/text/transform" のルールに準拠したテキストフィルターの書き方だったのですが、それはまた別の機会にでも

二重引用符などで面倒なことにならない cmd.exe の呼び方

環境変数を使おう。

func system(cmdline string) error {
    const CMDVAR = "CMDVAR"

    orgcmdarg := os.Getenv(CMDVAR)
    defer os.Setenv(CMDVAR, orgcmdarg)

    os.Setenv(CMDVAR, cmdline)

    cmd1 := exec.Command("cmd.exe", "/c", "%"+CMDVAR+"%")
    cmd1.Stdout = os.Stdout
    cmd1.Stderr = os.Stderr
    cmd1.Stdin = os.Stdin
    return cmd1.Run()
}

Goの"/path/filepath" に「拡張子を除く関数」がないのが辛い

まぁ、自分で書いても数行なんですけどね

without.go

func withoutExt(fname string) string {
    ext := filepath.Ext(fname)
    return fname[:len(fname)-len(ext)]
}

手短なクロージャーの説明を考えてみた。

  • 関数の中で関数を定義できる
  • 子関数は親関数のローカル変数を参照できる
  • 子関数は親関数の外部にも放り出せて、そこでも親関数のローカル変数を参照できる
    • ただし、子関数が定義された時点で見えていた変数のみ

「git new」コマンドをでっち上げる(Windowsでgitのサブコマンドを作る)

自分の場合、新規レポジトリを作る際、いつも定番的に実行しなければいけない作業がある

  • git init
  • 最初に空コミット作成
  • 改行コード変換の無効設定
  • 日本語ファイル名はそのまま表示させる
  • メールアドレス等の設定

次の記事によると、「git-XXXX」という実行ファイルを作ると、git XXXX というサブコマンドを作成できるようだ。

Windowsなので git-new.cmd というバッチファイルを作成して、自分の定番初期化作業を一括化してみよう。

git init 
git commit -m "empty" --allow-empty
echo "* -text" > .gitattributes
git add .gitattributes 
git commit -m "Add .gitattributes as autocrlf=false"
git config --local core.quotepath false
git config --local user.email zetamatta@example.com 
git config --local user.name  zetamatta

テスト

$ git new
git: 'new' is not a git command. See 'git --help'.

Did you mean this?
        notes
exit status 1

だめでした!

EXEなどの実行ファイルでないとダメなのか。でも、スクリプトレベルのものをいちいち実行ファイル作るのは面倒すぎるなぁ。Linux だとシェルスクリプトが大丈夫なのに…

#!/bin/sh

if [ ! -e .git ] ; then
    git init 
    git commit -m "empty" --allow-empty
fi
if [ ! -e .gitattributes ] ; then
    echo "* -text" > .gitattributes
    git add .gitattributes 
    git commit -m "Add .gitattributes as autocrlf=false"
fi
git config --local core.quotepath false
git config --local user.email zetamatta@example.com 
git config --local user.name  zetamatta

(最終版なので、いろいろ機能追加してますが、気にしないでください)

Git for Windows は MSYS ベースで動作しているので、普通に「git-new」という拡張子無しのテキストファイルを %PATH% 上において、シェルスクリプトを書けば Ok でした!

$ git new
Initialized empty Git repository in C:/Users/Hayama/Share/cmds/.git/
[master (root-commit) 6b0d022] empty
[master f9ca464] Add .gitattributes as autocrlf=false
 1 file changed, 1 insertion(+)
 create mode 100644 .gitattributes

以上

github の Releases のダウンロード数を curl と jq でお手軽に調べたいッ

次のような API があるようだ。

GET /repos/:owner/:repo/releases」の意味が分かりにくいが、「:owner」と「:repo」を、レポジトリのオーナー名とレポジトリ名に置き換えればよいようだ。つまり、https://github.com/zetamatta/nyagos の情報を見たい時は https://api.github.com/repos/zetamatta/nyagos/releases を開けばよろしい。ブラウザでも大丈夫で、別に認証も要らないようだ。

得られるデータは JSON なので、これを加工するツールが必要だ。自前で作ってもよいが、お手軽に jq とやらを使ってみよう。初めて使うので、コマンドがよく分からないが、jq コマンドを使う日常のご紹介 - Qiita やら、jq Manual (development version)などを見て、試行錯誤してみた結果、次の1行で期待する出力を得ることができだ。

curl https://api.github.com/repos/zetamatta/nyagos/releases | jq-win64.exe ".[].assets[] | .name, .download_count"
"nyagos-4.3.1_3-386.zip"
98
"nyagos-4.3.1_3-amd64.zip"
229
"nyagos-4.3.1_2-386.zip"
65
"nyagos-4.3.1_2-amd64.zip"
86
"nyagos-4.3.1_1-386.zip"
9
"nyagos-4.3.1_1-amd64.zip"
36
:以下省略

アクティブユーザ 200人くらいか。やっぱり、もう 64bit版をダウンロードするユーザの方が多いんだなぁ。

これが知りたかっただけだけど、ついでに jq の使い方が分かったので、得たものは大きい