yerba 0.7.5-x86_64-linux-gnu → 0.7.6-x86_64-linux-gnu

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aea01bbe9388549f54b3045ad2fe3aeb24416777d5ec11a8565f1643299e868c
4
- data.tar.gz: 5f128461b8d83b4116a43bddaf2c2d08088a9587913eb93dbb3499b1ae3bc4b4
3
+ metadata.gz: e02e1823fecca828b179ee43383dfbe5b3b53b08ff776ba952a083eda275afdb
4
+ data.tar.gz: 3de94c65f484ab647840b9791d7f905b3e44a835f027b5fdd2b6c4eb9a3895f2
5
5
  SHA512:
6
- metadata.gz: 1e0a00a599ac9563258226a26e72cc3bfe511aaa1a01f7be6434f2a2b02e9f871c1e91cbd1bbfa58e73c856d19aee0869c3d574bb67d00e8e882251d0536afa7
7
- data.tar.gz: 4e69ee00996dae0e5b87a5fec5cb37285773cba29cda748459a57c404ea8009265631e5f3d5fab111d4fec64ac49941071d6b818298dc00f0860f14b0d34bb27
6
+ metadata.gz: 81917ec519955c047960009895ff075657cb075b2e6a6ffb27a82aaff88cbf20950eb6d07f6eda669c3bb42f12c5880b1a2e68236b2a311de3513c75d97dbfb0
7
+ data.tar.gz: 34d9f864c6f08833abc0d32d73b14af7e6836ef99e14e640d168e5aef087ea8aef8e6d66c21db75862a033c9101f382827772fcad58d6473abff00b870d9a5c0
data/README.md CHANGED
@@ -539,6 +539,7 @@ Available pipeline steps:
539
539
  - `directives` Add or remove the document start marker (`---`), with optional `max` validation
540
540
  - `unique` Find or remove duplicate items in a sequence
541
541
  - `schema` Validate against a JSON schema (with optional `path` for scoping)
542
+ - `final_newline` Enforce exact number of trailing newlines (`count: 1` by default, strips extras)
542
543
 
543
544
  This makes it easy to enforce project-wide YAML conventions in CI:
544
545
 
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/yerba/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yerba
4
- VERSION = "0.7.5"
4
+ VERSION = "0.7.6"
5
5
  end
