Skip to content

Commit ef6ccc7

Browse files
Use relative path. Now fails on invalid paths. Add a readme
1 parent b5d9c80 commit ef6ccc7

File tree

4 files changed

+87
-37
lines changed

4 files changed

+87
-37
lines changed

Cargo.lock

+8-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
[package]
22
name = "kree"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
99
clap = { version = "4.0", features = ["derive"] }
10+
relative-path = "1.7.2"
1011
serde = { version = "1.0", features = ["derive"] }
1112
serde_json = "1.0.87"
1213
serde_yaml = "0.9"

README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Kree (Kustomization Tree)
2+
3+
Kree let you list all the resources included by a specific kustomizaition file.
4+
5+
Limitations:
6+
- Remote resources are currently ignored and will no appear in the ouput.
7+
8+
## Example
9+
10+
```bash
11+
> kree --help
12+
Usage: kree [OPTIONS] <PATH>
13+
14+
Arguments:
15+
<PATH>
16+
Path to the kustomization file or directory
17+
18+
Options:
19+
-f, --format <FORMAT>
20+
Output format
21+
22+
[default: text]
23+
24+
Possible values:
25+
- text: One path per line
26+
- json: JSON
27+
28+
-h, --help
29+
Print help information (use `-h` for a summary)
30+
```
31+
```bash
32+
> kree ../kustomize/examples/multibases
33+
../kustomize/examples/multibases/base/kustomization.yaml
34+
../kustomize/examples/multibases/base/pod.yaml
35+
../kustomize/examples/multibases/dev/kustomization.yaml
36+
../kustomize/examples/multibases/kustomization.yaml
37+
../kustomize/examples/multibases/production/kustomization.yaml
38+
../kustomize/examples/multibases/staging/kustomization.yaml
39+
```

src/main.rs

+38-35
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use clap::{Parser, ValueEnum};
2+
use relative_path::RelativePathBuf;
23
use serde::Deserialize;
34
use serde_json::json;
45
use serde_yaml;
56
use std::{
7+
env::current_dir,
68
fs,
79
io,
810
path::PathBuf,
@@ -13,7 +15,7 @@ use std::{
1315
#[command()]
1416
struct Args {
1517
/// Path to the kustomization file or directory
16-
path: PathBuf,
18+
path: RelativePathBuf,
1719

1820
/// Output format
1921
#[arg(short, long, value_enum, default_value = "text")]
@@ -37,35 +39,33 @@ struct Kustomization {
3739
}
3840

3941

40-
fn canonical_path(path: PathBuf) -> io::Result<PathBuf> {
41-
let mut canonical = path.canonicalize()?;
42+
fn normalize(root: &PathBuf, mut path: RelativePathBuf) -> RelativePathBuf {
43+
path.normalize();
4244

43-
if canonical.is_file() {
44-
return Ok(canonical);
45+
if path.to_logical_path(&root).is_dir() {
46+
path.push("kustomization.yml");
4547
}
4648

47-
if canonical.is_dir() {
48-
canonical.push("kustomization.yml");
49-
50-
if canonical.is_file() {
51-
return Ok(canonical);
52-
}
49+
if path.to_logical_path(&root).is_file() {
50+
return path;
51+
} else {
52+
path.set_extension("yaml");
53+
}
54+
55+
if path.to_logical_path(&root).is_file() {
56+
return path;
5357
}
5458

55-
let error = io::Error::new(
56-
io::ErrorKind::Other,
57-
format!("Invalid path {}", canonical.display())
58-
);
59-
return Err(error);
59+
panic!("Unable to normalize path {path}");
6060
}
6161

6262

63-
fn read_file(path: PathBuf) -> io::Result<String> {
63+
fn read_file(path: &PathBuf) -> io::Result<String> {
6464
return fs::read_to_string(path);
6565
}
6666

6767

68-
fn deserialize(path: PathBuf) -> Vec<Kustomization> {
68+
fn deserialize(path: &PathBuf) -> Vec<Kustomization> {
6969
let content = read_file(path).unwrap();
7070

7171
return serde_yaml::Deserializer::from_str(&content)
@@ -74,34 +74,37 @@ fn deserialize(path: PathBuf) -> Vec<Kustomization> {
7474
}
7575

7676

77-
fn run(path: PathBuf, result: &mut Vec<String>) {
78-
if let Ok(canonical) = canonical_path(path.clone()) {
79-
result.push(format!("{}", canonical.display()));
77+
fn run(root: &PathBuf, path: RelativePathBuf, result: &mut Vec<String>) {
78+
let current_path = normalize(&root, path.clone());
8079

81-
let resources: Vec<String> = deserialize(canonical.clone())
82-
.iter()
83-
.map(|doc| doc.resources.clone())
84-
.flatten()
85-
.collect();
80+
result.push(format!("{}", current_path));
8681

87-
for r in resources {
88-
let mut next_path = canonical
89-
.parent()
90-
.unwrap()
91-
.to_path_buf();
92-
next_path.push(PathBuf::from(r));
82+
let resources: Vec<String> = deserialize(&current_path.to_logical_path(root))
83+
.iter()
84+
.map(|doc| doc.resources.clone())
85+
.flatten()
86+
.collect();
87+
88+
for r in resources {
89+
let next_path = current_path
90+
.parent()
91+
.unwrap()
92+
.join_normalized(r);
9393

94-
run(next_path, result);
95-
};
94+
run(root, next_path, result);
9695
};
9796
}
9897

9998

10099
fn main() {
101100
let args = Args::parse();
101+
let root = current_dir().unwrap();
102102
let mut result = Vec::new();
103103

104-
run(args.path, &mut result);
104+
run(&root, args.path, &mut result);
105+
106+
result.sort();
107+
result.dedup();
105108

106109
match args.format {
107110
Some(Format::Json) => {

0 commit comments

Comments
 (0)