git ignoreコマンドで.gitignoreを取得する

割とみんな知ってるのかもしれないですが。 git-xxxという名称で実行可能ファイルをパスの通ったところに配置すると、git xxxというgitのサブコマンドの形で実行することができるようになります。これを利用したのが拙作git-license で、git license [option] license_name > LICENSEの形で実行するとLICENSEファイルを簡単に作成することができます。 その他、git configでエイリアスを指定して、サブコマンドとして登録することも可能です。 同様にして、git ignoreで`.gitignoreファイルを簡単に取得できるようにしてみましょう。 おそらく現代では多くの人が.gitignoreの生成やテンプレート化をして、あるいはテンプレート化されたものを利用しているのではないでしょうか。GitHubのWUI上でリポジトリを作成するときにも生成することができますし、そのさい使用される.gitignoreファイルとしてgithub/gitignore が提供されています。 今回紹介するのはgitignore.io というサービスです。 gitignore.ioはその名の通り、.gitignoreファイルを生成するサービスです。 基本的な使い方は非常に簡単で、ブラウザでアクセスして、テキストボックスに必要な言語、OS、エディタやIDEなどを指定していくだけです。指定が終わったらCreateボタンを押すことで、選択した対象用の.gitignoreテンプレートを全て含んだ.gitignoreファイルが作成されます。これを保存すれば良いですね。 しかし、その他の作業をコマンドラインから行なっていると、いちいちブラウザでアクセスして、マウスで操作して・・・というのが非常に面倒に感じます。 大丈夫です!gitignore.ioではもちろんAPIを提供しています(というか、WUIで生成された.gitignoreのURLがそのままAPIのURL)。 次のように実行してみます。 1 $ curl https://www.gitignore.io/api/go,emacs,macos https://www.gitignore.io/api/の後ろに、カンマ区切りで必要なものを列挙して行くだけで、簡単にコマンドラインから.gitignoreファイルを取得できます。 ここまでやったらもう少し簡単にしたいですね?いちいちURLを打つのは面倒ですし、忘れてしまうかもしれません。せっかくなのでgitのサブコマンドとしてgit ignoreとできるようにしてみましょう。次のコマンドを実行してみます。 1 $ git config --global alias.ignore '!gi() { curl -L -s https://www.gitignore.io/api/$@ ;}; gi' もしくは、~/.gitconfigファイルの[alias]のセクションに次のように設定しても良いでしょう。 1 2 [alias] ignore = !curl -L -s https://www.gitignore.io/api/$@ $@は引数をそのまま渡すという変数です。このように設定をすることで、git ignoreとしてgitignore.ioのAPIを利用することができるようになります。実際に使用する時は次のように使用します。 1 $ git ignore go,emacs,macos 言語や環境のリストは全てまとめて一つの引数のため、カンマの後にスペースを入れないことに注意です。指定できる環境の一覧はgit ignore listとすることで表示できます。 標準出力をそのままリダイレクトして、.gitignoreファイルに書き込めばプロジェクトの初期設定として使用できるでしょう。

2018-11-13 · nasa9084

jessevdk/go-flagsでサブコマンドを実装する

Go言語を用いてコマンドラインツールを開発する際、皆さんはフラグのパースやサブコマンドの実装にどんなパッケージを使用していますか?標準のflagパッケージのほか、、spf13/cobra 、alecthomas/kingpin などもよく使われているようです。 私は専ら、jessevdk/go-flags (以下go-flags)を使用しています。 go-flagsはその名の通り、基本的にはオプション/フラグの解析用パッケージで、ドキュメント もフラグ解析に関するものがほとんどです。 しかし、go-flagsでは、サブコマンドの実装も可能です。今回はこれに焦点を当ててご紹介していきます。 go-flagsでは、親コマンドにサブコマンドを登録する、という形でサブコマンドを実装していきます。サブコマンドは構造体として実装し、それぞれがオプションを格納する構造体を兼ねる形となります。 終端の、実際に何かの動作をするコマンドは Commander interfaceを実装している必要がありますが、中間のサブコマンド(docker containerのような、グルーピングのためのサブコマンド)はこれを実装していなくても構いません。 Commander interfaceの定義は次のようになっています。 1 2 3 type Commander interface { Execute(args []string) error } 非常に単純ですね。argsにはコマンドでパースされなかったあまりの引数が渡されます。 実際の実装例を見てみましょう。 1 2 3 4 5 6 7 8 type subcommand struct { verbose bool `short:"v" long:"verbose"` } func (cmd *subcommand) Execute(args []string) error { // some exec return nil } サブコマンドを実装したら、親のコマンドにサブコマンドとして登録します。 ドキュメントを見ると、Command構造体に登録する関数があること、Parser構造体はCommand構造体が埋め込まれていること、がわかります。 通常、go-flagsパッケージを使用する場合はパッケージグローバルのParse関数を使用することが多いと思うのですが、サブコマンドを実装する場合はトップレベルのパーサーを自分で作る必要があります。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 type options struct { // ... } var opts options // global option var parser = flags.NewParser(&opts, flags.Default) var subcmd subcommand func init() { parser.AddCommand("subcmd", "subcommand", "", &subcmd, ) } func main() { if _, err := parser.Parse(); err != nil { if fe, ok := err.(*flags.Error); ok && fe.Type == flags.ErrHelp { os.Exit(0) } log.Print(err) os.Exit(1) } } このように登録することで、subcmdという名前のサブコマンドが使用できるようになりました。go run main.go subcmdなどとすると、subcommand.Execute関数が実行されます。 実際にはParser.AddSubCommandのエラーをハンドリングしたりなど、もう少しやらなければならないことはあると思いますが、基本的には以上です。 ...

2018-11-06 · nasa9084

cut vs. parameter expansion

TL;DR:: bash/zsh parameter expansion is faster than cut. which is faster? Consider you want to take out hostname from URL or IP with port like some.mysql.server:3306 or 192.168.1.10:3306 using bash/zsh. There are some way to do this. The first way is using cut command: 1 2 $ TARGET="192.168.1.10:3306" $ echo ${TARGET} | cut -d ":" -f 1 Now printed 192.168.1.10 on your screen. The second way is using “shell parameter expansion”, which is functions of bash/zsh built-in. You can use shell parameter expansion like below: ...

2018-02-26 · nasa9084

Goでコマンドラインオプションを処理する

TL;DR github.com/jessevdk/go-flagsが便利 flagパッケージ コマンドライン・ツールを作ろうと考えたとき、避けては通れないのがコマンドラインオプションを如何に処理するか、ということです。 Go言語では、標準パッケージにflagというパッケージが存在し、これを用いることでコマンドラインオプションをパースすることが出来ます。 しかし、flagパッケージでは、ロングオプションとショートオプションを一度に定義することが出来ず、また、ロングオプションであろうとショートオプションであろうと-XXXという、ハイフンが一つつく形式のオプションとなります。 これはあまり一般的ではなく1、便利とも言いにくいでしょう。 そこで便利なのが、jessevdk/go-flags パッケージです。 go-flagsパッケージ jessevdk/go-flags パッケージは、その名の通り、コマンドラインオプションを取り扱うパッケージです。 ショートオプション、ロングオプションはもちろんのこと、ショートオプションをまとめて指定する、同じオプションを違う引数で複数回指定する、環境変数からの読み込み、デフォルト値の指定などに対応していて、一般的なオプションの処理に幅広く対応出来ます。 オプションは構造体として定義出来るため、パースした後の処理で取り回すのも簡単です。 簡単な例を見てみましょう。 1 2 3 4 5 6 7 8 9 10 11 12 type options struct { Name string `short:"n" long:"name" description:"listen address"` } func main() { var opts options if _, err := flags.Parse(&opts); err != nil { // some error handling return } fmt.Printf("Hello, %s\n", opts.name) } パッケージ宣言やインポートの節は省略していますが、上記をmain.goとして実行すると、以下の様に出力されます。 1 2 3 4 5 6 7 8 9 10 11 12 $ go run main.go -h Usage: main [OPTIONS] Application Options: -n, --name= listen address Help Options: -h, --help Show this help message $ go run main.go -n Foo Hello, Foo フィールドの設定 jessevdk/go-flagsパッケージでは、オプションを定義するために構造体を作ります。 構造体の各フィールドがオプション一つ一つに当たります。 そのため、細かい設定はタグで行うことになります。 以下で、このパッケージで使用できる、主なタグを紹介します。 ...

2018-02-24 · nasa9084

Generates LICENSE file: git-license

When we create a new repository on GitHub , we can choose an open source license. We choose an OSS license, then, LICENSE file is put into the new repository. Now, I’m usually using hub command to create a new repository. I’ll do below to create: 1 2 3 4 5 6 7 8 $ mkdir my_new_repository $ cd my_new_repository $ git init # # ... some code writing and commit ... # $ git create # git command is aliased to hub $ git push -u origin master In this flow, I can write description for repository1, set homepage2, make the repository private3, but I CANNOT choose LICENSE. I can choose and create LICENSE file on the GitHub web page, or I can copy from my other repositories because its content is fixed. However, I don’t do that. ...

2018-02-21 · nasa9084