やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

ライセンスのファイル名はどうすべきか?

 LICENSE or COPYING。拡張子は付けたらダメ? それとも.txt,.md,rstなどを付けるべき? マルチライセンスのときは?

結論

  1. LICENSE(.txt|.md)?
  2. LICENSE-{license_id}({ext})?

 LICENSEが一番よく見かける。任意でLICENSE.txtのように拡張子を付与してもよい。正式なルールはなく、慣習にすぎない。マルチライセンスのときはライセンスIDを付与する。

GitHubではどうしているか?: licensee

 ツールを使って判定している。これでマッチする名前なら何でもいい。

# Hash of Regex => score with which to score potential license files
FILENAME_REGEXES = {
  /\A#{LICENSE_REGEX}\z/                       => 1.00,  # LICENSE
  /\A#{LICENSE_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.95,  # LICENSE.md
  /\A#{COPYING_REGEX}\z/                       => 0.90,  # COPYING
  /\A#{COPYING_REGEX}#{PREFERRED_EXT_REGEX}\z/ => 0.85,  # COPYING.md
  /\A#{LICENSE_REGEX}#{OTHER_EXT_REGEX}\z/     => 0.80,  # LICENSE.textile
  /\A#{COPYING_REGEX}#{OTHER_EXT_REGEX}\z/     => 0.75,  # COPYING.textile
  /\A#{LICENSE_REGEX}[-_]/                     => 0.70,  # LICENSE-MIT
  /\A#{COPYING_REGEX}[-_]/                     => 0.65,  # COPYING-MIT
  /[-_]#{LICENSE_REGEX}/                       => 0.60,  # MIT-LICENSE-MIT
  /[-_]#{COPYING_REGEX}/                       => 0.55,  # MIT-COPYING
  /\A#{OFL_REGEX}#{PREFERRED_EXT_REGEX}/       => 0.50,  # OFL.md
  /\A#{OFL_REGEX}#{OTHER_EXT_REGEX}/           => 0.45,  # OFL.textile
  /\A#{OFL_REGEX}\z/                           => 0.40,  # OFL
  /\A#{PATENTS_REGEX}\z/                       => 0.35,  # PATENTS
  /\A#{PATENTS_REGEX}#{OTHER_EXT_REGEX}\z/     => 0.30,  # PATENTS.txt
  //                                           => 0.00   # Catch all
}.freeze

 各定数は以下。拡張子はmd,txtあたりが使うだろう。

PREFERRED_EXT = %w[md markdown txt html].freeze
PREFERRED_EXT_REGEX = /\.#{Regexp.union(PREFERRED_EXT)}\z/.freeze
OTHER_EXT_REGEX = %r{\.(?!spdx|header|gemspec)[^./]+\z}i.freeze
LICENSE_REGEX = /(un)?licen[sc]e/i.freeze
COPYING_REGEX = /copy(ing|right)/i.freeze
OFL_REGEX = /ofl/i.freeze
PATENTS_REGEX = /patents/i.freeze

なぜ大文字か?

 最初に目につきやすくするため。大文字はASCII文字コード順でソートすると先頭になる。小文字は大文字よりも後に表示される。

 実際は以下のような影響も受けるため、必ずしも先頭にはならない。

  • LC_COLLATEによってソート方法が変わる
  • ファイルよりディレクトリのほうが先に表示される(文字種関係なし)

なぜ拡張子がない?

 慣習。LinuxUnixでは基本的にテキストファイルであることが前提である。つまり拡張子は不要であるため付けていない。

拡張子はつけるべき?

 付けたほうが良いと思う。.txtまたは.md

拡張子 判断基準
慣習に従う(すべて大文字にするため)
幅広いOSでの利便性を求めるWindowsMac OSではファイルを起動するアプリを決定するのに役立つ。ないとテキストエディタで開けない)

拡張子がないことによる弊害

 開くべきアプリを特定できない。テキストエディタで開けない。

 また、以下のように拡張子がないとディレクトリとして判断してしまうアプリも存在するようだ。

LICENSE v COPYING ?

提唱者 ファイル名
FSF LICENSE or COPYING
GPLソフトウェア COPYING.txt
FreeBSD COPYRIGHT

 licenseeのスコア的にはLICENSEが有利。それを使ったほうがよい。

LICEN**S**E or LICEN**C**E ?

 英語の問題。

