Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package pik for openSUSE:Factory checked in 
at 2024-11-09 20:58:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pik (Old)
 and      /work/SRC/openSUSE:Factory/.pik.new.2017 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "pik"

Sat Nov  9 20:58:41 2024 rev:7 rq:1222972 version:0.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/pik/pik.changes  2024-10-09 22:13:58.948844311 
+0200
+++ /work/SRC/openSUSE:Factory/.pik.new.2017/pik.changes        2024-11-09 
20:59:29.413213746 +0100
@@ -1,0 +2,9 @@
+Sat Nov  9 13:47:41 UTC 2024 - Muhammad Akbar Yanuar Mantari <[email protected]>
+
+- Update to version 0.10.0
+  + Bugs fixes
+    - Fixed empty query for ports args and paths
+  + New Features
+    - Added sorting search results by match score
+
+-------------------------------------------------------------------

Old:
----
  pik-0.9.0.tar.gz

New:
----
  pik-0.10.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ pik.spec ++++++
--- /var/tmp/diff_new_pack.TzskwY/_old  2024-11-09 20:59:29.985237541 +0100
+++ /var/tmp/diff_new_pack.TzskwY/_new  2024-11-09 20:59:29.985237541 +0100
@@ -18,7 +18,7 @@
 
 %bcond_without test
 Name:           pik
-Version:        0.9.0
+Version:        0.10.0
 Release:        0
 Summary:        Process Interactive Kill
 License:        MIT

++++++ pik-0.9.0.tar.gz -> pik-0.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pik-0.9.0/Cargo.lock new/pik-0.10.0/Cargo.lock
--- old/pik-0.9.0/Cargo.lock    2024-10-09 11:13:08.000000000 +0200
+++ new/pik-0.10.0/Cargo.lock   2024-11-09 14:32:43.000000000 +0100
@@ -592,7 +592,7 @@
 
 [[package]]
 name = "pik"
