Repository: pre-commit/pre-commit

Issue:
Executable `rustup` not found
### search you tried in the issue tracker

Executable `rustup` not found

### describe your issue

Since pre-commit 3.2.0 our GitHub workflow is broken. 

This ins one of the last working runs:
https://github.com/mixxxdj/mixxx/actions/runs/4448394360/jobs/7811151308
Downloading pre_commit-3.1.1-py2.py3-none-any.whl (202 kB)

This is a failing one:
https://github.com/mixxxdj/mixxx/actions/runs/4451827087/jobs/7824682752
Downloading pre_commit-3.2.0-py2.py3-none-any.whl (202 kB)



### pre-commit --version

pre-commit 3.2.0

### .pre-commit-config.yaml

```yaml
# This is the configuration file for the pre-commit framework, a simple way
# to manage, install and run git hooks to catch common problems early on.
# See https://pre-commit.com/ for details.
#
# If you have Python >= 3.7 and python-pip installed, just run:
#
#     $ pip install --user pre-commit
#     $ git clone https://github.com/your-fork-of/mixxx.git
#     $ cd mixxx
#     $ pre-commit install
#     $ pre-commit install -t pre-push
#
# It will now run relevant hooks automatically on every `git commit` or
# `git push` in the mixxx git repository.
#
# If you have a problems with a particular hook, you can use the `$SKIP`
# environment variable to disable hooks:
#
#     $ SKIP=clang-format,end-of-file-fixer git commit
#
# This can also be used to separate logic changes and autoformatting into
# two subsequent commits.
#
# Using the `$SKIP` var is preferable to using `git commit --no-verify`
# because it won't prevent catching other, unrelated issues.

# _anlz.h/_pdb.h: Header files generated by Kaitai Struct
exclude: ^(lib/|src/test/.*data/).*|res/translations/.*\.ts|src/.*_(anlz|pdb)\.h$
minimum_pre_commit_version: 2.21.0
default_language_version:
  python: python3
  rust: 1.64.0
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.3.0
    hooks:
      - id: fix-byte-order-marker
        exclude: ^.*(\.cbproj|\.groupproj|\.props|\.sln|\.vcxproj|\.vcxproj.filters)$
      - id: check-case-conflict
      - id: check-json
      - id: check-merge-conflict
      - id: check-xml
      - id: check-yaml
        exclude: ^\.clang-format$
      - id: end-of-file-fixer
      - id: mixed-line-ending
      - id: trailing-whitespace
        exclude: \.(c|cc|cxx|cpp|frag|glsl|h|hpp|hxx|ih|ispc|ipp|java|js|m|mm|proto|vert)$
      - id: no-commit-to-branch
        # protect main and any branch that has a semver-like name
        args: [-b, main, -p, '^\d+\.\d+(?:\.\d+)?$']
  - repo: https://github.com/codespell-project/codespell
    rev: v2.2.2
    hooks:
      - id: codespell
        args:
          [
            --exclude-file,
            .codespellignorelines,
            --ignore-words,
            .codespellignore,
            --ignore-regex,
            "\\W(?:m_p*(?=[A-Z])|m_(?=\\w)|pp*(?=[A-Z])|k(?=[A-Z])|s_(?=\\w))",
          ]
        exclude: ^(packaging/wix/LICENSE.rtf|src/dialog/dlgabout\.cpp|.*\.(?:pot?|ts|wxl|svg))$
  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.25.0
    hooks:
      - id: eslint
        args: [--fix, --report-unused-disable-directives]
        files: \.m?js$
        types: [file]
        stages:
          - commit
          - manual
        additional_dependencies:
          - eslint@^v8.6.0
          - eslint-plugin-jsdoc@^v37.5.0
  - repo: local
    hooks:
      - id: clang-format
        name: clang-format
        description: "Run clang-format in two passes (reformat, then break long lines)"
        entry: python tools/clang_format.py
        require_serial: true
        stages:
          - commit
          - manual
        language: python
        additional_dependencies:
          - clang-format==14.0.6
        files: \.(c|cc|cxx|cpp|frag|glsl|h|hpp|hxx|ih|ispc|ipp|java|m|mm|proto|vert)$
  - repo: https://github.com/psf/black
    rev: 22.10.0
    hooks:
      - id: black
        files: ^tools/.*$
  - repo: https://github.com/pycqa/flake8
    rev: "5.0.4"
    hooks:
      - id: flake8
        files: ^tools/.*$
        types: [text, python]
  - repo: https://github.com/shellcheck-py/shellcheck-py
    rev: v0.8.0.4
    hooks:
      - id: shellcheck
  - repo: https://github.com/DavidAnson/markdownlint-cli2
    rev: v0.5.1
    hooks:
      - id: markdownlint-cli2
  - repo: https://github.com/python-jsonschema/check-jsonschema
    rev: 0.18.3
    hooks:
      - id: check-github-workflows
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v2.7.1
    hooks:
      - id: prettier
        types: [yaml]
  - repo: https://github.com/qarmin/qml_formatter.git
    rev: 0.2.0
    hooks:
      - id: qml_formatter
  - repo: local
    hooks:
      - id: qsscheck
        name: qsscheck
        description: Run qsscheck to detect broken QSS.
        entry: python tools/qsscheck.py
        args: [.]
        pass_filenames: false
        language: python
        additional_dependencies:
          - tinycss==0.4
        types: [text]
        files: ^.*\.qss$
        stages:
          - commit
          - manual
      - id: changelog
        name: changelog
        description: Add missing links to changelog.
        entry: python tools/changelog.py
        language: python
        types: [text]
        files: ^CHANGELOG.md$
      - id: qmllint
        name: qmllint
        entry: qmllint
        pass_filenames: true
        require_serial: true
        language: system
        types: [text]
        files: ^.*\.qml$
      - id: metainfo
        name: metainfo
        description: Update AppStream metainfo releases from CHANGELOG.md.
        entry: python tools/update_metainfo.py
        pass_filenames: false
        language: python
        additional_dependencies:
          - beautifulsoup4==4.11.1
          - lxml==4.9.1
          - Markdown==3.4.1
        types: [text]
        files: ^(CHANGELOG\.md|res/linux/org\.mixxx\.Mixxx\.metainfo.xml)$
```


