refactor: rename plugin features with type prefix for consistency
- Plugin features now use type_ prefix (meta_magic, filter_grep, etc.) - Added meta_all_musl and filter_all_musl for MUSL-compatible builds - grep filter plugin made optional via filter_grep feature flag - Removed regex crate from grep-related code, uses strip_prefix instead - Updated CHANGELOG.md with breaking change documentation
This commit is contained in:
@@ -2,6 +2,7 @@ use std::io::{Read, Result, Write};
|
||||
use std::str::FromStr;
|
||||
use strum::EnumString;
|
||||
|
||||
#[cfg(feature = "filter_grep")]
|
||||
pub mod grep;
|
||||
/// Filter plugin module for processing input streams.
|
||||
///
|
||||
@@ -16,7 +17,7 @@ pub mod grep;
|
||||
/// ```
|
||||
/// # use std::io::{Read, Write};
|
||||
/// # use keep::filter_plugin::parse_filter_string;
|
||||
/// let mut chain = parse_filter_string("head_lines(10)|grep(pattern=error)")?;
|
||||
/// let mut chain = parse_filter_string("head_lines(10)|tail_lines(5)")?;
|
||||
/// # let mut reader: &mut dyn Read = &mut std::io::empty();
|
||||
/// # let mut writer: Vec<u8> = Vec::new();
|
||||
/// # chain.filter(&mut reader, &mut writer)?;
|
||||
@@ -26,12 +27,13 @@ pub mod head;
|
||||
pub mod skip;
|
||||
pub mod strip_ansi;
|
||||
pub mod tail;
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
pub mod tokens;
|
||||
pub mod utils;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(feature = "filter_grep")]
|
||||
pub use grep::GrepFilter;
|
||||
pub use head::{HeadBytesFilter, HeadLinesFilter};
|
||||
pub use skip::{SkipBytesFilter, SkipLinesFilter};
|
||||
@@ -199,13 +201,14 @@ pub enum FilterType {
|
||||
TailLines,
|
||||
SkipBytes,
|
||||
SkipLines,
|
||||
#[cfg(feature = "filter_grep")]
|
||||
Grep,
|
||||
StripAnsi,
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
HeadTokens,
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
SkipTokens,
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
TailTokens,
|
||||
}
|
||||
|
||||
@@ -356,9 +359,8 @@ impl FilterChain {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use keep::filter_plugin::{FilterChain, GrepFilter};
|
||||
/// # use keep::filter_plugin::FilterChain;
|
||||
/// let mut chain = FilterChain::new();
|
||||
/// chain.add_plugin(Box::new(GrepFilter::new("error".to_string()).unwrap()));
|
||||
/// ```
|
||||
pub fn add_plugin(&mut self, plugin: Box<dyn FilterPlugin>) {
|
||||
self.plugins.push(plugin);
|
||||
@@ -535,6 +537,7 @@ fn create_filter_with_options(
|
||||
// Get the default options for this filter type by creating a temporary instance
|
||||
// To do this, we need to create a default instance of the appropriate filter
|
||||
let option_defs = match filter_type {
|
||||
#[cfg(feature = "filter_grep")]
|
||||
FilterType::Grep => grep::GrepFilter::new("".to_string())?.options(),
|
||||
FilterType::HeadBytes => head::HeadBytesFilter::new(0).options(),
|
||||
FilterType::HeadLines => head::HeadLinesFilter::new(0).options(),
|
||||
@@ -543,11 +546,11 @@ fn create_filter_with_options(
|
||||
FilterType::SkipBytes => skip::SkipBytesFilter::new(0).options(),
|
||||
FilterType::SkipLines => skip::SkipLinesFilter::new(0).options(),
|
||||
FilterType::StripAnsi => strip_ansi::StripAnsiFilter::new().options(),
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
FilterType::HeadTokens => tokens::HeadTokensFilter::new(0).options(),
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
FilterType::SkipTokens => tokens::SkipTokensFilter::new(0).options(),
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
FilterType::TailTokens => tokens::TailTokensFilter::new(0).options(),
|
||||
};
|
||||
|
||||
@@ -617,6 +620,7 @@ fn create_specific_filter(
|
||||
options: &HashMap<String, serde_json::Value>,
|
||||
) -> Result<Box<dyn FilterPlugin>> {
|
||||
match filter_type {
|
||||
#[cfg(feature = "filter_grep")]
|
||||
FilterType::Grep => {
|
||||
let pattern = options
|
||||
.get("pattern")
|
||||
@@ -717,7 +721,7 @@ fn create_specific_filter(
|
||||
}
|
||||
Ok(Box::new(strip_ansi::StripAnsiFilter::new()))
|
||||
}
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
FilterType::HeadTokens => {
|
||||
let count = options
|
||||
.get("count")
|
||||
@@ -735,7 +739,7 @@ fn create_specific_filter(
|
||||
f.encoding = encoding;
|
||||
Ok(Box::new(f))
|
||||
}
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
FilterType::SkipTokens => {
|
||||
let count = options
|
||||
.get("count")
|
||||
@@ -753,7 +757,7 @@ fn create_specific_filter(
|
||||
f.encoding = encoding;
|
||||
Ok(Box::new(f))
|
||||
}
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
FilterType::TailTokens => {
|
||||
let count = options
|
||||
.get("count")
|
||||
@@ -774,7 +778,7 @@ fn create_specific_filter(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
fn parse_encoding_option(
|
||||
options: &std::collections::HashMap<String, serde_json::Value>,
|
||||
) -> (crate::tokenizer::TokenEncoding, crate::tokenizer::Tokenizer) {
|
||||
|
||||
17
src/lib.rs
17
src/lib.rs
@@ -45,7 +45,7 @@ pub mod services;
|
||||
#[cfg(feature = "client")]
|
||||
pub mod client;
|
||||
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
pub mod tokenizer;
|
||||
|
||||
// Re-export Args struct for library usage
|
||||
@@ -56,9 +56,12 @@ pub use services::CoreError;
|
||||
|
||||
// Import all filter plugins to ensure they register themselves
|
||||
#[allow(unused_imports)]
|
||||
use filter_plugin::{grep, head, skip, strip_ansi, tail};
|
||||
#[cfg(feature = "filter_grep")]
|
||||
use filter_plugin::grep;
|
||||
#[allow(unused_imports)]
|
||||
use filter_plugin::{head, skip, strip_ansi, tail};
|
||||
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
#[allow(unused_imports)]
|
||||
use filter_plugin::tokens as token_filters;
|
||||
|
||||
@@ -66,19 +69,19 @@ use crate::meta_plugin::{
|
||||
cwd, digest, env, exec, hostname, keep_pid, read_rate, read_time, shell, shell_pid, user,
|
||||
};
|
||||
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
#[allow(unused_imports)]
|
||||
use crate::meta_plugin::magic_file;
|
||||
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
#[allow(unused_imports)]
|
||||
use crate::meta_plugin::tokens;
|
||||
|
||||
#[cfg(feature = "infer")]
|
||||
#[cfg(feature = "meta_infer")]
|
||||
#[allow(unused_imports)]
|
||||
use crate::meta_plugin::infer_plugin;
|
||||
|
||||
#[cfg(feature = "tree_magic_mini")]
|
||||
#[cfg(feature = "meta_tree_magic_mini")]
|
||||
#[allow(unused_imports)]
|
||||
use crate::meta_plugin::tree_magic_mini;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
use magic::{Cookie, CookieFlags};
|
||||
#[cfg(not(feature = "magic"))]
|
||||
#[cfg(not(feature = "meta_magic"))]
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use std::io::{self, Write};
|
||||
@@ -16,12 +16,12 @@ use crate::meta_plugin::{
|
||||
// separate cookies can be used from different threads concurrently without
|
||||
// synchronization. Using thread_local! avoids unsafe impl Send since the
|
||||
// storage is inherently !Send.
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
thread_local! {
|
||||
static MAGIC_COOKIE: std::cell::RefCell<Option<Cookie>> = const { std::cell::RefCell::new(None) };
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
#[derive(Debug)]
|
||||
pub struct MagicFileMetaPluginImpl {
|
||||
buffer: Vec<u8>,
|
||||
@@ -30,7 +30,7 @@ pub struct MagicFileMetaPluginImpl {
|
||||
base: BaseMetaPlugin,
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
impl MagicFileMetaPluginImpl {
|
||||
pub fn new(
|
||||
options: Option<std::collections::HashMap<String, serde_yaml::Value>>,
|
||||
@@ -113,7 +113,7 @@ impl MagicFileMetaPluginImpl {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
impl MetaPlugin for MagicFileMetaPluginImpl {
|
||||
fn is_finalized(&self) -> bool {
|
||||
self.is_finalized
|
||||
@@ -222,10 +222,10 @@ impl MetaPlugin for MagicFileMetaPluginImpl {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
pub use MagicFileMetaPluginImpl as MagicFileMetaPlugin;
|
||||
|
||||
#[cfg(not(feature = "magic"))]
|
||||
#[cfg(not(feature = "meta_magic"))]
|
||||
#[derive(Debug)]
|
||||
pub struct FallbackMagicFileMetaPlugin {
|
||||
buffer: Vec<u8>,
|
||||
@@ -234,7 +234,7 @@ pub struct FallbackMagicFileMetaPlugin {
|
||||
base: BaseMetaPlugin,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "magic"))]
|
||||
#[cfg(not(feature = "meta_magic"))]
|
||||
impl FallbackMagicFileMetaPlugin {
|
||||
pub fn new(
|
||||
options: Option<std::collections::HashMap<String, serde_yaml::Value>>,
|
||||
@@ -336,7 +336,7 @@ impl FallbackMagicFileMetaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "magic"))]
|
||||
#[cfg(not(feature = "meta_magic"))]
|
||||
impl MetaPlugin for FallbackMagicFileMetaPlugin {
|
||||
fn is_finalized(&self) -> bool {
|
||||
self.is_finalized
|
||||
@@ -441,7 +441,7 @@ impl MetaPlugin for FallbackMagicFileMetaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "magic"))]
|
||||
#[cfg(not(feature = "meta_magic"))]
|
||||
pub use FallbackMagicFileMetaPlugin as MagicFileMetaPlugin;
|
||||
|
||||
use crate::meta_plugin::register_meta_plugin;
|
||||
|
||||
@@ -8,7 +8,7 @@ pub mod digest;
|
||||
pub mod env;
|
||||
pub mod exec;
|
||||
pub mod hostname;
|
||||
#[cfg(feature = "infer")]
|
||||
#[cfg(feature = "meta_infer")]
|
||||
pub mod infer_plugin;
|
||||
pub mod keep_pid;
|
||||
pub mod magic_file;
|
||||
@@ -17,32 +17,32 @@ pub mod read_time;
|
||||
pub mod shell;
|
||||
pub mod shell_pid;
|
||||
pub mod text;
|
||||
#[cfg(feature = "tokens")]
|
||||
#[cfg(feature = "meta_tokens")]
|
||||
pub mod tokens;
|
||||
#[cfg(feature = "tree_magic_mini")]
|
||||
#[cfg(feature = "meta_tree_magic_mini")]
|
||||
pub mod tree_magic_mini;
|
||||
pub mod user;
|
||||
|
||||
pub use digest::DigestMetaPlugin;
|
||||
pub use exec::MetaPluginExec;
|
||||
#[cfg(feature = "magic")]
|
||||
#[cfg(feature = "meta_magic")]
|
||||
pub use magic_file::MagicFileMetaPlugin;
|
||||
// pub use text::TextMetaPlugin; // Removed duplicate
|
||||
pub use cwd::CwdMetaPlugin;
|
||||
pub use env::EnvMetaPlugin;
|
||||
pub use hostname::HostnameMetaPlugin;
|
||||
#[cfg(feature = "infer")]
|
||||
#[cfg(feature = "meta_infer")]
|
||||
pub use infer_plugin::InferMetaPlugin;
|
||||
pub use keep_pid::KeepPidMetaPlugin;
|
||||
pub use read_rate::ReadRateMetaPlugin;
|
||||
pub use read_time::ReadTimeMetaPlugin;
|
||||
pub use shell::ShellMetaPlugin;
|
||||
pub use shell_pid::ShellPidMetaPlugin;
|
||||
#[cfg(feature = "tree_magic_mini")]
|
||||
#[cfg(feature = "meta_tree_magic_mini")]
|
||||
pub use tree_magic_mini::TreeMagicMiniMetaPlugin;
|
||||
pub use user::UserMetaPlugin;
|
||||
|
||||
#[cfg(not(feature = "magic"))]
|
||||
#[cfg(not(feature = "meta_magic"))]
|
||||
pub use magic_file::FallbackMagicFileMetaPlugin as MagicFileMetaPlugin;
|
||||
|
||||
type PluginConstructor = fn(
|
||||
|
||||
@@ -22,7 +22,6 @@ use clap::Command;
|
||||
use clap::error::ErrorKind;
|
||||
use comfy_table::{Attribute, Cell, ContentArrangement, Table};
|
||||
use log::debug;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
@@ -56,23 +55,18 @@ pub enum OutputFormat {
|
||||
Yaml,
|
||||
}
|
||||
|
||||
static KEEP_META_RE: std::sync::LazyLock<Regex> =
|
||||
std::sync::LazyLock::new(|| Regex::new(r"^KEEP_META_(.+)$").unwrap());
|
||||
|
||||
pub const IMPORT_FORMAT_ERROR: &str =
|
||||
"Unsupported import format: {} (expected .keep.tar or .meta.yml)";
|
||||
|
||||
pub fn get_meta_from_env() -> HashMap<String, String> {
|
||||
debug!("COMMON: Getting meta from KEEP_META_*");
|
||||
let mut meta_env: HashMap<String, String> = HashMap::new();
|
||||
const PREFIX: &str = "KEEP_META_";
|
||||
for (key, value) in env::vars() {
|
||||
if let Some(meta_name_caps) = KEEP_META_RE.captures(key.as_str()) {
|
||||
let name = meta_name_caps.get(1).map(|m| m.as_str().to_string());
|
||||
if let Some(name) = name {
|
||||
if name != "PLUGINS" {
|
||||
debug!("COMMON: Found meta: {}={}", name, value);
|
||||
meta_env.insert(name, value);
|
||||
}
|
||||
if let Some(name) = key.strip_prefix(PREFIX) {
|
||||
if !name.is_empty() && name != "PLUGINS" {
|
||||
debug!("COMMON: Found meta: {}={}", name, value);
|
||||
meta_env.insert(name.to_string(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,6 +532,7 @@ pub struct TagsQuery {
|
||||
/// ```rust
|
||||
/// use keep::modes::server::common::ListItemsQuery;
|
||||
/// let query = ListItemsQuery {
|
||||
/// ids: None,
|
||||
/// tags: Some("important".to_string()),
|
||||
/// order: Some("newest".to_string()),
|
||||
/// start: Some(0),
|
||||
|
||||
@@ -179,12 +179,12 @@ async fn run_server(
|
||||
let addr: SocketAddr = bind_address.parse()?;
|
||||
|
||||
// Warn if authentication is enabled without TLS
|
||||
if config.password.is_some() || config.password_hash.is_some() || config.jwt_secret.is_some() {
|
||||
if config.cert_file.is_none() || config.key_file.is_none() {
|
||||
log::warn!(
|
||||
"SECURITY: Authentication enabled but TLS is not configured. Credentials will be transmitted in plain text!"
|
||||
);
|
||||
}
|
||||
if (config.password.is_some() || config.password_hash.is_some() || config.jwt_secret.is_some())
|
||||
&& (config.cert_file.is_none() || config.key_file.is_none())
|
||||
{
|
||||
log::warn!(
|
||||
"SECURITY: Authentication enabled but TLS is not configured. Credentials will be transmitted in plain text!"
|
||||
);
|
||||
}
|
||||
|
||||
// Build the app into a service
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
#[cfg(test)]
|
||||
pub mod digest_tests;
|
||||
|
||||
#[cfg(feature = "infer")]
|
||||
#[cfg(feature = "meta_infer")]
|
||||
#[cfg(test)]
|
||||
pub mod infer_tests;
|
||||
|
||||
#[cfg(feature = "tree_magic_mini")]
|
||||
#[cfg(feature = "meta_tree_magic_mini")]
|
||||
#[cfg(test)]
|
||||
pub mod tree_magic_mini_tests;
|
||||
|
||||
Reference in New Issue
Block a user