nixpkgs/pkgs/test/texlive/default.nix
Silvan Mosberger 4f0dadbf38 treewide: format all inactive Nix files
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-build a08b3a4d19.tar.gz \
      --argstr baseRev b32a094368
    result/bin/apply-formatting $NIXPKGS_PATH
2024-12-10 20:26:33 +01:00

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
'';
}