Make RustRover work with Rust from Nixpkgs
jetbrains nix rust
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: improve handling by using rustup toolchain link

WeetHet ab8af917 c84798a1

+145 -237
+81 -78
default.nix
··· 2 2 lib, 3 3 mkShell, 4 4 writeShellScriptBin, 5 - runCommand, 6 5 buildEnv, 7 - coreutils, 8 - nushell, 6 + rsync, 7 + lndir, 8 + rustup, 9 9 10 10 rustc, 11 11 cargo, ··· 20 20 assert withNonRustupSysroot -> rustLibSrc != null; 21 21 assert withNonRustupSysroot -> rustc-unwrapped != null; 22 22 let 23 - sysrootCacheDir = '' 24 - SYSROOT_HASH=$(echo "${rustc-unwrapped}" | ${coreutils}/bin/md5sum | ${coreutils}/bin/cut -d' ' -f1) 25 - CACHE_DIR="${projectRoot}/.idea/nix-rust-sysroot/$SYSROOT_HASH" 26 - ''; 27 - 28 - createFakeSysrootNonRustup = writeShellScriptBin "create-fake-sysroot" '' 29 - ${sysrootCacheDir} 30 - if [ ! -d "$CACHE_DIR" ]; then 31 - mkdir -p "$CACHE_DIR" 23 + ideaDir = "${projectRoot}/.idea/nix-rust"; 24 + sysrootDir = "${ideaDir}/sysroot"; 25 + rustupHome = "${ideaDir}/rustup-home"; 26 + fingerprintFile = "${ideaDir}/environment.fingerprint"; 27 + toolchainName = "nix-toolchain"; 32 28 33 - cp -r ${rustc-unwrapped}/* "$CACHE_DIR/" 34 - chmod -R u+w "$CACHE_DIR" 29 + tools = buildEnv { 30 + name = (args.name or "rr") + "-tools"; 31 + paths = addToToolchain; 32 + }; 35 33 36 - mkdir -p "$CACHE_DIR/lib/rustlib" 37 - if [ ! -d "$CACHE_DIR/lib/rustlib/src" ]; then 38 - cp -r ${rustc-unwrapped}/lib/rustlib/rustc-src "$CACHE_DIR/lib/rustlib/src" 39 - chmod -R u+w "$CACHE_DIR/lib/rustlib/src" 34 + environmentFingerprint = builtins.hashString "sha256" (toString [ 35 + rustc 36 + cargo 37 + rustup 38 + (lib.optionals withNonRustupSysroot [ 39 + rustc-unwrapped 40 + rustLibSrc 41 + ]) 42 + tools 43 + ]); 40 44 41 - rm -rf "$CACHE_DIR/lib/rustlib/src/rust/library" 42 - cp -r ${rustLibSrc} "$CACHE_DIR/lib/rustlib/src/rust/library" 43 - chmod -R u+w "$CACHE_DIR/lib/rustlib/src/rust/library" 45 + checkFingerprint = writeShellScriptBin "check-fingerprint" '' 46 + if [ -f "${fingerprintFile}" ] && [ -d ${sysrootDir} ]; then 47 + STORED_FINGERPRINT=$(cat "${fingerprintFile}") 48 + if [ "$STORED_FINGERPRINT" = "${environmentFingerprint}" ]; then 49 + echo "Environment is up to date at ${ideaDir}" 50 + exit 0 44 51 fi 45 52 fi 53 + echo "Environment changed, recreating..." 54 + rm -rf ${ideaDir} && exit 1 55 + ''; 46 56 47 - echo "$CACHE_DIR" 57 + createSysrootNonRustup = writeShellScriptBin "create-sysroot" '' 58 + mkdir -p ${sysrootDir} 59 + 60 + ${lib.getExe lndir} ${rustc-unwrapped} ${sysrootDir} 61 + 62 + mkdir -p "${sysrootDir}/lib/rustlib/src/rust" 63 + rm -rf "${sysrootDir}/lib/rustlib/src/rust/library" 64 + ${lib.getExe rsync} -aq ${rustLibSrc}/ "${sysrootDir}/lib/rustlib/src/rust/library/" 65 + chmod -R u+w "${sysrootDir}/lib/rustlib/src/rust/library" 66 + 67 + ${lib.getExe lndir} ${cargo}/bin ${sysrootDir}/bin 68 + ${lib.getExe lndir} ${tools}/bin ${sysrootDir}/bin 69 + 70 + echo "${environmentFingerprint}" > "${fingerprintFile}" 71 + echo "Sysroot created at ${sysrootDir}" 48 72 ''; 49 73 50 - createFakeSysrootRustup = writeShellScriptBin "create-fake-sysroot" '' 51 - ${sysrootCacheDir} 52 - if [ ! -d "$CACHE_DIR" ]; then 53 - mkdir -p "$CACHE_DIR" 54 - cp -r ${rustc}/* "$CACHE_DIR/" 55 - fi 74 + createSysrootRustup = writeShellScriptBin "create-sysroot" '' 75 + mkdir -p ${sysrootDir} 76 + ${lndir}/bin/lndir ${rustc} ${sysrootDir} >/dev/null 2>&1 77 + ${lndir}/bin/lndir ${cargo}/bin "${sysrootDir}/bin" >/dev/null 2>&1 78 + ${lndir}/bin/lndir ${tools}/bin "${sysrootDir}/bin" >/dev/null 2>&1 56 79 57 - echo "$CACHE_DIR" 80 + echo "${environmentFingerprint}" > "${fingerprintFile}" 81 + echo "Sysroot created at ${sysrootDir}" 58 82 ''; 59 - 60 - createFakeSysroot = 61 - if withNonRustupSysroot then createFakeSysrootNonRustup else createFakeSysrootRustup; 62 83 63 84 rustcWrapper = writeShellScriptBin "rustc" '' 64 85 if [ "$1" = "--print" ] && [ "$2" = "sysroot" ]; then 65 - exec ${lib.getExe createFakeSysroot} 86 + echo ${sysrootDir} 66 87 else 67 - exec ${rustc}/bin/rustc "$@" 88 + exec ${rustup}/bin/rustc "$@" 68 89 fi 69 90 ''; 70 91 71 - rustcWithRRLib = runCommand "rustc-wrapper-${rustc.version or "unknown"}" { } '' 72 - mkdir -p $out/bin 73 - ln -s ${rustc}/bin/* $out/bin 74 - rm $out/bin/rustc 75 - ln -s ${rustcWrapper}/bin/rustc $out/bin/rustc 76 - ${lib.concatMapStrings (output: "ln -s ${rustc.${output}} \$${output}\n") ( 77 - lib.remove "out" rustc.outputs 78 - )} 92 + rustupWrapper = writeShellScriptBin "rustup" '' 93 + export RUSTUP_HOME="${rustupHome}" 94 + export PATH="${ideaDir}"/bin:$PATH 95 + if [ "$1" = "component" ] && [ "$2" = "list" ]; then 96 + shift 2 97 + exec ${./list-components.sh} ${sysrootDir} "$@" 98 + else 99 + exec -a "$0" ${rustup}/bin/rustup "$@" 100 + fi 79 101 ''; 80 102 81 - tools = buildEnv { 82 - name = (args.name or "rr") + "-tools"; 83 - paths = addToToolchain; 84 - }; 103 + createSysroot = if withNonRustupSysroot then createSysrootNonRustup else createSysrootRustup; 85 104 86 - cargoWrapper = writeShellScriptBin "cargo" '' 87 - export PATH="${rustc}/bin:${tools}/bin:$PATH" 88 - args=() 89 - for arg in "$@"; do 90 - if [[ "$arg" != +* ]]; then 91 - args+=("$arg") 92 - fi 93 - done 94 - exec ${cargo}/bin/cargo "''${args[@]}" 95 - ''; 105 + createEnvironment = writeShellScriptBin "create-environment" '' 106 + ${lib.getExe checkFingerprint} && exit 0 107 + 108 + mkdir -p .idea 109 + ${lib.getExe createSysroot} 96 110 97 - baseToolchain = buildEnv { 98 - name = (args.name or "rr") + "-base-toolchain"; 99 - paths = [ 100 - (lib.hiPrio cargoWrapper) 101 - rustcWithRRLib 102 - tools 103 - ]; 104 - }; 111 + mkdir -p ${ideaDir}/bin 105 112 106 - fakeRustup = writeShellScriptBin "rustup" '' 107 - export PATH="${baseToolchain}/bin:$PATH" 108 - exec ${lib.getExe nushell} ${./src/rustup.nu} $@ 109 - ''; 113 + ${lib.getExe lndir} ${rustup}/bin ${ideaDir}/bin && rm ${ideaDir}/bin/rustc ${ideaDir}/bin/rustup 114 + ${lib.getExe lndir} ${rustcWrapper}/bin ${ideaDir}/bin 115 + ${lib.getExe lndir} ${rustupWrapper}/bin ${ideaDir}/bin 110 116 111 - toolchain = buildEnv { 112 - name = (args.name or "rr") + "-toolchain"; 117 + mkdir -p "$RUSTUP_HOME/toolchains" 113 118 114 - paths = [ 115 - baseToolchain 116 - fakeRustup 117 - ]; 118 - }; 119 + ${rustup}/bin/rustup toolchain link ${toolchainName} "${sysrootDir}" 120 + ${rustup}/bin/rustup default ${toolchainName} 121 + ''; 119 122 in 120 123 mkShell ( 121 124 args 122 125 // { 123 - packages = (args.packages or [ ]) ++ [ toolchain ]; 126 + packages = (args.packages or [ ]) ++ [ rustup ]; 124 127 128 + env.RUSTUP_HOME = rustupHome; 125 129 shellHook = (args.shellHook or "") + '' 126 - mkdir -p .idea 127 - ln -snf ${toolchain} .idea/rust-toolchain 130 + ${lib.getExe createEnvironment} 128 131 ''; 129 132 } 130 133 )
+64
list-components.sh
··· 1 + #!/usr/bin/env bash 2 + 3 + INSTALLED_ONLY=false 4 + if [[ "$2" == "--installed" ]] || [[ "$1" == "--installed" ]]; then 5 + INSTALLED_ONLY=true 6 + if [[ "$1" == "--installed" ]]; then 7 + SYSROOT="$2" 8 + else 9 + SYSROOT="$1" 10 + fi 11 + else 12 + SYSROOT="$1" 13 + fi 14 + 15 + if [[ -z "$SYSROOT" ]] || [[ ! -d "$SYSROOT" ]]; then 16 + echo "Error: Invalid sysroot directory" >&2 17 + exit 1 18 + fi 19 + 20 + declare -A COMPONENTS 21 + COMPONENTS=( 22 + ["rustc"]="bin/rustc" 23 + ["cargo"]="bin/cargo" 24 + ["clippy"]="bin/clippy-driver" 25 + ["rustfmt"]="bin/rustfmt" 26 + ["rust-docs"]="share/doc/rust/html/index.html" 27 + ["rust-std"]="lib/rustlib" 28 + ["rust-analyzer"]="bin/rust-analyzer" 29 + ["llvm-tools"]="lib/rustlib/*/bin/llvm-*" 30 + ) 31 + 32 + declare -A INSTALLED 33 + for component in "${!COMPONENTS[@]}"; do 34 + path="${COMPONENTS[$component]}" 35 + if [[ "$path" == *"*"* ]]; then 36 + if compgen -G "$SYSROOT/$path" > /dev/null 2>&1; then 37 + INSTALLED[$component]=true 38 + else 39 + INSTALLED[$component]=false 40 + fi 41 + else 42 + if [[ -e "$SYSROOT/$path" ]]; then 43 + INSTALLED[$component]=true 44 + else 45 + INSTALLED[$component]=false 46 + fi 47 + fi 48 + done 49 + 50 + if $INSTALLED_ONLY; then 51 + for component in rustc cargo rust-std clippy rustfmt rust-docs rust-analyzer llvm-tools; do 52 + if [[ "${INSTALLED[$component]}" == "true" ]]; then 53 + echo "$component" 54 + fi 55 + done 56 + else 57 + for component in rustc cargo rust-std clippy rustfmt rust-docs rust-analyzer llvm-tools; do 58 + if [[ "${INSTALLED[$component]}" == "true" ]]; then 59 + echo "$component (installed)" 60 + else 61 + echo "$component" 62 + fi 63 + done 64 + fi
-159
src/rustup.nu
··· 1 - #!/usr/bin/env nu 2 - 3 - def get_target [] { 4 - rustc -vV | lines | where ($it | str starts-with "host:") | first | split row ":" | get 1 | str trim 5 - } 6 - 7 - def get_toolchain_name [] { 8 - $"stable-(get_target)" 9 - } 10 - 11 - def main [ 12 - --verbose (-v) 13 - --quiet (-q) 14 - --version (-V) 15 - --help (-h) 16 - ...args 17 - ] { 18 - if $version { 19 - print "rustup 1.28.2 (1970-01-01)" 20 - return 21 - } 22 - 23 - if $help or ($args | is-empty) { 24 - print "rustup 1.28.2 (1970-01-01)" 25 - print "" 26 - print "The Rust toolchain installer" 27 - print "" 28 - print "Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]" 29 - print "" 30 - print "Commands:" 31 - print " toolchain Install, uninstall, or list toolchains" 32 - print " default Set the default toolchain" 33 - print " show Show the active and installed toolchains or profiles" 34 - print " update Update Rust toolchains and rustup" 35 - print " check Check for updates to Rust toolchains and rustup" 36 - print " target Modify a toolchain's supported targets" 37 - print " component Modify a toolchain's installed components" 38 - print " override Modify toolchain overrides for directories" 39 - print " run Run a command with an environment configured for a given toolchain" 40 - print " which Display which binary will be run for a given command" 41 - print " doc Open the documentation for the current toolchain" 42 - print " man View the man page for a given command" 43 - print " self Modify the rustup installation" 44 - print " set Alter rustup settings" 45 - print " completions Generate tab-completion scripts for your shell" 46 - print " help Print this message or the help of the given subcommand(s)" 47 - print "" 48 - print "Arguments:" 49 - print " [+toolchain] Release channel (e.g. +stable) or custom toolchain to set override" 50 - print "" 51 - print "Options:" 52 - print " -v, --verbose Set log level to 'DEBUG' if 'RUSTUP_LOG' is unset" 53 - print " -q, --quiet Disable progress output, set log level to 'WARN' if 'RUSTUP_LOG' is unset" 54 - print " -h, --help Print help" 55 - print " -V, --version Print version" 56 - return 57 - } 58 - 59 - let command = ($args | first) 60 - let rest = ($args | skip 1) 61 - 62 - match $command { 63 - "show" => { 64 - if ($rest | is-empty) or (($rest | first) == "active-toolchain") { 65 - let toolchain = (get_toolchain_name) 66 - print $"($toolchain) \(default\)" 67 - } else { 68 - print $"installed toolchains" 69 - print "--------------------" 70 - print "" 71 - let toolchain = (get_toolchain_name) 72 - print $"($toolchain) \(default\)" 73 - } 74 - } 75 - "which" => { 76 - if ($rest | length) > 0 { 77 - let cmd = ($rest | first) 78 - try { 79 - which $cmd | get path.0 80 - } catch { 81 - print $"error: toolchain '(get_toolchain_name)' does not have binary '($cmd)'" 82 - } 83 - } 84 - } 85 - "run" => { 86 - if ($rest | length) > 1 { 87 - let rest = ($rest | skip 1) 88 - let cmd = ($rest | first) 89 - let cmd_args = ($rest | skip 1) 90 - ^$cmd ...$cmd_args 91 - } 92 - } 93 - "default" => { 94 - if ($rest | is-empty) { 95 - let toolchain = (get_toolchain_name) 96 - print $"($toolchain) \(default\)" 97 - } else { 98 - print $"info: default toolchain set to '($rest | first)'" 99 - } 100 - } 101 - "toolchain" => { 102 - if ($rest | is-empty) or (($rest | first) == "list") { 103 - let toolchain = (get_toolchain_name) 104 - print $"($toolchain) \(default\)" 105 - } 106 - } 107 - "target" => { 108 - if ($rest | length) > 0 { 109 - let subcmd = ($rest | first) 110 - if $subcmd == "list" { 111 - if ($rest | length) > 1 and (($rest | get 1) == "--installed") { 112 - print (get_target) 113 - } else { 114 - print (get_target) 115 - } 116 - } 117 - } 118 - } 119 - "component" => { 120 - if ($rest | length) > 0 { 121 - let subcmd = ($rest | first) 122 - if $subcmd == "list" { 123 - let has_rustc = (which rustc | is-not-empty) 124 - let has_cargo = (which cargo | is-not-empty) 125 - let has_rustfmt = (which rustfmt | is-not-empty) 126 - let has_rust_analyzer = (which rust-analyzer | is-not-empty) 127 - let has_clippy = (which clippy-driver | is-not-empty) 128 - let has_miri = (which miri | is-not-empty) 129 - 130 - if ($rest | length) > 1 and (($rest | get 1) == "--installed") { 131 - print "rust-std" 132 - if $has_rustc { print "rustc" } 133 - if $has_cargo { print "cargo" } 134 - if $has_rustfmt { print "rustfmt" } 135 - if $has_rust_analyzer { print "rust-analyzer" } 136 - if $has_clippy { print "clippy" } 137 - if $has_miri { print "miri" } 138 - } else { 139 - print "rust-std (installed)" 140 - if $has_rustc { print "rustc (installed)" } else { print "rustc" } 141 - if $has_cargo { print "cargo (installed)" } else { print "cargo" } 142 - if $has_rustfmt { print "rustfmt (installed)" } else { print "rustfmt" } 143 - print "rust-docs" 144 - if $has_rust_analyzer { print "rust-analyzer (installed)" } else { print "rust-analyzer" } 145 - if $has_clippy { print "clippy (installed)" } else { print "clippy" } 146 - if $has_miri { print "miri (installed)" } else { print "miri" } 147 - print "rust-src (installed)" 148 - print "rust-mingw" 149 - print "llvm-tools" 150 - print "rustc-dev" 151 - } 152 - } 153 - } 154 - } 155 - _ => { 156 - print $"error: unknown command: '($command)'" 157 - } 158 - } 159 - }