data/rust/Cargo.lock CHANGED
@@ -1772,7 +1772,7 @@ dependencies = [
1772
1772
 
1773
1773
  [[package]]
1774
1774
  name = "yerba"
1775
- version = "0.7.5"
1775
+ version = "0.7.6"
1776
1776
  dependencies = [
1777
1777
  "cbindgen",
1778
1778
  "clap",
data/rust/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "yerba"
3
- version = "0.7.5"
3
+ version = "0.7.6"
4
4
  edition = "2021"
5
5
  authors = ["Marco Roth <marco.roth@intergga.ch>"]
6
6
  description = "YAML Editing and Refactoring with Better Accuracy"
@@ -656,6 +656,18 @@ impl Document {
656
656
  self.reparse(&new_source)
657
657
  }
658
658
 
659
+ pub fn enforce_final_newline(&mut self, count: usize) -> Result<(), YerbaError> {
660
+ let source = self.to_string();
661
+ let trimmed = source.trim_end_matches('\n');
662
+ let expected = format!("{}{}", trimmed, "\n".repeat(count));
663
+
664
+ if source != expected {
665
+ self.reparse(&expected)
666
+ } else {
667
+ Ok(())
668
+ }
669
+ }
670
+
659
671
  pub fn enforce_key_style(&mut self, style: &crate::KeyStyle, dot_path: Option<&str>) -> Result<(), YerbaError> {
660
672
  let scope_ranges: Vec<TextRange> = match dot_path {
661
673
  Some(path) if !path.is_empty() => self.navigate_all_compact(path).iter().map(|node| node.text_range()).collect(),
@@ -41,6 +41,7 @@ pub enum PipelineStep {
41
41
  Directives(DirectivesConfig),
42
42
  Unique(UniqueConfig),
43
43
  Schema(SchemaConfig),
44
+ FinalNewline(FinalNewlineConfig),
44
45
  }
45
46
 
46
47
  #[derive(Debug, Clone, Deserialize)]
@@ -95,6 +96,16 @@ pub struct SchemaConfig {
95
96
  pub items: bool,
96
97
  }
97
98
 
99
+ #[derive(Debug, Clone, Deserialize)]
100
+ pub struct FinalNewlineConfig {
101
+ #[serde(default = "default_one")]
102
+ pub count: usize,
103
+ }
104
+
105
+ fn default_one() -> usize {
106
+ 1
107
+ }
108
+
98
109
  #[derive(Debug, Clone, Deserialize)]
99
110
  pub struct RenameConfig {
100
111
  pub from: String,
@@ -188,8 +199,13 @@ impl<'de> Deserialize<'de> for PipelineStep {
188
199
  return Ok(PipelineStep::Schema(config));
189
200
  }
190
201
 
202
+ if let Some(value) = mapping.get(yaml_serde::Value::String("final_newline".to_string())) {
203
+ let config: FinalNewlineConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
204
+ return Ok(PipelineStep::FinalNewline(config));
205
+ }
206
+
191
207
  Err(serde::de::Error::custom(
192
- "unknown pipeline step: expected sort_keys, quote_style, collection_style, sequence_indent, set, insert, delete, rename, remove, blank_lines, sort, directives, unique, or schema",
208
+ "unknown pipeline step: expected sort_keys, quote_style, collection_style, sequence_indent, set, insert, delete, rename, remove, blank_lines, sort, directives, unique, schema, or final_newline",
193
209
  ))
194
210
  }
195
211
  }
@@ -359,6 +375,22 @@ impl Yerbafile {
359
375
  results.extend(file_results);
360
376
  }
361
377
 
378
+ if !self.pipeline.is_empty() {
379
+ if let Some(ref global_glob) = self.files {
380
+ if let Ok(paths) = glob::glob(global_glob) {
381
+ let unprocessed: Vec<String> = paths
382
+ .filter_map(|entry| entry.ok())
383
+ .map(|path| path.to_string_lossy().to_string())
384
+ .filter(|file| !globally_processed.contains(file.as_str()))
385
+ .collect();
386
+
387
+ let global_results: Vec<RuleResult> = unprocessed.par_iter().map(|file| self.apply_global_pipeline_to_file(file, write)).collect();
388
+
389
+ results.extend(global_results);
390
+ }
391
+ }
392
+ }
393
+
362
394
  results
363
395
  }
364
396
 
@@ -436,9 +468,55 @@ impl Yerbafile {
436
468
  ran_global = true;
437
469
  }
438
470
 
471
+ if !ran_global && self.should_run_global_pipeline(file) {
472
+ results.push(self.apply_global_pipeline_to_file(file, write));
473
+ }
474
+
439
475
  results
440
476
  }
441
477
 
478
+ fn apply_global_pipeline_to_file(&self, file: &str, write: bool) -> RuleResult {
479
+ let mut document = match Document::parse_file(file) {
480
+ Ok(document) => document,
481
+ Err(error) => {
482
+ return RuleResult {
483
+ file: file.to_string(),
484
+ changed: false,
485
+ error: Some(error),
486
+ }
487
+ }
488
+ };
489
+
490
+ let original = document.to_string();
491
+
492
+ if let Err(error) = execute_pipeline(&mut document, &self.pipeline, None, file, self) {
493
+ return RuleResult {
494
+ file: file.to_string(),
495
+ changed: false,
496
+ error: Some(error),
497
+ };
498
+ }
499
+
500
+ let new_content = document.to_string();
501
+ let changed = new_content != original;
502
+
503
+ if changed && write {
504
+ if let Err(error) = fs::write(file, &new_content) {
505
+ return RuleResult {
506
+ file: file.to_string(),
507
+ changed,
508
+ error: Some(YerbaError::IoError(error)),
509
+ };
510
+ }
511
+ }
512
+
513
+ RuleResult {
514
+ file: file.to_string(),
515
+ changed,
516
+ error: None,
517
+ }
518
+ }
519
+
442
520
  fn relativize_path(&self, file_path: &str) -> Option<String> {
443
521
  let path = Path::new(file_path);
444
522
 
@@ -744,6 +822,8 @@ fn execute_step(document: &mut Document, step: &PipelineStep, base_path: Option<
744
822
 
745
823
  Ok(())
746
824
  }
825
+
826
+ PipelineStep::FinalNewline(config) => document.enforce_final_newline(config.count),
747
827
  }
748
828
  }
749
829
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yerba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.7.6
5
5
  platform: x86_64-linux-gnu
6
6
  authors:
7
7
  - Marco Roth
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-07 00:00:00.000000000 Z
11
+ date: 2026-07-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A CLI tool for editing YAML while preserving structure, comments, and
14
14
  format.