Deno.args
やDeno.exit
などの機能を使い、Deno で CLI ツールを作っていく。
Deno のバージョンは1.3.1
で動作確認している。
コマンドライン引数の受け取り方
渡されたコマンドライン引数は、Deno.args
で取得することができる。
例えば$ deno run cli.ts a b --foo 1 -b 2
を実行すると、以下の結果になる。
// cli.ts console.log(Deno.args); // [ "a", "b", "--foo", "1", "-b", "2" ]
このままでも使えないことはないが、標準モジュールが提供しているparse
メソッドを使うと、より使いやすくなる。
import { parse } from "https://deno.land/std@0.66.0/flags/mod.ts"; console.log(Deno.args); // [ "a", "b", "--foo", "1", "-b", "2" ] const parsedArgs = parse(Deno.args); console.log(parsedArgs); // { _: [ "a", "b" ], foo: 1, b: 2 } console.log(parsedArgs.foo); // 1 console.log(parsedArgs.b); // 2
parse(Deno.args)
はオブジェクトを返し、_
プロパティには、フラグと関連付けられなかった全てのコマンドライン引数が入る。今回の例だとa
とb
が該当する。
終了コード
Deno.exit
メソッドで、プロセスを終了させることができる。このメソッドに渡した引数が、終了コードになる。
以下のコードは、Deno.exit(3);
の行でプロセスが終了してしまうので、b
は表示されない。
console.log('a'); Deno.exit(3); console.log('b');
直前に実行したコマンドの終了コードは$?
に入っているので、確認してみる。
$ deno run cli.ts a $ echo $? 3
Deno.exit
に引数を渡さなかったり、Deno.exit
を実行することなくプロセスが終了したりした場合は、0
が終了コードになる。
テキストファイルを読み込む CLI ツール
ちょっとしたサンプルとして、指定された名前のファイルがカレントディレクトリにあった場合、それをテキストファイルとして読み込んで表示するプログラムを書いた。
const fileName = Deno.args[0]; const filePath = `${Deno.cwd()}/${fileName}`; // Deno.cwd() で、カレントディレクトリのパスを取得できる const fileData = await Deno.readFile(filePath); const decoder = new TextDecoder("utf-8"); const fileText = decoder.decode(fileData); console.log(fileText);
Hello!
と書かれたhello.txt
を用意した上で、実行してみる。
$ deno run cli.ts hello.txt error: Uncaught PermissionDenied: read access to <CWD>, run again with the --allow-read flag
権限がないため、エラーになった。--allow-read
をつければ、実行できる。
$ deno run --allow-read cli.ts hello.txt Hello!
CLI ツールの配布方法
Deno には、deno install
という、CLI ツールの配布やインストールを簡単に行えるサブコマンドが用意されている。
例えば、console.log("Hi!");
とだけ書かれたsay_hi.ts
という名前のファイルを、Gist に置く。
そしてそれをインストールする。
$ deno install https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts Download https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts Check https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts ✅ Successfully installed say_hi
そうすると、say_hi
コマンドが使えるようになっている。
$ say_hi Hi!
このように、非常に簡単にインストールできる。
配布する側も、ただウェブ上にファイルを置くだけでよい。
インストールされる場所
デフォルトだと、$HOME/.deno
というディレクトリに、bin/インストールしたファイル名(拡張子は省略)
という形でインストールされる。
対象のディレクトリは--root
で指定することも可能。
$ deno install --root ./ https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts $ ls ./bin/ say_hi
./
を指定したので、./bin/say_hi
としてインストールされた。
インストールされるファイルの名前
インストールしようとした場所に既に同名のファイルがある場合は、エラーになる。
$ deno install https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts Download https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts Check https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts error: Existing installation found. Aborting (Use -f to overwrite).
エラーメッセージにあるように-f
オプションをつけることで、上書きできる。
また、-n
オプションを使うと、インストールされる名前を指定することができる。
$ deno install -n greet https://gist.githubusercontent.com/numb86/0f3352f26cadbead72c98557ba4dae03/raw/76ba53c6e7c3864f30f9f543d051a1e3d7f4dea9/say_hi.ts $ greet Hi!
指定しなかった場合は拡張子を省略したファイル名になるのだが、ファイル名がmod.ts
やcli.ts
の場合は、親のディレクトリ名になる。
例えば、以下の内容のcli.ts
というファイルを Gist に置き、それをインストールする。
console.log("Hello!");
そうすると、cli.ts
の親ディレクトリであるaf5628023388ce6e280fbcb328e1081fa1cb4179
という名前でインストールされる。
$ deno install https://gist.githubusercontent.com/numb86/26045a06e6d9ff5ca294d7b291120c95/raw/af5628023388ce6e280fbcb328e1081fa1cb4179/cli.ts Download https://gist.githubusercontent.com/numb86/26045a06e6d9ff5ca294d7b291120c95/raw/af5628023388ce6e280fbcb328e1081fa1cb4179/cli.ts Check https://gist.githubusercontent.com/numb86/26045a06e6d9ff5ca294d7b291120c95/raw/af5628023388ce6e280fbcb328e1081fa1cb4179/cli.ts ✅ Successfully installed af5628023388ce6e280fbcb328e1081fa1cb4179 $ af5628023388ce6e280fbcb328e1081fa1cb4179 Hello!
権限の指定
--allow-read
のような権限の指定は、インストール時に行う。
例として、先程作ったテキストファイルを読み込むプログラムを、read_file.ts
としてGist に置く。
何の権限も指定せずにこれをインストールしてみると、成功する。
$ deno install https://gist.githubusercontent.com/numb86/1bd65079ceafc1c23fce14915af37178/raw/e9873beb7d9d76913192affc43674b1edef85bbb/read_file.ts Download https://gist.githubusercontent.com/numb86/1bd65079ceafc1c23fce14915af37178/raw/e9873beb7d9d76913192affc43674b1edef85bbb/read_file.ts Check https://gist.githubusercontent.com/numb86/1bd65079ceafc1c23fce14915af37178/raw/e9873beb7d9d76913192affc43674b1edef85bbb/read_file.ts ✅ Successfully installed read_file
だがread_file
を実行すると、失敗する。実行時に--allow-read
を付けることもできない。
$ read_file hello.txt error: Uncaught PermissionDenied: read access to <CWD>, run again with the --allow-read flag $ read_file --allow-read hello.txt error: Uncaught PermissionDenied: read access to <CWD>, run again with the --allow-read flag
--allow-read
をつけて、インストールし直す。
$ deno install -f --allow-read https://gist.githubusercontent.com/numb86/1bd65079ceafc1c23fce14915af37178/raw/e9873beb7d9d76913192affc43674b1edef85bbb/read_file.ts Download https://gist.githubusercontent.com/numb86/1bd65079ceafc1c23fce14915af37178/raw/e9873beb7d9d76913192affc43674b1edef85bbb/read_file.ts Check https://gist.githubusercontent.com/numb86/1bd65079ceafc1c23fce14915af37178/raw/e9873beb7d9d76913192affc43674b1edef85bbb/read_file.ts ✅ Successfully installed read_file
これで、実行できるようになった。
$ read_file hello.txt Hello!
ローカルファイルもインストール可能
ウェブ上のあるファイルだけでなく、ローカルにあるファイルもインストールできる。
// say_bye.ts console.log("Bye");
$ deno install say_bye.ts Check file:///Users/numb/hello-deno/say_bye.ts ✅ Successfully installed say_bye $ say_bye Bye