コンテンツにスキップ

13. 変更履歴

各バージョンで何が変わり、それがあなたの側で何を壊しうるか。

バージョンはまだ 0.x なので、マイナーの更新でも何かが壊れることがあります。 壊れる場合は、その項目が「何が」「どう対応するか」を明記します。ここでは何も 黙って変わりません。


  • スクリプトが、拒否されるかわりにプロセスを異常終了させられました。 ソースの入れ子がそのまま呼び出しスタックの入れ子になり、括弧2000個ほどで スタックが溢れ、実行は SIGABRT で死んでいました——終了コード3もメッセージも なく、捕まえようもありません。6つの形が該当します:((((…))))、!!!!…、 ----…、入れ子の配列、入れ子のブロック、そして "#{"#{…}"}"。パーサは深さを 数えるようになり、128段を超えると拒否します。人が書くどんなスクリプトより ずっと深く、スタックが尽きる場所よりずっと手前です。いちばん困るのは、他人の スクリプトに対して最初に実行するコマンドでした——pdfl lint が報告せずに 死んでいたのです。
  • パッケージが、インストール先の外にあるファイルを指定できました。 検査は .. と先頭の / を拒んでいましたが、C:/Windows/evil.dll や \\server\share\x は素通りでした。どちらもそれらを含まず、Windows では 絶対パスであり、インストール先と連結するとその連結先が捨てられます。いまは すべてのパスのすべての構成要素が単純な名前であることを求め、その規則は 展開するプラットフォームによって変わりません。
  • パッケージが、読み込み中にメモリを食い尽くせました。 マニフェストを見る前に 各エントリを丸ごとメモリに読み込んでいました——マニフェストが一度も触れない エントリまで。そのため圧縮したゼロ299 KB が380 MB を占め、もっと大きければ マシンごと持っていかれました。展開は64 MB で止まります。スクリプトと表から成る 実際のパッケージよりはるかに大きい値です。
  • --pages 1-20000000 は、文書を開く前からページ番号を確保していました—— 214 MB を使って、そのうえで何も言いません。100万ページを超える範囲は拒否します。
  • 上の修正は、これまで無かったところに上限を設けます。そのため以前は通っていた ものの一部が通らなくなります——128段を超えて入れ子になったスクリプト、64 MB を 超えて展開されるパッケージ、: や \ を含むファイル名を持つパッケージ、 100万ページを超えるページ範囲です。いずれも実際のスクリプト・パッケージ・文書 の中身からは遠く外れていますが、以前は失敗しなかったので、見つけてもらうのでは なく書き留めておきます。

ビューアのモードを廃止しました。 Flip、Fade、Blend スライダ、Differences スライダ、そしてそれらを操作していた space と d のキーはもうありません。

影響を受けるのは生成されるビューアだけです。レポートも終了コードもオプションも 変わらないので、pdfl の出力を読んでいるものは何も気づきません。3つのペインが これらのモードの用途に答えます——2つのファイルが交互ではなく同時に画面に 出ているからです。モードやキーの名前を書いた独自の手順書があるなら、見直しが 必要です。

  • pixelcompare のビューアが、モードを選ぶ1枚のペインではなく、3つのペインを 横に並べた形になりました——元のファイル、新しいファイル、そして両方に差分を 重ねて着色したもの。3つ目がワイプするあいだ左右の参照は動かないので、ワイプが 何と何のあいだを切っているのかが見えます。
  • どのペインも同じ2本のバー——縦と横——を同じ位置に持ち、6本すべてが一緒に 動きます。バーはポインタについてきます。つかむものも狙うものもなく、交点は マウスのある場所です。差分のペインでは2本とも切れ目になり、新しいファイルは 縦のバーの右かつ横のバーの下に現れ、交点が現れている領域の角になります。 残る2つでは、ページの同じ列・同じ行を通る定規です。横のバーは一番上から 始まるので、ポインタがペインに入るまでは縦のバーが高さいっぱいの普通のワイプ のままです。
  • ホイールで3つのペインが一緒に、ポインタの下の点を中心に最大8倍までズームし、 縮小はページが収まる大きさで止まります。どちらのボタンでもドラッグすると ページそのものが、3つまとめて、ズームに関わらずポインタと同じ速さで動きます。 バーの太さはどのズームでも変わりません。Reset view はズーム、移動、バーを 最初の状態に戻し、戻すものがないあいだは無効です。別のページへ移っても同じ ことが起きます——ズームはそれを設定したページのものだからです。
  • ペインの大きさはウィンドウを基準に決まります。どんなウィンドウの形でも比較の 全体がスクロールなしで画面に収まり、それぞれがページの縦横比を保ちます。2つの ファイルでページの大きさが食い違う場合も、引き伸ばさず丸ごと収めます。
  • 開いた時点で、違いのあるページに合わせます。All で残りが戻ります。長い 文書では、そのページこそ開いた理由です。

