1{
2 lib,
3 config,
4 newScope,
5 runCommand,
6}:
7
8let
9 unionOfDisjoints = lib.fold lib.attrsets.unionOfDisjoint { };
10
11 addTests =
12 attrPath: drv:
13 if !lib.isDerivation drv then
14 drv
15 else
16 let
17 name = lib.concatStringsSep "." attrPath;
18
19 inherit (drv) scriptName;
20 scriptPath = "share/mpv/scripts/${scriptName}";
21 fullScriptPath = "${drv}/${scriptPath}";
22 in
23 drv.overrideAttrs (old: {
24 passthru = (old.passthru or { }) // {
25 tests = unionOfDisjoints [
26 (old.passthru.tests or { })
27
28 {
29 scriptName-is-valid =
30 runCommand "mpvScripts.${name}.passthru.tests.scriptName-is-valid"
31 {
32 meta.maintainers = with lib.maintainers; [ nicoo ];
33 preferLocalBuild = true;
34 }
35 ''
36 if [ -e "${fullScriptPath}" ]; then
37 touch $out
38 else
39 echo "mpvScripts.${name} does not contain a script named \"${scriptName}\"" >&2
40 exit 1
41 fi
42 '';
43 }
44
45 # can't check whether `fullScriptPath` is a directory, in pure-evaluation mode
46 (lib.optionalAttrs
47 (
48 !lib.any (s: lib.hasSuffix s drv.passthru.scriptName) [
49 ".js"
50 ".lua"
51 ".so"
52 ]
53 )
54 {
55 single-main-in-script-dir =
56 runCommand "mpvScripts.${name}.passthru.tests.single-main-in-script-dir"
57 {
58 meta.maintainers = with lib.maintainers; [ nicoo ];
59 preferLocalBuild = true;
60 }
61 ''
62 die() {
63 echo "$@" >&2
64 exit 1
65 }
66
67 cd "${drv}/${scriptPath}" # so the glob expands to filenames only
68 mains=( main.* )
69 if [ "''${#mains[*]}" -eq 1 ]; then
70 touch $out
71 elif [ "''${#mains[*]}" -eq 0 ]; then
72 die "'${scriptPath}' contains no 'main.*' file"
73 else
74 die "'${scriptPath}' contains multiple 'main.*' files:" "''${mains[*]}"
75 fi
76 '';
77 }
78 )
79 ];
80 };
81 });
82
83 scope =
84 self:
85 with lib;
86 pipe
87 {
88 inherit (self) callPackage;
89 directory = ./scripts;
90 }
91 [
92 packagesFromDirectoryRecursive
93 recurseIntoAttrs
94 (mapAttrsRecursiveCond (x: x.recurseForDerivations or false) addTests)
95 ];
96
97 mkAliases = self: {
98 inherit (self.builtins)
99 acompressor
100 autocrop
101 autodeint
102 autoload
103 ; # added 2024-11-28
104 inherit (self.eisa01)
105 smart-copy-paste-2
106 smartskip
107 ; # added 2025-03-09
108 inherit (self.occivink)
109 blacklistExtensions
110 crop
111 encode
112 seekTo
113 ; # added 2024-11-28
114 youtube-quality = throw "'youtube-quality' is no longer maintained, use 'quality-menu' instead"; # added 2023-07-14
115 };
116in
117
118lib.pipe scope [
119 (lib.makeScope newScope)
120 (
121 self:
122 let
123 aliases = mkAliases self;
124 in
125 assert builtins.intersectAttrs self aliases == { };
126 self // lib.optionalAttrs config.allowAliases aliases
127 )
128]