diff options
author | Ludovic Courtès <ludo@gnu.org> | 2017-09-13 15:07:17 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2017-09-16 17:47:45 +0200 |
commit | c7ae219e399804a8eb33f176e532a79b389ee1f1 (patch) | |
tree | 0ad5ed041fcc2c29610ce55103beaa65f5adf1a0 | |
parent | dab666cd8d91bf2c4aacc920e3ea2ec01221123f (diff) | |
download | guix-c7ae219e399804a8eb33f176e532a79b389ee1f1.tar.gz |
ui: Generalize relevance computation.
* guix/ui.scm (relevance, package-relevance): New procedures. (%package-metrics): New variable. * guix/scripts/package.scm (find-packages-by-description)[score] [package-score]: Remove. Use 'package-relevance' instead.
-rw-r--r-- | guix/scripts/package.scm | 21 | ||||
-rw-r--r-- | guix/ui.scm | 43 |
2 files changed, 44 insertions, 20 deletions
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm index 9ec6950c4b..4adc705220 100644 --- a/guix/scripts/package.scm +++ b/guix/scripts/package.scm @@ -246,27 +246,8 @@ specified in MANIFEST, a manifest object." "Return two values: the list of packages whose name, synopsis, or description matches at least one of REGEXPS sorted by relevance, and the list of relevance scores." - (define (score str) - (let ((counts (filter-map (lambda (regexp) - (match (regexp-exec regexp str) - (#f #f) - (m (match:count m)))) - regexps))) - ;; Compute a score that's proportional to the number of regexps matched - ;; and to the number of matches for each regexp. - (* (length counts) (reduce + 0 counts)))) - - (define (package-score package) - (+ (* 3 (score (package-name package))) - (* 2 (match (package-synopsis package) - ((? string? str) (score (P_ str))) - (#f 0))) - (match (package-description package) - ((? string? str) (score (P_ str))) - (#f 0)))) - (let ((matches (fold-packages (lambda (package result) - (match (package-score package) + (match (package-relevance package regexps) ((? zero?) result) (score diff --git a/guix/ui.scm b/guix/ui.scm index b0108d0705..a51877c04d 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -85,6 +85,8 @@ string->recutils package->recutils package-specification->name+version+output + relevance + package-relevance string->generations string->duration matching-generations @@ -1024,6 +1026,47 @@ WIDTH columns. EXTRA-FIELDS is a list of symbol/value pairs to emit." extra-fields) (newline port)) +(define (relevance obj regexps metrics) + "Compute a \"relevance score\" for OBJ as a function of its number of +matches of REGEXPS and accordingly to METRICS. METRICS is list of +field/weight pairs, where FIELD is a procedure that returns a string +describing OBJ, and WEIGHT is a positive integer denoting the weight of this +field in the final score. + +A score of zero means that OBJ does not match any of REGEXPS. The higher the +score, the more relevant OBJ is to REGEXPS." + (define (score str) + (let ((counts (filter-map (lambda (regexp) + (match (regexp-exec regexp str) + (#f #f) + (m (match:count m)))) + regexps))) + ;; Compute a score that's proportional to the number of regexps matched + ;; and to the number of matches for each regexp. + (* (length counts) (reduce + 0 counts)))) + + (fold (lambda (metric relevance) + (match metric + ((field . weight) + (match (field obj) + (#f relevance) + (str (+ relevance + (* (score str) weight))))))) + 0 + metrics)) + +(define %package-metrics + ;; Metrics used to compute the "relevance score" of a package against a set + ;; of regexps. + `((,package-name . 3) + (,package-synopsis-string . 2) + (,package-description-string . 1))) + +(define (package-relevance package regexps) + "Return a score denoting the relevance of PACKAGE for REGEXPS. A score of +zero means that PACKAGE does not match any of REGEXPS." + (relevance package regexps %package-metrics)) + (define (string->generations str) "Return the list of generations matching a pattern in STR. This function accepts the following patterns: \"1\", \"1,2,3\", \"1..9\", \"1..\", \"..9\"." |