1000ch.net

2017.02.15

テキストファイル中に含まれるURLが有効かどうかチェックするツールを作った

前略、 1000ch/reachable-urls というテキストファイルに含まれる URL が有効かどうかチェックするツールを作った。一応程度に @inao さんに報告したらなんと使ってくれて、案外便利だったようで色々フィードバックをもらいながらコツコツ直した。今はバグも取れてきて安定してきたので、そろそろメジャーリリースしようかと考えている。

インストールと使い方

Node.js 製なのでインストールは npm で。インストールすると reachable-urls コマンドが使えるようになる。グローバルにインストールしてもいいし、ローカルにインストールして npm test で実行するのも悪く無さそう。

$ npm install -g reachable-urls

引数にはファイルパスか glob を指定する。テキストファイルならなんでも OK なので、プレーンテキストなのかマークダウンなのかは問わない。テキストファイルから正規表現で URL を抜き出して sindresorhus/is-reachable でチェックするという単純な仕組みで出来ている。

$ reachable-urls ./*.md

reachable-urls demo

CLI だけでなく、もちろん require() しても使える。

const assert = require('assert');
const reachableUrls = require('reachable-urls');

reachableUrls('https://github.com https://foobarbaz.com').then(result => {
  assert.deepEqual(result, {
    'https://github.com': true,
    'https://foobarbaz.com': false
  });
})

実装するかもしれない機能リスト

http / https プロトコル以外のチェック

@Jxck 氏によるバグ報告で気付いたが、 sindresorhus/is-reachable で WebSocket のプロトコルである wswss をチェックできない。これは内部で使っている silverwind/port-numbers で WebSocket が使うポート番号を引いてこれていないことが問題。

設定に、以下のような WebSocket 要の定義を追加すれば動きそうだが、Service Name and Transport Protocol Port Number Registry を元に記述しているようで WebSocket の定義追加を憚られている。

"ws": {
  "ports": [
    "80/tcp"
  ]
},
"wss": {
  "ports": [
    "443/tcp"
  ]
},

ユースケースとしては、全プロトコル対応の URL ヘルスチェックではなく、リンク先にページがあるかどうかを想定しているので、ひとまずチェック対象を httphttps に限定することにした。

標準入力 --stdin オプション

作った当初は glob で充分じゃろと思っていたが、 --stdin でパイプできても良さそう。

// foo.md の中身を reachable-urls へ渡す
$ cat foo.md | reachable-urls --stdin

ネットワーク越しにチェックする --url オプション

ぶっちゃけこれは要らないかなと思っているけどメモがてら。

// https://google.com のレスポンスに含まれる URL が有効化をチェックする
$ reachable-urls --url https://google.com