From: Zac Medico <zmedico@gentoo.org>
To: gentoo-portage-dev@lists.gentoo.org
Cc: Zac Medico <zmedico@gentoo.org>
Subject: [gentoo-portage-dev] [PATCH] emerge: add --search-fuzzy and --search-fuzzy-cutoff options (bug 65566)
Date: Sun, 3 Apr 2016 22:03:02 -0700 [thread overview]
Message-ID: <1459746182-13420-1-git-send-email-zmedico@gentoo.org> (raw)
Add --search-fuzzy option, with adjustable similarity ratio cutoff that
defaults to 0.8 (80% similarity).
X-Gentoo-bug: 65566
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=65566
---
man/emerge.1 | 13 ++++++++++++-
pym/_emerge/actions.py | 6 ++++--
pym/_emerge/main.py | 32 +++++++++++++++++++++++++++++++-
pym/_emerge/search.py | 25 +++++++++++++++++++++++--
4 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/man/emerge.1 b/man/emerge.1
index bfa2f73..2727ccb 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -1,4 +1,4 @@
-.TH "EMERGE" "1" "Feb 2016" "Portage VERSION" "Portage"
+.TH "EMERGE" "1" "Apr 2016" "Portage VERSION" "Portage"
.SH "NAME"
emerge \- Command\-line interface to the Portage system
.SH "SYNOPSIS"
@@ -854,6 +854,17 @@ If ebuilds using EAPIs which \fIdo not\fR support \fBHDEPEND\fR are built in
the same \fBemerge\fR run as those using EAPIs which \fIdo\fR support
\fBHDEPEND\fR, this option affects only the former.
.TP
+.BR "\-\-search\-fuzzy [ y | n ]"
+Enable or disable fuzzy search for search actions.
+.TP
+.BR "\-\-search\-fuzzy\-cutoff CUTOFF"
+Set similarity ratio cutoff (a floating-point number between 0 and 1).
+Results with similarity ratios lower than the cutoff are discarded.
+This option has no effect unless the \fB\-\-search\-fuzzy\fR option
+is enabled.
+.br
+Defaults to 0.8 (80% similarity).
+.TP
.BR "\-\-search\-index < y | n >"
Enable or disable indexed search for search actions. This option is
enabled by default. The search index needs to be regenerated by
diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py
index 59626ad..caae79a 100644
--- a/pym/_emerge/actions.py
+++ b/pym/_emerge/actions.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2015 Gentoo Foundation
+# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import division, print_function, unicode_literals
@@ -1955,7 +1955,9 @@ def action_search(root_config, myopts, myfiles, spinner):
spinner, "--searchdesc" in myopts,
"--quiet" not in myopts, "--usepkg" in myopts,
"--usepkgonly" in myopts,
- search_index = myopts.get("--search-index", "y") != "n")
+ search_index=myopts.get("--search-index", "y") != "n",
+ fuzzy=myopts.get("--search-fuzzy", False),
+ fuzzy_cutoff=myopts.get("--search-fuzzy-cutoff"))
for mysearch in myfiles:
try:
searchinstance.execute(mysearch)
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index 5dbafee..06c385e 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2015 Gentoo Foundation
+# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -156,6 +156,7 @@ def insert_optional_args(args):
'--rebuild-if-unbuilt' : y_or_n,
'--rebuilt-binaries' : y_or_n,
'--root-deps' : ('rdeps',),
+ '--search-fuzzy' : y_or_n,
'--select' : y_or_n,
'--selective' : y_or_n,
"--use-ebuild-visibility": y_or_n,
@@ -647,6 +648,16 @@ def parse_opts(tmpcmdline, silent=False):
"choices" :("True", "rdeps")
},
+ "--search-fuzzy": {
+ "help": "Enable or disable fuzzy search",
+ "choices": true_y_or_n
+ },
+
+ "--search-fuzzy-cutoff": {
+ "help": "Set similarity ratio cutoff (a floating-point number between 0 and 1)",
+ "action": "store"
+ },
+
"--search-index": {
"help": "Enable or disable indexed search (enabled by default)",
"choices": y_or_n
@@ -908,6 +919,11 @@ def parse_opts(tmpcmdline, silent=False):
if myoptions.root_deps in true_y:
myoptions.root_deps = True
+ if myoptions.search_fuzzy in true_y:
+ myoptions.search_fuzzy = True
+ else:
+ myoptions.search_fuzzy = None
+
if myoptions.select in true_y:
myoptions.select = True
myoptions.oneshot = False
@@ -1000,6 +1016,20 @@ def parse_opts(tmpcmdline, silent=False):
myoptions.rebuilt_binaries_timestamp = rebuilt_binaries_timestamp
+ if myoptions.search_fuzzy_cutoff:
+ try:
+ fuzzy_cutoff = float(myoptions.search_fuzzy_cutoff)
+ except ValueError:
+ fuzzy_cutoff = 0.0
+
+ if fuzzy_cutoff <= 0.0:
+ fuzzy_cutoff = None
+ if not silent:
+ parser.error("Invalid --search-fuzzy-cutoff parameter: '%s'\n" % \
+ (myoptions.search_fuzzy_cutoff,))
+
+ myoptions.search_fuzzy_cutoff = fuzzy_cutoff
+
if myoptions.use_ebuild_visibility in true_y:
myoptions.use_ebuild_visibility = True
else:
diff --git a/pym/_emerge/search.py b/pym/_emerge/search.py
index 32d326e..3210854 100644
--- a/pym/_emerge/search.py
+++ b/pym/_emerge/search.py
@@ -1,8 +1,9 @@
-# Copyright 1999-2015 Gentoo Foundation
+# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import unicode_literals
+import difflib
import re
import portage
from portage import os
@@ -28,7 +29,8 @@ class search(object):
# public interface
#
def __init__(self, root_config, spinner, searchdesc,
- verbose, usepkg, usepkgonly, search_index=True):
+ verbose, usepkg, usepkgonly, search_index=True,
+ fuzzy=False, fuzzy_cutoff=None):
"""Searches the available and installed packages for the supplied search key.
The list of available and installed packages is created at object instantiation.
This makes successive searches faster."""
@@ -42,6 +44,8 @@ class search(object):
self.spinner = None
self.root_config = root_config
self.setconfig = root_config.setconfig
+ self.fuzzy = fuzzy
+ self.fuzzy_cutoff = 0.8 if fuzzy_cutoff is None else fuzzy_cutoff
self.matches = {"pkg" : []}
self.mlen = 0
@@ -248,11 +252,26 @@ class search(object):
if self.searchkey.startswith('@'):
match_category = 1
self.searchkey = self.searchkey[1:]
+ fuzzy = False
if regexsearch:
self.searchre=re.compile(self.searchkey,re.I)
else:
self.searchre=re.compile(re.escape(self.searchkey), re.I)
+ # Fuzzy search does not support regular expressions, therefore
+ # it is disabled for regular expression searches.
+ if self.fuzzy:
+ fuzzy = True
+ cutoff = self.fuzzy_cutoff
+ seq_match = difflib.SequenceMatcher()
+ seq_match.set_seq2(self.searchkey.lower())
+
+ def fuzzy_search(match_string):
+ seq_match.set_seq1(match_string.lower())
+ return (seq_match.real_quick_ratio() >= cutoff and
+ seq_match.quick_ratio() >= cutoff and
+ seq_match.ratio() >= cutoff)
+
for package in self._cp_all():
self._spinner_update()
@@ -280,6 +299,8 @@ class search(object):
continue
yield ("desc", package)
+ elif fuzzy and fuzzy_search(match_string):
+ yield ("pkg", package)
self.sdict = self.setconfig.getSets()
for setname in self.sdict:
--
2.7.4
next reply other threads:[~2016-04-04 5:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-04 5:03 Zac Medico [this message]
2016-04-04 8:39 ` [gentoo-portage-dev] [PATCH] emerge: add --search-fuzzy and --search-fuzzy-cutoff options (bug 65566) Alexander Berntsen
2016-04-08 6:21 ` Zac Medico
2016-04-08 11:33 ` Alexander Berntsen
2016-07-25 2:58 ` Zac Medico
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1459746182-13420-1-git-send-email-zmedico@gentoo.org \
--to=zmedico@gentoo.org \
--cc=gentoo-portage-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox