13. Änderungen
Was sich in jeder Version geändert hat und was davon bei Ihnen brechen kann.
Die Version ist noch 0.x, ein Minor-Sprung darf also etwas brechen. Wenn er es
tut, sagt der Eintrag genau was und wie man sich anpasst. Hier ändert sich
nichts stillschweigend.
Behoben
Abschnitt betitelt „Behoben“- Ein Skript konnte den Prozess abbrechen, statt abgelehnt zu werden.
Verschachtelung im Quelltext wurde zu Verschachtelung auf dem Aufrufstapel:
rund zweitausend Klammern brachten den Stapel zum Überlaufen und der Lauf
starb mit SIGABRT — kein Exit-Code 3, keine Meldung, nichts Abfangbares.
Sechs Formen taten das:
((((…)))),!!!!…,----…, verschachtelte Listen, verschachtelte Blöcke und"#{"#{…}"}". Der Parser zählt jetzt seine Tiefe und lehnt jenseits von 128 Ebenen ab — weit mehr als jedes von Hand geschriebene Skript und weit unter dem, wo der Stapel endet. Am schlimmsten traf es den Befehl, den man bei einem fremden Skript zuerst ausführt:pdfl lintstarb, statt zu berichten. - Ein Paket konnte eine Datei außerhalb seines Installationsordners
benennen. Die Prüfung wies
..und ein führendes/ab, nicht aberC:/Windows/evil.dlloder\\server\share\x— beide enthalten nichts davon und sind unter Windows absolut, wo das Zusammenfügen mit dem Zielordner den Ordner verwirft. Jeder Bestandteil jedes Pfades muss nun ein einfacher Name sein, geprüft nach Regeln, die sich mit der entpackenden Plattform nicht ändern. - Ein Paket konnte beim Lesen den Speicher erschöpfen. Einträge wurden ganz in den Speicher gelesen, bevor das Manifest zu Rate gezogen wurde — auch Einträge, die es nie erwähnt —, sodass 299 KB komprimierter Nullen 380 MB belegten und mehr die Maschine. Das Entpacken endet jetzt bei 64 MB, weit über jedem echten Paket aus Skripten und Tabellen.
--pages 1-20000000legte die Seitenzahlen an, noch bevor ein Dokument geöffnet war — 214 MB, um dann nichts zu sagen. Bereiche über einer Million Seiten werden abgelehnt.
Gut zu wissen
Abschnitt betitelt „Gut zu wissen“- Die Korrekturen oben ziehen Grenzen, wo es keine gab: Einiges, was bisher
angenommen wurde, wird jetzt abgelehnt — ein Skript tiefer als 128 Ebenen, ein
Paket, das über 64 MB hinaus entpackt, ein Paket mit
:oder\im Dateinamen, und ein Seitenbereich über einer Million. Alles weit außerhalb dessen, was ein echtes Skript, Paket oder Dokument enthält — aber nichts davon schlug vorher fehl, deshalb steht es hier, statt entdeckt zu werden.
Die Modi des Betrachters sind entfallen. Flip, Fade, der
Blend-Regler und der Differences-Regler samt den Tasten space und d
gibt es nicht mehr.
Betroffen ist nur der erzeugte Betrachter — kein Bericht, kein Exit-Code und keine Option ändert sich, wer die Ausgabe von
pdflliest, merkt also nichts. Drei Bereiche beantworten, wofür diese Modi da waren: Beide Dateien sind gleichzeitig auf dem Schirm statt nacheinander. Eigene Anleitungen, die einen Modus oder eine Taste nennen, brauchen einen Durchgang.
Geändert
Abschnitt betitelt „Geändert“- Der
pixelcompare-Betrachter besteht aus drei Bereichen nebeneinander — dem Original, der neuen Datei und beiden mit den eingefärbten Unterschieden — statt aus einem Bereich mit Moduswahl. Die beiden Referenzen bleiben stehen, während der dritte wischt: Man sieht, wozwischen der Wischer schneidet. - Jeder Bereich trägt dasselbe Leistenpaar — eine stehende, eine liegende — an derselben Stelle, und alle sechs bewegen sich gemeinsam. Sie folgen dem Zeiger: nichts zu greifen, nichts zu treffen, der Kreuzungspunkt ist dort, wo die Maus steht. Im Differenzbereich schneiden die Leisten, die neue Datei erscheint also rechts der stehenden und unterhalb der liegenden und ihr Kreuzungspunkt ist die Ecke des Freigelegten; in den beiden anderen sind sie Lineale auf derselben Spalte und derselben Zeile der Seite. Die liegende Leiste beginnt oben, womit die stehende ein gewöhnlicher Wischer über die volle Höhe bleibt, bis der Zeiger einen Bereich betritt.
- Das Mausrad zoomt alle drei Bereiche gemeinsam, bis 8×, um den Punkt unter dem Zeiger und endet beim Herauszoomen an der eingepassten Seite. Ziehen mit irgendeiner Maustaste bewegt die Seite selbst, in allen dreien zugleich und im Tempo des Zeigers, gleich bei welchem Zoom. Die Leisten behalten bei jedem Zoom ihre Stärke. Reset view setzt Zoom, Verschiebung und Leisten auf den Ausgangszustand zurück und ist deaktiviert, solange es nichts zurückzunehmen gibt; ein Seitenwechsel tut dasselbe, denn ein Zoom gehört zu seiner Seite.
- Die Bereiche werden am Fenster bemessen: der ganze Vergleich passt ohne Scrollen auf den Schirm, bei jedem Fensterformat, und jeder behält die Proportionen der Seite. Wo die Dateien sich über die Seitengröße uneinig sind, wird jede ganz im gemeinsamen Rahmen gezeigt statt verzerrt.
- Er öffnet auf den Seiten, die sich unterscheiden; All holt den Rest zurück. In einem langen Dokument sind genau diese Seiten der Grund, ihn zu öffnen.
Die Kennung eines loading-Befunds ändert sich. Sie leitet sich aus der
Meldung ab, und die Meldung trägt die Zeilenumbrüche von pdfium nicht mehr.
Betroffen sind nur Befunde aus einem Dokument, das nicht lesbar war — kein eigener Check erzeugt so einen. Genehmigt eine Baseline eine solche Kennung, muss sie neu aufgenommen werden. Deshalb ist dies ein Minor und kein Patch: Auf der Kennung ruht die Baseline, also ändert sie sich nicht stillschweigend.
Behoben
Abschnitt betitelt „Behoben“pdfl packschrieb eine verschachtelte Datei mit dem Trennzeichen der bauenden Maschine auf — unter Windowsdaten\chargen.csv. Ein Paket wird auf der einen Maschine gebaut und auf einer anderen installiert: alles außer/ergibt ein Paket, das sich installiert und dann seine eigenen Dateien nicht findet, auch unsere Prüfung nicht. Unter Linux und macOS gebaute Pakete waren nie betroffen.--outputund--output-filewurden ignoriert, wenn die PDF nicht lesbar war.run,fixundcomparegaben JSON auf stdout aus, egal was verlangt wurde: Eine Pipeline, die JUnit in einer Datei anforderte, bekam gar keine Datei und einen Bericht auf einem Strom, den sie nicht las — eine defekte Eingabe sah aus wie ein Lauf, den es nie gab, während der Exit-Code korrekt10sagte. Der Fehlerbericht geht jetzt denselben Weg wie jeder andere.- Ein Fehler von pdfium erreichte den Bericht als über drei Zeilen ausgedrucktes Rust-Enum. Eine Diagnose ist ein Feld einer CSV-Zeile und ein XML-Attribut, deshalb wird sie jetzt auf eine Zeile gefaltet.
-
pdfl pixelcomparezeigt je Stufe einen Fortschrittsbalken — Rastern beider Dateien, Vergleichen, Schreiben des Betrachters. Gezeichnet wird nur, wenn stderr ein Terminal ist, denn der Balken überschreibt seine eigene Zeile und eine Logdatei hat keinen Cursor; umgeleitet bleibt er still.--quietschaltet ihn überall ab. -
--jobs <n>beipdfl pixelcomparevergleicht so viele Seiten gleichzeitig und steht standardmäßig auf einer pro CPU: 41 Seiten mit 150 dpi gehen von 3,6s auf 1,2s. Nur der Vergleich läuft parallel — pdfium serialisiert jeden Aufruf hinter einem einzigen globalen Lock, das Rastern kann es also nicht, und deshalb ist der Gewinn dreifach statt achtfach. Der Bericht hängt nicht vom Wert ab: die Seiten werden in Seitenreihenfolge zusammengeführt, also sind die Diagnosen, ihre Reihenfolge und ihre Fingerabdrücke identisch — und die Dateien des Betrachters ebenso.Hier ist der Standard eine pro CPU, während
testundwatchauf--jobs 1stehen. Dort ist ein Job ein Kindprozess mit eigenem Dokument; hier liegen die Seiten schon im Speicher und die Threads teilen sie sich.
pdfl pixelcomparevergleicht zwei PDFs danach, wie sie aussehen, statt nach ihrem Text, Seite für Seite, und meldet den Anteil abweichender Pixel. Eine nur verschobene Seite wird vor dem Vergleich ausgerichtet, damit ein Pixel Versatz nicht die Änderung begräbt, auf die es ankommt.--viewer <ordner>beipixelcompareschreibt eine eigenständige Anwendung — kein CDN, kein Bundler, kein Server — zum Wischen, Umschalten oder Überblenden zwischen beiden Dateien, mit den Unterschieden an Ort und Stelle eingefärbt: Rot für fehlende Farbe, Grün für neue, Blau für gleiches Gewicht in anderer Farbe. Die Seitenleiste filtert auf Changed only, und die Pfeiltasten folgen dem Filter — bei einem langen Dokument ist das Blättern an den unveränderten Seiten vorbei die langsame Arbeit.
if/else if/elseals Ausdruck: der Wert ist der letzte Ausdruck des gelaufenen Zweigs — dieselbe Regel, der eine Funktion schon folgt. Damit taugt es als Wert (const LIMIT = if gestrichen { 300 } else { 260 }) wie als Wächter um Anweisungen, ohne zweite Syntax. Ein Zweig, der nicht läuft, liefertnull, und jeder Zweig hat einen eigenen Gültigkeitsbereich — einer außerhalb bereits vorhandenen Variablen zuzuweisen ändert weiterhin jene.
Behoben
Abschnitt betitelt „Behoben“--varerreicht jetzt auchpdfl testundpdfl watch, nicht nurpdfl run. Keines der beiden reichte es an die gestarteten Kindprozesse weiter, ein Skript, dasvars.*liest, konnte also weder getestet noch beobachtet werden: jeder Fall oder jede Datei scheiterte mit „was not provided“, unabhängig vom Inhalt.
pdfl packverpackt keine Tabellendateien mehr (.xlsx,.xls,.ods) und nennt die Datei, die draußen blieb. Keinedata::-Funktion kann eine öffnen; ein Paket, das sie mitführte, installierte sauber und scheiterte beim ersten Nachschlagen. Wer eine Tabelle paketierte, exportiert sie vorher nach.csvoder.json.
--tags TAGbeirunfiltert, welche Checks laufen. Wiederholbar; ein Check läuft, wenn er einen der angegebenen Tags trägt.--jsonbeiinspectundlint,--output jsonbeidoc. Jeder Unterbefehl ist nun maschinell lesbar.--output sarifund--output junit, überall wo ein Berichtsformat gewählt wird —run,compare,watchundfix. SARIF liest GitHub code scanning; JUnit liest das Test-Panel jeder CI.pdfl completions <shell>gibt ein Vervollständigungsskript für bash, zsh, fish, elvish oder powershell aus.--quietbei jedem Befehl unterdrückt Fortschritt und Bestätigungen auf stderr. Fehler erscheinen weiterhin, undprint()bleibt unangetastet — das ist die Ausgabe des Skripts selbst, und sie zu schlucken würde ändern, was das Skript tut.data::load_datasetunddata::lookup_valuelesen neben.csvauch.json: ein Array von Arrays, oder ein Array von Objekten, dessen erstes Objekt die Spalten in der Reihenfolge der Datei benennt.pdfl test <skript>führt ein Skript über einen Ordner PDFs aus und vergleicht jeden Bericht mit dem daneben aufgezeichneten. Ein Profil, das plötzlich etwas anderes findet, lässt so einen Test scheitern, statt jemanden weiter hinten zu überraschen.--updatezeichnet die erwarteten Berichte auf.--jobs <n>beipdfl testlässt so viele Fälle gleichzeitig laufen, jeden als eigenen Prozess. Acht Dateien à 41 Seiten: 8,9s bei--jobs 1, 1,1s bei--jobs 8. Die Vorgabe bleibt1, da jeder Job ein Dokument im Speicher hält;--jobs 0gibt einen je CPU.--jobs <n>auch beipdfl watch: die Dateien werden von Kindprozessen geprüft, ein Stapeldurchlauf skaliert also genauso (9,5s auf 1,2s bei acht Dateien à 41 Seiten). Der geschriebene Bericht ist unabhängig von--jobsidentisch.--eventsbeipdfl watchwartet auf Dateisystem-Benachrichtigungen statt auf einen Zeitgeber. Opt-in, nicht Vorgabe: inotify meldet auf einem NFS- oder SMB-Mount nur, was die lokale Maschine schreibt, ein Netz-Hot-Folder verstummte also. Lässt sich der Watcher nicht anlegen, sagt watch das und nimmt wieder den Zeitgeber.--journal <datei>beipdfl watch: ein nur angehängtes Protokoll des Geprüften, ein JSON-Objekt je Datei. Ein erneuter Lauf mit demselben Journal überspringt die darin verzeichneten Dateien — ein bei viertausend von fünftausend unterbrochener Stapel erledigt die restlichen tausend — meldet ihre Urteile aber weiterhin, ein fortgesetzter Stapel behauptet also nie, ein Ordner sei sauber.--timeout <s>beipdfl watchbeendet die Prüfung einer Datei nach so vielen Sekunden und meldet sie als abgelehnt — ein Befund,check_name: "timeout"— statt den Stapel hängen zu lassen. Rekursion in einem.pdfl-Skript ist bereits tiefenbegrenzt, das Flag ist also für das, was ein Skript nicht verursachen kann: pdfium, das bei einem fehlerhaften oder feindseligen PDF in eine Schleife gerät oder blockiert.
Wissenswert
Abschnitt betitelt „Wissenswert“- Ein Tag, den kein Check trägt, ist ein Fehler, kein leeres Bestehen. Sonst würde eine Pipeline mit vertipptem Tag nichts prüfen und eine saubere Datei melden.
- Eine
ruleträgt keine Tags,--tagsüberspringt sie also — dieselbe Antwort wie für einen Check ohne Tag. - Der JSON-Bericht hat
checks_runbekommen: die Checks und Rules, die gelaufen sind. Das hebtschema_versionnicht an, denn ein Leser, der unbekannte Felder ignoriert, übersteht es. JUnit braucht es: die Diagnosen nennen nur die Checks, die etwas gefunden haben, und ein sauberer Lauf, der als null Tests gemeldet wird, ist für eine CI ein Lauf, der nie stattfand.
Behoben
Abschnitt betitelt „Behoben“pdfl watchwacht jetzt auf, wenn die frischeste Datei fertig geschrieben ist, statt bis zu ein ganzes Intervall später. Mit--debounce 3000wird eine ankommende Datei nach etwa 3s gemeldet statt nach bis zu 6s.
- Skripte nehmen Werte von der Kommandozeile:
--var name=wert, gelesen alsvars.name. Ein fehlender Wert nennt das Flag, das ihn liefern würde, statt sich zu nichts aufzulösen. - Vier ausgearbeitete Beispiele für den Vergleich zweier Dokumente mit
visual:::proof.pdfl,reprint.pdfl,scope.pdflundintake.pdfl.
Nichts. Ein Skript, das vars nie erwähnt, verhält sich genau wie vorher.
Die Diagnose-Kennungen haben eine andere Form. Sie waren PDFL-001, ein
Zähler innerhalb des Laufs; jetzt leiten sie sich aus dem Befund selbst ab, etwa
PDFL-093751a2.
Alles, was auf
PDFL-\d+passt, passt nicht mehr. Dafür überlebt eine Kennung jetzt einen Check, der darüber eingefügt wird — und genau das macht eine freigegebene Baseline haltbar.
Eine unlesbare Eingabe endet mit 10 statt 2. Eine kaputte und eine
abgelehnte Datei waren für eine Pipeline nicht unterscheidbar.
Behandelt Ihre CI
2als „diese Datei wurde abgelehnt“, sieht sie jetzt10, wenn die Datei nie beurteilt wurde. Befunde nutzen weiterhin0,1und2; ein Syntaxfehler im Skript weiterhin3.
- Ein Check kann den Schweregrad seiner Befunde deklarieren:
check "..." severity: warning { ... }—error(Vorgabe),warningoderinfo. Erst dadurch hat--fail-on warningetwas, worauf es wirken kann. - Der JSON-Bericht beginnt mit
schema_version, damit ein Konsument weiß, welche Form er liest. Sie steigt nur, wenn ein Leser der vorherigen Ausgabe brechen würde; ein zusätzliches Feld lässt sie unverändert.
Behoben
Abschnitt betitelt „Behoben“- Der PDF-Bericht war teilweise portugiesisch: die Abschnittsüberschrift lautete
Diagnósticos, und jede Diagnose trug(linha N). Beides ist jetzt englisch, wie es die Dokumentation immer versprochen hat.
Die Release-Ziele heißen amd64 statt x64, damit hat sich jeder
Asset-Name geändert.
Portable Archive werden nicht mehr veröffentlicht, mit Ausnahme eines für Linux amd64.
Alles, was
pdfl-<version>-linux-x64.tar.gzlädt, oder irgendein portables Archiv außer Linux amd64, muss angepasst werden. Installieren Sie in der CI aus dem.deb— die Rezepte dieser Dokumentation wurden darauf umgestellt — oder nehmen Sie das Linux-amd64-Tarball, wo Installieren nicht in Frage kommt.
Behoben
Abschnitt betitelt „Behoben“- Zwei Lücken, gefunden beim Abgleich der Dokumentation mit dem Quelltext:
text::detect_personal_dataundtext::detect_piinehmen eine optionale Zeichenkette, die nirgends dokumentiert war, undfix::reorder_pagesstand in zwei verschiedenen Schreibweisen zwischen den Sprachen.
- Installer für jede Plattform:
.debfür Linux,.dmgfür macOS,-setup.exeund.msifür Windows. - macOS-Intel-Builds, quer übersetzt vom Apple-Silicon-Runner.
Behoben
Abschnitt betitelt „Behoben“- Der Windows-Installer wurde mit Pfaden gebaut, die gegen das falsche Verzeichnis auflösten, und erzeugte deshalb nie eine Datei.
- Die Release-Pakete trugen die C-Header und Build-Dateien von pdfium mit, die nur jemanden betreffen, der gegen pdfium compiliert. Rund 550 KB je Paket.
- Windows x64 kommt zu den veröffentlichten Plattformen.
Die mitgelieferte
pdfium.dllliegt inpdfium\bin, nicht inpdfium\lib. Wenn Siepdflselbst paketieren, behalten Sie das ausgelieferte Layout: die Binärdatei sucht die Bibliothek neben sich.
Release-Assets tragen die Version im Namen, als
pdfl-<version>-<ziel>.tar.gz, und das Verzeichnis darin ebenso.
.../releases/latest/download/<name>löst nicht mehr auf, denn dieser Endpunkt braucht den exakten Dateinamen. Laden Sie stattdessen per Muster:gh release download --pattern 'pdfl-*-linux-amd64.*'.
- Quelltext, README und Beispiele sind auf Englisch. Die Dokumentation bleibt in sieben Sprachen.
Erste öffentliche Version. Die Sprache, der Interpreter und zehn CLI-Befehle, mit Dokumentation in sieben Sprachen.