### ~/.cache/pre-commit/pre-commit.log (if present)

2023-03-18T11:16:24.8724175Z [INFO][m Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
2023-03-18T11:16:25.3378859Z [INFO][m Initializing environment for https://github.com/codespell-project/codespell.
2023-03-18T11:16:25.8998370Z [INFO][m Initializing environment for https://github.com/pre-commit/mirrors-eslint.
2023-03-18T11:16:26.3373046Z [INFO][m Initializing environment for https://github.com/pre-commit/mirrors-eslint:eslint@^v8.6.0,eslint-plugin-jsdoc@^v37.5.0.
2023-03-18T11:16:26.7769485Z [INFO][m Initializing environment for local:clang-format==14.0.6.
2023-03-18T11:16:26.7823306Z [INFO][m Initializing environment for https://github.com/psf/black.
2023-03-18T11:16:27.4353970Z [INFO][m Initializing environment for https://github.com/pycqa/flake8.
2023-03-18T11:16:27.9719090Z [INFO][m Initializing environment for https://github.com/shellcheck-py/shellcheck-py.
2023-03-18T11:16:28.4303322Z [INFO][m Initializing environment for https://github.com/DavidAnson/markdownlint-cli2.
2023-03-18T11:16:28.9106462Z [INFO][m Initializing environment for https://github.com/python-jsonschema/check-jsonschema.
2023-03-18T11:16:29.5219475Z [INFO][m Initializing environment for https://github.com/pre-commit/mirrors-prettier.
2023-03-18T11:16:29.9463012Z [INFO][m Initializing environment for https://github.com/pre-commit/mirrors-prettier:prettier@2.7.1.
2023-03-18T11:16:30.3722936Z [INFO][m Initializing environment for https://github.com/qarmin/qml_formatter.git.
2023-03-18T11:16:30.7800010Z [INFO][m Initializing environment for local:tinycss==0.4.
2023-03-18T11:16:30.7845724Z [INFO][m Initializing environment for local.
2023-03-18T11:16:30.7890533Z [INFO][m Initializing environment for local:beautifulsoup4==4.11.1,lxml==4.9.1,Markdown==3.4.1.
2023-03-18T11:16:30.7935963Z [INFO][m Installing environment for https://github.com/pre-commit/pre-commit-hooks.
2023-03-18T11:16:30.7936430Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:16:30.7937142Z [INFO][m This may take a few minutes...
2023-03-18T11:16:36.1315607Z [INFO][m Installing environment for https://github.com/codespell-project/codespell.
2023-03-18T11:16:36.1316105Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:16:36.1316598Z [INFO][m This may take a few minutes...
2023-03-18T11:16:41.0677859Z [INFO][m Installing environment for https://github.com/pre-commit/mirrors-eslint.
2023-03-18T11:16:41.0678364Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:16:41.0678749Z [INFO][m This may take a few minutes...
2023-03-18T11:16:52.1967027Z [INFO][m Installing environment for local.
2023-03-18T11:16:52.1967972Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:16:52.1968731Z [INFO][m This may take a few minutes...
2023-03-18T11:16:54.9343036Z [INFO][m Installing environment for https://github.com/psf/black.
2023-03-18T11:16:54.9343514Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:16:54.9343897Z [INFO][m This may take a few minutes...
2023-03-18T11:16:59.3853467Z [INFO][m Installing environment for https://github.com/pycqa/flake8.
2023-03-18T11:16:59.3853994Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:16:59.3854348Z [INFO][m This may take a few minutes...
2023-03-18T11:17:01.9111743Z [INFO][m Installing environment for https://github.com/shellcheck-py/shellcheck-py.
2023-03-18T11:17:01.9112317Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:17:01.9112658Z [INFO][m This may take a few minutes...
2023-03-18T11:17:04.9449677Z [INFO][m Installing environment for https://github.com/DavidAnson/markdownlint-cli2.
2023-03-18T11:17:04.9450176Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:17:04.9450535Z [INFO][m This may take a few minutes...
2023-03-18T11:17:25.7010838Z [INFO][m Installing environment for https://github.com/python-jsonschema/check-jsonschema.
2023-03-18T11:17:25.7011350Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:17:25.7011717Z [INFO][m This may take a few minutes...
2023-03-18T11:17:29.8214983Z [INFO][m Installing environment for https://github.com/pre-commit/mirrors-prettier.
2023-03-18T11:17:29.8215477Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:17:29.8215817Z [INFO][m This may take a few minutes...
2023-03-18T11:17:36.7285087Z [INFO][m Installing environment for https://github.com/qarmin/qml_formatter.git.
2023-03-18T11:17:36.7285587Z [INFO][m Once installed this environment will be reused.
2023-03-18T11:17:36.7285924Z [INFO][m This may take a few minutes...
2023-03-18T11:17:37.1457698Z An unexpected error has occurred: CalledProcessError: command: ('rustup', 'toolchain', 'install', '--no-self-update', '1.64.0')
2023-03-18T11:17:37.1458511Z return code: 1
2023-03-18T11:17:37.1458692Z stdout:
2023-03-18T11:17:37.1458924Z     Executable `rustup` not found
2023-03-18T11:17:37.1459148Z stderr: (none)



Discussion:
can you get the copy of the pre-commit log?  that's the more useful log file
### version information

```
pre-commit version: 3.2.0
git --version: git version 2.37.3
sys.version:
    3.10.7 (main, Sep  6 2022, 21:22:27) [GCC 12.2.0]
sys.executable: /usr/sbin/python
os.name: posix
sys.platform: linux
```

### error information

```
An unexpected error has occurred: CalledProcessError: command: ('rustup', 'toolchain', 'install', '--no-self-update', '1.64.0')
return code: 1
stdout:
    Executable `rustup` not found
stderr: (none)
```

```
Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/pre_commit/error_handler.py", line 73, in error_handler
    yield
  File "/usr/lib/python3.10/site-packages/pre_commit/main.py", line 409, in main
    return run(args.config, store, args)
  File "/usr/lib/python3.10/site-packages/pre_commit/commands/run.py", line 442, in run
    install_hook_envs(to_install, store)
  File "/usr/lib/python3.10/site-packages/pre_commit/repository.py", line 248, in install_hook_envs
    _hook_install(hook)
  File "/usr/lib/python3.10/site-packages/pre_commit/repository.py", line 95, in _hook_install
    lang.install_environment(
  File "/usr/lib/python3.10/site-packages/pre_commit/languages/rust.py", line 148, in install_environment
    install_rust_with_toolchain(_rust_toolchain(version))
  File "/usr/lib/python3.10/site-packages/pre_commit/languages/rust.py", line 107, in install_rust_with_toolchain
    cmd_output_b(
  File "/usr/lib/python3.10/site-packages/pre_commit/util.py", line 110, in cmd_output_b
    raise CalledProcessError(returncode, cmd, stdout_b, stderr_b)
pre_commit.util.CalledProcessError: command: ('rustup', 'toolchain', 'install', '--no-self-update', '1.64.0')
return code: 1
stdout:
    Executable `rustup` not found
stderr: (none)
```

Resolving patch:
diff --git a/pre_commit/languages/rust.py b/pre_commit/languages/rust.py
--- a/pre_commit/languages/rust.py
+++ b/pre_commit/languages/rust.py
@@ -80,9 +80,9 @@ def _add_dependencies(
     lang_base.setup_cmd(prefix, ('cargo', 'add', *crates))
 
 
-def install_rust_with_toolchain(toolchain: str) -> None:
+def install_rust_with_toolchain(toolchain: str, envdir: str) -> None:
     with tempfile.TemporaryDirectory() as rustup_dir:
-        with envcontext((('RUSTUP_HOME', rustup_dir),)):
+        with envcontext((('CARGO_HOME', envdir), ('RUSTUP_HOME', rustup_dir))):
             # acquire `rustup` if not present
             if parse_shebang.find_executable('rustup') is None:
                 # We did not detect rustup and need to download it first.
@@ -145,7 +145,7 @@ def install_environment(
         ctx.enter_context(in_env(prefix, version))
 
         if version != 'system':
-            install_rust_with_toolchain(_rust_toolchain(version))
+            install_rust_with_toolchain(_rust_toolchain(version), envdir)
 
             tmpdir = ctx.enter_context(tempfile.TemporaryDirectory())
             ctx.enter_context(envcontext((('RUSTUP_HOME', tmpdir),)))


Test patch: