Skip to content

Commit 30b0a05

Browse files
jorgemoyaclaude
andcommitted
fix(cli): use writeEnv for channel link and keep existing values on empty
`catalyst channel link` inlined its own .env.local dump instead of going through writeEnv, so it skipped the .env.example ordering/comments and overwrote the file rather than reconciling it. Route it through writeEnv like `channel create --link`. Also stop empty CLI-supplied values from clobbering existing on-disk values: the channel init API returns blank placeholders for keys it does not own (e.g. MAKESWIFT_SITE_API_KEY), which were wiping the user's real value on re-run. An empty supplied value now falls back to the existing .env.local value. Refs LTRAC-974 Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c502098 commit 30b0a05

3 files changed

Lines changed: 38 additions & 11 deletions

File tree

packages/catalyst/src/cli/commands/channel.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { select } from '@inquirer/prompts';
22
import { Command, InvalidArgumentError, Option } from 'commander';
33
import type Conf from 'conf';
44
import { colorize } from 'consola/utils';
5-
import { outputFileSync } from 'fs-extra/esm';
6-
import { join } from 'node:path';
75

86
import { runChannelSiteUrlFlow } from '../lib/channel-site-flow';
97
import {
@@ -231,12 +229,7 @@ Examples:
231229

232230
// Writes .env.local in the current working directory — `channel link`
233231
// runs from inside `core/`, the same place `dev`/`build`/`deploy` run.
234-
outputFileSync(
235-
join(process.cwd(), '.env.local'),
236-
`${Object.entries(envVars)
237-
.map(([key, value]) => `${key}=${value}`)
238-
.join('\n')}\n`,
239-
);
232+
writeEnv(process.cwd(), envVars);
240233

241234
const label = channelName ? `"${channelName}" (${channelId})` : `${channelId}`;
242235

packages/catalyst/src/cli/lib/write-env.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,32 @@ ENABLE_ADMIN_ROUTE=false
121121
expect(local).toContain('ENABLE_ADMIN_ROUTE=false');
122122
});
123123

124+
it('does not clobber an existing value when the CLI supplies an empty placeholder', () => {
125+
// The channel init API returns blank placeholders for keys it does not own
126+
// (e.g. MAKESWIFT_SITE_API_KEY). Those must not wipe a value the user
127+
// already set on disk.
128+
writeExample(`# Store hash comment.
129+
BIGCOMMERCE_STORE_HASH=
130+
131+
# Makeswift comment.
132+
MAKESWIFT_SITE_API_KEY=
133+
`);
134+
writeLocal(`BIGCOMMERCE_STORE_HASH=old_hash
135+
MAKESWIFT_SITE_API_KEY=user_makeswift_key
136+
`);
137+
138+
writeEnv(projectDir, {
139+
BIGCOMMERCE_STORE_HASH: 'new_hash',
140+
MAKESWIFT_SITE_API_KEY: '',
141+
});
142+
143+
const local = readLocal();
144+
145+
expect(local).toContain('BIGCOMMERCE_STORE_HASH=new_hash');
146+
// The empty CLI value falls back to the user's existing value.
147+
expect(local).toContain('MAKESWIFT_SITE_API_KEY=user_makeswift_key');
148+
});
149+
124150
it('reconciles a stale .env.local by inserting a newly documented key in canonical position', () => {
125151
// The existing file predates ENABLE_ADMIN_ROUTE being documented and also
126152
// carries an unknown key the user added by hand.

packages/catalyst/src/cli/lib/write-env.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,17 @@ export const writeEnv = (projectDir: string, envVars: Record<string, string>) =>
5050

5151
// CLI-supplied vars win over what's already on disk so a re-run (e.g.
5252
// `channel link`) updates credentials in place; anything the CLI didn't touch
53-
// falls back to the user's existing value.
54-
const resolve = (key: string): string | undefined =>
55-
key in envVars ? envVars[key] : existingLocal.get(key);
53+
// falls back to the user's existing value. An empty CLI value is treated as
54+
// "not supplied" — the channel init API returns blank placeholders for keys it
55+
// doesn't own (e.g. MAKESWIFT_SITE_API_KEY), and those must not clobber a real
56+
// value the user already has on disk.
57+
const resolve = (key: string): string | undefined => {
58+
if (key in envVars && envVars[key] !== '') {
59+
return envVars[key];
60+
}
61+
62+
return existingLocal.get(key);
63+
};
5664

5765
// Without a template we can't follow the documented ordering/comments, so fall
5866
// back to a flat merge that still preserves the user's existing values.

0 commit comments

Comments
 (0)