yerba 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/src/document.rs +34 -7
- data/rust/src/main.rs +5 -1
- data/rust/src/yerbafile.rs +28 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ab1031fe2ea6b59f49bad4c2b7acf7e6679f16a97cbf7fa93d4e2790cc3c421
|
|
4
|
+
data.tar.gz: 79f77237c9ecbc6ed8404d31d50407e9ab4296829c8db983fba2300347ff06bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b38dcb297b53bdae8ac76a174922a544271a0564111149a864a2d0b6a4e5572b9219b266e29e22510cf567ac48b351d08ab47a9fb563734ea3834bed3655396b
|
|
7
|
+
data.tar.gz: 41907521d78760c21315891b7aa26bc772b7f9f871f72275f215f65e42726313612e61997d8458823e4d67ed25cb6dca5bf7dfcae913306a0e4cd5269f5065a0
|
data/README.md
CHANGED
|
@@ -36,7 +36,7 @@ yerba get config.yml path.to.key
|
|
|
36
36
|
|
|
37
37
|
### Development
|
|
38
38
|
|
|
39
|
-
After checking out the repo, run `
|
|
39
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rake test` to run the tests.
|
|
40
40
|
|
|
41
41
|
### Rust
|
|
42
42
|
|
data/lib/yerba/version.rb
CHANGED
data/rust/Cargo.lock
CHANGED
data/rust/Cargo.toml
CHANGED
data/rust/src/document.rs
CHANGED
|
@@ -974,9 +974,14 @@ impl Document {
|
|
|
974
974
|
}
|
|
975
975
|
}
|
|
976
976
|
|
|
977
|
-
pub fn sort_items(
|
|
977
|
+
pub fn sort_items(
|
|
978
|
+
&mut self,
|
|
979
|
+
dot_path: &str,
|
|
980
|
+
sort_fields: &[SortField],
|
|
981
|
+
case_sensitive: bool,
|
|
982
|
+
) -> Result<(), YerbaError> {
|
|
978
983
|
if dot_path.contains("[].") {
|
|
979
|
-
return self.sort_each_items(dot_path, sort_fields);
|
|
984
|
+
return self.sort_each_items(dot_path, sort_fields, case_sensitive);
|
|
980
985
|
}
|
|
981
986
|
|
|
982
987
|
let keys: Vec<&str> = dot_path.split('.').collect();
|
|
@@ -1022,7 +1027,11 @@ impl Document {
|
|
|
1022
1027
|
let value_a = &values_a[index];
|
|
1023
1028
|
let value_b = &values_b[index];
|
|
1024
1029
|
|
|
1025
|
-
let ordering =
|
|
1030
|
+
let ordering = if case_sensitive {
|
|
1031
|
+
value_a.cmp(value_b)
|
|
1032
|
+
} else {
|
|
1033
|
+
value_a.to_lowercase().cmp(&value_b.to_lowercase())
|
|
1034
|
+
};
|
|
1026
1035
|
|
|
1027
1036
|
let ordering = if field.ascending { ordering } else { ordering.reverse() };
|
|
1028
1037
|
|
|
@@ -1032,7 +1041,11 @@ impl Document {
|
|
|
1032
1041
|
}
|
|
1033
1042
|
|
|
1034
1043
|
if sort_fields.is_empty() && !values_a.is_empty() && !values_b.is_empty() {
|
|
1035
|
-
return
|
|
1044
|
+
return if case_sensitive {
|
|
1045
|
+
values_a[0].cmp(&values_b[0])
|
|
1046
|
+
} else {
|
|
1047
|
+
values_a[0].to_lowercase().cmp(&values_b[0].to_lowercase())
|
|
1048
|
+
};
|
|
1036
1049
|
}
|
|
1037
1050
|
|
|
1038
1051
|
std::cmp::Ordering::Equal
|
|
@@ -1055,7 +1068,12 @@ impl Document {
|
|
|
1055
1068
|
self.apply_edit(sequence_range, &sequence_text)
|
|
1056
1069
|
}
|
|
1057
1070
|
|
|
1058
|
-
fn sort_each_items(
|
|
1071
|
+
fn sort_each_items(
|
|
1072
|
+
&mut self,
|
|
1073
|
+
dot_path: &str,
|
|
1074
|
+
sort_fields: &[SortField],
|
|
1075
|
+
case_sensitive: bool,
|
|
1076
|
+
) -> Result<(), YerbaError> {
|
|
1059
1077
|
let (parent_path, child_path) = if let Some(last_bracket) = dot_path.rfind("[].") {
|
|
1060
1078
|
(&dot_path[..last_bracket + 2], &dot_path[last_bracket + 3..])
|
|
1061
1079
|
} else {
|
|
@@ -1114,7 +1132,12 @@ impl Document {
|
|
|
1114
1132
|
let value_a = &values_a[index];
|
|
1115
1133
|
let value_b = &values_b[index];
|
|
1116
1134
|
|
|
1117
|
-
let ordering =
|
|
1135
|
+
let ordering = if case_sensitive {
|
|
1136
|
+
value_a.cmp(value_b)
|
|
1137
|
+
} else {
|
|
1138
|
+
value_a.to_lowercase().cmp(&value_b.to_lowercase())
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1118
1141
|
let ordering = if field.ascending { ordering } else { ordering.reverse() };
|
|
1119
1142
|
|
|
1120
1143
|
if ordering != std::cmp::Ordering::Equal {
|
|
@@ -1123,7 +1146,11 @@ impl Document {
|
|
|
1123
1146
|
}
|
|
1124
1147
|
|
|
1125
1148
|
if sort_fields.is_empty() && !values_a.is_empty() && !values_b.is_empty() {
|
|
1126
|
-
return
|
|
1149
|
+
return if case_sensitive {
|
|
1150
|
+
values_a[0].cmp(&values_b[0])
|
|
1151
|
+
} else {
|
|
1152
|
+
values_a[0].to_lowercase().cmp(&values_b[0].to_lowercase())
|
|
1153
|
+
};
|
|
1127
1154
|
}
|
|
1128
1155
|
|
|
1129
1156
|
std::cmp::Ordering::Equal
|
data/rust/src/main.rs
CHANGED
|
@@ -265,6 +265,9 @@ enum Command {
|
|
|
265
265
|
/// Comma-separated sort fields, optionally with :desc (e.g. "date:desc,title")
|
|
266
266
|
#[arg(long)]
|
|
267
267
|
by: Option<String>,
|
|
268
|
+
/// Case-sensitive sort (default: case-insensitive)
|
|
269
|
+
#[arg(long)]
|
|
270
|
+
case_sensitive: bool,
|
|
268
271
|
#[arg(long)]
|
|
269
272
|
dry_run: bool,
|
|
270
273
|
},
|
|
@@ -669,6 +672,7 @@ fn main() {
|
|
|
669
672
|
file,
|
|
670
673
|
path,
|
|
671
674
|
by,
|
|
675
|
+
case_sensitive,
|
|
672
676
|
dry_run,
|
|
673
677
|
} => {
|
|
674
678
|
let sort_fields = by.as_deref().map(yerba::SortField::parse_list).unwrap_or_default();
|
|
@@ -676,7 +680,7 @@ fn main() {
|
|
|
676
680
|
for resolved_file in resolve_files(&file) {
|
|
677
681
|
let mut document = parse_file(&resolved_file);
|
|
678
682
|
|
|
679
|
-
if document.sort_items(&path, &sort_fields).is_ok() {
|
|
683
|
+
if document.sort_items(&path, &sort_fields, case_sensitive).is_ok() {
|
|
680
684
|
output(&resolved_file, &document, dry_run);
|
|
681
685
|
}
|
|
682
686
|
}
|
data/rust/src/yerbafile.rs
CHANGED
|
@@ -31,6 +31,17 @@ pub enum PipelineStep {
|
|
|
31
31
|
Rename(RenameConfig),
|
|
32
32
|
Remove(RemoveConfig),
|
|
33
33
|
BlankLines(BlankLinesConfig),
|
|
34
|
+
Sort(SortConfig),
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#[derive(Debug, Clone, Deserialize)]
|
|
38
|
+
pub struct SortConfig {
|
|
39
|
+
#[serde(default)]
|
|
40
|
+
pub path: Option<String>,
|
|
41
|
+
#[serde(default)]
|
|
42
|
+
pub by: Option<String>,
|
|
43
|
+
#[serde(default)]
|
|
44
|
+
pub case_sensitive: bool,
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
#[derive(Debug, Clone, Deserialize)]
|
|
@@ -123,8 +134,13 @@ impl<'de> Deserialize<'de> for PipelineStep {
|
|
|
123
134
|
return Ok(PipelineStep::BlankLines(config));
|
|
124
135
|
}
|
|
125
136
|
|
|
137
|
+
if let Some(value) = mapping.get(serde_yaml::Value::String("sort".to_string())) {
|
|
138
|
+
let config: SortConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
139
|
+
return Ok(PipelineStep::Sort(config));
|
|
140
|
+
}
|
|
141
|
+
|
|
126
142
|
Err(serde::de::Error::custom(
|
|
127
|
-
"unknown pipeline step: expected get, sort_keys, quote_style, set, insert, delete, rename, remove, or
|
|
143
|
+
"unknown pipeline step: expected get, sort_keys, quote_style, set, insert, delete, rename, remove, blank_lines, or sort",
|
|
128
144
|
))
|
|
129
145
|
}
|
|
130
146
|
}
|
|
@@ -501,6 +517,17 @@ fn execute_step(
|
|
|
501
517
|
|
|
502
518
|
document.enforce_blank_lines(&full_path, config.count)
|
|
503
519
|
}
|
|
520
|
+
|
|
521
|
+
PipelineStep::Sort(config) => {
|
|
522
|
+
let full_path = resolve_step_path(base_path, config.path.as_deref());
|
|
523
|
+
let sort_fields = config
|
|
524
|
+
.by
|
|
525
|
+
.as_deref()
|
|
526
|
+
.map(crate::SortField::parse_list)
|
|
527
|
+
.unwrap_or_default();
|
|
528
|
+
|
|
529
|
+
document.sort_items(&full_path, &sort_fields, config.case_sensitive)
|
|
530
|
+
}
|
|
504
531
|
}
|
|
505
532
|
}
|
|
506
533
|
|