Skip to content

Commit 477e1c2

Browse files
authored
fixing wrap bug - filling out changelog (#43)
Signed-off-by: Daniel Guns <danbguns@gmail.com>
1 parent 87b21b0 commit 477e1c2

16 files changed

Lines changed: 232 additions & 231 deletions

CHANGELOG.md

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,68 +18,73 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
## [0.4.0] - 2025-11-20
1919

2020
### Added
21-
-
21+
- Support for Flux operator CRDs (#33)
22+
- Screenshot image to documentation (#31, #32)
2223

23-
### Changed
24-
-
24+
## [0.3.1] - 2025-11-20
2525

2626
### Fixed
27-
-
28-
29-
## [0.3.1] - 2025-11-20
27+
- Fixed trace functionality (#28)
28+
- Replaced hardcoded strings with configuration (#27)
3029

31-
### Added
32-
-
30+
## [0.3.0] - 2025-11-18
3331

3432
### Changed
35-
-
33+
- Default mode set to readOnly (#23)
3634

37-
### Fixed
38-
-
35+
## [0.2.4] - 2025-11-16
3936

40-
## [0.3.0] - 2025-11-18
37+
### Changed
38+
- Workflow tweaks and improvements (#19)
4139

42-
### Added
43-
-
40+
## [0.2.2] - 2025-11-16
4441

4542
### Changed
46-
-
43+
- Code hygiene improvements (#16)
44+
- Workflow release changes (#16)
4745

48-
### Fixed
49-
-
46+
## [0.2.1] - 2025-11-16
5047

51-
## [0.2.4] - 2025-11-16
48+
### Changed
49+
- Version bump to 0.2.1
5250

53-
### Added
54-
-
51+
## [0.2.0] - 2025-11-16
5552

56-
### Changed
57-
-
53+
### Added
54+
- ReadOnly mode support
55+
- Configuration and config-cli functionality
5856

5957
### Fixed
60-
-
58+
- OpenSSL build issues (#10, #8)
59+
- Windows temporary file handling (#9)
6160

62-
## [0.2.3] - 2025-11-16
61+
## [0.1.5] - 2025-11-16
6362

6463
### Added
65-
-
64+
- OpenSSL support
65+
- Debug logging (#7)
66+
- Proxy support (#6)
6667

67-
### Changed
68-
-
68+
## [0.1.4] - 2025-11-16
6969

70-
### Fixed
71-
-
70+
### Added
71+
- Homebrew support (#5)
7272

73-
## [0.2.2] - 2025-11-16
73+
## [0.1.3] - 2025-11-16
7474

7575
### Added
76-
-
76+
- Homebrew macOS architecture support (#4)
7777

78-
### Changed
79-
-
78+
## [0.1.2] - 2025-11-16
8079

81-
### Fixed
82-
-
80+
### Added
81+
- Homebrew macOS architecture support (#3)
82+
- macOS M-chip (Apple Silicon) support (#2)
83+
84+
## [0.1.1] - 2025-11-16
85+
86+
### Added
87+
- Binstall support
8388

8489
## [0.1.0] - YYYY-MM-DD
8590

src/models/_generated/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
#![allow(clippy::all)]
77
#![allow(unknown_lints)]
8-
#![allow(doc_markdown)]
8+
#![allow(clippy::doc_markdown)]
99
#![allow(clippy::doc_overindented_list_items)]
1010

1111
pub mod flux_operator_fluxinstances;

src/models/flux_resource_kind.rs

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! type safety for resource kind references.
66
77
use std::fmt;
8+
use std::str::FromStr;
89

910
/// Enumeration of all Flux CRD resource kinds
1011
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -61,29 +62,10 @@ impl FluxResourceKind {
6162
}
6263
}
6364

64-
/// Try to parse a string into a FluxResourceKind
65-
pub fn from_str(s: &str) -> Option<Self> {
66-
match s {
67-
"GitRepository" => Some(FluxResourceKind::GitRepository),
68-
"OCIRepository" => Some(FluxResourceKind::OCIRepository),
69-
"HelmRepository" => Some(FluxResourceKind::HelmRepository),
70-
"Bucket" => Some(FluxResourceKind::Bucket),
71-
"HelmChart" => Some(FluxResourceKind::HelmChart),
72-
"ExternalArtifact" => Some(FluxResourceKind::ExternalArtifact),
73-
"Kustomization" => Some(FluxResourceKind::Kustomization),
74-
"HelmRelease" => Some(FluxResourceKind::HelmRelease),
75-
"ImageRepository" => Some(FluxResourceKind::ImageRepository),
76-
"ImagePolicy" => Some(FluxResourceKind::ImagePolicy),
77-
"ImageUpdateAutomation" => Some(FluxResourceKind::ImageUpdateAutomation),
78-
"Alert" => Some(FluxResourceKind::Alert),
79-
"Provider" => Some(FluxResourceKind::Provider),
80-
"Receiver" => Some(FluxResourceKind::Receiver),
81-
"ResourceSet" => Some(FluxResourceKind::ResourceSet),
82-
"ResourceSetInputProvider" => Some(FluxResourceKind::ResourceSetInputProvider),
83-
"FluxReport" => Some(FluxResourceKind::FluxReport),
84-
"FluxInstance" => Some(FluxResourceKind::FluxInstance),
85-
_ => None,
86-
}
65+
/// Try to parse a string into a FluxResourceKind, returning None if invalid
66+
/// Use this when you want Option<Self> instead of Result<Self, String>
67+
pub fn parse_optional(s: &str) -> Option<Self> {
68+
s.parse().ok()
8769
}
8870

8971
/// Try to parse a string (case-insensitive) into a FluxResourceKind
@@ -134,6 +116,34 @@ impl From<FluxResourceKind> for String {
134116
}
135117
}
136118

119+
impl FromStr for FluxResourceKind {
120+
type Err = String;
121+
122+
fn from_str(s: &str) -> Result<Self, Self::Err> {
123+
match s {
124+
"GitRepository" => Ok(FluxResourceKind::GitRepository),
125+
"OCIRepository" => Ok(FluxResourceKind::OCIRepository),
126+
"HelmRepository" => Ok(FluxResourceKind::HelmRepository),
127+
"Bucket" => Ok(FluxResourceKind::Bucket),
128+
"HelmChart" => Ok(FluxResourceKind::HelmChart),
129+
"ExternalArtifact" => Ok(FluxResourceKind::ExternalArtifact),
130+
"Kustomization" => Ok(FluxResourceKind::Kustomization),
131+
"HelmRelease" => Ok(FluxResourceKind::HelmRelease),
132+
"ImageRepository" => Ok(FluxResourceKind::ImageRepository),
133+
"ImagePolicy" => Ok(FluxResourceKind::ImagePolicy),
134+
"ImageUpdateAutomation" => Ok(FluxResourceKind::ImageUpdateAutomation),
135+
"Alert" => Ok(FluxResourceKind::Alert),
136+
"Provider" => Ok(FluxResourceKind::Provider),
137+
"Receiver" => Ok(FluxResourceKind::Receiver),
138+
"ResourceSet" => Ok(FluxResourceKind::ResourceSet),
139+
"ResourceSetInputProvider" => Ok(FluxResourceKind::ResourceSetInputProvider),
140+
"FluxReport" => Ok(FluxResourceKind::FluxReport),
141+
"FluxInstance" => Ok(FluxResourceKind::FluxInstance),
142+
_ => Err(format!("Unknown Flux resource kind: {}", s)),
143+
}
144+
}
145+
}
146+
137147
#[cfg(test)]
138148
mod tests {
139149
use super::*;
@@ -148,14 +158,14 @@ mod tests {
148158
#[test]
149159
fn test_from_str() {
150160
assert_eq!(
151-
FluxResourceKind::from_str("GitRepository"),
161+
FluxResourceKind::parse_optional("GitRepository"),
152162
Some(FluxResourceKind::GitRepository)
153163
);
154164
assert_eq!(
155-
FluxResourceKind::from_str("OCIRepository"),
165+
FluxResourceKind::parse_optional("OCIRepository"),
156166
Some(FluxResourceKind::OCIRepository)
157167
);
158-
assert_eq!(FluxResourceKind::from_str("Unknown"), None);
168+
assert_eq!(FluxResourceKind::parse_optional("Unknown"), None);
159169
}
160170

161171
#[test]

src/trace/core.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub async fn trace_object(
3535

3636
// Check if the initial object itself is a Kustomization or HelmRelease
3737
use crate::models::FluxResourceKind;
38-
let initial_kind = FluxResourceKind::from_str(resource_type);
38+
let initial_kind = FluxResourceKind::parse_optional(resource_type);
3939
if matches!(
4040
initial_kind,
4141
Some(FluxResourceKind::Kustomization) | Some(FluxResourceKind::HelmRelease)
@@ -129,7 +129,7 @@ async fn walk_owner_chain(
129129

130130
// If this is a Kustomization or HelmRelease, resolve its source
131131
if matches!(
132-
FluxResourceKind::from_str(&flux_owner.kind),
132+
FluxResourceKind::parse_optional(&flux_owner.kind),
133133
Some(FluxResourceKind::Kustomization) | Some(FluxResourceKind::HelmRelease)
134134
) {
135135
let source =
@@ -217,7 +217,7 @@ async fn walk_owner_chain(
217217

218218
// If this is a Kustomization or HelmRelease, resolve its source
219219
if matches!(
220-
FluxResourceKind::from_str(owner_kind),
220+
FluxResourceKind::parse_optional(owner_kind),
221221
Some(FluxResourceKind::Kustomization) | Some(FluxResourceKind::HelmRelease)
222222
) {
223223
let source =
@@ -274,7 +274,7 @@ async fn resolve_source(
274274
) -> Result<Option<TraceNode>> {
275275
use crate::models::FluxResourceKind;
276276

277-
match FluxResourceKind::from_str(&node.kind) {
277+
match FluxResourceKind::parse_optional(&node.kind) {
278278
Some(FluxResourceKind::Kustomization) => {
279279
resolve_kustomization_source(client, node, default_ns).await
280280
}
@@ -527,7 +527,7 @@ fn parse_namespaced_name(ref_str: &str, default_ns: &str) -> (String, String) {
527527

528528
/// Check if a resource kind is a Flux resource
529529
fn is_flux_resource(kind: &str) -> bool {
530-
FluxResourceKind::from_str(kind).is_some()
530+
FluxResourceKind::parse_optional(kind).is_some()
531531
}
532532

533533
/// Find Flux owner from labels

src/tui/api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::watcher::{
1212

1313
/// Get GroupVersionKind for a resource type
1414
pub fn get_gvk_for_resource_type(resource_type: &str) -> Result<(String, String, String)> {
15-
let (group, version, plural) = match FluxResourceKind::from_str(resource_type) {
15+
let (group, version, plural) = match FluxResourceKind::parse_optional(resource_type) {
1616
Some(FluxResourceKind::GitRepository) => (
1717
GitRepository::api_group(),
1818
GitRepository::api_version(),

src/tui/app.rs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,24 @@ use ratatui::{
1414
use std::collections::HashMap;
1515
use std::sync::{Arc, RwLock};
1616

17+
// Type aliases for complex types
18+
type TraceRequest = (
19+
String,
20+
String,
21+
String,
22+
kube::Client,
23+
tokio::sync::oneshot::Sender<anyhow::Result<crate::tui::trace::TraceResult>>,
24+
);
25+
26+
type OperationRequest = (
27+
String,
28+
String,
29+
String,
30+
char,
31+
kube::Client,
32+
tokio::sync::oneshot::Sender<anyhow::Result<()>>,
33+
);
34+
1735
/// Main application state
1836
pub struct App {
1937
state: ResourceState,
@@ -166,15 +184,7 @@ impl App {
166184
self.yaml_fetch_pending = None;
167185
}
168186

169-
pub fn trigger_trace(
170-
&mut self,
171-
) -> Option<(
172-
String,
173-
String,
174-
String,
175-
kube::Client,
176-
tokio::sync::oneshot::Sender<anyhow::Result<crate::tui::trace::TraceResult>>,
177-
)> {
187+
pub fn trigger_trace(&mut self) -> Option<TraceRequest> {
178188
if let Some((ref resource_type, ref namespace, ref name)) = self.trace_pending {
179189
if let Some(ref client) = self.kube_client {
180190
let (tx, rx) = tokio::sync::oneshot::channel();
@@ -606,39 +616,27 @@ impl App {
606616
op_key: char,
607617
) {
608618
// Check readonly mode - prevent modification operations
609-
if self.config.read_only {
610-
if self.operation_registry.get_by_keybinding(op_key).is_some() {
611-
// All operations are modifications, so block them all in readonly mode
612-
self.status_message = Some((
613-
"Readonly mode is enabled. Use :readonly to toggle write actions.".to_string(),
614-
true,
615-
));
616-
return;
617-
}
619+
if self.config.read_only && self.operation_registry.get_by_keybinding(op_key).is_some() {
620+
// All operations are modifications, so block them all in readonly mode
621+
self.status_message = Some((
622+
"Readonly mode is enabled. Use :readonly to toggle write actions.".to_string(),
623+
true,
624+
));
625+
return;
618626
}
619627

620-
if self.operation_registry.get_by_keybinding(op_key).is_some() {
621-
if self.kube_client.is_some() {
622-
let rt = resource_type.to_string();
623-
let ns = namespace.to_string();
624-
let n = name.to_string();
628+
if self.operation_registry.get_by_keybinding(op_key).is_some() && self.kube_client.is_some()
629+
{
630+
let rt = resource_type.to_string();
631+
let ns = namespace.to_string();
632+
let n = name.to_string();
625633

626-
// Mark operation as pending - will be executed in main loop
627-
self.pending_operation = Some((rt, ns, n, op_key));
628-
}
634+
// Mark operation as pending - will be executed in main loop
635+
self.pending_operation = Some((rt, ns, n, op_key));
629636
}
630637
}
631638

632-
pub fn trigger_operation_execution(
633-
&mut self,
634-
) -> Option<(
635-
String,
636-
String,
637-
String,
638-
char,
639-
kube::Client,
640-
tokio::sync::oneshot::Sender<anyhow::Result<()>>,
641-
)> {
639+
pub fn trigger_operation_execution(&mut self) -> Option<OperationRequest> {
642640
if let Some((ref resource_type, ref namespace, ref name, op_key)) = self.pending_operation {
643641
if let Some(ref client) = self.kube_client {
644642
if self.operation_registry.get_by_keybinding(op_key).is_some() {

src/tui/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async fn fetch_resource_yaml(
5757
}};
5858
}
5959

60-
match FluxResourceKind::from_str(resource_type) {
60+
match FluxResourceKind::parse_optional(resource_type) {
6161
Some(FluxResourceKind::GitRepository) => fetch_resource!(GitRepository),
6262
Some(FluxResourceKind::OCIRepository) => fetch_resource!(OCIRepository),
6363
Some(FluxResourceKind::HelmRepository) => fetch_resource!(HelmRepository),

0 commit comments

Comments
 (0)