18
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DartAdvent Calendar 2014

Day 11

Dartでコマンドラインツールを作る

Last updated at Posted at 2014-12-10

「Dart Advent Calendar 2014」 11日目は@zukkunが担当します。

Dartは、JavaScriptの代替として登場しましたが、独自のVMを持ち、コマンドラインからDartのプログラムを実行する環境が提供されています。

今回は、Dartでのコマンドラインツールを作る方法を、以下のページを参考にしながら紹介しようと思います。

Write Command-Line Apps | Dart: Structured web apps

動作確認環境はMac OS X 10.9.5です。(Dartは、Windows、Linuxでも使えます)

Dartをインストール

Dartがインストールされていなければ、まずDartをインストールします。

Mac環境では、Homebrewを使ってDartをインストールすることができます。

$ brew tap dart-lang/dart
$ brew install dart

はじめにbrew tapでリポジトリを追加する必要があるので注意です。

参考:Dart News & Updates: Dart launches support for Homebrew

インストールができたら、Dartがインストールされたか確認します。

$ dart --version
Dart VM version: 1.7.2 (Tue Oct 14 06:58:25 2014) on "macos_x64"

簡単なDartプログラムを書く

まず、簡単なDartのプログラムを書きます。

hello.dart
main() {
  print('hello');
}

これを実行してみます。

$ dart hello.dart
hello

helloが出力されます。

これで一応コマンドラインのアプリケーションが作れました。

もう少しコマンドラインツールっぽくしてみましょう。

コマンドライン引数を受け取る

Dartでコマンドライン引数を受け取るには、main関数の引数にList<string>を型とした引数を加えます。

hello.dart
main(List<string> arguments) {
  print('hello $arguments');
}

引数の内容をそのままhelloのあとに表示するようにしてみました。

試しに適当に引数を与えて実行してみます。

$ dart hello.dart foo bar 123
hello [foo, bar, 123]

コマンドライン引数がリストとしてそのまま文字列展開されて出力されました。

コマンドライン引数を解析する

自力でコマンドライン引数の内容を解析してもいいですが、複雑なものとなるとけっこう大変です。

そんなときは、このパッケージを使いましょう。

args 0.12.1 | Pub Package Manager

こちら、パッケージとして公開されていますが、Dart Team謹製の公式パッケージです。

パッケージをインストールするために、pubspec.yamlを書きます。

pubspec.yaml
name: hello
dependencies:
  args: any

依存パッケージにargsを追加しました。

pub getで依存パッケージを取得します。

$ pub get
Resolving dependencies... (2.5s)
+ args 0.12.1
+ collection 1.1.0
Downloading collection 1.1.0...
Changed 2 dependencies!

真偽値としてオプションを受け付ける

Dartプログラムに、コマンドライン引数の解析の処理を追加します。

hello.dart
import 'package:args/args.dart';

ArgResults argResults;

main(List<string> arguments) {
  final parser = new ArgParser()
    ..addFlag('hoge', negatable: false, abbr: 'h');

  argResults = parser.parse(arguments);

  print('hello ${argResults['hoge']}');
}

ArgParseraddFlagで「オプションを指定したか、していないか」の真偽値で引数を受け取ることができます。

negatableは、否定形の引数を受け付けるかを指定できます。(falseを指定しなければ、--no-hogeという指定を受け付ける)

abbrはAbbreviationの略で、「省略」を意味します。今回'h'としているので、-hという指定でも--hogeと同じ意味を持たせることが出来ます。

$ dart hello.dart --hoge
hello true
$ dart hello.dart
hello false
$ dart hello.dart -h
hello true

値付きのオプションを受け付ける

真偽値ではなく値付きでオプションを受け付ける場合は、addOptionを使います。

hello.dart
import 'package:args/args.dart';

ArgResults argResults;

main(List<string> arguments) {
  final parser = new ArgParser()
    ..addFlag('hoge', negatable: false, abbr: 'h')
    ..addOption('foo', abbr: 'f');

  argResults = parser.parse(arguments);

  print('hello ${argResults['foo']}');
}
$ dart hello.dart --foo bar
hello bar
$ dart hello.dart
hello null

他にも、デフォルト値の指定や、バリデーションの機能など、盛りだくさんです。

また、GitやRailsなどで見る<プログラム名> <コマンド名> <パラメータ>のような「コマンド形式」でのコマンドライン引数の受け取りのためのaddCommandなどもあります。

コマンドラインツールをインストールする

作ったコマンドラインツールを実行するためにはdart hello.dartのように、dartコマンドの引数としてプログラムのファイル名を指定してあげる必要がありましたが、これをhelloという独立したコマンドとして実行できるように環境にインストールすることができます。

まず、先ほど作ったhello.dartを、pubspec.yamlがあるディレクトリから見てbin/hello.dartとしてファイルを移動させます。(binディレクトリ無ければ作ります)

そして、pubspec.yamlexecutablesを追加し、その中にhelloを追加します。

pubspec.yaml
name: hello
dependencies:
  args: any
executables:
  hello:

次にpub globalというコマンドを使用します。

参考:pub global | Dart: Structured web apps

通常は、pub.dartlang.orgに公開された実行可能なパッケージをインストールするときに使用しますが、先ほど作成したhello.dartをインストールしてみます。(pub global上では「インストール」ではなく「アクティベート」と呼んでいますが、便宜上インストールと書きます)

pub globalのあとにactivateを指定し、--source pathオプションをつけ、そのあとにpubspec.yamlが存在するパスを指定することで、ローカル環境にあるパッケージを指定してインストールできます。

$ cd <pubspec.yamlがあるパス>
$ pub global activate --source path .
Activated hello 0.0.0 at path "<pubspec.yamlがあるパス>".
Installed executable hello.

これでhelloというコマンドが使えるようになりました。

$ hello
hello null
$ hello --foo bar
hello bar

helloコマンドの実態は~/.pub-cache/bin/helloとして作られており、中身は以下のようになっています。

hello
#!/usr/bin/env sh
# This file was created by pub v1.7.2.
# Package: hello
# Version: 0.0.0
# Executable: hello
# Script: hello
pub global run hello:hello "$@"

pub globalのアクティベートまわりやrunなどの仕様の説明については割愛します。

コマンドラインツールをアンインストールする

インストールしたコマンドラインツールをアンインストールする場合はpub global deactivateを使います。

$ pub global deactivate hello
Deactivated package hello 0.0.0 at path "<先ほどのpubspec.yamlがあったパス>".

これでhelloが使えなくなりました。

$ hello
zsh: command not found: hello

細かい機能や仕様の話など、まだまだ語り尽くせないものがありますので、機会があれば触って解説できたらと思います。

明日は…………担当者がいない?!どうする @laco0416 さん!

Twitterより引用
@zukkun@laco0416 Dart Advent Calendarの明日の担当者いません!」
@laco0416@zukkun 書いてどうぞ!」

明日は@zukkunさんです!俺だ!

18
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?