diff --git a/Cargo.lock b/Cargo.lock index b3b3621bdb..d3bcc9e7a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -768,6 +768,11 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "doc-comment" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "dtoa" version = "0.4.4" @@ -1960,6 +1965,7 @@ dependencies = [ "strip-ansi-escapes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sysinfo 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3090,6 +3096,18 @@ dependencies = [ "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sysinfo" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -3773,6 +3791,7 @@ dependencies = [ "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0ad6bf6a88548d1126045c413548df1453d9be094a8ab9fd59bf1fdd338da4f" "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" @@ -4016,6 +4035,7 @@ dependencies = [ "checksum syn 0.15.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ee06ea4b620ab59a2267c6b48be16244a3389f8bfa0986bdd15c35b890b00af3" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e80b8831c5a543192ffc3727f01cf0e57579c6ac15558e3048bfb5708892167b" +"checksum sysinfo 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ee7d12b854e48e680bf4b10856a7867e843845158fa8226e6c2f6cc38539cb01" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" diff --git a/Cargo.toml b/Cargo.toml index e772655ba6..bba70806c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ homepage = "https://github.com/nushell/nushell" [dependencies] rustyline = "5.0.1" +sysinfo = "0.9" chrono = { version = "0.4.7", features = ["serde"] } chrono-tz = "0.5.1" derive-new = "0.5.7" @@ -119,10 +120,6 @@ path = "src/plugins/skip.rs" name = "nu_plugin_sys" path = "src/plugins/sys.rs" -[[bin]] -name = "nu_plugin_ps" -path = "src/plugins/ps.rs" - [[bin]] name = "nu_plugin_tree" path = "src/plugins/tree.rs" diff --git a/src/cli.rs b/src/cli.rs index 19be94e93f..af81058723 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -152,6 +152,7 @@ pub async fn cli() -> Result<(), Box> { command("from-json", Box::new(from_json::from_json)), command("from-toml", Box::new(from_toml::from_toml)), command("from-xml", Box::new(from_xml::from_xml)), + command("ps", Box::new(ps::ps)), command("ls", Box::new(ls::ls)), command("cd", Box::new(cd::cd)), command("size", Box::new(size::size)), diff --git a/src/commands.rs b/src/commands.rs index 3f3ac5c0e5..9366257a8d 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -28,6 +28,7 @@ crate mod open; crate mod pick; crate mod plugin; crate mod prev; +crate mod ps; crate mod reject; crate mod rm; crate mod save; diff --git a/src/commands/ps.rs b/src/commands/ps.rs new file mode 100644 index 0000000000..3bac046889 --- /dev/null +++ b/src/commands/ps.rs @@ -0,0 +1,17 @@ +use crate::errors::ShellError; +use crate::object::process::process_dict; +use crate::prelude::*; +use sysinfo::{RefreshKind, SystemExt}; + +pub fn ps(args: CommandArgs, _registry: &CommandRegistry) -> Result { + let mut system = sysinfo::System::new_with_specifics(RefreshKind::new().with_processes()); + system.refresh_processes(); + let list = system.get_process_list(); + + let list = list + .into_iter() + .map(|(_, process)| process_dict(process, Tag::unknown_origin(args.call_info.name_span))) + .collect::>(); + + Ok(list.from_input_stream()) +} diff --git a/src/object.rs b/src/object.rs index 5c5fa96a69..8cc86d4568 100644 --- a/src/object.rs +++ b/src/object.rs @@ -4,6 +4,7 @@ crate mod dict; crate mod files; crate mod into; crate mod meta; +crate mod process; crate mod types; #[allow(unused)] diff --git a/src/object/process.rs b/src/object/process.rs new file mode 100644 index 0000000000..2d90dba2d7 --- /dev/null +++ b/src/object/process.rs @@ -0,0 +1,29 @@ +use crate::object::{TaggedDictBuilder, Value}; +use crate::prelude::*; +use itertools::join; +use sysinfo::ProcessExt; + +crate fn process_dict(proc: &sysinfo::Process, tag: impl Into) -> Tagged { + let mut dict = TaggedDictBuilder::new(tag); + + let cmd = proc.cmd(); + + let cmd_value = if cmd.len() == 0 { + Value::nothing() + } else { + Value::string(join(cmd, "")) + }; + + dict.insert("pid", Value::int(proc.pid() as i64)); + dict.insert("status", Value::string(proc.status().to_string())); + dict.insert("cpu", Value::float(proc.cpu_usage() as f64)); + //dict.insert("name", Value::string(proc.name())); + match cmd_value { + Value::Primitive(Primitive::Nothing) => { + dict.insert("name", Value::string(proc.name())); + } + _ => dict.insert("name", cmd_value), + } + + dict.into_tagged_value() +} diff --git a/src/plugins/ps.rs b/src/plugins/ps.rs deleted file mode 100644 index 0fc36e774f..0000000000 --- a/src/plugins/ps.rs +++ /dev/null @@ -1,71 +0,0 @@ -#![feature(async_await)] - -use futures::executor::block_on; -use futures::stream::StreamExt; -use heim::process; -use indexmap::IndexMap; -use nu::{ - serve_plugin, CallInfo, Plugin, ReturnSuccess, ReturnValue, ShellError, Signature, Tag, Tagged, - TaggedDictBuilder, Value, -}; - -struct Ps; -impl Ps { - fn new() -> Ps { - Ps - } -} - -async fn ps(tag: Tag) -> Vec> { - let mut output = vec![]; - - let mut process = process::processes(); - while let Some(process) = process.next().await { - if let Ok(process) = process { - let mut dict = TaggedDictBuilder::new(tag); - dict.insert("pid", Value::int(process.pid() as i64)); - if let Ok(parent) = process.parent_pid().await { - dict.insert("parent", Value::int(parent as i64)); - } - if let Ok(status) = process.status().await { - dict.insert("status", Value::string(format!("{:?}", status))); - } - if let Ok(name) = process.name().await { - dict.insert("name", Value::string(name)); - } - if let Ok(exe) = process.exe().await { - dict.insert("exe", Value::string(exe.to_string_lossy().to_string())); - } - - output.push(dict.into_tagged_value()); - } - } - - output -} - -impl Plugin for Ps { - fn config(&mut self) -> Result { - Ok(Signature { - name: "ps".to_string(), - positional: vec![], - is_filter: true, - named: IndexMap::new(), - rest_positional: true, - }) - } - fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - Ok(block_on(ps(Tag::unknown_origin(callinfo.name_span))) - .into_iter() - .map(|x| ReturnSuccess::value(x)) - .collect()) - } - - fn filter(&mut self, _: Tagged) -> Result, ShellError> { - Ok(vec![]) - } -} - -fn main() { - serve_plugin(&mut Ps::new()); -}