Skip to content

Commit

Permalink
Merge pull request #13094 from conda/23.7.x-resolve-conflict
Browse files Browse the repository at this point in the history
Merge `23.7.x` branch back into `main`
  • Loading branch information
kenodegard committed Sep 12, 2023
2 parents 4a76fea + bf39e8d commit 1e5d737
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 10 deletions.
13 changes: 10 additions & 3 deletions .authors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@
first_commit: 2016-12-11 16:14:03
- name: Ken Odegard
email: kodegard@anaconda.com
num_commits: 558
num_commits: 566
first_commit: 2016-09-27 18:04:21
github: kenodegard
aliases:
Expand Down Expand Up @@ -2003,7 +2003,7 @@
- name: Daniel Holth
email: dholth@anaconda.com
github: dholth
num_commits: 68
num_commits: 70
first_commit: 2021-11-18 08:57:14
- name: John Flavin
email: flavinj@gmail.com
Expand Down Expand Up @@ -2083,7 +2083,7 @@
github: beeankha
alternate_emails:
- beeankha@gmail.com
num_commits: 25
num_commits: 29
first_commit: 2022-05-12 13:39:02
- name: Kian-Meng Ang
email: kianmeng.ang@gmail.com
Expand Down Expand Up @@ -2364,3 +2364,10 @@
github: marcoesters
num_commits: 1
first_commit: 2023-07-11 05:47:23
- name: Peter Talley
email: peterctalley@gmail.com
github: otaithleigh
aliases:
- P. Talley
num_commits: 1
first_commit: 2023-08-25 20:43:39
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ Paul Yim <pseudoyim@users.noreply.github.com>
Pavel Zwerschke <pavelzw@gmail.com>
Pete Bachant <petebachant@gmail.com>
Peter Cable <petercable@gmail.com>
Peter Talley <peterctalley@gmail.com> P. Talley <peterctalley@gmail.com>
Peter Williams <peter@newton.cx>
Phil Elson <pelson.pub@gmail.com>
Philip Thomas <pthomas.v3@gmail.com> psthomas <pthomas.v3@gmail.com>
Expand Down
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ Authors are sorted alphabetically.
* Pavel Zwerschke
* Pete Bachant
* Peter Cable
* Peter Talley
* Peter Williams
* Phil Elson
* Philip Thomas
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
[//]: # (current developments)

## 23.7.4 (2023-09-12)

### Enhancements

* Use `os.scandir()` to find conda subcommands without `stat()` overhead. (#13033, #13067)

### Bug fixes

* Fix S3 bucket name. (#12989)
* Fix performance regression of basic commands (e.g., `conda info`) on WSL. (#13035)
* Catch `PermissionError` raised by `conda.cli.find_commands.find_commands` when user's `$PATH` contains restricted paths. (#13062, #13089)
* Fix sorting error for `conda config --show-sources --json`. (#13076)

### Contributors

* @beeankha
* @dholth
* @kenodegard
* @otaithleigh made their first contribution in https://github.com/conda/conda/pull/13035


## 23.7.3 (2023-08-21)

### Bug fixes
Expand Down
18 changes: 11 additions & 7 deletions conda/cli/find_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys
import sysconfig
from functools import lru_cache
from os.path import basename, expanduser, isdir, isfile, join
from os.path import basename, expanduser, isfile, join

from ..common.compat import on_win

Expand Down Expand Up @@ -61,16 +61,20 @@ def find_commands(include_others=True):
dir_paths.extend(os.environ.get("PATH", "").split(os.pathsep))

if on_win:
pat = re.compile(r"conda-([\w\-]+)\.(exe|bat)$")
pat = re.compile(r"conda-([\w\-]+)(\.(exe|bat))?$")
else:
pat = re.compile(r"conda-([\w\-]+)$")

res = set()
for dir_path in dir_paths:
if not isdir(dir_path):
try:
for entry in os.scandir(dir_path):
m = pat.match(entry.name)
if m and entry.is_file():
res.add(m.group(1))
except (FileNotFoundError, NotADirectoryError, PermissionError):
# FileNotFoundError: path doesn't exist
# NotADirectoryError: path is not a directory
# PermissionError: user doesn't have read access
continue
for fn in os.listdir(dir_path):
m = pat.match(fn)
if m and isfile(join(dir_path, fn)):
res.add(m.group(1))
return tuple(sorted(res))
80 changes: 80 additions & 0 deletions tests/cli/test_find_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright (C) 2012 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause
import os
from pathlib import Path

import pytest
from pytest import MonkeyPatch

from conda.cli.find_commands import find_commands, find_executable
from conda.common.compat import on_win


@pytest.fixture
def faux_path(tmp_path: Path, monkeypatch: MonkeyPatch) -> Path:
if not on_win:
# make a read-only location, none of these should show up in the tests
permission = tmp_path / "permission"
permission.mkdir(mode=0o333, exist_ok=True)
(permission / "conda-permission").touch()
(permission / "conda-permission.bat").touch()
(permission / "conda-permission.exe").touch()
monkeypatch.setenv("PATH", str(permission), prepend=os.pathsep)

# missing directory
missing_dir = tmp_path / "missing-directory"
monkeypatch.setenv("PATH", str(missing_dir), prepend=os.pathsep)

# not directory
not_dir = tmp_path / "not-directory"
not_dir.touch()
monkeypatch.setenv("PATH", str(not_dir), prepend=os.pathsep)

# bad executables
bad = tmp_path / "bad"
bad.mkdir(exist_ok=True)
(bad / "non-conda-bad").touch()
(bad / "non-conda-bad.bat").touch()
(bad / "non-conda-bad.exe").touch()
monkeypatch.setenv("PATH", str(bad), prepend=os.pathsep)

# good executables
bin_ = tmp_path / "bin"
bin_.mkdir(exist_ok=True)
(bin_ / "conda-bin").touch()
monkeypatch.setenv("PATH", str(bin_), prepend=os.pathsep)

bat = tmp_path / "bat"
bat.mkdir(exist_ok=True)
(bat / "conda-bat.bat").touch()
monkeypatch.setenv("PATH", str(bat), prepend=os.pathsep)

exe = tmp_path / "exe"
exe.mkdir(exist_ok=True)
(exe / "conda-exe.exe").touch()
monkeypatch.setenv("PATH", str(exe), prepend=os.pathsep)

yield tmp_path

if not on_win:
# undo read-only for clean removal
permission.chmod(permission.stat().st_mode | 0o444)


def test_find_executable(faux_path: Path):
assert (faux_path / "bin" / "conda-bin").samefile(find_executable("conda-bin"))
if on_win:
assert (faux_path / "bat" / "conda-bat.bat").samefile(
find_executable("conda-bat")
)
assert (faux_path / "exe" / "conda-exe.exe").samefile(
find_executable("conda-exe")
)


def test_find_commands(faux_path: Path):
find_commands.cache_clear()
if on_win:
assert {"bin", "bat", "exe"}.issubset(find_commands())
else:
assert {"bin"}.issubset(find_commands())

0 comments on commit 1e5d737

Please sign in to comment.