From be5f09736df5a8d897a8b2271398dfceb921c427 Mon Sep 17 00:00:00 2001 From: Anthony Scopatz Date: Fri, 28 Aug 2020 14:55:36 -0500 Subject: [PATCH] exact find --- conda_suggest/find.py | 28 +++++++++++++++++++++++----- conda_suggest/generate.py | 2 +- tests/test_find.py | 19 ++++++++++++++++--- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/conda_suggest/find.py b/conda_suggest/find.py index dade281..704257a 100644 --- a/conda_suggest/find.py +++ b/conda_suggest/find.py @@ -1,11 +1,19 @@ """Finds possible packages to install for executables.""" import os +import sys import glob import bisect import itertools MAPFILES = {} +PATH_SEP = ";" if os.name == "nt" else ":" +DEFAULT_CONDA_SUGGEST_PATH = os.environ.get("CONDA_SUGGEST_PATH", + PATH_SEP.join([ + os.path.join(os.path.expanduser("~"), ".local", "share", "conda-suggest"), + os.path.join(sys.exec_prefix, "share", "conda-suggest") + ]) +) class Mapfile: @@ -30,7 +38,7 @@ def __init__(self, filename): def exact_find(self, exe): """Finds the set of packages for an executable""" # a space is less than all other real characters - left = bisect_left((exe, " "), self.entries) + left = bisect.bisect_left(self.entries, (exe, " ")) if left == len(self.entries) or self.entries[left][0] != exe: # Executable not found if self.subdir.startswith("win") and not exe.endswith(".exe") and not exe.endswith(".bat"): @@ -39,10 +47,20 @@ def exact_find(self, exe): else: return set() # a tilde is greater than other real characters - right = bisect_right((exe, "~"), self.entries, lo=left) + right = bisect.bisect_right(self.entries, (exe, "~"), lo=left) return self.entries[left:right] +def get_mapfilenames(conda_suggest_path=None): + """Get's the mapfilenames on the system.""" + if conda_suggest_path is None: + conda_suggest_path = DEFAULT_CONDA_SUGGEST_PATH + mapfilenames = [] + for d in conda_suggest_path.split(PATH_SEP): + mapfilenames.extend(glob.iglob(os.path.join(d, "*.map"))) + return mapfilenames + + def get_mapfile(filename): """Gets a mapfile from the cache or makes a new one""" global MAPFILES @@ -58,10 +76,10 @@ def exact_find_in_mapfile(exe, filename): return {(mapfile.channel, mapfile.subdir, e, p) for e, p in mapfile.exact_find(exe)} -def exact_find(exe): +def exact_find(exe, conda_suggest_path=None): """Finds the execuable names""" - filenames = glob.glob("*.map") + filenames = get_mapfilenames(conda_suggest_path=conda_suggest_path) finds = set() - for filename in filename: + for filename in filenames: finds |= exact_find_in_mapfile(exe, filename) return finds diff --git a/conda_suggest/generate.py b/conda_suggest/generate.py index c37f5c1..681dd4e 100644 --- a/conda_suggest/generate.py +++ b/conda_suggest/generate.py @@ -13,7 +13,7 @@ "noarch", "linux-64", "osx-64", - "osx-arm64", + #"osx-arm64", "win-64", "linux-ppc64le", "linux-aarch64", diff --git a/tests/test_find.py b/tests/test_find.py index f72b4dc..5725ad8 100644 --- a/tests/test_find.py +++ b/tests/test_find.py @@ -1,6 +1,8 @@ """Tests the finding capabilites""" import pytest +from conda_suggest.find import MAPFILES, exact_find + LINUX_MAPFILE = """-pkg-config:pkg-config .appmode-post-link.sh:appmode @@ -22,6 +24,17 @@ zzxordir:zziplib """ - -def test_find_exact_linux(tmpdir): - pass \ No newline at end of file +@pytest.mark.parametrize("exe,exp", [ + ("-pkg-config", {"pkg-config",}), + ("zzxordir", {"zziplib",}), + ("gcc", {"c-compiler", "fortran-compiler"}), + ("not-a-command", set()), +]) +def test_find_exact_linux(exe, exp, tmpdir): + MAPFILES.clear() + p = tmpdir.join("test.linux-64.map") + p.write(LINUX_MAPFILE) + obs = exact_find(exe, conda_suggest_path=str(tmpdir)) + obs_pkgs = {pkg for _, _, _, pkg in obs} + assert exp == obs_pkgs + MAPFILES.clear()