loading の所見の識別子が変わります。 識別子はメッセージから導かれ、その メッセージはもう pdfium が入れていた改行を含みません。

影響を受けるのは読めなかった文書からの所見だけで、あなたの check がこれを 生むことはありません。ベースラインがその識別子を承認しているなら、記録し直す 必要があります。これが、このリリースをパッチではなくマイナーにしている理由です ——識別子はベースラインの土台であり、黙って変わってよいものではありません。

  • pdfl pack が、入れ子のファイルをパッケージを作った機械の区切り文字で記録して いました——Windows では data\batches.csv。パッケージはある機械で作られ別の機械に インストールされるものなので、/ 以外はインストールできても自分のファイルを 見つけられないパッケージになります。私たちの検証も見つけられませんでした。Linux と macOS で作られたパッケージは影響を受けていません。
  • PDF が読めないとき --output と --output-file が無視されていました。 run、fix、compare は何を指定されても stdout に JSON を出していたため、 JUnit をファイルで求めたパイプラインはファイルを1つも受け取れず、読んでいない ストリームにレポートが流れていました——終了コードは正しく 10 を返している のに、壊れた入力が「実行されなかった」ように見えていたのです。失敗のレポートも 他のすべてと同じ経路を通るようになりました。
  • pdfium のエラーが、3行にわたって整形された Rust の enum のままレポートに 届いていました。診断は CSV 行の1フィールドであり XML の属性でもあるので、 1行に畳むようにしました。

  • pdfl pixelcompare が各段階で進捗バーを表示します——両ファイルのラスタライズ、 比較、ビューアの書き出し。描くのは stderr が端末のときだけです。バーは自分の行を 上書きして動くもので、ログファイルには動かせるカーソルがないからです。リダイレクト 時は黙ります。--quiet はどの場合でも黙らせます。

  • pdfl pixelcompare の --jobs <n> が、その数だけページを同時に比較します。 既定は CPU 1つにつき1件で、150 dpi の41ページが3.6秒から1.2秒になります。並列に なるのは比較だけです——pdfium はすべての呼び出しを1つのグローバルロックの背後で 直列化するため、ラスタライズは並列にできません。3倍であって8倍でないのはそのため です。値を変えてもレポートは変わりません。ページはページ順に畳み直されるので、 診断も、その順序も、指紋も同一で、ビューアのファイルも同じです。

    ここでの既定は CPU 1つにつき1件ですが、test と watch は --jobs 1 です。 あちらでは1ジョブが自分の文書を抱えた子プロセスであり、こちらではページが すでにメモリにあってスレッドがそれを共有します。


  • pdfl pixelcompare が、テキストではなく見た目で2つの PDF をページごとに比較し、 異なるピクセルの割合を報告します。位置がずれただけのページは比較前に揃えるので、 1ピクセルのずれが本当に大事な変化を埋もれさせません。
  • pixelcompare の --viewer <フォルダ> は、自己完結したアプリケーションを 書き出します——CDN もバンドラもサーバも不要。2つのファイルをワイプ、フリップ、 フェードで見比べられ、差分はその場に着色されます:消えたインキは赤、新しい インキは緑、同じ太さで色が違うものは青。ページ一覧は Changed only に 絞り込め、矢印キーもその絞り込みに従います——長い文書では、動いていない ページを送っていくのが仕事の遅い部分です。

  • if / else if / else を式として追加しました。値は実行された分岐の最後の 式で、これは関数がすでに従っている規則と同じです。そのため値としても (const LIMIT = if coated { 300 } else { 260 })、文を囲むガードとしても使え、 第2の構文を必要としません。実行されない分岐は null を返し、各分岐は独自の スコープを持ちます——外にすでにある変数への代入は、これまでどおりその変数を 更新します。

  • --var が pdfl run だけでなく pdfl test と pdfl watch にも届くように なりました。どちらも自分が起動する子プロセスに渡していなかったため、 vars.* を読むスクリプトはテストも監視もできませんでした——内容に関わらず、 すべてのケースやファイルが「was not provided」で失敗していました。

  • pdfl pack は表計算ファイルを同梱しなくなりました(.xlsx、.xls、 .ods)。除外したファイル名は表示します。data:: のどの関数もそれらを開けず、 同梱したパッケージはインストールに成功しても最初の参照で失敗していました。 表計算を同梱していた場合は、先に .csv か .json に書き出してください。
  • run の --tags TAG。実行する check を絞り込みます。繰り返し指定でき、 指定したタグのいずれかを持つ check が実行されます。
  • inspect と lint の --json、doc の --output json。すべての サブコマンドがプログラムから読めるようになりました。
  • --output sarif と --output junit。レポート形式を選ぶところすべて——run、 compare、watch、fix——で使えます。SARIF は GitHub code scanning が読む 形式、JUnit はあらゆる CI のテストパネルが読む形式です。
  • pdfl completions <shell> が bash、zsh、fish、elvish、powershell 用の補完 スクリプトを出力します。
  • すべてのコマンドで使える --quiet が、stderr への進捗と確認メッセージを止め ます。エラーは表示され、print() はそのままです——あれはスクリプト自身の出力 であり、握りつぶすとスクリプトの振る舞いが変わってしまいます。
  • data::load_dataset と data::lookup_value が .csv に加えて .json を 読みます。配列の配列、またはオブジェクトの配列で、最初のオブジェクトが ファイルに書かれた順で列名を決めます。
  • pdfl test <script> が PDF のフォルダに対してスクリプトを実行し、各レポートを 隣に記録されたものと比較します。プロファイルが違うものを見つけ始めたら、下流の 誰かを驚かせる前にテストが落ちます。--update で期待するレポートを記録します。
  • pdfl test の --jobs <n> が、指定した数のケースを同時に——それぞれ独立した プロセスとして——実行します。41ページのファイル8つで、--jobs 1 が8.9秒、 --jobs 8 が1.1秒。各ジョブが文書をメモリに抱えるため既定は 1 のままです。 --jobs 0 で CPU 1つにつき1件になります。
  • pdfl watch にも --jobs <n>。ファイルは子プロセスが検証するので、バッチの 1回のパスも同じようにスケールします(41ページのファイル8つで9.5秒→1.2秒)。 書き出されるレポートは --jobs の値によらず同一です。
  • pdfl watch の --events。タイマーではなくファイルシステムの通知を待ちます。 既定ではなくオプトインです。NFS や SMB のマウントでは inotify がローカルの 書き込みしか報告せず、ネットワークのホットフォルダが黙り込むためです。監視を 開始できないときは、その旨を告げてタイマーに戻ります。
  • pdfl watch の --journal <ファイル>。検証したものを追記のみで記録します (1ファイルにつき JSON 1つ)。同じ journal で再実行すると、そこに載っている ファイルは飛ばされます——5000個中4000個で中断したバッチは残り1000個を片付けます ——が、判定は引き続き報告されるので、再開したバッチが「フォルダはきれい」と 言うことはありません。
  • pdfl watch の --timeout <秒> は、その秒数を超えたファイルの解析を強制終了 し、不合格として報告します——1つの所見、check_name: "timeout"——バッチを止め たままにする代わりに。.pdfl スクリプトの再帰にはすでに深さの上限があるため、 これはスクリプトでは起こせないもの、つまり不正または悪意ある PDF に対して pdfium がループしたり止まったりする場合のためにあります。
  • どの check も持たないタグはエラーであり、空の合格ではありません。そうで なければ、タグを綴り間違えたパイプラインは何も検証せずに「きれいなファイル」 と報告してしまいます。
  • rule はタグを持たないため --tags では飛ばされます。タグのない check と 同じ扱いです。
  • JSON レポートに checks_run(実行された check と rule)が加わりました。 schema_version は上げていません。未知のフィールドを無視する読み手はこれを 問題なく通過するからです。JUnit にはこれが要ります——診断は何かを見つけた check しか名指さず、きれいな実行がテスト0件として報告されると、CI はそれを 「実行されなかった」と受け取ります。
  • pdfl watch が、最も新しいファイルが書き終わった時点で起きるようになりました。 以前は最大で1周期ぶん遅れていました。--debounce 3000 の場合、到着したファイル は最大6秒ではなく約3秒後に報告されます。

  • スクリプトがコマンドラインから値を受け取ります。--var 名前=値 を vars.名前 として読みます。渡されていない値は、何もない値に解決される のではなく、それを与えるフラグの名前を示します。
  • visual:: で2つの文書を比較する実用例が4つ:proof.pdfl、reprint.pdfl、 scope.pdfl、intake.pdfl。

