Skip to content

Commit

Permalink
refactor(pod): package by feature
Browse files Browse the repository at this point in the history
  • Loading branch information
sarub0b0 committed Mar 18, 2024
1 parent c92aa72 commit 873b77c
Show file tree
Hide file tree
Showing 24 changed files with 406 additions and 315 deletions.
2 changes: 1 addition & 1 deletion src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crossbeam::channel::Receiver;

use crate::{
context::{Context, Namespace},
features::pod::message::LogMessage,
message::Message,
ui::{
event::{exec_to_window_event, EventResult},
Expand All @@ -18,7 +19,6 @@ use crate::{
context_message::{ContextMessage, ContextResponse},
namespace_message::{NamespaceMessage, NamespaceResponse},
network::{NetworkMessage, NetworkResponse},
pod::LogMessage,
yaml::{YamlMessage, YamlResourceListItem, YamlResponse},
Kube, KubeTable, KubeTableRow,
},
Expand Down
1 change: 1 addition & 0 deletions src/features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod pod;
3 changes: 3 additions & 0 deletions src/features/pod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod kube;
pub mod view;
pub mod message;
6 changes: 6 additions & 0 deletions src/features/pod/kube.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
mod filter;
mod log;
mod pod;

pub use log::*;
pub use pod::*;
File renamed without changes.
File renamed without changes.
17 changes: 2 additions & 15 deletions src/workers/kube/pod/log.rs → src/features/pod/kube/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ use crate::{
message::Message,
workers::kube::{
client::KubeClient,
pod::filter::{Filter, LabelSelector, RetrievableResource},
worker::{AbortWorker, Worker},
Kube,
},
};

pub use self::log_streamer::LogPrefixType;
pub use super::filter::{Filter, LabelSelector, RetrievableResource};

use self::{
log_collector::{LogBuffer, LogCollector},
Expand All @@ -39,7 +38,7 @@ use self::{
#[macro_export]
macro_rules! send_response {
($tx:expr, $msg:expr) => {
use $crate::workers::kube::pod::LogMessage;
use $crate::features::pod::message::LogMessage;

$tx.send(LogMessage::Response($msg).into())
.expect("Failed to send LogMessage::Response");
Expand All @@ -63,18 +62,6 @@ impl LogConfig {
}
}

#[derive(Debug)]
pub enum LogMessage {
Request(LogConfig),
Response(Result<Vec<String>>),
}

impl From<LogMessage> for Message {
fn from(m: LogMessage) -> Message {
Message::Kube(Kube::Log(m))
}
}

#[derive(Clone)]
pub struct LogWorker {
tx: Sender<Message>,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions src/features/pod/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use anyhow::Result;

use crate::{message::Message, workers::Kube};

use super::kube::LogConfig;

#[derive(Debug)]
pub enum LogMessage {
Request(LogConfig),
Response(Result<Vec<String>>),
}

impl From<LogMessage> for Message {
fn from(m: LogMessage) -> Message {
Message::Kube(Kube::Log(m))
}
}
4 changes: 4 additions & 0 deletions src/features/pod/view.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod tab;
mod widgets;

pub use tab::*;
84 changes: 84 additions & 0 deletions src/features/pod/view/tab.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::{cell::RefCell, rc::Rc};

use crossbeam::channel::Sender;
use ratatui::layout::{Constraint, Direction};

use crate::{
action::view_id,
clipboard::Clipboard,
context::Namespace,
message::Message,
ui::{
tab::{LayoutElement, NestedLayoutElement, NestedWidgetLayout},
widget::Widget,
Tab,
},
};

use super::widgets::{log_query_help_widget, log_query_widget, log_widget, pod_widget};

pub struct PodTab {
pub tab: Tab<'static>,
pub log_query_help_popup: Widget<'static>,
}

impl PodTab {
pub fn new(
title: &'static str,
tx: &Sender<Message>,
clipboard: &Option<Rc<RefCell<Clipboard>>>,
split_direction: Direction,
namespaces: Rc<RefCell<Namespace>>,
) -> Self {
let pod_widget = pod_widget(tx);
let log_query_widget = log_query_widget(tx, namespaces);
let log_widget = log_widget(clipboard);
let log_query_help_widget = log_query_help_widget();

let layout = layout(split_direction);

let mut tab = Tab::new(
view_id::tab_pod,
title,
[pod_widget, log_query_widget, log_widget],
layout,
);

tab.activate_widget_by_id(view_id::tab_pod_widget_pod);

Self {
tab,
log_query_help_popup: log_query_help_widget,
}
}
}

fn layout(split_direction: Direction) -> NestedWidgetLayout {
let pod_layout = {
let constraint = match split_direction {
Direction::Horizontal => Constraint::Percentage(50),
Direction::Vertical => Constraint::Percentage(45), // log_query領域分小さくする
};

NestedLayoutElement(constraint, LayoutElement::WidgetIndex(0))
};

let log_query_layout =
NestedLayoutElement(Constraint::Length(3), LayoutElement::WidgetIndex(1));

let log_layout = NestedLayoutElement(
Constraint::Percentage(50),
LayoutElement::NestedElement(
NestedWidgetLayout::default()
.direction(Direction::Vertical)
.nested_widget_layout([
log_query_layout,
NestedLayoutElement(Constraint::Min(3), LayoutElement::WidgetIndex(2)),
]),
),
);

NestedWidgetLayout::default()
.direction(split_direction)
.nested_widget_layout([pod_layout, log_layout])
}
9 changes: 9 additions & 0 deletions src/features/pod/view/widgets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod log;
mod log_query;
mod log_query_help;
mod pod;

pub(super) use log::*;
pub(super) use log_query::*;
pub(super) use log_query_help::*;
pub(super) use pod::*;
56 changes: 56 additions & 0 deletions src/features/pod/view/widgets/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::{cell::RefCell, rc::Rc};

use crossterm::event::KeyCode;
use ratatui::widgets::Block;

use crate::{
action::view_id,
clipboard::Clipboard,
message::UserEvent,
ui::{
event::EventResult,
widget::{config::WidgetConfig, Item, Text, Widget, WidgetTrait as _},
Window,
},
};

pub fn log_widget(clipboard: &Option<Rc<RefCell<Clipboard>>>) -> Widget<'static> {
let builder = Text::builder()
.id(view_id::tab_pod_widget_log)
.widget_config(&WidgetConfig::builder().title("Log").build())
.wrap()
.follow()
.block_injection(block_injection())
.action(UserEvent::from(KeyCode::Enter), add_blankline());

if let Some(cb) = clipboard {
builder.clipboard(cb.clone())
} else {
builder
}
.build()
.into()
}

fn block_injection() -> impl Fn(&Text, bool, bool) -> Block<'static> {
|text: &Text, is_active: bool, is_mouse_over: bool| {
let (index, size) = text.state();

let mut config = text.widget_config().clone();

*config.title_mut() = format!("Log [{}/{}]", index, size).into();

config.render_block(text.can_activate() && is_active, is_mouse_over)
}
}

fn add_blankline() -> impl Fn(&mut Window) -> EventResult {
move |w: &mut Window| {
let w = w.find_widget_mut(view_id::tab_pod_widget_log);

w.select_last();
w.append_widget_item(Item::Single(Default::default()));

EventResult::Nop
}
}
68 changes: 68 additions & 0 deletions src/features/pod/view/widgets/log_query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::{cell::RefCell, rc::Rc};

use crossbeam::channel::Sender;
use crossterm::event::KeyCode;

use crate::{
action::view_id,
context::Namespace,
features::pod::{
kube::{LogConfig, LogPrefixType},
message::LogMessage,
},
message::{Message, UserEvent},
ui::{
event::EventResult,
widget::{
config::WidgetConfig, input::InputFormBuilder, SelectedItem, Widget, WidgetTrait as _,
},
Window,
},
};

pub fn log_query_widget(tx: &Sender<Message>, namespaces: Rc<RefCell<Namespace>>) -> Widget<'static> {
let tx = tx.clone();

InputFormBuilder::default()
.id(view_id::tab_pod_widget_log_query)
.widget_config(WidgetConfig::builder().title("Log Query").build())
.actions(UserEvent::from(KeyCode::Enter), exec_query(tx, namespaces))
.build()
.into()
}

fn exec_query(
tx: Sender<Message>,
namespaces: Rc<RefCell<Namespace>>,
) -> impl Fn(&mut Window) -> EventResult {
move |w: &mut Window| {
let widget = w.find_widget_mut(view_id::tab_pod_widget_log_query);

let Some(SelectedItem::Literal { metadata: _, item }) = widget.widget_item() else {
return EventResult::Ignore;
};

if item == "?" || item == "help" {
widget.clear();
w.open_popup(view_id::tab_pod_widget_log_query_help);
return EventResult::Nop;
}

w.widget_clear(view_id::tab_pod_widget_log);

let namespaces = namespaces.borrow();

let prefix_type = if 1 < namespaces.len() {
LogPrefixType::All
} else {
LogPrefixType::PodAndContainer
};

let config = LogConfig::new(item, namespaces.to_owned(), prefix_type);

tx.send(LogMessage::Request(config).into())
.expect("Failed to send LogMessage::Request");

EventResult::Ignore
}
}
58 changes: 58 additions & 0 deletions src/features/pod/view/widgets/log_query_help.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crossterm::event::KeyCode;
use indoc::indoc;

use crate::{
action::view_id,
message::UserEvent,
ui::{
event::EventResult,
widget::{config::WidgetConfig, Text, Widget},
Window,
},
};

pub fn log_query_help_widget() -> Widget<'static> {
Text::builder()
.id(view_id::tab_pod_widget_log_query_help)
.widget_config(&WidgetConfig::builder().title("Log Query Help").build())
.items(content())
.action(UserEvent::from(KeyCode::Enter), close_popup())
.build()
.into()
}

fn content() -> Vec<String> {
indoc! {r#"
Usage: QUERY [ QUERY ]...
Queries:
pod:<regex> (alias: pods, po, p)
!pod:<regex> (alias: !pods, !po, p)
container:<regex> (alias: containers, co, c)
!container:<regex> (alias: !containers, !co, !c)
log:<regex> (alias: logs, lo, l)
!log:<regex> (alias: !logs, !lo, !l)
label:<selector> (alias: labels)
field:<selector> (alias: fields)
<resource>/<name>
Resources:
pod (alias: pods, po)
replicaset (alias: replicasets, rs)
deployment (alias: deployments, deploy)
statefulset (alias: statefulsets, sts)
daemonset (alias: daemonsets, ds)
service (alias: services, svc)
job (alias: jobs)
"# }
.lines()
.map(ToString::to_string)
.collect()
}

fn close_popup() -> impl Fn(&mut Window) -> EventResult {
move |w: &mut Window| {
w.close_popup();
EventResult::Nop
}
}
Loading

0 comments on commit 873b77c

Please sign in to comment.