1# Even though pCloud Drive is redistributed as a plug-n-play AppImage, it
2# requires a little bit more love because of the way Nix launches those types
3# of applications.
4#
5# What Nix does, simplifying a bit, is that it extracts an AppImage and starts
6# it via buildFHSEnv - this is totally fine for majority of apps, but makes
7# it by-design *impossible* to launch SUID wrappers [^1]; in case of pCloud,
8# it's fusermount.
9# (so pCloud starts, but silently fails to mount the FUSE drive.)
10#
11# To overcome this issue, we're manually extracting the AppImage and then treat
12# it as if it was a regular, good-ol' application requiring some standard path
13# fixes.
14#
15# ^1 https://github.com/NixOS/nixpkgs/issues/69338
16
17{
18 # Build dependencies
19 appimageTools,
20 autoPatchelfHook,
21 patchelfUnstable,
22 fetchzip,
23 lib,
24 stdenv,
25
26 # Runtime dependencies;
27 # A few additional ones (e.g. Node) are already shipped together with the
28 # AppImage, so we don't have to duplicate them here.
29 alsa-lib,
30 dbus-glib,
31 fuse,
32 gsettings-desktop-schemas,
33 gtk3,
34 libdbusmenu-gtk2,
35 libXdamage,
36 nss,
37 udev,
38}:
39
40let
41 pname = "pcloud";
42 version = "1.14.13";
43 code = "XZevXB5ZOmw7nYNHSdpci0bD848nbhyClpf7";
44
45 # Archive link's codes: https://www.pcloud.com/release-notes/linux.html
46 src = fetchzip {
47 url = "https://api.pcloud.com/getpubzip?code=${code}&filename=pcloud-${version}.zip";
48 hash = "sha256-luyFMLNdbogaNF/4y9fZbZ1eBFPmyF2q/Xb1EfsSPz0=";
49 };
50
51 appimageContents = appimageTools.extractType2 {
52 inherit pname version;
53 src = "${src}/pcloud";
54 };
55
56in
57stdenv.mkDerivation {
58 inherit pname version;
59
60 src = appimageContents;
61
62 dontConfigure = true;
63 dontBuild = true;
64
65 nativeBuildInputs = [
66 autoPatchelfHook
67 patchelfUnstable
68 ];
69
70 buildInputs = [
71 alsa-lib
72 dbus-glib
73 fuse
74 gtk3
75 libdbusmenu-gtk2
76 libXdamage
77 nss
78 udev
79 ];
80
81 installPhase = ''
82 mkdir "$out"
83 cp -ar . "$out/app"
84 cd "$out"
85
86 # Remove the AppImage runner, since users are not supposed to use it; the
87 # actual entry point is the `pcloud` binary
88 rm app/AppRun
89
90 # Adjust directory structure, so that the `.desktop` etc. files are
91 # properly detected
92 mkdir bin
93 mv app/usr/share .
94 mv app/usr/lib .
95
96 # Adjust the `.desktop` file
97 mkdir share/applications
98
99 substitute \
100 app/pcloud.desktop \
101 share/applications/pcloud.desktop \
102 --replace 'Name=pcloud' 'Name=pCloud' \
103 --replace 'Exec=AppRun' 'Exec=${pname}'
104
105 # Build the main executable
106 cat > bin/pcloud <<EOF
107 #! $SHELL -e
108
109 # This is required for the file picker dialog - otherwise pcloud just
110 # crashes
111 export XDG_DATA_DIRS="${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}:${gtk3}/share/gsettings-schemas/${gtk3.name}:$XDG_DATA_DIRS"
112
113 exec "$out/app/pcloud"
114 EOF
115
116 chmod +x bin/pcloud
117
118 ln -snf $out/share/icons/hicolor/512x512/apps/pcloud.png $out/app/pcloud.png
119 '';
120
121 meta = with lib; {
122 description = "Secure and simple to use cloud storage for your files; pCloud Drive, Electron Edition";
123 homepage = "https://www.pcloud.com/";
124 sourceProvenance = with sourceTypes; [ binaryNativeCode ];
125 license = licenses.unfree;
126 maintainers = with maintainers; [ patryk27 ];
127 platforms = [ "x86_64-linux" ];
128 mainProgram = "pcloud";
129 };
130}