ありません。vars に触れないスクリプトの挙動は以前とまったく同じです。


診断の識別子の形が変わりました。 以前は実行内の連番 PDFL-001 でしたが、 いまは所見そのものから導かれます(例:PDFL-093751a2)。

PDFL-\d+ に一致させていたものは一致しなくなります。その代わり、上に check を挿入しても識別子は変わりません。承認済みのベースラインを維持できるのは、 これがあるからです。

読めない入力の終了コードが 2 から 10 になりました。 壊れたファイルと 不合格のファイルが、パイプラインからは区別できませんでした。

CI が 2 を「このファイルは不合格」と解釈しているなら、そもそも判定に至って いない場合に 10 が返ります。所見は引き続き 0・1・2、スクリプトの構文 エラーは引き続き 3 です。

  • check が自分の所見の重大度を宣言できます。 check "..." severity: warning { ... } — error(既定)、warning、info。 これにより --fail-on warning が作用する対象を持ちます。
  • JSON レポートの先頭に schema_version が入り、消費側がどの形を読んでいるか 分かります。以前の出力を読んでいた側が壊れる場合にのみ上がり、フィールドの 追加では上がりません。

  • PDF レポートの一部がポルトガル語のままでした。節見出しが Diagnósticos、 各診断に (linha N) が付いていました。どちらも英語になり、ドキュメントが ずっと約束してきた状態になりました。

リリース対象名が x64 から amd64 になり、すべてのアセット名が変わりました。

可搬アーカイブの公開をやめました。 Linux amd64 の1つだけが残ります。

pdfl-<version>-linux-x64.tar.gz を取得しているもの、あるいは Linux amd64 以外の可搬アーカイブを使っているものは変更が必要です。CI では .deb から インストールしてください(本ドキュメントのレシピはそのように更新済みです)。 インストールできない環境では Linux amd64 の tarball を使ってください。

  • ドキュメントとソースを突き合わせて見つかった2つの欠落。 text::detect_personal_data と text::detect_pii は文字列を省略可能な引数 として受け取りますが、どこにも書かれていませんでした。また fix::reorder_pages の書き方が言語間で2通りに分かれていました。

  • 各プラットフォームのインストーラ:Linux は .deb、macOS は .dmg、Windows は -setup.exe と .msi。
  • macOS Intel 版。Apple Silicon のランナーからクロスビルドしています。
  • Windows インストーラが誤ったディレクトリを基準にパスを解決してビルドされて おり、ファイルが生成されていませんでした。
  • リリースパッケージに pdfium の C ヘッダとビルドファイルが同梱されていました。 pdfium に対してコンパイルする人にしか関係しないもので、1パッケージあたり およそ 550 KB です。

  • Windows x64 が公開プラットフォームに加わりました。

同梱の pdfium.dll は pdfium\lib ではなく pdfium\bin にあります。pdfl を自分で再パッケージする場合は配布時の配置を保ってください。バイナリは自分の 隣でライブラリを探します。


リリースアセットの名前にバージョンが入りました。 pdfl-<version>-<target>.tar.gz の形で、中のディレクトリにも入ります。

.../releases/latest/download/<name> は解決しなくなります。この エンドポイントは正確なファイル名を要求するためです。パターンで取得して ください:gh release download --pattern 'pdfl-*-linux-amd64.*'。

  • コード、README、サンプルが英語になりました。ドキュメントは7言語のままです。

最初の公開版。言語、インタプリタ、10個の CLI コマンド、7言語のドキュメント。


← レシピ · 目次

DigitalOceanこのサイトのホスティングを提供してくださる DigitalOcean に感謝します。