-version = "0.9.0"
+version = "0.10.0"
 dependencies = [
  "anyhow",
  "chrono",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pik-0.9.0/Cargo.toml new/pik-0.10.0/Cargo.toml
--- old/pik-0.9.0/Cargo.toml    2024-10-09 11:13:08.000000000 +0200
+++ new/pik-0.10.0/Cargo.toml   2024-11-09 14:32:43.000000000 +0100
@@ -1,6 +1,6 @@
 [package]
 name = "pik"
-version = "0.9.0"
+version = "0.10.0"
 edition = "2021"
 authors = ["Jacek Kurlit"]
 keywords = ["terminal", "process", "linux", "system", "kill"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pik-0.9.0/pik.spec new/pik-0.10.0/pik.spec
--- old/pik-0.9.0/pik.spec      2024-10-09 11:13:08.000000000 +0200
+++ new/pik-0.10.0/pik.spec     2024-11-09 14:32:43.000000000 +0100
@@ -1,5 +1,5 @@
 Name: pik
-Version: 0.9.0
+Version: 0.10.0
 Release: 1%{?dist}
 License: MIT
 Summary: Process Interactive Kill is a tool that helps to find and kill process
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pik-0.9.0/src/processes/filters.rs 
new/pik-0.10.0/src/processes/filters.rs
--- old/pik-0.9.0/src/processes/filters.rs      2024-10-09 11:13:08.000000000 
+0200
+++ new/pik-0.10.0/src/processes/filters.rs     2024-11-09 14:32:43.000000000 
+0100
@@ -1,7 +1,7 @@
 use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
 use sysinfo::Uid;
 
-use super::{utils::get_process_args, ProcessInfo};
+use super::{utils::get_process_args, MatchData, ProcessInfo};
 
 pub(super) struct QueryFilter {
     query: String,
@@ -40,8 +40,7 @@
             matcher,
         }
     }
-
-    pub(super) fn accept(&self, prc: &impl ProcessInfo, ports: Option<&str>) 
-> bool {
+    pub(super) fn accept(&self, prc: &impl ProcessInfo, ports: Option<&str>) 
-> MatchData {
         match self.search_by {
             SearchBy::Cmd => self.query_match_str(prc.cmd()),
             SearchBy::Path => self.query_matches_opt(prc.cmd_path()),
@@ -50,39 +49,74 @@
             SearchBy::Pid => self.query_eq_u32(prc.pid()),
             SearchBy::ProcessFamily => self.query_matches_process_family(prc),
             SearchBy::Everywhere => {
-                self.query_match_str(prc.cmd())
-                    || self.query_matches_opt(prc.cmd_path())
-                    || self.query_matches_opt(ports)
-                    || self.query_contains_vec(get_process_args(prc))
+                let matched = self.query_match_str(prc.cmd());
+                if matched.positive_match() {
+                    return matched;
+                }
+                let matched = self.query_matches_opt(prc.cmd_path());
+                if matched.positive_match() {
+                    return matched;
+                }
+                let matched = self.query_matches_opt(ports);
+                if matched.positive_match() {
+                    return matched;
+                }
+                let matched = self.query_contains_vec(get_process_args(prc));
+                if matched.positive_match() {
+                    return matched;
+                }
+                MatchData::none()
             }
-            SearchBy::None => true,
+            SearchBy::None => MatchData::perfect(),
         }
     }
 
-    fn query_match_str(&self, s: &str) -> bool {
-        let score = self.matcher.fuzzy_match(s, self.query.as_str());
-        // TODO: fine-tune the score threshold or make it configurable?
-        score.map(|s| s >= 0).unwrap_or(false)
+    fn query_match_str(&self, s: &str) -> MatchData {
+        if self.query.is_empty() {
+            return MatchData::perfect();
+        }
+        match self.matcher.fuzzy_match(s, self.query.as_str()) {
+            Some(score) => MatchData::new(score),
+            None => MatchData::none(),
+        }
     }
 
-    fn query_matches_opt(&self, s: Option<&str>) -> bool {
-        s.map(|s| self.query_match_str(s)).unwrap_or(false)
+    fn query_matches_opt(&self, s: Option<&str>) -> MatchData {
+        s.map(|s| self.query_match_str(s))
+            .unwrap_or(MatchData::none())
     }
 
-    fn query_contains_vec(&self, s: Vec<&str>) -> bool {
-        s.iter().any(|a| a.to_lowercase().contains(&self.query))
+    fn query_contains_vec(&self, items: Vec<&str>) -> MatchData {
+        if items
+            .iter()
+            .any(|item| item.to_lowercase().contains(&self.query))
+        {
+            MatchData::perfect()
+        } else {
+            MatchData::none()
+        }
     }
 
-    fn query_eq_u32(&self, s: u32) -> bool {
-        s.to_string() == self.query
+    fn query_eq_u32(&self, s: u32) -> MatchData {
+        if s.to_string() == self.query {
+            MatchData::perfect()
+        } else {
+            MatchData::none()
+        }
     }
 
-    fn query_matches_process_family(&self, prc: &impl ProcessInfo) -> bool {
-        self.query_eq_u32(prc.pid())
-            || prc
-                .parent_id()
-                .map(|pid| self.query_eq_u32(pid))
-                .unwrap_or(false)
+    fn query_matches_process_family(&self, prc: &impl ProcessInfo) -> 
MatchData {
+        if prc.pid().to_string() == self.query {
+            return MatchData::perfect();
+        }
+        if prc
+            .parent_id()
+            .map(|pid| pid.to_string() == self.query)
+            .unwrap_or(false)
+        {
+            return MatchData::perfect();
+        }
+        MatchData::none()
     }
 }
 
@@ -179,22 +213,22 @@
             cmd: "TeSt".to_string(),
             ..Default::default()
         };
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd = "test".to_string();
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd = "TEST".to_string();
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd = "Testificator".to_string();
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd = "online_TESTER".to_string();
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd = "xxx".to_string();
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -204,26 +238,33 @@
             cmd_path: Some("/TeSt".to_string()),
             ..Default::default()
         };
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         // tests that fuzzy search works
         process.cmd_path = Some("/taest".to_string());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd_path = Some("/test".to_string());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd_path = Some("/TEST".to_string());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd_path = Some("/testing_dir".to_string());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd_path = Some("/cargo/tests".to_string());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
+
+        process.cmd_path = Some("/xxx".to_string());
+        assert!(filter.accept(&process, None).negative_match());
 
+        // '/' accepts all non empty paths
+        let filter = QueryFilter::new("/");
         process.cmd_path = Some("/xxx".to_string());
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
+        process.cmd_path = None;
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -232,22 +273,29 @@
         let mut process = MockProcessInfo::default();
 
         process = process.with_args(&["-TeSt"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["-test"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["-TEST"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["arg1, arg2, --testifier"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["testimony"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["-xxx"]);
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
+
+        // '-' accepts all non empty args
+        let filter = QueryFilter::new("-");
+        process = process.with_args(&["-arg"]);
+        assert!(filter.accept(&process, None).positive_match());
+        process = process.with_args(&[]);
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -258,7 +306,7 @@
             args: vec!["-test".into(), "-xxx".into()],
             ..Default::default()
         };
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -266,15 +314,22 @@
         let filter = QueryFilter::new(":12");
         let process = MockProcessInfo::default();
 
-        assert!(filter.accept(&process, Some("1234")));
+        assert!(filter.accept(&process, Some("1234")).positive_match());
+
+        assert!(filter.accept(&process, Some("3312")).positive_match());
 
-        assert!(filter.accept(&process, Some("3312")));
+        assert!(filter.accept(&process, Some("5125")).positive_match());
 
-        assert!(filter.accept(&process, Some("5125")));
+        assert!(filter
+            .accept(&process, Some("1111, 2222, 1234"))
+            .positive_match());
 
-        assert!(filter.accept(&process, Some("1111, 2222, 1234")));
+        assert!(filter.accept(&process, Some("7777")).negative_match());
 
-        assert!(!filter.accept(&process, Some("7777")));
+        //':' accepts all non empty ports
+        let filter = QueryFilter::new(":");
+        assert!(filter.accept(&process, Some("5125")).positive_match());
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -285,9 +340,9 @@
             ..Default::default()
         };
 
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
         process.pid = 12345;
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -298,16 +353,16 @@
             ..Default::default()
         };
 
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
         process.pid = 555;
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
 
         process.parent_pid = Some(1234);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
         process.parent_pid = Some(555);
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
         process.parent_pid = None;
-        assert!(!filter.accept(&process, None));
+        assert!(filter.accept(&process, None).negative_match());
     }
 
     #[test]
@@ -317,39 +372,39 @@
             cmd: "TEST".into(),
             ..Default::default()
         };
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd_path = Some("/tEsT".into());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["-TeSt"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         filter = QueryFilter::new("~80");
-        assert!(filter.accept(&process, Some("8080")));
+        assert!(filter.accept(&process, Some("8080")).positive_match());
 
         process.cmd = "xxx".into();
         process.cmd_path = Some("/xxx".into());
         process = process.with_args(&["-xxx"]);
-        assert!(!filter.accept(&process, Some("1234")));
+        assert!(filter.accept(&process, Some("1234")).negative_match());
     }
 
     #[test]
     fn query_filter_search_by_none() {
         let filter = QueryFilter::new("");
         let mut process = MockProcessInfo::default();
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd = "TeSt".to_string();
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process.cmd_path = Some("/TeSt".to_string());
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
         process = process.with_args(&["-TeSt"]);
-        assert!(filter.accept(&process, None));
+        assert!(filter.accept(&process, None).positive_match());
 
-        assert!(filter.accept(&process, Some("1234")));
+        assert!(filter.accept(&process, Some("1234")).positive_match());
     }
 
     #[test]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pik-0.9.0/src/processes.rs 
new/pik-0.10.0/src/processes.rs
--- old/pik-0.9.0/src/processes.rs      2024-10-09 11:13:08.000000000 +0200
+++ new/pik-0.10.0/src/processes.rs     2024-11-09 14:32:43.000000000 +0100
@@ -94,7 +94,7 @@
 #[derive(Debug)]
 pub struct ProcessSearchResults {
     pub search_by: SearchBy,
-    items: Vec<Process>,
+    pub items: Vec<ResultItem>,
 }
 
 impl ProcessSearchResults {
@@ -115,15 +115,15 @@
 
     pub fn nth(&self, index: Option<usize>) -> Option<&Process> {
         let index = index?;
-        self.items.get(index)
+        self.items.get(index).map(|item| &item.process)
     }
 
     pub fn remove(&mut self, pid: u32) {
-        self.items.retain(|prc| prc.pid != pid)
+        self.items.retain(|item| item.process.pid != pid)
     }
 
     pub fn iter(&self) -> impl Iterator<Item = &Process> {
-        self.items.iter()
+        self.items.iter().map(|i| &i.process)
     }
 }
 
@@ -147,20 +147,28 @@
         let process_filter = QueryFilter::new(query);
         let options_filter = OptionsFilter::new(options, 
&self.current_user_id);
 
-        let items = self
+        let mut items = self
             .sys
             .processes()
             .values()
             .filter_map(|prc| {
                 let ports = self.process_ports.get(&prc.pid().as_u32());
-                if !options_filter.accept(prc)
-                    || !process_filter.accept(prc, ports.map(|p| p.as_str()))
-                {
+                if !options_filter.accept(prc) {
                     return None;
                 }
-                Some(self.create_process_info(prc, ports))
+
+                let match_data = process_filter.accept(prc, ports.map(|p| 
p.as_str()));
+                if match_data.negative_match() {
+                    return None;
+                }
+                Some(ResultItem::new(
+                    match_data,
+                    self.create_process_info(prc, ports),
+                ))
             })
-            .collect();
+            .collect::<Vec<ResultItem>>();
+
+        items.sort_by(|a, b| b.match_data.score.cmp(&a.match_data.score));
 
         ProcessSearchResults {
             search_by: process_filter.search_by,
@@ -275,3 +283,45 @@
             .unwrap_or_default()
     }
 }
+
+#[derive(Debug)]
+pub struct ResultItem {
+    pub match_data: MatchData,
+    pub process: Process,
+}
+
+impl ResultItem {
+    pub fn new(match_data: MatchData, process: Process) -> Self {
+        Self {
+            match_data,
+            process,
+        }
+    }
+}
+
+#[derive(PartialEq, Eq, Debug)]
+pub struct MatchData {
+    pub score: i64,
+}
+
+impl MatchData {
+    pub fn new(score: i64) -> Self {
+        Self { score }
+    }
+
+    pub fn perfect() -> Self {
+        Self { score: i64::MAX }
+    }
+
+    pub fn none() -> Self {
+        Self { score: -1 }
+    }
+
+    pub fn positive_match(&self) -> bool {
+        self.score > 0
+    }
+
+    pub fn negative_match(&self) -> bool {
+        self.score <= 0
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pik-0.9.0/tests/processes_search.rs 
new/pik-0.10.0/tests/processes_search.rs
--- old/pik-0.9.0/tests/processes_search.rs     2024-10-09 11:13:08.000000000 
+0200
+++ new/pik-0.10.0/tests/processes_search.rs    2024-11-09 14:32:43.000000000 
+0100
@@ -1,6 +1,6 @@
 use std::{thread, time::Duration};
 
-use pik::processes::{FilterOptions, ProcessManager};
+use pik::processes::{FilterOptions, ProcessManager, ProcessSearchResults};
 
 use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
 
@@ -10,6 +10,7 @@
     let results = process_manager.find_processes("cargo", 
FilterOptions::default());
     assert!(!results.is_empty());
     assert!(results.iter().all(|p| fuzzy_matches(&p.cmd, "cargo")));
+    assert!(results_are_sorted_by_score(results));
 }
 
 #[test]
@@ -20,6 +21,7 @@
     assert!(results
         .iter()
         .all(|p| fuzzy_matches(p.cmd_path.as_ref().unwrap(), "cargo")));
+    assert!(results_are_sorted_by_score(results));
 }
 
 #[test]
@@ -32,6 +34,7 @@
         .all(|p| fuzzy_matches(p.cmd_path.as_ref().unwrap(), "cargo")
             || p.args.contains("cargo")
             || fuzzy_matches(&p.cmd, "cargo")));
+    assert!(results_are_sorted_by_score(results));
 }
 
 #[test]
@@ -40,6 +43,7 @@
     let results = process_manager.find_processes("-test", 
FilterOptions::default());
     assert!(!results.is_empty());
     assert!(results.iter().all(|p| fuzzy_matches(&p.args, "test")));
+    assert!(results_are_sorted_by_score(results));
 }
 
 use http_test_server::TestServer;
@@ -53,6 +57,7 @@
     let results = process_manager.find_processes(&format!(":{}", port), 
FilterOptions::default());
     assert!(!results.is_empty());
     assert!(results.iter().all(|p| p.ports == Some(format!("{}", port))));
+    assert!(results_are_sorted_by_score(results));
 }
 
 #[test]
@@ -65,6 +70,7 @@
         .find_processes(&format!("!{}", cargo_process_pid), 
FilterOptions::default());
     assert_eq!(restults.len(), 1);
     assert_eq!(restults.nth(Some(0)).unwrap().pid, cargo_process_pid);
+    assert!(results_are_sorted_by_score(results));
 }
 
 #[test]
@@ -79,6 +85,7 @@
     assert!(results
         .iter()
         .all(|p| p.pid == cargo_process_pid || p.parent_pid == 
Some(cargo_process_pid)));
+    assert!(results_are_sorted_by_score(results));
 }
 
 fn fuzzy_matches(value: &str, pattern: &str) -> bool {
@@ -87,3 +94,11 @@
         .unwrap_or(0)
         > 0
 }
+
+fn results_are_sorted_by_score(results: ProcessSearchResults) -> bool {
+    results
+        .items
+        .iter()
+        .zip(results.items.iter().skip(1))
+        .all(|(a, b)| a.match_data.score >= b.match_data.score)
+}

Reply via email to