Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit 83aacb9

Browse files
committed
make the .NET Core SDK a proper dependency rather than copy over some libraries + restructure to also support home manager + readded extensionDir option for those that use e.g. .vscode-oss
1 parent ea87c7c commit 83aacb9

File tree

9 files changed

+173
-114
lines changed

9 files changed

+173
-114
lines changed

README.md

+20-4
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,32 @@ Experimental support for Live Share in Visual Studio Code for NixOS. The need to
1717
}
1818
```
1919

20+
### Home Manager
21+
22+
```nix
23+
{
24+
imports = [
25+
"${builtins.fetchGit {
26+
url = "https://github.com/msteen/nixos-vsliveshare.git";
27+
ref = "refs/heads/master";
28+
}}/modules/vsliveshare/home.nix"
29+
];
30+
31+
services.vsliveshare.enable = true;
32+
}
33+
```
34+
2035
## Usage
2136

2237
You can manually run `fix-vsliveshare` to fix the current extension within ~/.vscode/extensions (i.e. when installed through vscode's extension management). Or you can have this done automatically whenever a new version is installed with `systemctl --user enable auto-fix-vsliveshare && systemctl --user start auto-fix-vsliveshare`. In both cases you will have to reload the VS Code window to get the fixed Live Share to load. In the case of the auto fixer, note that if you reload too fast (e.g. immediately after the Live Share extension is installed through VS Code's extension manager) then the fix might not have enough time to fully build, so either give it a few seconds or if you were to fast, simply reload the window yet again.
2338

24-
It is also possible to install an older version again, if for some reason a later version breaks, by passing the version (e.g. `fix-vsliveshare 1.0.614`) or the extension directory name (e.g. `fix-vsliveshare ms-vsliveshare.vsliveshare-1.0.1653`).
39+
### Older versions
2540

26-
## Limitations
41+
At some point the package is likely to break again due to changes made to the extension that break the way it is packaged in NixOS
42+
There will be an update that causes the current package to fail to build for that version, e.g. due to structural changes made to the extension. In that case please create an issue here and in the meantime you can [downgrade the Live Share extension](https://github.com/microsoft/vscode/issues/30579#issuecomment-456028574), which will pin the extension that particular version regardless of future updates. Then we can run the fixer by passing it the older version (e.g. `fix-vsliveshare 1.0.1653`) or the older extension directory name (e.g. `fix-vsliveshare ms-vsliveshare.vsliveshare-1.0.1653`).
2743

28-
* The auto fixer is very experimental, I tested it once with an old version of Live Share present (i.e. an actual update) and the rest of the time through fresh installs, so the might still be some remaining bugs in the mechanism.
44+
## Limitations
2945

3046
* The things that need patching in the extension's source code so far have been almost consistent, but the structure of the package itself has changed over the versions (e.g. `extension.js -> extension-prod.js`), so these kind of changes might cause the fix to fail for later versions.
3147

32-
* I have only tested this under `nixos-20.03`.
48+
* The package requires SDK 3 which is only available in `nixos-20.03` and up.

default.nix

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
{
2-
imports = [
3-
./modules/vsliveshare.nix
4-
];
5-
}
1+
import ./modules/vsliveshare

modules/vsliveshare.nix

-94
This file was deleted.

modules/vsliveshare/default.nix

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import ./module.nix ({ packages, name, description, script }:
2+
3+
{
4+
environment.systemPackages = packages;
5+
6+
services.gnome3.gnome-keyring.enable = true;
7+
8+
systemd.user.services.${name} = {
9+
inherit description;
10+
serviceConfig = {
11+
ExecStart = script;
12+
};
13+
wantedBy = [ "graphical-session.target" ];
14+
};
15+
})

modules/vsliveshare/home.nix

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import ./module.nix ({ packages, name, description, script }:
2+
3+
{
4+
home = { inherit packages; };
5+
6+
services.gnome-keyring.enable = true;
7+
8+
systemd.user.services.${name} = {
9+
Unit = {
10+
Description = description;
11+
After = [ "graphical-session-pre.target" ];
12+
PartOf = [ "graphical-session.target" ];
13+
};
14+
15+
Service = {
16+
ExecStart = script;
17+
};
18+
19+
Install = {
20+
WantedBy = [ "graphical-session-pre.target" ];
21+
};
22+
};
23+
})

modules/vsliveshare/module.nix

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
moduleConfig:
2+
{ config, lib, pkgs, ... }:
3+
4+
with lib;
5+
6+
let
7+
cfg = config.services.vsliveshare;
8+
9+
fix-vsliveshare = pkgs.callPackage ../../pkgs/fix-vsliveshare { inherit (cfg) extensionsDir; };
10+
11+
in {
12+
options.services.vsliveshare = with types; {
13+
enable = mkEnableOption "VS Code Live Share extension";
14+
extensionsDir = mkOption {
15+
type = str;
16+
default = "$HOME/.vscode/extensions";
17+
description = ''
18+
The VS Code extensions directory.
19+
CAUTION: The fix will remove ms-vsliveshare.vsliveshare-* inside this directory!
20+
'';
21+
};
22+
};
23+
24+
config = mkIf cfg.enable (moduleConfig rec {
25+
packages = with pkgs; [ bash desktop-file-utils xlibs.xprop fix-vsliveshare ];
26+
name = "auto-fix-vsliveshare";
27+
description = "Automatically fix the VS Code Live Share extension";
28+
script = pkgs.writeShellScript "${name}.sh" ''
29+
PATH=${makeBinPath (with pkgs; [ coreutils inotify-tools fix-vsliveshare ])}
30+
mkdir -p "${cfg.extensionsDir}" &&
31+
while IFS=: read -r name event; do
32+
if [[ $event == 'CREATE,ISDIR' && $name == .ms-vsliveshare.vsliveshare-* ]]; then
33+
extension=''${name:1}
34+
elif [[ $event == 'CLOSE_NOWRITE,CLOSE,ISDIR' && -n $extension && $name == ms-vsliveshare.vsliveshare-* ]]; then
35+
fix-vsliveshare "$extension"
36+
extension=
37+
fi
38+
done < <(inotifywait -q -m -e CREATE,ISDIR -e CLOSE_NOWRITE,CLOSE,ISDIR --format '%f:%e' "${cfg.extensionsDir}")
39+
'';
40+
});
41+
}

pkgs/fix-vsliveshare/default.nix

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{ writeShellScriptBin, lib, coreutils, findutils, nix-prefetch, nix, file, gnugrep, jq
2+
, extensionsDir }:
3+
4+
writeShellScriptBin "fix-vsliveshare" ''
5+
PATH=${lib.makeBinPath [ coreutils findutils nix-prefetch nix file gnugrep jq ]}
6+
7+
if (( $# >= 1 )); then
8+
version=$1
9+
else
10+
version=$(find "${extensionsDir}" -mindepth 1 -maxdepth 1 -name 'ms-vsliveshare.vsliveshare-*' -printf '%f' | sort -rV | head -n1)
11+
fi
12+
version=''${version/ms-vsliveshare.vsliveshare-/}
13+
if [[ ! $version =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
14+
echo "Invalid version '$version'." >&2
15+
exit 1
16+
fi
17+
18+
sha256=$(nix-prefetch -q '
19+
callPackage ${toString ../vsliveshare} {
20+
version = "'"$version"'";
21+
sha256 = "0000000000000000000000000000000000000000000000000000";
22+
}') &&
23+
out=$(nix-build --expr '
24+
with import <nixpkgs> {};
25+
callPackage ${toString ../vsliveshare} {
26+
version = "'"$version"'";
27+
sha256 = "'"$sha256"'";
28+
}') ||
29+
{
30+
echo "Failed to build VS Code Live Share version '$version'." >&2
31+
exit 1
32+
}
33+
34+
src=$out/share/vscode/extensions/ms-vsliveshare.vsliveshare
35+
dst="${extensionsDir}"/ms-vsliveshare.vsliveshare-$version
36+
37+
# Remove all previous versions of VS Code Live Share.
38+
find "${extensionsDir}" -mindepth 1 -maxdepth 1 -name 'ms-vsliveshare.vsliveshare-*' -exec rm -r {} +
39+
40+
# Create the extension directory.
41+
mkdir -p "$dst"
42+
43+
cd "$src"
44+
45+
# Copy over executable files and symlink files that should remain unchanged or that are ELF executables.
46+
executables=()
47+
while read -rd ''' file; do
48+
if [[ ! -x $file ]] || file "$file" | grep -wq ELF; then
49+
mkdir -p "$(dirname "$dst/$file")"
50+
ln -s "$src/$file" "$dst/$file"
51+
else
52+
executables+=( "$file" )
53+
fi
54+
done < <(find . -mindepth 1 -type f \( -executable -o -name \*.a -o -name \*.dll -o -name \*.pdb \) -printf '%P\0')
55+
cp --parents --no-clobber --no-preserve=mode,ownership,timestamps -t "$dst" "''${executables[@]}"
56+
chmod -R +x "$dst"
57+
58+
# Copy over the remaining directories and files.
59+
find . -mindepth 1 -type d -printf '%P\0' |
60+
xargs -0r mkdir -p
61+
find . -mindepth 1 ! -type d ! \( -type f \( -executable -o -name \*.a -o -name \*.dll -o -name \*.pdb \) \) -printf '%P\0' |
62+
xargs -0r cp --parents --no-clobber --no-preserve=mode,ownership,timestamps -t "$dst"
63+
64+
# Make sure the version is not marked obsolete, otherwise vscode won't load the extension.
65+
[[ -e "${extensionsDir}"/.obsolete ]] &&
66+
obsolete_json=$(< "${extensionsDir}"/.obsolete) &&
67+
jq 'del(."'"$(basename "$dst")"'")' <<< "$obsolete_json" > "${extensionsDir}"/.obsolete || true
68+
''

pkgs/vsliveshare/default.nix

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Baseed on previous attempts of others: https://github.com/NixOS/nixpkgs/issues/41189
2-
{ lib, vscode-utils, gccStdenv, autoPatchelfHook, bash, dos2unix, file, makeWrapper, dotnet-sdk
2+
{ lib, vscode-utils, gccStdenv, autoPatchelfHook, bash, dos2unix, file, makeWrapper, dotnet-sdk_3
33
, curl, gcc, icu, libkrb5, libsecret, libunwind, libX11, lttng-ust, openssl, utillinux, zlib
44
, version, sha256
55
}:
@@ -45,7 +45,6 @@ in ((vscode-utils.override { stdenv = gccStdenv; }).buildVscodeMarketplaceExtens
4545
# which is less likely to break in the future.
4646
postPatch = ''
4747
sed -i \
48-
-e 's/installFileExistsAsync() {/& return Promise.resolve(true);/' \
4948
-e 's/updateExecutablePermissionsAsync() {/& return;/' \
5049
-e 's/isInstallCorrupt(traceSource, manifest) {/& return false;/' \
5150
out/prod/extension-prod.js
@@ -58,17 +57,13 @@ in ((vscode-utils.override { stdenv = gccStdenv; }).buildVscodeMarketplaceExtens
5857
shopt -s extglob
5958
cd $out/share/vscode/extensions/ms-vsliveshare.vsliveshare
6059
60+
# FIXME: I think the noop-syslog.so workaround fails due to no longer using a locally copied SDK.
6161
# A workaround to prevent the journal filling up due to diagnostic logging.
6262
# See: https://github.com/MicrosoftDocs/live-share/issues/1272
63-
gcc -fPIC -shared -ldl -o dotnet_modules/noop-syslog.so ${./noop-syslog.c}
6463
65-
# Normally the copying of the right executables and libraries is done externally at a later time,
64+
# Normally the copying of the right executables is done externally at a later time,
6665
# but we want it done at installation time.
67-
# FIXME: Surely there is a better way than copying over the shared .NET libraries.
68-
cp \
69-
${dotnet-sdk}/shared/Microsoft.NETCore.App/*/* \
70-
dotnet_modules/exes/linux-x64/* \
71-
dotnet_modules
66+
cp dotnet_modules/exes/linux-x64/* dotnet_modules
7267
7368
# The other runtimes won't be used and thus are just a waste of space.
7469
rm -r dotnet_modules/runtimes/!(linux-x64)
@@ -94,7 +89,7 @@ in ((vscode-utils.override { stdenv = gccStdenv; }).buildVscodeMarketplaceExtens
9489
mv $root/dotnet_modules/vsls-agent{,-wrapped}
9590
makeWrapper $root/dotnet_modules/vsls-agent{-wrapped,} \
9691
--prefix LD_LIBRARY_PATH : "$rpath" \
97-
--set LD_PRELOAD "$root/dotnet_modules/noop-syslog.so"
92+
--set DOTNET_ROOT ${dotnet-sdk_3}
9893
'';
9994

10095
meta = {

pkgs/vsliveshare/noop-syslog.c

-1
This file was deleted.

0 commit comments

Comments
 (0)