From 894e1934dec1b82fff418562e02d04fdc9edff08 Mon Sep 17 00:00:00 2001 From: Hamcha Date: Fri, 17 Nov 2023 22:15:59 +0100 Subject: [PATCH] add nix support --- Cargo.lock | 376 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 7 +- README.md | 32 +++- src/templaters/json.rs | 3 +- src/templaters/mod.rs | 17 +- src/templaters/nix.rs | 56 ++++++ 6 files changed, 469 insertions(+), 22 deletions(-) create mode 100644 src/templaters/nix.rs diff --git a/Cargo.lock b/Cargo.lock index 8ad7e69..fe5ba5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.3.2" @@ -116,7 +125,7 @@ checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object", @@ -141,6 +150,16 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +[[package]] +name = "bstr" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -156,18 +175,48 @@ dependencies = [ "serde", ] +[[package]] +name = "cbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29b6ad25ae296159fb0da12b970b2fe179b234584d7cd294c891e2bbb284466b" +dependencies = [ + "num-traits", +] + [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "clap" version = "4.3.10" @@ -175,6 +224,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a" dependencies = [ "clap_builder", + "clap_derive", + "once_cell", ] [[package]] @@ -187,7 +238,19 @@ dependencies = [ "anstyle", "clap_lex", "once_cell", - "strsim", + "strsim 0.10.0", +] + +[[package]] +name = "clap_derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -213,13 +276,46 @@ dependencies = [ "winapi", ] +[[package]] +name = "countme" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58" + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + [[package]] name = "encoding_rs" version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -372,7 +468,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi", ] @@ -383,6 +479,19 @@ version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +[[package]] +name = "globset" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "h2" version = "0.3.20" @@ -402,6 +511,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + [[package]] name = "hashbrown" version = "0.12.3" @@ -414,6 +529,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -517,6 +638,23 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -603,11 +741,35 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] [[package]] name = "mime" @@ -655,6 +817,44 @@ dependencies = [ "tokio", ] +[[package]] +name = "nix-editor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f6bd8df3788c4d2c5c0a74957dc4d747808a3fe934e3d398cbaf6786f416ae" +dependencies = [ + "clap 4.3.10", + "nixpkgs-fmt", + "owo-colors", + "rnix 0.11.0", + "thiserror", +] + +[[package]] +name = "nixpkgs-fmt" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f1bdfcb88bb9dc3ae8a6ef55cda89eb33d7c69a98411b4cdb845adf391a7587" +dependencies = [ + "clap 2.34.0", + "crossbeam-channel", + "ignore", + "libc", + "rnix 0.10.2", + "rowan 0.12.6", + "serde_json", + "smol_str", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -680,6 +880,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "parking_lot" version = "0.12.1" @@ -696,7 +902,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", @@ -855,12 +1061,65 @@ dependencies = [ "winapi", ] +[[package]] +name = "rnix" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8024a523e8836f1a5d051203dc00d833357fee94e351b51348dfaeca5364daa9" +dependencies = [ + "cbitset", + "rowan 0.12.6", + "smol_str", +] + +[[package]] +name = "rnix" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb35cedbeb70e0ccabef2a31bcff0aebd114f19566086300b8f42c725fc2cb5f" +dependencies = [ + "rowan 0.15.13", +] + +[[package]] +name = "rowan" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b36e449f3702f3b0c821411db1cbdf30fb451726a9456dce5dabcd44420043" +dependencies = [ + "countme 2.0.4", + "hashbrown 0.9.1", + "memoffset 0.6.5", + "rustc-hash", + "serde", + "text-size", +] + +[[package]] +name = "rowan" +version = "0.15.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "906057e449592587bf6724f00155bf82a6752c868d78a8fb3aa41f4e6357cfe8" +dependencies = [ + "countme 3.0.1", + "hashbrown 0.12.3", + "memoffset 0.9.0", + "rustc-hash", + "text-size", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.2" @@ -911,6 +1170,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -990,10 +1258,11 @@ dependencies = [ "anyhow", "base64", "bytes", - "clap", + "clap 4.3.10", "env_logger", "log", "mockito", + "nix-editor", "percent-encoding", "reqwest", "serde", @@ -1031,6 +1300,15 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "smol_str" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" +dependencies = [ + "serde", +] + [[package]] name = "socket2" version = "0.4.9" @@ -1047,6 +1325,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "strsim" version = "0.10.0" @@ -1073,6 +1357,54 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "text-size" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" +dependencies = [ + "serde", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1155,7 +1487,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "pin-project-lite", "tracing-core", ] @@ -1196,6 +1528,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "unsafe-libyaml" version = "0.2.8" @@ -1225,6 +1563,22 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1246,7 +1600,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -1271,7 +1625,7 @@ version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", diff --git a/Cargo.toml b/Cargo.toml index bde0769..9ddd986 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,12 +10,17 @@ bytes = { version = "1", features = ["serde"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_yaml = "0.9" -reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] } +reqwest = { version = "0.11", default-features = false, features = [ + "blocking", + "json", + "rustls-tls", +] } base64 = "0.21" clap = { version = "4", features = ["cargo", "env"] } percent-encoding = "2.3.0" log = "0.4.19" env_logger = "0.10.0" +nix-editor = "0.3.0" [dev-dependencies] mockito = "1.1" diff --git a/README.md b/README.md index c76334b..dd549a5 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,37 @@ GitOps-enabled environments use git repositories to store deployment manifests. ### Git Providers -- `gitea` Gitea / Forgejo -- `gitlab` GitLab (both self-managed and gitlab.com) +- Gitea / Forgejo +- GitLab (both self-managed and gitlab.com) - (planned) Azure DevOps - (planned) BitBucket (only BitBucket cloud ie. bitbucket.org) - (planned) GitHub (both GitHub.com and GitHub Enterprise Server) + ### Templaters -- `json` JSON (generic) -- `yaml` YAML (generic) +- JSON (generic) +- YAML (generic) +- Nix + +## Usage + +### Using Templaters + +#### Nix + +The Nix templater replaces attributes within a Nix file. Arrays and other field types are not supported. + +For each templater entry, specify a `file` (path from repo root) and a dictionary of changes (field path = new value). + +Values will by default be wrapped with "" to indicate strings, if you want to specify a raw identifier (like a number or identifier), prefix the value with `r##`. +```json +{ + "templater": "nix", + "file": "path/to/file.nix", + "changes": { + "path.to.field": "new_string_value", + "path.to.other.field": "r##my_dynamic value" + } +} +``` diff --git a/src/templaters/json.rs b/src/templaters/json.rs index 654c9c9..688eeae 100644 --- a/src/templaters/json.rs +++ b/src/templaters/json.rs @@ -1,8 +1,7 @@ -use std::collections::HashMap; - use anyhow::{anyhow, Result}; use bytes::Bytes; use serde_json::Value; +use std::collections::HashMap; /// returns the value at the given path fn patch(base: &mut Value, path: &str, value: &str) -> Result<()> { diff --git a/src/templaters/mod.rs b/src/templaters/mod.rs index c02c869..158a48e 100644 --- a/src/templaters/mod.rs +++ b/src/templaters/mod.rs @@ -1,11 +1,10 @@ -use std::collections::HashMap; - +use crate::{commit::FileList, repository::Repository}; use anyhow::Result; use serde::Deserialize; - -use crate::{commit::FileList, repository::Repository}; +use std::collections::HashMap; mod json; +mod nix; mod yaml; #[derive(Debug, Deserialize)] @@ -19,6 +18,10 @@ pub enum Mutation { file: String, changes: HashMap, }, + Nix { + file: String, + changes: HashMap, + }, } pub fn mutate( @@ -41,6 +44,12 @@ pub fn mutate( let patched = yaml::update_file(&to_patch, changes)?; FileList::from([(file.into(), patched)]) } + Mutation::Nix { file, changes } => { + let to_patch = repository.get(file, branch)?; + log::debug!("patching Nix file file={file} branch={branch}"); + let patched = nix::update_file(&to_patch, changes)?; + FileList::from([(file.into(), patched)]) + } }; changed.extend(delta); } diff --git a/src/templaters/nix.rs b/src/templaters/nix.rs new file mode 100644 index 0000000..88c0469 --- /dev/null +++ b/src/templaters/nix.rs @@ -0,0 +1,56 @@ +use anyhow::Result; +use bytes::Bytes; +use std::collections::HashMap; +use std::str; + +pub fn update_file(file: &Bytes, changes: &HashMap) -> Result { + let mut file_str: String = str::from_utf8(&file).unwrap().to_string(); + + // apply changes + for (path, value) in changes { + let new_value = if value.starts_with("r##") { + value.strip_prefix("r##").unwrap().to_string() + } else { + format!("\"{}\"", value) + }; + file_str = nix_editor::write::write(&file_str, path, &new_value)?; + } + + Ok(Bytes::from(file_str)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_update_file() { + let original = r#" + { + test = { + nested = "original"; + }; + + test.inline = "original"; + }"#; + + let file = update_file( + &Bytes::from(original), + &HashMap::from([ + ("test.nested".to_string(), "changed".to_string()), + ("test.inline".to_string(), "changed".to_string()), + ]), + ) + .unwrap(); + + let file_str = str::from_utf8(&file).unwrap(); + assert_eq!( + nix_editor::read::readvalue(file_str, "test.nested").unwrap(), + "\"changed\"" + ); + assert_eq!( + nix_editor::read::readvalue(file_str, "test.inline").unwrap(), + "\"changed\"" + ); + } +}