├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── src ├── flatpak.rs ├── main.rs └── structure.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "bitflags" 7 | version = "1.3.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 10 | 11 | [[package]] 12 | name = "block-buffer" 13 | version = "0.10.3" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 16 | dependencies = [ 17 | "generic-array", 18 | ] 19 | 20 | [[package]] 21 | name = "cc" 22 | version = "1.0.79" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 25 | 26 | [[package]] 27 | name = "chroma" 28 | version = "0.1.0" 29 | dependencies = [ 30 | "clap", 31 | "hex", 32 | "serde", 33 | "serde_json", 34 | "sha3", 35 | ] 36 | 37 | [[package]] 38 | name = "clap" 39 | version = "4.1.8" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5" 42 | dependencies = [ 43 | "bitflags", 44 | "clap_derive", 45 | "clap_lex", 46 | "is-terminal", 47 | "once_cell", 48 | "strsim", 49 | "termcolor", 50 | ] 51 | 52 | [[package]] 53 | name = "clap_derive" 54 | version = "4.1.8" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0" 57 | dependencies = [ 58 | "heck", 59 | "proc-macro-error", 60 | "proc-macro2", 61 | "quote", 62 | "syn", 63 | ] 64 | 65 | [[package]] 66 | name = "clap_lex" 67 | version = "0.3.2" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09" 70 | dependencies = [ 71 | "os_str_bytes", 72 | ] 73 | 74 | [[package]] 75 | name = "cpufeatures" 76 | version = "0.2.5" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 79 | dependencies = [ 80 | "libc", 81 | ] 82 | 83 | [[package]] 84 | name = "crypto-common" 85 | version = "0.1.6" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 88 | dependencies = [ 89 | "generic-array", 90 | "typenum", 91 | ] 92 | 93 | [[package]] 94 | name = "digest" 95 | version = "0.10.6" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 98 | dependencies = [ 99 | "block-buffer", 100 | "crypto-common", 101 | ] 102 | 103 | [[package]] 104 | name = "errno" 105 | version = "0.2.8" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" 108 | dependencies = [ 109 | "errno-dragonfly", 110 | "libc", 111 | "winapi", 112 | ] 113 | 114 | [[package]] 115 | name = "errno-dragonfly" 116 | version = "0.1.2" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 119 | dependencies = [ 120 | "cc", 121 | "libc", 122 | ] 123 | 124 | [[package]] 125 | name = "generic-array" 126 | version = "0.14.6" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 129 | dependencies = [ 130 | "typenum", 131 | "version_check", 132 | ] 133 | 134 | [[package]] 135 | name = "heck" 136 | version = "0.4.1" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 139 | 140 | [[package]] 141 | name = "hermit-abi" 142 | version = "0.3.1" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" 145 | 146 | [[package]] 147 | name = "hex" 148 | version = "0.4.3" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 151 | 152 | [[package]] 153 | name = "io-lifetimes" 154 | version = "1.0.6" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3" 157 | dependencies = [ 158 | "libc", 159 | "windows-sys", 160 | ] 161 | 162 | [[package]] 163 | name = "is-terminal" 164 | version = "0.4.4" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" 167 | dependencies = [ 168 | "hermit-abi", 169 | "io-lifetimes", 170 | "rustix", 171 | "windows-sys", 172 | ] 173 | 174 | [[package]] 175 | name = "itoa" 176 | version = "1.0.6" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 179 | 180 | [[package]] 181 | name = "keccak" 182 | version = "0.1.3" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" 185 | dependencies = [ 186 | "cpufeatures", 187 | ] 188 | 189 | [[package]] 190 | name = "libc" 191 | version = "0.2.139" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" 194 | 195 | [[package]] 196 | name = "linux-raw-sys" 197 | version = "0.1.4" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" 200 | 201 | [[package]] 202 | name = "once_cell" 203 | version = "1.17.1" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" 206 | 207 | [[package]] 208 | name = "os_str_bytes" 209 | version = "6.4.1" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" 212 | 213 | [[package]] 214 | name = "proc-macro-error" 215 | version = "1.0.4" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 218 | dependencies = [ 219 | "proc-macro-error-attr", 220 | "proc-macro2", 221 | "quote", 222 | "syn", 223 | "version_check", 224 | ] 225 | 226 | [[package]] 227 | name = "proc-macro-error-attr" 228 | version = "1.0.4" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 231 | dependencies = [ 232 | "proc-macro2", 233 | "quote", 234 | "version_check", 235 | ] 236 | 237 | [[package]] 238 | name = "proc-macro2" 239 | version = "1.0.51" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" 242 | dependencies = [ 243 | "unicode-ident", 244 | ] 245 | 246 | [[package]] 247 | name = "quote" 248 | version = "1.0.23" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" 251 | dependencies = [ 252 | "proc-macro2", 253 | ] 254 | 255 | [[package]] 256 | name = "rustix" 257 | version = "0.36.9" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" 260 | dependencies = [ 261 | "bitflags", 262 | "errno", 263 | "io-lifetimes", 264 | "libc", 265 | "linux-raw-sys", 266 | "windows-sys", 267 | ] 268 | 269 | [[package]] 270 | name = "ryu" 271 | version = "1.0.13" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 274 | 275 | [[package]] 276 | name = "serde" 277 | version = "1.0.153" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "3a382c72b4ba118526e187430bb4963cd6d55051ebf13d9b25574d379cc98d20" 280 | dependencies = [ 281 | "serde_derive", 282 | ] 283 | 284 | [[package]] 285 | name = "serde_derive" 286 | version = "1.0.153" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "1ef476a5790f0f6decbc66726b6e5d63680ed518283e64c7df415989d880954f" 289 | dependencies = [ 290 | "proc-macro2", 291 | "quote", 292 | "syn", 293 | ] 294 | 295 | [[package]] 296 | name = "serde_json" 297 | version = "1.0.94" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" 300 | dependencies = [ 301 | "itoa", 302 | "ryu", 303 | "serde", 304 | ] 305 | 306 | [[package]] 307 | name = "sha3" 308 | version = "0.10.6" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" 311 | dependencies = [ 312 | "digest", 313 | "keccak", 314 | ] 315 | 316 | [[package]] 317 | name = "strsim" 318 | version = "0.10.0" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 321 | 322 | [[package]] 323 | name = "syn" 324 | version = "1.0.109" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 327 | dependencies = [ 328 | "proc-macro2", 329 | "quote", 330 | "unicode-ident", 331 | ] 332 | 333 | [[package]] 334 | name = "termcolor" 335 | version = "1.2.0" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" 338 | dependencies = [ 339 | "winapi-util", 340 | ] 341 | 342 | [[package]] 343 | name = "typenum" 344 | version = "1.16.0" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 347 | 348 | [[package]] 349 | name = "unicode-ident" 350 | version = "1.0.8" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 353 | 354 | [[package]] 355 | name = "version_check" 356 | version = "0.9.4" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 359 | 360 | [[package]] 361 | name = "winapi" 362 | version = "0.3.9" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 365 | dependencies = [ 366 | "winapi-i686-pc-windows-gnu", 367 | "winapi-x86_64-pc-windows-gnu", 368 | ] 369 | 370 | [[package]] 371 | name = "winapi-i686-pc-windows-gnu" 372 | version = "0.4.0" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 375 | 376 | [[package]] 377 | name = "winapi-util" 378 | version = "0.1.5" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 381 | dependencies = [ 382 | "winapi", 383 | ] 384 | 385 | [[package]] 386 | name = "winapi-x86_64-pc-windows-gnu" 387 | version = "0.4.0" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 390 | 391 | [[package]] 392 | name = "windows-sys" 393 | version = "0.45.0" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 396 | dependencies = [ 397 | "windows-targets", 398 | ] 399 | 400 | [[package]] 401 | name = "windows-targets" 402 | version = "0.42.1" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" 405 | dependencies = [ 406 | "windows_aarch64_gnullvm", 407 | "windows_aarch64_msvc", 408 | "windows_i686_gnu", 409 | "windows_i686_msvc", 410 | "windows_x86_64_gnu", 411 | "windows_x86_64_gnullvm", 412 | "windows_x86_64_msvc", 413 | ] 414 | 415 | [[package]] 416 | name = "windows_aarch64_gnullvm" 417 | version = "0.42.1" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" 420 | 421 | [[package]] 422 | name = "windows_aarch64_msvc" 423 | version = "0.42.1" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" 426 | 427 | [[package]] 428 | name = "windows_i686_gnu" 429 | version = "0.42.1" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" 432 | 433 | [[package]] 434 | name = "windows_i686_msvc" 435 | version = "0.42.1" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" 438 | 439 | [[package]] 440 | name = "windows_x86_64_gnu" 441 | version = "0.42.1" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" 444 | 445 | [[package]] 446 | name = "windows_x86_64_gnullvm" 447 | version = "0.42.1" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" 450 | 451 | [[package]] 452 | name = "windows_x86_64_msvc" 453 | version = "0.42.1" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" 456 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chroma" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.1.8", features = ["derive"] } 10 | hex = "0.4.3" 11 | serde = { version = "1.0.153", features = ["derive"] } 12 | serde_json = "1.0.94" 13 | sha3 = "0.10.6" 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chroma 2 | One copy of Electron to rule them all. 3 | 4 | chroma keeps a central, up-to-date version of Electron, and makes all your installed Electron apps use it, in order to save disk space. 5 | 6 | ## State of the Project 7 | 8 | Supported platforms: 9 | * [X] Linux 10 | * [X] regular installs 11 | * [ ] flatpak (WIP: sandboxing issues) 12 | * [ ] AppImages 13 | * [ ] Windows 14 | * [ ] macOS 15 | 16 | ## Installing 17 | 18 | Rust and cargo are required. Install them with [rustup](https://rustup.rs/). 19 | 20 | Installation is a little rough and unintuitive right now, due to the lack of code for fetching the latest Electron. It'll get easier in the future. 21 | 22 | * as root: `mkdir /var/lib/chroma/` 23 | * grab the [latest electron ZIP](https://github.com/electron/electron/releases/latest) for your platform 24 | * as root: unzip into `/var/lib/chroma/electron` 25 | * as self: `cargo install --git https://github.com/mogery/chroma` 26 | 27 | ## Usage 28 | 29 | ### Regular installs 30 | 31 | For example, if you want to chromafy Slack: 32 | ```bash 33 | chroma raw $(where slack) 34 | ``` 35 | 36 | ### Flatpak 37 | 38 | **WARNING: Flatpak support does not work right now: this will mangle your app.** 39 | 40 | For example, if you want to chromafy Slack: 41 | ```bash 42 | chroma flatpak com.slack.Slack 43 | ``` 44 | -------------------------------------------------------------------------------- /src/flatpak.rs: -------------------------------------------------------------------------------- 1 | use std::{path::{Path, PathBuf}, fs}; 2 | 3 | use serde_json::Value; 4 | 5 | pub fn find_chrome_pak

(dir: P) -> Option 6 | where P: AsRef{ 7 | 8 | for file in dir.as_ref().read_dir().unwrap() { 9 | let file = file.unwrap(); 10 | let typ = file.file_type().unwrap(); 11 | 12 | if typ.is_file() { 13 | if file.file_name() == "chrome_100_percent.pak" { 14 | return Some(file.path()); 15 | } 16 | } else if typ.is_dir() { 17 | match find_chrome_pak(file.path()) { 18 | Some(x) => return Some(x), 19 | None => {}, 20 | } 21 | } 22 | } 23 | 24 | None 25 | } 26 | 27 | pub fn get_flatpak_dir(id: &str) -> Option { 28 | let base = PathBuf::from(format!("/var/lib/flatpak/app/{}/current/active/files/", id)); 29 | if !base.exists() { 30 | return None; 31 | } 32 | 33 | let chrome_pak = find_chrome_pak(&base).expect("Can't find Electron app."); 34 | let dir = chrome_pak.parent().unwrap(); 35 | 36 | Some(PathBuf::from(dir)) 37 | } 38 | 39 | pub fn get_flatpak_replaced_file(id: &str) -> PathBuf { 40 | let base = PathBuf::from(format!("/var/lib/flatpak/app/{}/current/active/files/", id)); 41 | let manifest_text = fs::read_to_string(base.join("manifest.json")).unwrap(); 42 | let manifest: Value = serde_json::from_str(&manifest_text).unwrap(); 43 | 44 | let command = manifest.get("command").unwrap().as_str().unwrap(); 45 | let wrapper = fs::read_to_string(base.join("bin/").join(command)).unwrap(); 46 | let mut tok = wrapper.split(" "); 47 | 48 | while tok.next().unwrap() != "zypak-wrapper" {} 49 | let replaced_relative = Path::new(tok.next().unwrap()).strip_prefix("/app/").unwrap(); 50 | 51 | base.join(replaced_relative) 52 | } 53 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{fs::{self, hard_link}, path::Path, os::unix::fs::symlink, process}; 2 | use clap::{Parser, Subcommand}; 3 | 4 | use crate::{structure::{get_chroma_dir, get_electron_dir, get_apps_dir, get_flatpak_hash, get_path_hash}, flatpak::{get_flatpak_dir, get_flatpak_replaced_file}}; 5 | 6 | pub(crate) mod structure; 7 | pub(crate) mod flatpak; 8 | 9 | #[derive(Subcommand)] 10 | enum Commands { 11 | Flatpak { 12 | id: String, 13 | }, 14 | Raw { 15 | path: String, 16 | }, 17 | } 18 | 19 | #[derive(Parser)] 20 | #[command(author, version, about, long_about = None)] 21 | #[command(propagate_version = true)] 22 | struct Args { 23 | #[command(subcommand)] 24 | command: Commands, 25 | } 26 | 27 | fn main() { 28 | let args = Args::parse(); 29 | 30 | let chroma_dir = get_chroma_dir(); 31 | let electron_dir = get_electron_dir(&chroma_dir).expect("Electron not found"); 32 | let apps_dir = get_apps_dir(&chroma_dir); 33 | 34 | let (dir_path, hash, target_path) = match &args.command { 35 | Commands::Flatpak { id } => { 36 | let dir_path = get_flatpak_dir(&id).expect("Flatpak app doesn't exist"); 37 | let hash = get_flatpak_hash(&id); 38 | let target_path = get_flatpak_replaced_file(&id); 39 | (dir_path, hash, target_path) 40 | }, 41 | Commands::Raw { path } => { 42 | let target_path = Path::new(&path).canonicalize().expect("Invalid path"); 43 | let dir_path = target_path.parent().unwrap().to_owned(); 44 | let hash = get_path_hash(&target_path); 45 | (dir_path, hash, target_path) 46 | }, 47 | }; 48 | 49 | println!("{:?} {:?} {:?}", dir_path, hash, target_path); 50 | 51 | let app_dir = apps_dir.join(Path::new(&hash)); 52 | if app_dir.exists() { 53 | fs::remove_dir_all(&app_dir).unwrap(); 54 | } 55 | 56 | fs::create_dir(&app_dir).expect(&format!("Failed to create app directory {:?}", app_dir)); 57 | 58 | for file in electron_dir.read_dir().unwrap() { 59 | let file = file.unwrap(); 60 | let file_path = file.path(); 61 | let filename = file_path.file_name().unwrap(); 62 | let typ = file.file_type().unwrap(); 63 | if typ.is_dir() { 64 | if filename != "resources" { 65 | symlink(file.path(), app_dir.join(file.path().file_name().unwrap())).unwrap(); 66 | } 67 | } else if typ.is_file() { 68 | if filename == "electron" { 69 | hard_link(file.path(), app_dir.join(target_path.file_name().unwrap())).unwrap(); 70 | } else { 71 | hard_link(file.path(), app_dir.join(file.path().file_name().unwrap())).unwrap(); 72 | } 73 | } else { 74 | panic!("{:?} is neither a directory or a file?", file.path()); 75 | } 76 | } 77 | 78 | symlink(dir_path.join("resources"), app_dir.join("resources")).unwrap(); 79 | 80 | for file in dir_path.read_dir().unwrap() { 81 | let file = file.unwrap(); 82 | let file_path = file.path(); 83 | let filename = file_path.file_name().unwrap(); 84 | let typ = file.file_type().unwrap(); 85 | 86 | if typ.is_dir() { 87 | if filename != "resources" { 88 | fs::remove_dir_all(file.path()).unwrap(); 89 | } 90 | } else { 91 | fs::remove_file(file.path()).unwrap(); 92 | } 93 | } 94 | 95 | let _ = fs::remove_file(&target_path).is_ok(); 96 | 97 | symlink(app_dir.join(target_path.file_name().unwrap()), &target_path).unwrap(); 98 | 99 | if let Commands::Flatpak { id } = args.command { 100 | let x = process::Command::new("flatpak") 101 | .args(["override", &format!("--filesystem={}", app_dir.to_str().unwrap()), &id]) 102 | .output() 103 | .expect("Failed to do Flatpak sandboxing"); 104 | 105 | println!("Flatpak did a {}: {:?} {:?}", x.status, std::str::from_utf8(&x.stdout), std::str::from_utf8(&x.stderr)) 106 | } 107 | 108 | println!("{:#?}", app_dir); 109 | } 110 | -------------------------------------------------------------------------------- /src/structure.rs: -------------------------------------------------------------------------------- 1 | use std::{path::{PathBuf, Path}, fs}; 2 | 3 | use sha3::{Sha3_256, Digest}; 4 | 5 | pub fn get_chroma_dir() -> PathBuf { 6 | let chroma_dir = Path::new("/var/lib/chroma/"); 7 | if !chroma_dir.exists() { 8 | println!("Creating chroma directory at {:?}...", chroma_dir); 9 | fs::create_dir(&chroma_dir).expect("Failed to create directory .chroma"); 10 | } 11 | 12 | chroma_dir.to_owned() 13 | } 14 | 15 | pub fn get_apps_dir

(chroma_dir: P) -> PathBuf 16 | where P: AsRef 17 | { 18 | let apps_dir = chroma_dir.as_ref().join("apps"); 19 | if !apps_dir.exists() { 20 | fs::create_dir(&apps_dir).expect("Failed to create directory .chroma/apps"); 21 | } 22 | 23 | apps_dir 24 | } 25 | 26 | pub fn get_electron_dir

(chroma_dir: P) -> Option 27 | where P: AsRef 28 | { 29 | let electron_dir = chroma_dir.as_ref().join("electron"); 30 | 31 | if electron_dir.exists() { 32 | Some(electron_dir) 33 | } else { 34 | None 35 | } 36 | } 37 | 38 | fn get_hash(x: T) -> String 39 | where T: AsRef { 40 | let mut hasher = Sha3_256::new(); 41 | hasher.update(x.as_ref()); 42 | let result = hasher.finalize(); 43 | hex::encode(result) 44 | } 45 | 46 | pub fn get_path_hash

(path: P) -> String 47 | where P: AsRef { 48 | get_hash(path.as_ref().to_str().unwrap()) 49 | } 50 | 51 | pub fn get_flatpak_hash(id: &str) -> String { 52 | get_hash("flatpak:".to_owned() + id) 53 | } --------------------------------------------------------------------------------