Skip to content

Commit 409a200

Browse files
authored
Merge pull request #156 from xscriptor/plugins/upload
merge upload plugins into main
2 parents 678c40b + e1cfc21 commit 409a200

15 files changed

Lines changed: 792 additions & 35 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
/target
2-
plugins/animate-logo/target
2+
plugins/*/target

plugins/docker/Cargo.lock

Lines changed: 107 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/docker/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "xfetch-plugin-docker"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
serde = { version = "1", features = ["derive"] }
8+
serde_json = "1"

plugins/docker/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<div align="center">
2+
<h1> Docker Plugin</h1>
3+
<p>Displays running Docker container statistics in xfetch.</p>
4+
</div>
5+
6+
<br>
7+
8+
<div align="center">
9+
<table>
10+
<tr>
11+
<td><strong>Kind</strong></td>
12+
<td><code>info_provider</code></td>
13+
</tr>
14+
<tr>
15+
<td><strong>Binary</strong></td>
16+
<td><code>xfetch-plugin-docker</code></td>
17+
</tr>
18+
<tr>
19+
<td><strong>Dependencies</strong></td>
20+
<td><code>docker</code> CLI</td>
21+
</tr>
22+
</table>
23+
</div>
24+
25+
<br>
26+
27+
<h2>Build</h2>
28+
29+
<pre><code>cargo build --release --manifest-path plugins/docker/Cargo.toml</code></pre>
30+
31+
<p>The binary will be created at:</p>
32+
33+
<pre><code>plugins/docker/target/release/xfetch-plugin-docker</code></pre>
34+
35+
<h2>Install</h2>
36+
37+
<pre><code>xfetch plugin install ./plugins/docker</code></pre>
38+
39+
<h2>Configuration</h2>
40+
41+
<p>Add the plugin to your <code>config.jsonc</code>:</p>
42+
43+
<pre><code class="language-jsonc">{
44+
"info_plugins": [
45+
{
46+
"plugin": "docker"
47+
}
48+
],
49+
"modules": [
50+
"os",
51+
"kernel",
52+
"plugin:docker",
53+
"shell",
54+
"cpu",
55+
"memory"
56+
]
57+
}</code></pre>
58+
59+
<p>The docker plugin does not require any arguments. It reads directly from the <code>docker</code> CLI.</p>
60+
61+
<h2>Output</h2>
62+
63+
<table>
64+
<thead>
65+
<tr>
66+
<th>State</th>
67+
<th>Example Output</th>
68+
</tr>
69+
</thead>
70+
<tbody>
71+
<tr>
72+
<td>Daemon running with containers</td>
73+
<td><pre> Containers: 15 total<br> ▶ 3 running<br> ⏸ 1 paused<br> ⏹ 11 stopped</pre></td>
74+
</tr>
75+
<tr>
76+
<td>Docker installed but daemon not running</td>
77+
<td><code> Docker: daemon not running</code></td>
78+
</tr>
79+
<tr>
80+
<td>Docker CLI not found</td>
81+
<td><code> Docker: not found</code></td>
82+
</tr>
83+
</tbody>
84+
</table>
85+
86+
<h2>How It Works</h2>
87+
88+
<ol>
89+
<li>xfetch sends a JSON request with <code>kind: "info_provider"</code>.</li>
90+
<li>The plugin runs <code>docker info --format '{{.Containers}} {{.ContainersRunning}} ...'</code>.</li>
91+
<li>The plugin returns a JSON response with the formatted lines.</li>
92+
<li>xfetch displays them under the <code>plugin:docker</code> module key.</li>
93+
</ol>
94+
95+
<h2>Protocol</h2>
96+
97+
<h3>Request</h3>
98+
99+
<pre><code class="language-json">{
100+
"version": 1,
101+
"kind": "info_provider",
102+
"args": null
103+
}</code></pre>
104+
105+
<h3>Response</h3>
106+
107+
<pre><code class="language-json">{
108+
"lines": [
109+
" Containers: 15 total",
110+
" ▶ 3 running",
111+
" ⏸ 1 paused",
112+
" ⏹ 11 stopped"
113+
]
114+
}</code></pre>
115+
116+
<h2>Notes</h2>
117+
118+
<ul>
119+
<li>Requires the <code>docker</code> CLI to be installed and available in <code>PATH</code>.</li>
120+
<li>If the Docker daemon is not running, the plugin reports it gracefully.</li>
121+
<li>No authentication or configuration is needed.</li>
122+
</ul>

plugins/docker/src/main.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use serde::Deserialize;
2+
use serde::Serialize;
3+
use std::io::{self, Read, Write};
4+
use std::process::Command;
5+
6+
#[derive(Debug, Deserialize)]
7+
#[allow(dead_code)]
8+
struct PluginRequest {
9+
version: Option<u32>,
10+
kind: Option<String>,
11+
args: Option<PluginArgs>,
12+
}
13+
14+
#[derive(Debug, Deserialize)]
15+
struct PluginArgs {}
16+
17+
#[derive(Debug, Serialize)]
18+
struct PluginResponse {
19+
lines: Vec<String>,
20+
}
21+
22+
fn main() {
23+
let mut input = String::new();
24+
if io::stdin().read_to_string(&mut input).is_err() {
25+
return;
26+
}
27+
28+
let _request: PluginRequest = match serde_json::from_str(&input) {
29+
Ok(value) => value,
30+
Err(_) => return,
31+
};
32+
33+
let lines = get_docker_info();
34+
35+
let response = PluginResponse { lines };
36+
if let Ok(body) = serde_json::to_string(&response) {
37+
let _ = io::stdout().write_all(body.as_bytes());
38+
}
39+
}
40+
41+
fn get_docker_info() -> Vec<String> {
42+
let mut result = Vec::new();
43+
44+
let info_output = Command::new("docker")
45+
.args(["info", "--format", "{{.Containers}} {{.ContainersRunning}} {{.ContainersPaused}} {{.ContainersStopped}}"])
46+
.output();
47+
48+
match info_output {
49+
Ok(output) if output.status.success() => {
50+
let stats = String::from_utf8_lossy(&output.stdout);
51+
let parts: Vec<&str> = stats.trim().split_whitespace().collect();
52+
if parts.len() >= 4 {
53+
let total = parts[0];
54+
let running = parts[1];
55+
let paused = parts[2];
56+
let stopped = parts[3];
57+
result.push(format!(" Containers: {} total", total));
58+
result.push(format!(" ▶ {} running", running));
59+
result.push(format!(" ⏸ {} paused", paused));
60+
result.push(format!(" ⏹ {} stopped", stopped));
61+
}
62+
}
63+
Ok(_) => result.push(" Docker: daemon not running".to_string()),
64+
Err(_) => result.push(" Docker: not found".to_string()),
65+
}
66+
67+
result
68+
}

0 commit comments

Comments
 (0)