Make RustRover work with Rust from Nixpkgs
at main 3.9 kB view raw
1{ 2 lib, 3 mkShell, 4 writeShellScriptBin, 5 buildEnv, 6 rsync, 7 lndir, 8 rustup, 9 10 rustc, 11 cargo, 12 rustc-unwrapped, 13 withNonRustupSysroot ? true, 14 rustLibSrc ? null, 15 addToToolchain ? [ ], 16 17 projectRoot, 18}: 19args: 20assert withNonRustupSysroot -> rustLibSrc != null; 21assert withNonRustupSysroot -> rustc-unwrapped != null; 22let 23 ideaDir = "${projectRoot}/.idea/nix-rust"; 24 sysrootDir = "${ideaDir}/sysroot"; 25 rustupHome = "${ideaDir}/rustup-home"; 26 fingerprintFile = "${ideaDir}/environment.fingerprint"; 27 envFile = "${ideaDir}/shell-env"; 28 toolchainName = "nix-toolchain"; 29 30 tools = buildEnv { 31 name = (args.name or "rr") + "-tools"; 32 paths = addToToolchain; 33 }; 34 35 environmentFingerprint = builtins.hashString "sha256" (toString [ 36 rustc 37 cargo 38 rustup 39 (lib.optionals withNonRustupSysroot [ 40 rustc-unwrapped 41 rustLibSrc 42 ]) 43 tools 44 ]); 45 46 checkFingerprint = writeShellScriptBin "check-fingerprint" '' 47 if [ -f "${fingerprintFile}" ] && [ -d ${sysrootDir} ]; then 48 STORED_FINGERPRINT=$(cat "${fingerprintFile}") 49 if [ "$STORED_FINGERPRINT" = "${environmentFingerprint}" ]; then 50 echo "Environment is up to date at ${ideaDir}" 51 exit 0 52 fi 53 fi 54 echo "Environment changed, recreating..." 55 rm -rf ${ideaDir} && exit 1 56 ''; 57 58 createSysrootNonRustup = writeShellScriptBin "create-sysroot" '' 59 mkdir -p ${sysrootDir} 60 61 ${lib.getExe lndir} ${rustc-unwrapped} ${sysrootDir} 62 63 mkdir -p "${sysrootDir}/lib/rustlib/src/rust" 64 rm -rf "${sysrootDir}/lib/rustlib/src/rust/library" 65 ${lib.getExe rsync} -aq ${rustLibSrc}/ "${sysrootDir}/lib/rustlib/src/rust/library/" 66 chmod -R u+w "${sysrootDir}/lib/rustlib/src/rust/library" 67 68 ${lib.getExe lndir} ${cargo}/bin ${sysrootDir}/bin 69 ${lib.getExe lndir} ${tools}/bin ${sysrootDir}/bin 70 71 echo "${environmentFingerprint}" > "${fingerprintFile}" 72 echo "Sysroot created at ${sysrootDir}" 73 ''; 74 75 createSysrootRustup = writeShellScriptBin "create-sysroot" '' 76 mkdir -p ${sysrootDir} 77 ${lndir}/bin/lndir ${rustc} ${sysrootDir} >/dev/null 2>&1 78 ${lndir}/bin/lndir ${cargo}/bin "${sysrootDir}/bin" >/dev/null 2>&1 79 ${lndir}/bin/lndir ${tools}/bin "${sysrootDir}/bin" >/dev/null 2>&1 80 81 echo "${environmentFingerprint}" > "${fingerprintFile}" 82 echo "Sysroot created at ${sysrootDir}" 83 ''; 84 85 sourceEnv = '' 86 if [ -f "${envFile}" ]; then 87 set -a && source "${envFile}" && set +a 88 fi 89 ''; 90 91 rustcWrapper = writeShellScriptBin "rustc" '' 92 ${sourceEnv} 93 if [ "$1" = "--print" ] && [ "$2" = "sysroot" ]; then 94 echo ${sysrootDir} 95 else 96 exec ${rustup}/bin/rustc "$@" 97 fi 98 ''; 99 100 rustupWrapper = writeShellScriptBin "rustup" '' 101 ${sourceEnv} 102 if [ "$1" = "component" ] && [ "$2" = "list" ]; then 103 shift 2 104 exec ${./list-components.sh} ${sysrootDir} "$@" 105 else 106 exec -a "$0" ${rustup}/bin/rustup "$@" 107 fi 108 ''; 109 110 createSysroot = if withNonRustupSysroot then createSysrootNonRustup else createSysrootRustup; 111 112 createEnvironment = writeShellScriptBin "create-environment" '' 113 ${lib.getExe checkFingerprint} && exit 0 114 115 mkdir -p .idea 116 ${lib.getExe createSysroot} 117 118 mkdir -p ${ideaDir}/bin 119 120 ${lib.getExe lndir} ${rustup}/bin ${ideaDir}/bin && rm ${ideaDir}/bin/rustc ${ideaDir}/bin/rustup 121 ${lib.getExe lndir} ${rustcWrapper}/bin ${ideaDir}/bin 122 ${lib.getExe lndir} ${rustupWrapper}/bin ${ideaDir}/bin 123 124 mkdir -p "$RUSTUP_HOME/toolchains" 125 126 ${rustup}/bin/rustup toolchain link ${toolchainName} "${sysrootDir}" 127 ${rustup}/bin/rustup default ${toolchainName} 128 ''; 129in 130mkShell ( 131 args 132 // { 133 packages = (args.packages or [ ]) ++ [ rustup ]; 134 135 env.RUSTUP_HOME = rustupHome; 136 shellHook = (args.shellHook or "") + '' 137 ${lib.getExe createEnvironment} 138 export -p | grep -vE '^declare -x (TMPDIR|TMP|TEMP|TEMPDIR)=' > "${envFile}" 139 ''; 140 } 141)