英単語 イギリス アメリ
license 動詞 動詞・名詞
licence 名詞 (使わない)

 licenseのほうが利用範囲が広い。よってlicenseのみ出力ファイル名として採用したほうがいい。ただしファイル検出するときはlicenceも含めるべき。

COPYING or COPYRIGHT or COPY

 どれでもいい。慣習的にはCOPYINGにしたほうがよい。licenseeでは以下の正規表現にマッチしているかで判定している。スコアに差はない。

COPYING_REGEX = /copy(ing|right)/i.freeze

 /iによってignore case(大文字小文字を区別しない)になっている。慣習的にはすべて大文字にしたほうがよい。

マルチライセンス(デュアルライセンス)のときは?

 方法は2通りある。

  • (A) 複数のライセンスファイルを作る
  • (B) ひとつのライセンスファイルに内容を結合させる

 (B) はダメだと思う。ライセンスによってはライセンスファイルの内容を改変したらダメなものもあるっぽいから。実際は知らん。加工するのが面倒くさいのでやりたくない。

 (A) はファイル名の問題がある。異なる一意の名前にする必要がある。それは慣習であるLICENSE(.txt)?を破らねばならないことを意味する。2つ以上の異なる名前が必要だから。

 たとえばMITApache-2.0のいずれかひとつを選択できるデュアルライセンスだったとすると以下。

  • LICENSE-MIT
  • LICENSE-APACHE

 これは実際にあるrust-lang/rustリポジトリのもの。ただし問題もある。

  • 拡張子がない
  • 正式なライセンスID名ではない

 もしこれらを解決しようとすると以下のようになる。

  • LICENSE-MIT.txt
  • LICENSE-Apache-2.0.txt

 これらには以下の問題がある。

 私の独断だが、LICENSEの部分を大文字にしておけばいいと思う。それ以降は自由にしたい。

 大文字小文字が混在してもかまわないことにしたい。ソート順に関わるが、LICENSE*が並んでいればライセンスファイルであると判断できるはず。あとは細かいことなので適当でいい。

 どうしてもソート順にこだわるならLICENSE以降をすべて大文字または小文字にすればいい。別に揃っていなくてもソート順だけの話なので割とどうでもいい。そんなに沢山のライセンスファイルは作らないはずだし、あったところでソート順により困ることはほとんどないだろう。ACCAbcのうちACCのほうが先に出てしまったとして、一体何が困るというのか。

 ライセンスIDや.も同じ。別にどうでもいい。licenseeが認識できるかどうかだけが重要。

区切り文字: _ or -

 HTML上で表示するとき_が下線に隠れて見えなくなることがある。そのときはスペースと区別がつかなくなってしまう。それを避けるために区切り文字には-を使う。

 HTMLはリンク<a>にマウスオーバーすると下線が表示されることが多い。このとき上述の問題が生じる。

 以下のような問題になるときはほとんどないと思われる。念の為。

  • プログラミング言語の変数名につけられる名前に使える記号は_である。-は使えない
    • もしファイル名をそのまま変数名として使うならリネームが必要である

 ライセンスIDには.が使われうる。AGPL-3.0-onlyなどバージョン値を示すところに。これに関してはファイル名として使ってしまってもよいことにしたい。リネームが面倒だし可読性も悪くなるから。たとえばAGPL-3-0-onlyのようにしてもコレジャナイ感ある。.はHTML下線で見えなくなってもいい。

区切り文字: .

 拡張子として使われる。もし自作プログラミングで拡張子を識別するアルゴリズムに失敗したらバグになる。

  • OK: 拡張子は最に見つかった.以降の文字列である
  • NG: 拡張子は最に見つかった.以降の文字列である

 A.B.txtだと以下のようになる。

  • OK: A.B + txt
  • NG: A + B.txt

 ディレクトリとの区別は名前ですべきではない。ファイルシステムAPIによって識別すべきである。どうしても文字列ですべき文脈があるなら、以下のルールでやるとよい。

 licenseeではLICENSE.MITのようにすると認識されなくなってしまう。正規表現[-_]にあるように-_のいずれかのみ有効。_はHTML下線で見えなくなることを考えて-を使うのが良さそう。

所感

 慣習とかやめて? すぐグチャグチャになるから。後始末が大変になるから。早いうちにキッチリカッチリ完全無欠の完璧に定義してくれ。

 先人達の偉大さに感謝。こんなつまらないことに多大な労力をかけてlicenseeを作ってくれたのだから。でもまだだ。もっと楽がしたいんだよ。

対象環境

$ uname -a
Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux