1{
2 stdenv,
3 lib,
4 buildEnv,
5 writeShellScriptBin,
6 fetchurl,
7 vscode,
8 unzip,
9 jq,
10 vscode-extension-update-script,
11}:
12let
13 buildVscodeExtension = lib.extendMkDerivation {
14 constructDrv = stdenv.mkDerivation;
15 excludeDrvArgNames = [
16 "vscodeExtUniqueId"
17 ];
18 extendDrvArgs =
19 finalAttrs:
20 {
21 pname ? null, # Only optional for backward compatibility.
22 # Same as "Unique Identifier" on the extension's web page.
23 # For the moment, only serve as unique extension dir.
24 vscodeExtPublisher,
25 vscodeExtName,
26 vscodeExtUniqueId,
27 configurePhase ? ''
28 runHook preConfigure
29 runHook postConfigure
30 '',
31 buildPhase ? ''
32 runHook preBuild
33 runHook postBuild
34 '',
35 dontPatchELF ? true,
36 dontStrip ? true,
37 nativeBuildInputs ? [ ],
38 passthru ? { },
39 ...
40 }@args:
41 {
42 pname = "vscode-extension-${pname}";
43
44 passthru = {
45 updateScript = vscode-extension-update-script { };
46 }
47 // passthru
48 // {
49 inherit vscodeExtPublisher vscodeExtName vscodeExtUniqueId;
50 };
51
52 inherit
53 configurePhase
54 buildPhase
55 dontPatchELF
56 dontStrip
57 ;
58
59 # Some .vsix files contain other directories (e.g., `package`) that we don't use.
60 # If other directories are present but `sourceRoot` is unset, the unpacker phase fails.
61 sourceRoot = args.sourceRoot or "extension";
62
63 # This cannot be removed, it is used by some extensions.
64 installPrefix = "share/vscode/extensions/${vscodeExtUniqueId}";
65
66 nativeBuildInputs = [ unzip ] ++ nativeBuildInputs;
67
68 installPhase =
69 args.installPhase or ''
70 runHook preInstall
71
72 mkdir -p "$out/$installPrefix"
73 find . -mindepth 1 -maxdepth 1 | xargs -d'\n' mv -t "$out/$installPrefix/"
74
75 runHook postInstall
76 '';
77 };
78 };
79
80 fetchVsixFromVscodeMarketplace =
81 mktplcExtRef: fetchurl (import ./mktplcExtRefToFetchArgs.nix mktplcExtRef);
82
83 buildVscodeMarketplaceExtension = lib.extendMkDerivation {
84 constructDrv = buildVscodeExtension;
85 excludeDrvArgNames = [
86 "mktplcRef"
87 "vsix"
88 ];
89 extendDrvArgs =
90 finalAttrs:
91 {
92 name ? "",
93 src ? null,
94 vsix ? null,
95 mktplcRef,
96 ...
97 }:
98 assert "" == name;
99 assert null == src;
100 {
101 inherit (mktplcRef) version;
102 pname = "${mktplcRef.publisher}-${mktplcRef.name}";
103 src = if (vsix != null) then vsix else fetchVsixFromVscodeMarketplace mktplcRef;
104 vscodeExtPublisher = mktplcRef.publisher;
105 vscodeExtName = mktplcRef.name;
106 vscodeExtUniqueId = "${mktplcRef.publisher}.${mktplcRef.name}";
107 };
108 };
109
110 mktplcRefAttrList = [
111 "name"
112 "publisher"
113 "version"
114 "sha256"
115 "hash"
116 "arch"
117 ];
118
119 mktplcExtRefToExtDrv =
120 ext:
121 buildVscodeMarketplaceExtension (
122 removeAttrs ext mktplcRefAttrList
123 // {
124 mktplcRef = builtins.intersectAttrs (lib.genAttrs mktplcRefAttrList (_: null)) ext;
125 }
126 );
127
128 extensionFromVscodeMarketplace = mktplcExtRefToExtDrv;
129 extensionsFromVscodeMarketplace =
130 mktplcExtRefList: builtins.map extensionFromVscodeMarketplace mktplcExtRefList;
131
132 vscodeWithConfiguration = import ./vscodeWithConfiguration.nix {
133 inherit lib extensionsFromVscodeMarketplace writeShellScriptBin;
134 vscodeDefault = vscode;
135 };
136
137 vscodeExts2nix = import ./vscodeExts2nix.nix {
138 inherit lib writeShellScriptBin;
139 vscodeDefault = vscode;
140 };
141
142 vscodeEnv = import ./vscodeEnv.nix {
143 inherit
144 lib
145 buildEnv
146 writeShellScriptBin
147 extensionsFromVscodeMarketplace
148 jq
149 ;
150 vscodeDefault = vscode;
151 };
152
153 toExtensionJsonEntry = ext: rec {
154 identifier = {
155 id = ext.vscodeExtUniqueId;
156 uuid = "";
157 };
158
159 version = ext.version;
160
161 relativeLocation = ext.vscodeExtUniqueId;
162
163 location = {
164 "$mid" = 1;
165 fsPath = ext.outPath + "/share/vscode/extensions/${ext.vscodeExtUniqueId}";
166 path = location.fsPath;
167 scheme = "file";
168 };
169
170 metadata = {
171 id = "";
172 publisherId = "";
173 publisherDisplayName = ext.vscodeExtPublisher;
174 targetPlatform = "undefined";
175 isApplicationScoped = false;
176 updated = false;
177 isPreReleaseVersion = false;
178 installedTimestamp = 0;
179 preRelease = false;
180 };
181 };
182
183 toExtensionJson = extensions: builtins.toJSON (map toExtensionJsonEntry extensions);
184in
185{
186 inherit
187 fetchVsixFromVscodeMarketplace
188 buildVscodeExtension
189 buildVscodeMarketplaceExtension
190 extensionFromVscodeMarketplace
191 extensionsFromVscodeMarketplace
192 vscodeWithConfiguration
193 vscodeExts2nix
194 vscodeEnv
195 toExtensionJsonEntry
196 toExtensionJson
197 ;
198}