Skip to content

Commit 1036626

Browse files
RedEagle-dhclaude
andcommitted
feat: cache prompted values to avoid duplicate prompts
When generating .env files, if the same environment variable key appears in multiple .env.example files, the user was prompted for each occurrence. Now, values entered by the user (or auto-generated) are cached and reused for subsequent occurrences of the same key. This provides a much better UX when working with monorepos that have many packages sharing common env vars. Bumps version to 2.0.7. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1beebfc commit 1036626

File tree

10 files changed

+31
-17
lines changed

10 files changed

+31
-17
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "zenv"
3-
version = "2.0.6"
3+
version = "2.0.7"
44
edition = "2021"
55
authors = ["Dave"]
66
description = "Environment variable validation and generation for TypeScript/Node.js projects with Zod schemas"

npm/darwin-arm64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modlogtv/zenv-darwin-arm64",
3-
"version": "2.0.6",
3+
"version": "2.0.7",
44
"description": "zenv binary for macOS ARM64 (Apple Silicon)",
55
"license": "MIT",
66
"repository": {

npm/darwin-x64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modlogtv/zenv-darwin-x64",
3-
"version": "2.0.6",
3+
"version": "2.0.7",
44
"description": "zenv binary for macOS x64 (Intel)",
55
"license": "MIT",
66
"repository": {

npm/linux-arm64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modlogtv/zenv-linux-arm64",
3-
"version": "2.0.6",
3+
"version": "2.0.7",
44
"description": "zenv binary for Linux ARM64",
55
"license": "MIT",
66
"repository": {

npm/linux-x64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modlogtv/zenv-linux-x64",
3-
"version": "2.0.6",
3+
"version": "2.0.7",
44
"description": "zenv binary for Linux x64",
55
"license": "MIT",
66
"repository": {

npm/win32-x64/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modlogtv/zenv-win32-x64",
3-
"version": "2.0.6",
3+
"version": "2.0.7",
44
"description": "zenv binary for Windows x64",
55
"license": "MIT",
66
"repository": {

npm/zenv/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modlogtv/zenv",
3-
"version": "2.0.6",
3+
"version": "2.0.7",
44
"description": "Zod-powered environment variable validation and generation for TypeScript/Node.js projects.",
55
"keywords": [
66
"env",
@@ -29,11 +29,11 @@
2929
"bin.js"
3030
],
3131
"optionalDependencies": {
32-
"@modlogtv/zenv-darwin-arm64": "2.0.6",
33-
"@modlogtv/zenv-darwin-x64": "2.0.6",
34-
"@modlogtv/zenv-linux-arm64": "2.0.6",
35-
"@modlogtv/zenv-linux-x64": "2.0.6",
36-
"@modlogtv/zenv-win32-x64": "2.0.6"
32+
"@modlogtv/zenv-darwin-arm64": "2.0.7",
33+
"@modlogtv/zenv-darwin-x64": "2.0.7",
34+
"@modlogtv/zenv-linux-arm64": "2.0.7",
35+
"@modlogtv/zenv-linux-x64": "2.0.7",
36+
"@modlogtv/zenv-win32-x64": "2.0.7"
3737
},
3838
"engines": {
3939
"node": ">=16"

src/generator/mod.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub struct Generator {
4343
dry_run: bool,
4444
force: bool,
4545
non_interactive: bool,
46+
/// Cache for prompted values - avoids asking for the same key multiple times
47+
prompted_values: HashMap<String, String>,
4648
}
4749

4850
impl Generator {
@@ -59,11 +61,12 @@ impl Generator {
5961
dry_run,
6062
force,
6163
non_interactive,
64+
prompted_values: HashMap::new(),
6265
}
6366
}
6467

6568
/// Run the generator
66-
pub fn run(&self) -> Result<GenerationReport, AppError> {
69+
pub fn run(&mut self) -> Result<GenerationReport, AppError> {
6770
let mut report = GenerationReport::new();
6871

6972
// Find all .env.example files
@@ -144,7 +147,7 @@ impl Generator {
144147

145148
/// Process a single .env.example file
146149
fn process_env_example(
147-
&self,
150+
&mut self,
148151
file: &EnvExampleFile,
149152
report: &mut GenerationReport,
150153
) -> Result<(), AppError> {
@@ -224,10 +227,15 @@ impl Generator {
224227

225228
/// Get value for a variable based on its metadata
226229
fn get_var_value(
227-
&self,
230+
&mut self,
228231
var: &EnvVarDefinition,
229232
report: &mut GenerationReport,
230233
) -> Result<Option<String>, AppError> {
234+
// Check if we already have a cached value for this key
235+
if let Some(cached) = self.prompted_values.get(&var.name) {
236+
return Ok(Some(cached.clone()));
237+
}
238+
231239
match &var.value_source {
232240
ValueSource::Prompt { description } => {
233241
if self.non_interactive {
@@ -255,12 +263,16 @@ impl Generator {
255263

256264
let value = prompts::prompt_input(&prompt_text, var.default_value.as_deref())?;
257265
report.vars_prompted.push(var.name.clone());
266+
// Cache the prompted value for reuse
267+
self.prompted_values.insert(var.name.clone(), value.clone());
258268
Ok(Some(value))
259269
}
260270

261271
ValueSource::Generate { length } => {
262272
let value = secrets::generate_secret(*length);
263273
report.vars_generated.push(var.name.clone());
274+
// Cache the generated value for reuse
275+
self.prompted_values.insert(var.name.clone(), value.clone());
264276
Ok(Some(value))
265277
}
266278

@@ -278,6 +290,8 @@ impl Generator {
278290
None,
279291
)?;
280292
report.vars_prompted.push(var.name.clone());
293+
// Cache the prompted value for reuse
294+
self.prompted_values.insert(var.name.clone(), value.clone());
281295
Ok(Some(value))
282296
} else {
283297
Ok(None)

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn run_generate(
110110
) -> Result<bool, AppError> {
111111
let target_dir = args.directory.clone().unwrap_or_else(|| root_dir.clone());
112112

113-
let generator = generator::Generator::new(
113+
let mut generator = generator::Generator::new(
114114
target_dir,
115115
config,
116116
args.dry_run,

0 commit comments

Comments
 (0)