Skip to content

Commit 11c47e0

Browse files
mafredrijohnstcn
andauthored
feat: Rename config-ssh --diff to --dry-run (#2575)
* feat: Rename config-ssh `--diff` to `--dry-run` Since the intent between diff and dry-run are different, this change allows for interactive prompts to be shown during `--dry-run`, previously prompts were disabled. Dry-run can also be chanied with `--yes` and `--use-previous-options` for non-interactive modes. Dry-run is like a normal run with changes replaced by diff. Fixes #2530 Co-authored-by: Cian Johnston <cian@coder.com>
1 parent bd19fcb commit 11c47e0

File tree

2 files changed

+53
-57
lines changed

2 files changed

+53
-57
lines changed

cli/configssh.go

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,6 @@ func (o sshConfigOptions) equal(other sshConfigOptions) bool {
5757
return slices.Equal(opt1, opt2)
5858
}
5959

60-
func (o sshConfigOptions) asArgs() (args []string) {
61-
for _, opt := range o.sshOptions {
62-
args = append(args, "--ssh-option", fmt.Sprintf("%q", opt))
63-
}
64-
return args
65-
}
66-
6760
func (o sshConfigOptions) asList() (list []string) {
6861
for _, opt := range o.sshOptions {
6962
list = append(list, fmt.Sprintf("ssh-option: %s", opt))
@@ -140,11 +133,8 @@ func configSSH() *cobra.Command {
140133
sshConfigOpts sshConfigOptions
141134
usePreviousOpts bool
142135
coderConfigFile string
143-
showDiff bool
136+
dryRun bool
144137
skipProxyCommand bool
145-
146-
// Diff should exit with status 1 when files differ.
147-
filesDiffer bool
148138
)
149139
cmd := &cobra.Command{
150140
Annotations: workspaceCommand,
@@ -156,14 +146,9 @@ func configSSH() *cobra.Command {
156146
157147
` + cliui.Styles.Code.Render("$ coder config-ssh -o ForwardAgent=yes") + `
158148
159-
- You can use -D (or --diff) to display the changes that will be made.
149+
- You can use --dry-run (or -n) to see the changes that would be made.
160150
161-
` + cliui.Styles.Code.Render("$ coder config-ssh --diff"),
162-
PostRun: func(cmd *cobra.Command, args []string) {
163-
if showDiff && filesDiffer {
164-
os.Exit(1) //nolint: revive
165-
}
166-
},
151+
` + cliui.Styles.Code.Render("$ coder config-ssh --dry-run"),
167152
RunE: func(cmd *cobra.Command, args []string) error {
168153
client, err := createClient(cmd)
169154
if err != nil {
@@ -173,7 +158,9 @@ func configSSH() *cobra.Command {
173158
recvWorkspaceConfigs := sshPrepareWorkspaceConfigs(cmd.Context(), client)
174159

175160
out := cmd.OutOrStdout()
176-
if showDiff {
161+
if dryRun {
162+
// Print everything except diff to stderr so
163+
// that it's possible to capture the diff.
177164
out = cmd.OutOrStderr()
178165
}
179166
binaryFile, err := currentBinPath(out)
@@ -186,7 +173,6 @@ func configSSH() *cobra.Command {
186173
return xerrors.Errorf("user home dir failed: %w", err)
187174
}
188175

189-
sshConfigFileOrig := sshConfigFile
190176
if strings.HasPrefix(sshConfigFile, "~/") {
191177
sshConfigFile = filepath.Join(homedir, sshConfigFile[2:])
192178
}
@@ -221,7 +207,7 @@ func configSSH() *cobra.Command {
221207
// or when a previous config does not exist.
222208
if usePreviousOpts && lastConfig != nil {
223209
sshConfigOpts = *lastConfig
224-
} else if !showDiff && lastConfig != nil && !sshConfigOpts.equal(*lastConfig) {
210+
} else if lastConfig != nil && !sshConfigOpts.equal(*lastConfig) {
225211
newOpts := sshConfigOpts.asList()
226212
newOptsMsg := "\n\n New options: none"
227213
if len(newOpts) > 0 {
@@ -244,7 +230,10 @@ func configSSH() *cobra.Command {
244230
// Selecting "no" will use the last config.
245231
sshConfigOpts = *lastConfig
246232
}
247-
_, _ = fmt.Fprint(out, "\n")
233+
// Only print when prompts are shown.
234+
if yes, _ := cmd.Flags().GetBool("yes"); !yes {
235+
_, _ = fmt.Fprint(out, "\n")
236+
}
248237
}
249238

250239
configModified := configRaw
@@ -316,15 +305,25 @@ func configSSH() *cobra.Command {
316305
configModified = buf.Bytes()
317306
}
318307

319-
if showDiff {
320-
if len(changes) > 0 {
321-
// Write to stderr to avoid dirtying the diff output.
322-
_, _ = fmt.Fprint(out, "The following changes will be made to your SSH configuration:\n\n")
323-
for _, change := range changes {
324-
_, _ = fmt.Fprintf(out, " * %s\n", change)
325-
}
308+
if len(changes) > 0 {
309+
dryRunDisclaimer := ""
310+
if dryRun {
311+
dryRunDisclaimer = " (dry-run, no changes will be made)"
312+
}
313+
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
314+
Text: fmt.Sprintf("The following changes will be made to your SSH configuration:\n\n * %s\n\n Continue?%s", strings.Join(changes, "\n * "), dryRunDisclaimer),
315+
IsConfirm: true,
316+
})
317+
if err != nil {
318+
return nil
326319
}
320+
// Only print when prompts are shown.
321+
if yes, _ := cmd.Flags().GetBool("yes"); !yes {
322+
_, _ = fmt.Fprint(out, "\n")
323+
}
324+
}
327325

326+
if dryRun {
328327
color := isTTYOut(cmd)
329328
diffFns := []func() ([]byte, error){
330329
func() ([]byte, error) { return diffBytes(sshConfigFile, configRaw, configModified, color) },
@@ -340,34 +339,11 @@ func configSSH() *cobra.Command {
340339
return xerrors.Errorf("diff failed: %w", err)
341340
}
342341
if len(diff) > 0 {
343-
filesDiffer = true
344-
// Always write to stdout.
342+
// Write diff to stdout.
345343
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\n%s", diff)
346344
}
347345
}
348-
349-
return nil
350-
}
351-
352-
if len(changes) > 0 {
353-
// In diff mode we don't prompt re-using the previous
354-
// configuration, so we output the entire command.
355-
var args []string
356-
if sshConfigFileOrig != sshDefaultConfigFileName {
357-
args = append(args, "--ssh-config-file", sshConfigFileOrig)
358-
}
359-
args = append(args, sshConfigOpts.asArgs()...)
360-
args = append(args, "--diff")
361-
diffCommand := fmt.Sprintf("$ %s %s", cmd.CommandPath(), strings.Join(args, " "))
362-
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
363-
Text: fmt.Sprintf("The following changes will be made to your SSH configuration:\n\n * %s\n\n To see changes, run diff:\n\n %s\n\n Continue?", strings.Join(changes, "\n * "), diffCommand),
364-
IsConfirm: true,
365-
})
366-
if err != nil {
367-
return nil
368-
}
369-
_, _ = fmt.Fprint(out, "\n")
370-
346+
} else {
371347
if !bytes.Equal(configRaw, configModified) {
372348
err = writeWithTempFileAndMove(sshConfigFile, bytes.NewReader(configModified))
373349
if err != nil {
@@ -394,7 +370,7 @@ func configSSH() *cobra.Command {
394370
}
395371
cliflag.StringVarP(cmd.Flags(), &sshConfigFile, "ssh-config-file", "", "CODER_SSH_CONFIG_FILE", sshDefaultConfigFileName, "Specifies the path to an SSH config.")
396372
cmd.Flags().StringArrayVarP(&sshConfigOpts.sshOptions, "ssh-option", "o", []string{}, "Specifies additional SSH options to embed in each host stanza.")
397-
cmd.Flags().BoolVarP(&showDiff, "diff", "D", false, "Show diff of changes that will be made.")
373+
cmd.Flags().BoolVarP(&dryRun, "dry-run", "n", false, "Perform a trial run with no changes made, showing a diff at the end.")
398374
cmd.Flags().BoolVarP(&skipProxyCommand, "skip-proxy-command", "", false, "Specifies whether the ProxyCommand option should be skipped. Useful for testing.")
399375
_ = cmd.Flags().MarkHidden("skip-proxy-command")
400376
cliflag.BoolVarP(cmd.Flags(), &usePreviousOpts, "use-previous-options", "", "CODER_SSH_USE_PREVIOUS_OPTIONS", false, "Specifies whether or not to keep options from previous run of config-ssh.")
@@ -575,7 +551,7 @@ func diffBytes(name string, b1, b2 []byte, color bool) ([]byte, error) {
575551
if color {
576552
opts = append(opts, write.TerminalColor())
577553
}
578-
err := diff.Text(name, name+".new", b1, b2, &buf, opts...)
554+
err := diff.Text(name, name, b1, b2, &buf, opts...)
579555
if err != nil {
580556
return nil, err
581557
}
@@ -584,7 +560,7 @@ func diffBytes(name string, b1, b2 []byte, color bool) ([]byte, error) {
584560
//
585561
// Example:
586562
// --- /home/user/.ssh/config
587-
// +++ /home/user/.ssh/config.new
563+
// +++ /home/user/.ssh/config
588564
if bytes.Count(b, []byte{'\n'}) == 2 {
589565
b = nil
590566
}

cli/configssh_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,26 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
494494
"--yes",
495495
},
496496
},
497+
{
498+
name: "Do not overwrite config when using --dry-run",
499+
writeConfig: writeConfig{
500+
ssh: strings.Join([]string{
501+
baseHeader,
502+
"",
503+
}, "\n"),
504+
},
505+
wantConfig: wantConfig{
506+
ssh: strings.Join([]string{
507+
baseHeader,
508+
"",
509+
}, "\n"),
510+
},
511+
args: []string{
512+
"--ssh-option", "ForwardAgent=yes",
513+
"--dry-run",
514+
"--yes",
515+
},
516+
},
497517

498518
// Tests for deprecated split coder config.
499519
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy