mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-09 14:33:22 +00:00
4f0dadbf38
After final improvements to the official formatter implementation, this commit now performs the first treewide reformat of Nix files using it. This is part of the implementation of RFC 166. Only "inactive" files are reformatted, meaning only files that aren't being touched by any PR with activity in the past 2 months. This is to avoid conflicts for PRs that might soon be merged. Later we can do a full treewide reformat to get the rest, which should not cause as many conflicts. A CI check has already been running for some time to ensure that new and already-formatted files are formatted, so the files being reformatted here should also stay formatted. This commit was automatically created and can be verified using nix-builda08b3a4d19
.tar.gz \ --argstr baseRevb32a094368
result/bin/apply-formatting $NIXPKGS_PATH
982 lines
28 KiB
Nix
982 lines
28 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
buildEnv,
|
|
runCommand,
|
|
fetchurl,
|
|
file,
|
|
texlive,
|
|
writeShellScript,
|
|
writeText,
|
|
texliveInfraOnly,
|
|
texliveConTeXt,
|
|
texliveSmall,
|
|
texliveMedium,
|
|
texliveFull,
|
|
}:
|
|
|
|
rec {
|
|
|
|
mkTeXTest = lib.makeOverridable (
|
|
{
|
|
name,
|
|
format,
|
|
text,
|
|
texLive ? texliveSmall,
|
|
options ? "-interaction=errorstopmode",
|
|
preTest ? "",
|
|
postTest ? "",
|
|
...
|
|
}@attrs:
|
|
runCommand "texlive-test-tex-${name}"
|
|
(
|
|
{
|
|
nativeBuildInputs = [ texLive ] ++ attrs.nativeBuildInputs or [ ];
|
|
text = builtins.toFile "${name}.tex" text;
|
|
}
|
|
// builtins.removeAttrs attrs [
|
|
"nativeBuildInputs"
|
|
"text"
|
|
"texLive"
|
|
]
|
|
)
|
|
''
|
|
export HOME="$(mktemp -d)"
|
|
mkdir "$out"
|
|
cd "$out"
|
|
cp "$text" "$name.tex"
|
|
${preTest}
|
|
$format $options "$name.tex"
|
|
${postTest}
|
|
''
|
|
);
|
|
|
|
tlpdbNix =
|
|
runCommand "texlive-test-tlpdb-nix"
|
|
{
|
|
nixpkgsTlpdbNix = ../../tools/typesetting/tex/texlive/tlpdb.nix;
|
|
tlpdbNix = texlive.tlpdb.nix;
|
|
}
|
|
''
|
|
mkdir -p "$out"
|
|
diff -u "''${nixpkgsTlpdbNix}" "''${tlpdbNix}" | tee "$out/tlpdb.nix.patch"
|
|
'';
|
|
|
|
# test two completely different font discovery mechanisms, both of which were once broken:
|
|
# - lualatex uses its own luaotfload script (#220228)
|
|
# - xelatex uses fontconfig (#228196)
|
|
opentype-fonts = lib.recurseIntoAttrs rec {
|
|
lualatex = mkTeXTest {
|
|
name = "opentype-fonts-lualatex";
|
|
format = "lualatex";
|
|
texLive = texliveSmall.withPackages (ps: [ ps.libertinus-fonts ]);
|
|
text = ''
|
|
\documentclass{article}
|
|
\usepackage{fontspec}
|
|
\setmainfont{Libertinus Serif}
|
|
\begin{document}
|
|
\LaTeX{} is great
|
|
\end{document}
|
|
'';
|
|
};
|
|
xelatex = lualatex.override {
|
|
name = "opentype-fonts-xelatex";
|
|
format = "xelatex";
|
|
};
|
|
};
|
|
|
|
chktex =
|
|
runCommand "texlive-test-chktex"
|
|
{
|
|
nativeBuildInputs = [
|
|
(texlive.withPackages (ps: [ ps.chktex ]))
|
|
];
|
|
input = builtins.toFile "chktex-sample.tex" ''
|
|
\documentclass{article}
|
|
\begin{document}
|
|
\LaTeX is great
|
|
\end{document}
|
|
'';
|
|
}
|
|
''
|
|
# chktex is supposed to return 2 when it (successfully) finds warnings, but no errors,
|
|
# see http://git.savannah.nongnu.org/cgit/chktex.git/commit/?id=ec0fb9b58f02a62ff0bfec98b997208e9d7a5998
|
|
(set +e; chktex -v -nall -w1 "$input" 2>&1; [ $? = 2 ] || exit 1; set -e) | tee "$out"
|
|
# also check that the output does indeed contain "One warning printed"
|
|
grep "One warning printed" "$out"
|
|
'';
|
|
|
|
context = mkTeXTest {
|
|
name = "texlive-test-context";
|
|
format = "context";
|
|
texLive = texliveConTeXt;
|
|
# check that the PDF has been created: we have hit cases of context
|
|
# failing with exit status 0 due to a misconfigured texlive
|
|
postTest = ''
|
|
if [[ ! -f "$name".pdf ]] ; then
|
|
echo "ConTeXt test failed: file '$name.pdf' not found"
|
|
exit 1
|
|
fi
|
|
'';
|
|
text = ''
|
|
\starttext
|
|
\startsection[title={ConTeXt test document}]
|
|
This is an {\em incredibly} simple ConTeXt document.
|
|
\stopsection
|
|
\stoptext
|
|
'';
|
|
};
|
|
|
|
dvipng = lib.recurseIntoAttrs {
|
|
# https://github.com/NixOS/nixpkgs/issues/75605
|
|
basic =
|
|
runCommand "texlive-test-dvipng-basic"
|
|
{
|
|
nativeBuildInputs = [
|
|
file
|
|
texliveMedium
|
|
];
|
|
input = fetchurl {
|
|
name = "test_dvipng.tex";
|
|
url = "http://git.savannah.nongnu.org/cgit/dvipng.git/plain/test_dvipng.tex?id=b872753590a18605260078f56cbd6f28d39dc035";
|
|
sha256 = "1pjpf1jvwj2pv5crzdgcrzvbmn7kfmgxa39pcvskl4pa0c9hl88n";
|
|
};
|
|
}
|
|
''
|
|
cp "$input" ./document.tex
|
|
|
|
latex document.tex
|
|
dvipng -T tight -strict -picky document.dvi
|
|
for f in document*.png; do
|
|
file "$f" | tee output
|
|
grep PNG output
|
|
done
|
|
|
|
mkdir "$out"
|
|
mv document*.png "$out"/
|
|
'';
|
|
|
|
# test dvipng's limited capability to render postscript specials via GS
|
|
ghostscript =
|
|
runCommand "texlive-test-ghostscript"
|
|
{
|
|
nativeBuildInputs = [
|
|
file
|
|
(texliveSmall.withPackages (ps: [ ps.dvipng ]))
|
|
];
|
|
input = builtins.toFile "postscript-sample.tex" ''
|
|
\documentclass{minimal}
|
|
\begin{document}
|
|
Ni
|
|
\special{ps:
|
|
newpath
|
|
0 0 moveto
|
|
7 7 rlineto
|
|
0 7 moveto
|
|
7 -7 rlineto
|
|
stroke
|
|
showpage
|
|
}
|
|
\end{document}
|
|
'';
|
|
gs_trap = writeShellScript "gs_trap.sh" ''
|
|
exit 1
|
|
'';
|
|
}
|
|
''
|
|
cp "$gs_trap" ./gs
|
|
export PATH=$PWD:$PATH
|
|
# check that the trap works
|
|
gs && exit 1
|
|
|
|
cp "$input" ./document.tex
|
|
|
|
latex document.tex
|
|
dvipng -T 1in,1in -strict -picky document.dvi
|
|
for f in document*.png; do
|
|
file "$f" | tee output
|
|
grep PNG output
|
|
done
|
|
|
|
mkdir "$out"
|
|
mv document*.png "$out"/
|
|
'';
|
|
};
|
|
|
|
# https://github.com/NixOS/nixpkgs/issues/75070
|
|
dvisvgm =
|
|
runCommand "texlive-test-dvisvgm"
|
|
{
|
|
nativeBuildInputs = [
|
|
file
|
|
texliveMedium
|
|
];
|
|
input = builtins.toFile "dvisvgm-sample.tex" ''
|
|
\documentclass{article}
|
|
\begin{document}
|
|
mwe
|
|
\end{document}
|
|
'';
|
|
}
|
|
''
|
|
cp "$input" ./document.tex
|
|
|
|
latex document.tex
|
|
dvisvgm document.dvi -n -o document_dvi.svg
|
|
cat document_dvi.svg
|
|
file document_dvi.svg | grep SVG
|
|
|
|
pdflatex document.tex
|
|
dvisvgm -P document.pdf -n -o document_pdf.svg
|
|
cat document_pdf.svg
|
|
file document_pdf.svg | grep SVG
|
|
|
|
mkdir "$out"
|
|
mv document*.svg "$out"/
|
|
'';
|
|
|
|
texdoc =
|
|
runCommand "texlive-test-texdoc"
|
|
{
|
|
nativeBuildInputs = [
|
|
(texlive.withPackages (ps: [
|
|
ps.luatex
|
|
ps.texdoc
|
|
ps.texdoc.texdoc
|
|
]))
|
|
];
|
|
}
|
|
''
|
|
texdoc --version
|
|
|
|
texdoc --debug --list texdoc | tee "$out"
|
|
grep texdoc.pdf "$out"
|
|
'';
|
|
|
|
# check that the default language is US English
|
|
defaultLanguage = lib.recurseIntoAttrs rec {
|
|
# language.def
|
|
etex = mkTeXTest {
|
|
name = "default-language-etex";
|
|
format = "etex";
|
|
text = ''
|
|
\catcode`\@=11
|
|
\ifnum\language=\lang@USenglish \message{[tests.texlive] Default language is US English.}
|
|
\else\errmessage{[tests.texlive] Error: default language is NOT US English.}\fi
|
|
\ifnum\language=0\message{[tests.texlive] Default language has id 0.}
|
|
\else\errmessage{[tests.texlive] Error: default language does NOT have id 0.}\fi
|
|
\bye
|
|
'';
|
|
};
|
|
# language.dat
|
|
latex = mkTeXTest {
|
|
name = "default-language-latex";
|
|
format = "latex";
|
|
text = ''
|
|
\makeatletter
|
|
\ifnum\language=\l@USenglish \GenericWarning{}{[tests.texlive] Default language is US English}
|
|
\else\GenericError{}{[tests.texlive] Error: default language is NOT US English}{}{}\fi
|
|
\ifnum\language=0\GenericWarning{}{[tests.texlive] Default language has id 0}
|
|
\else\GenericError{}{[tests.texlive] Error: default language does NOT have id 0}{}{}\fi
|
|
\stop
|
|
'';
|
|
};
|
|
# language.dat.lua
|
|
luatex = etex.override {
|
|
name = "default-language-luatex";
|
|
format = "luatex";
|
|
};
|
|
};
|
|
|
|
# check that all languages are available, including synonyms
|
|
allLanguages =
|
|
let
|
|
hyphenBase = texlive.pkgs.hyphen-base;
|
|
texLive = texliveFull;
|
|
in
|
|
lib.recurseIntoAttrs {
|
|
# language.def
|
|
etex = mkTeXTest {
|
|
name = "all-languages-etex";
|
|
format = "etex";
|
|
inherit hyphenBase texLive;
|
|
text = ''
|
|
\catcode`\@=11
|
|
\input kvsetkeys.sty
|
|
\def\CheckLang#1{
|
|
\ifcsname lang@#1\endcsname\message{[tests.texlive] Found language #1}
|
|
\else\errmessage{[tests.texlive] Error: missing language #1}\fi
|
|
}
|
|
\comma@parse{@texLanguages@}\CheckLang
|
|
\bye
|
|
'';
|
|
preTest = ''
|
|
texLanguages="$(sed -n -E 's/^\\addlanguage\s*\{([^}]+)\}.*$/\1/p' < "$hyphenBase"/tex/generic/config/language.def)"
|
|
texLanguages="''${texLanguages//$'\n'/,}"
|
|
substituteInPlace "$name.tex" --subst-var texLanguages
|
|
'';
|
|
};
|
|
# language.dat
|
|
latex = mkTeXTest {
|
|
name = "all-languages-latex";
|
|
format = "latex";
|
|
inherit hyphenBase texLive;
|
|
text = ''
|
|
\makeatletter
|
|
\@for\Lang:=italian,@texLanguages@\do{
|
|
\ifcsname l@\Lang\endcsname
|
|
\GenericWarning{}{[tests.texlive] Found language \Lang}
|
|
\else
|
|
\GenericError{}{[tests.texlive] Error: missing language \Lang}{}{}
|
|
\fi
|
|
}
|
|
\stop
|
|
'';
|
|
preTest = ''
|
|
texLanguages="$(sed -n -E 's/^([^%= \t]+).*$/\1/p' < "$hyphenBase"/tex/generic/config/language.dat)"
|
|
texLanguages="''${texLanguages//$'\n'/,}"
|
|
substituteInPlace "$name.tex" --subst-var texLanguages
|
|
'';
|
|
};
|
|
# language.dat.lua
|
|
luatex = mkTeXTest {
|
|
name = "all-languages-luatex";
|
|
format = "luatex";
|
|
inherit hyphenBase texLive;
|
|
text = ''
|
|
\directlua{
|
|
require('luatex-hyphen.lua')
|
|
langs = '@texLanguages@,'
|
|
texio.write('\string\n')
|
|
for l in langs:gmatch('([^,]+),') do
|
|
if luatexhyphen.lookupname(l) \string~= nil then
|
|
texio.write('[tests.texlive] Found language '..l..'.\string\n')
|
|
else
|
|
error('[tests.texlive] Error: missing language '..l..'.', 2)
|
|
end
|
|
end
|
|
}
|
|
\bye
|
|
'';
|
|
preTest = ''
|
|
texLanguages="$(sed -n -E 's/^.*\[("|'\''')(.*)("|'\''')].*$/\2/p' < "$hyphenBase"/tex/generic/config/language.dat.lua)"
|
|
texLanguages="''${texLanguages//$'\n'/,}"
|
|
substituteInPlace "$name.tex" --subst-var texLanguages
|
|
'';
|
|
};
|
|
};
|
|
|
|
# test that language files are generated as expected
|
|
hyphen-base =
|
|
runCommand "texlive-test-hyphen-base"
|
|
{
|
|
hyphenBase = texlive.pkgs.hyphen-base;
|
|
schemeFull = texliveFull;
|
|
schemeInfraOnly = texliveInfraOnly;
|
|
}
|
|
''
|
|
mkdir -p "$out"/{scheme-infraonly,scheme-full}
|
|
|
|
# create language files with no hyphenation patterns
|
|
cat "$hyphenBase"/tex/generic/config/language.us >language.dat
|
|
cat "$hyphenBase"/tex/generic/config/language.us.def >language.def
|
|
cat "$hyphenBase"/tex/generic/config/language.us.lua >language.dat.lua
|
|
|
|
cat >>language.dat.lua <<EOF
|
|
}
|
|
EOF
|
|
|
|
cat >>language.def <<EOF
|
|
%%% No changes may be made beyond this point.
|
|
|
|
\uselanguage {USenglish} %%% This MUST be the last line of the file.
|
|
EOF
|
|
|
|
for fname in language.{dat,def,dat.lua} ; do
|
|
diff --ignore-matching-lines='^\(%\|--\) Generated by ' -u \
|
|
{"$hyphenBase","$schemeFull"/share/texmf-var}/tex/generic/config/"$fname" \
|
|
| tee "$out/scheme-full/$fname.patch"
|
|
diff --ignore-matching-lines='^\(%\|--\) Generated by ' -u \
|
|
{,"$schemeInfraOnly"/share/texmf-var/tex/generic/config/}"$fname" \
|
|
| tee "$out/scheme-infraonly/$fname.patch"
|
|
done
|
|
'';
|
|
|
|
# verify that the restricted mode gets enabled when
|
|
# needed (detected by checking if it disallows --gscmd)
|
|
repstopdf =
|
|
runCommand "texlive-test-repstopdf"
|
|
{
|
|
nativeBuildInputs = [ (texlive.withPackages (ps: [ ps.epstopdf ])) ];
|
|
}
|
|
''
|
|
! (epstopdf --gscmd echo /dev/null 2>&1 || true) | grep forbidden >/dev/null
|
|
(repstopdf --gscmd echo /dev/null 2>&1 || true) | grep forbidden >/dev/null
|
|
mkdir "$out"
|
|
'';
|
|
|
|
# verify that the restricted mode gets enabled when
|
|
# needed (detected by checking if it disallows --gscmd)
|
|
rpdfcrop =
|
|
runCommand "texlive-test-rpdfcrop"
|
|
{
|
|
nativeBuildInputs = [ (texlive.withPackages (ps: [ ps.pdfcrop ])) ];
|
|
}
|
|
''
|
|
! (pdfcrop --gscmd echo $(command -v pdfcrop) 2>&1 || true) | grep 'restricted mode' >/dev/null
|
|
(rpdfcrop --gscmd echo $(command -v pdfcrop) 2>&1 || true) | grep 'restricted mode' >/dev/null
|
|
mkdir "$out"
|
|
'';
|
|
|
|
# check that all binaries run successfully, in the following sense:
|
|
# (1) run --version, -v, --help, -h successfully; or
|
|
# (2) run --help, -h, or no argument with error code but show help text; or
|
|
# (3) run successfully on a test.tex or similar file
|
|
# we ignore the binaries that cannot be tested as above, and are either
|
|
# compiled binaries or trivial shell wrappers
|
|
binaries =
|
|
let
|
|
# TODO known broken binaries
|
|
broken = [
|
|
# *.inc files in source container rather than run
|
|
"texaccents"
|
|
|
|
# 'Error initialising QuantumRenderer: no suitable pipeline found'
|
|
"tlcockpit"
|
|
] ++ lib.optional stdenv.hostPlatform.isDarwin "epspdftk"; # wish shebang is a script, not a binary!
|
|
|
|
# (1) binaries requiring -v
|
|
shortVersion = [
|
|
"devnag"
|
|
"diadia"
|
|
"pmxchords"
|
|
"ptex2pdf"
|
|
"simpdftex"
|
|
"ttf2afm"
|
|
];
|
|
# (1) binaries requiring --help or -h
|
|
help = [
|
|
"arlatex"
|
|
"bundledoc"
|
|
"cachepic"
|
|
"checklistings"
|
|
"dvipos"
|
|
"extractres"
|
|
"fig4latex"
|
|
"fragmaster"
|
|
"kpsewhere"
|
|
"latex-git-log"
|
|
"ltxfileinfo"
|
|
"mendex"
|
|
"pdflatexpicscale"
|
|
"perltex"
|
|
"pn2pdf"
|
|
"psbook"
|
|
"psnup"
|
|
"psresize"
|
|
"purifyeps"
|
|
"simpdftex"
|
|
"tex2xindy"
|
|
"texluac"
|
|
"texluajitc"
|
|
"upmendex"
|
|
"urlbst"
|
|
"yplan"
|
|
];
|
|
shortHelp = [
|
|
"adhocfilelist"
|
|
"authorindex"
|
|
"bbl2bib"
|
|
"bibdoiadd"
|
|
"bibmradd"
|
|
"biburl2doi"
|
|
"bibzbladd"
|
|
"bookshelf-listallfonts"
|
|
"bookshelf-mkfontsel"
|
|
"ctanupload"
|
|
"disdvi"
|
|
"dvibook"
|
|
"dviconcat"
|
|
"getmapdl"
|
|
"latex2man"
|
|
"listings-ext.sh"
|
|
"pygmentex"
|
|
];
|
|
# (2) binaries that return non-zero exit code even if correctly asked for help
|
|
ignoreExitCode = [
|
|
"authorindex"
|
|
"bookshelf-listallfonts"
|
|
"bookshelf-mkfontsel"
|
|
"dvibook"
|
|
"dviconcat"
|
|
"dvipos"
|
|
"extractres"
|
|
"fig4latex"
|
|
"fragmaster"
|
|
"latex2man"
|
|
"latex-git-log"
|
|
"listings-ext.sh"
|
|
"psbook"
|
|
"psnup"
|
|
"psresize"
|
|
"purifyeps"
|
|
"tex2xindy"
|
|
"texluac"
|
|
"texluajitc"
|
|
];
|
|
# (2) binaries that print help on no argument, returning non-zero exit code
|
|
noArg = [
|
|
"a2ping"
|
|
"bg5+latex"
|
|
"bg5+pdflatex"
|
|
"bg5latex"
|
|
"bg5pdflatex"
|
|
"cef5latex"
|
|
"cef5pdflatex"
|
|
"ceflatex"
|
|
"cefpdflatex"
|
|
"cefslatex"
|
|
"cefspdflatex"
|
|
"chkdvifont"
|
|
"dvi2fax"
|
|
"dvired"
|
|
"dviselect"
|
|
"dvitodvi"
|
|
"epsffit"
|
|
"findhyph"
|
|
"gbklatex"
|
|
"gbkpdflatex"
|
|
"komkindex"
|
|
"kpsepath"
|
|
"listbib"
|
|
"listings-ext"
|
|
"mag"
|
|
"mathspic"
|
|
"mf2pt1"
|
|
"mk4ht"
|
|
"mkt1font"
|
|
"mkgrkindex"
|
|
"musixflx"
|
|
"pdf2ps"
|
|
"pdfclose"
|
|
"pdftosrc"
|
|
"pdfxup"
|
|
"pedigree"
|
|
"pfb2pfa"
|
|
"pk2bm"
|
|
"prepmx"
|
|
"ps2pk"
|
|
"psselect"
|
|
"pstops"
|
|
"rubibtex"
|
|
"rubikrotation"
|
|
"sjislatex"
|
|
"sjispdflatex"
|
|
"srcredact"
|
|
"t4ht"
|
|
"teckit_compile"
|
|
"tex4ht"
|
|
"texdiff"
|
|
"texdirflatten"
|
|
"texplate"
|
|
"tie"
|
|
"ttf2kotexfont"
|
|
"ttfdump"
|
|
"vlna"
|
|
"vpl2ovp"
|
|
"vpl2vpl"
|
|
"yplan"
|
|
];
|
|
# (3) binaries requiring a .tex file
|
|
contextTest = [ "htcontext" ];
|
|
latexTest = [
|
|
"de-macro"
|
|
"e2pall"
|
|
"htlatex"
|
|
"htxelatex"
|
|
"makeindex"
|
|
"pslatex"
|
|
"rumakeindex"
|
|
"tpic2pdftex"
|
|
"wordcount"
|
|
"xhlatex"
|
|
];
|
|
texTest = [
|
|
"fontinst"
|
|
"htmex"
|
|
"httex"
|
|
"httexi"
|
|
"htxetex"
|
|
];
|
|
# tricky binaries or scripts that are obviously working but are hard to test
|
|
# (e.g. because they expect user input no matter the arguments)
|
|
# (printafm comes from ghostscript, not texlive)
|
|
ignored = [
|
|
# compiled binaries
|
|
"dt2dv"
|
|
"dv2dt"
|
|
"dvi2tty"
|
|
"dvidvi"
|
|
"dvispc"
|
|
"otp2ocp"
|
|
"outocp"
|
|
"pmxab"
|
|
|
|
# GUI scripts that accept no argument or crash without a graphics server; please test manualy
|
|
"epspdftk"
|
|
"texdoctk"
|
|
"tlshell"
|
|
"xasy"
|
|
|
|
# requires Cinderella, not open source and not distributed via Nixpkgs
|
|
"ketcindy"
|
|
];
|
|
# binaries that need a combined scheme and cannot work standalone
|
|
needScheme = [
|
|
# pfarrei: require working kpse to find lua module
|
|
"a5toa4"
|
|
|
|
# bibexport: requires kpsewhich
|
|
"bibexport"
|
|
|
|
# crossrefware: require bibtexperllibs under TEXMFROOT
|
|
"bbl2bib"
|
|
"bibdoiadd"
|
|
"bibmradd"
|
|
"biburl2doi"
|
|
"bibzbladd"
|
|
"checkcites"
|
|
"ltx2crossrefxml"
|
|
|
|
# epstopdf: requires kpsewhich
|
|
"epstopdf"
|
|
"repstopdf"
|
|
|
|
# requires kpsewhich
|
|
"memoize-extract.pl"
|
|
"memoize-extract.py"
|
|
|
|
# require other texlive binaries in PATH
|
|
"allcm"
|
|
"allec"
|
|
"chkweb"
|
|
"fontinst"
|
|
"ht*"
|
|
"installfont-tl"
|
|
"kanji-config-updmap-sys"
|
|
"kanji-config-updmap-user"
|
|
"kpse*"
|
|
"latexfileversion"
|
|
"mkocp"
|
|
"mkofm"
|
|
"mtxrunjit"
|
|
"pdftex-quiet"
|
|
"pslatex"
|
|
"rumakeindex"
|
|
"texconfig"
|
|
"texconfig-sys"
|
|
"texexec"
|
|
"texlinks"
|
|
"texmfstart"
|
|
"typeoutfileinfo"
|
|
"wordcount"
|
|
"xdvi"
|
|
"xhlatex"
|
|
|
|
# misc luatex binaries searching for luatex in PATH
|
|
"citeproc-lua"
|
|
"context"
|
|
"contextjit"
|
|
"ctanbib"
|
|
"digestif"
|
|
"epspdf"
|
|
"l3build"
|
|
"luafindfont"
|
|
"luaotfload-tool"
|
|
"luatools"
|
|
"make4ht"
|
|
"pmxchords"
|
|
"tex4ebook"
|
|
"texblend"
|
|
"texdoc"
|
|
"texfindpkg"
|
|
"texlogsieve"
|
|
"xindex"
|
|
|
|
# requires full TEXMFROOT (e.g. for config)
|
|
"mktexfmt"
|
|
"mktexmf"
|
|
"mktexpk"
|
|
"mktextfm"
|
|
"psnup"
|
|
"psresize"
|
|
"pstops"
|
|
"tlmgr"
|
|
"updmap"
|
|
"webquiz"
|
|
|
|
# texlive-scripts: requires texlive.infra's TeXLive::TLUtils under TEXMFROOT
|
|
"fmtutil"
|
|
"fmtutil-sys"
|
|
"fmtutil-user"
|
|
|
|
# texlive-scripts: not used in nixpkgs, need updmap in PATH
|
|
"updmap-sys"
|
|
"updmap-user"
|
|
];
|
|
|
|
# simple test files
|
|
contextTestTex = writeText "context-test.tex" ''
|
|
\starttext
|
|
A simple test file.
|
|
\stoptext
|
|
'';
|
|
latexTestTex = writeText "latex-test.tex" ''
|
|
\documentclass{article}
|
|
\begin{document}
|
|
A simple test file.
|
|
\end{document}
|
|
'';
|
|
texTestTex = writeText "tex-test.tex" ''
|
|
Hello.
|
|
\bye
|
|
'';
|
|
|
|
# link all binaries in single derivation
|
|
binPackages = lib.catAttrs "out" (lib.attrValues texlive.pkgs);
|
|
binaries = buildEnv {
|
|
name = "texlive-binaries";
|
|
paths = binPackages;
|
|
};
|
|
in
|
|
runCommand "texlive-test-binaries"
|
|
{
|
|
inherit
|
|
binaries
|
|
contextTestTex
|
|
latexTestTex
|
|
texTestTex
|
|
;
|
|
texliveScheme = texliveFull;
|
|
}
|
|
''
|
|
loadables="$(command -v bash)"
|
|
loadables="''${loadables%/bin/bash}/lib/bash"
|
|
enable -f "$loadables/realpath" realpath
|
|
mkdir -p "$out"
|
|
export HOME="$(mktemp -d)"
|
|
declare -i binCount=0 ignoredCount=0 brokenCount=0 failedCount=0
|
|
cp "$contextTestTex" context-test.tex
|
|
cp "$latexTestTex" latex-test.tex
|
|
cp "$texTestTex" tex-test.tex
|
|
|
|
testBin () {
|
|
path="$(realpath "$bin")"
|
|
path="''${path##*/}"
|
|
if [[ -z "$ignoreExitCode" ]] ; then
|
|
PATH="$path" "$bin" $args >"$out/$base.log" 2>&1
|
|
ret=$?
|
|
if [[ $ret == 0 ]] && grep -i 'command not found' "$out/$base.log" >/dev/null ; then
|
|
echo "command not found when running '$base''${args:+ $args}'"
|
|
return 1
|
|
fi
|
|
return $ret
|
|
else
|
|
PATH="$path" "$bin" $args >"$out/$base.log" 2>&1
|
|
ret=$?
|
|
if [[ $ret == 0 ]] && grep -i 'command not found' "$out/$base.log" >/dev/null ; then
|
|
echo "command not found when running '$base''${args:+ $args}'"
|
|
return 1
|
|
fi
|
|
if ! grep -Ei '(Example:|Options:|Syntax:|Usage:|improper command|SYNOPSIS)' "$out/$base.log" >/dev/null ; then
|
|
echo "did not find usage info when running '$base''${args:+ $args}'"
|
|
return $ret
|
|
fi
|
|
fi
|
|
}
|
|
|
|
for bin in "$binaries"/bin/* ; do
|
|
base="''${bin##*/}"
|
|
args=
|
|
ignoreExitCode=
|
|
binCount=$((binCount + 1))
|
|
|
|
# ignore non-executable files (such as context.lua)
|
|
if [[ ! -x "$bin" ]] ; then
|
|
ignoredCount=$((ignoredCount + 1))
|
|
continue
|
|
fi
|
|
|
|
case "$base" in
|
|
${lib.concatStringsSep "|" ignored})
|
|
ignoredCount=$((ignoredCount + 1))
|
|
continue ;;
|
|
${lib.concatStringsSep "|" broken})
|
|
brokenCount=$((brokenCount + 1))
|
|
continue ;;
|
|
${lib.concatStringsSep "|" help})
|
|
args=--help ;;
|
|
${lib.concatStringsSep "|" shortHelp})
|
|
args=-h ;;
|
|
${lib.concatStringsSep "|" noArg})
|
|
;;
|
|
${lib.concatStringsSep "|" contextTest})
|
|
args=context-test.tex ;;
|
|
${lib.concatStringsSep "|" latexTest})
|
|
args=latex-test.tex ;;
|
|
${lib.concatStringsSep "|" texTest})
|
|
args=tex-test.tex ;;
|
|
${lib.concatStringsSep "|" shortVersion})
|
|
args=-v ;;
|
|
ebong)
|
|
touch empty
|
|
args=empty ;;
|
|
ht)
|
|
args='latex latex-test.tex' ;;
|
|
pdf2dsc)
|
|
args='--help --help --help' ;;
|
|
typeoutfileinfo)
|
|
args=/dev/null ;;
|
|
*)
|
|
args=--version ;;
|
|
esac
|
|
|
|
case "$base" in
|
|
${lib.concatStringsSep "|" (ignoreExitCode ++ noArg)})
|
|
ignoreExitCode=1 ;;
|
|
esac
|
|
|
|
case "$base" in
|
|
${lib.concatStringsSep "|" needScheme})
|
|
bin="$texliveScheme/bin/$base"
|
|
if [[ ! -f "$bin" ]] ; then
|
|
ignoredCount=$((ignoredCount + 1))
|
|
continue
|
|
fi ;;
|
|
esac
|
|
|
|
if testBin ; then : ; else # preserve exit code
|
|
echo "failed '$base''${args:+ $args}' (exit code: $?)"
|
|
sed 's/^/ > /' < "$out/$base.log"
|
|
failedCount=$((failedCount + 1))
|
|
fi
|
|
done
|
|
|
|
echo "tested $binCount binaries: $ignoredCount ignored, $brokenCount broken, $failedCount failed"
|
|
[[ $failedCount = 0 ]]
|
|
'';
|
|
|
|
# check that all scripts have a Nix shebang
|
|
shebangs =
|
|
let
|
|
binPackages = lib.catAttrs "out" (lib.attrValues texlive.pkgs);
|
|
in
|
|
runCommand "texlive-test-shebangs" { } (
|
|
''
|
|
echo "checking that all texlive scripts shebangs are in '$NIX_STORE'"
|
|
declare -i scriptCount=0 invalidCount=0
|
|
''
|
|
+ (lib.concatMapStrings (pkg: ''
|
|
for bin in '${pkg.outPath}'/bin/* ; do
|
|
grep -I -q . "$bin" || continue # ignore binary files
|
|
[[ -x "$bin" ]] || continue # ignore non-executable files (such as context.lua)
|
|
scriptCount=$((scriptCount + 1))
|
|
read -r cmdline < "$bin"
|
|
read -r interp <<< "$cmdline"
|
|
if [[ "$interp" != "#!$NIX_STORE"/* && "$interp" != "#! $NIX_STORE"/* ]] ; then
|
|
echo "error: non-nix shebang '$interp' in script '$bin'"
|
|
invalidCount=$((invalidCount + 1))
|
|
fi
|
|
done
|
|
'') binPackages)
|
|
+ ''
|
|
echo "checked $scriptCount scripts, found $invalidCount non-nix shebangs"
|
|
[[ $invalidCount -gt 0 ]] && exit 1
|
|
mkdir -p "$out"
|
|
''
|
|
);
|
|
|
|
# verify that the precomputed licensing information in default.nix
|
|
# does indeed match the metadata of the individual packages.
|
|
#
|
|
# This is part of the test suite (and not the normal evaluation) to save
|
|
# time for "normal" evaluations. To be more in line with the other tests, this
|
|
# also builds a derivation, even though it is essentially an eval-time assertion.
|
|
licenses =
|
|
let
|
|
concatLicenses = builtins.foldl' (acc: el: if builtins.elem el acc then acc else acc ++ [ el ]);
|
|
# converts a license to its attribute name in lib.licenses
|
|
licenseToAttrName =
|
|
license: builtins.head (builtins.attrNames (lib.filterAttrs (n: v: license == v) lib.licenses));
|
|
lt = (a: b: a < b);
|
|
|
|
savedLicenses = scheme: scheme.meta.license;
|
|
savedLicensesAttrNames = scheme: map licenseToAttrName (savedLicenses scheme);
|
|
|
|
correctLicenses =
|
|
scheme:
|
|
builtins.foldl' (
|
|
acc: pkg: concatLicenses acc (lib.toList (pkg.meta.license or [ ]))
|
|
) [ ] scheme.passthru.requiredTeXPackages;
|
|
correctLicensesAttrNames = scheme: lib.sort lt (map licenseToAttrName (correctLicenses scheme));
|
|
|
|
hasLicenseMismatch =
|
|
scheme:
|
|
(lib.isDerivation scheme) && (savedLicensesAttrNames scheme) != (correctLicensesAttrNames scheme);
|
|
incorrectSchemes = lib.filterAttrs (n: hasLicenseMismatch) (texlive.combined // texlive.schemes);
|
|
prettyPrint = name: scheme: ''
|
|
license info for ${name} is incorrect! Note that order is enforced.
|
|
saved: [ ${lib.concatStringsSep " " (savedLicensesAttrNames scheme)} ]
|
|
correct: [ ${lib.concatStringsSep " " (correctLicensesAttrNames scheme)} ]
|
|
'';
|
|
errorText = lib.concatStringsSep "\n\n" (lib.mapAttrsToList prettyPrint incorrectSchemes);
|
|
in
|
|
runCommand "texlive-test-license"
|
|
{
|
|
inherit errorText;
|
|
}
|
|
(
|
|
if (incorrectSchemes == { }) then
|
|
"echo everything is fine! > $out"
|
|
else
|
|
''
|
|
echo "$errorText"
|
|
false
|
|
''
|
|
);
|
|
|
|
# verify that all fixed hashes are present
|
|
# this is effectively an eval-time assertion, converted into a derivation for
|
|
# ease of testing
|
|
fixedHashes =
|
|
let
|
|
fods = lib.concatMap (
|
|
p:
|
|
lib.optional (p ? tex && lib.isDerivation p.tex) p.tex
|
|
++ lib.optional (p ? texdoc) p.texdoc
|
|
++ lib.optional (p ? texsource) p.texsource
|
|
++ lib.optional (p ? tlpkg) p.tlpkg
|
|
) (lib.attrValues texlive.pkgs);
|
|
errorText = lib.concatMapStrings (
|
|
p:
|
|
lib.optionalString (
|
|
!p ? outputHash
|
|
) "${p.pname}-${p.tlOutputName} does not have a fixed output hash\n"
|
|
) fods;
|
|
in
|
|
runCommand "texlive-test-fixed-hashes"
|
|
{
|
|
inherit errorText;
|
|
passAsFile = [ "errorText" ];
|
|
}
|
|
''
|
|
if [[ -s "$errorTextPath" ]] ; then
|
|
cat "$errorTextPath"
|
|
echo Failed: some TeX Live packages do not have fixed output hashes. Please read UPGRADING.md for how to generate a new fixed-hashes.nix.
|
|
exit 1
|
|
else
|
|
touch "$out"
|
|
fi
|
|
'';
|
|
}
|