@@ -7,13 +7,14 @@ import (
7
7
"io"
8
8
"io/fs"
9
9
"os"
10
- "os/exec"
11
10
"path/filepath"
12
11
"runtime"
13
12
"sort"
14
13
"strings"
15
14
16
15
"github.com/cli/safeexec"
16
+ "github.com/pkg/diff"
17
+ "github.com/pkg/diff/write"
17
18
"github.com/spf13/cobra"
18
19
"golang.org/x/exp/slices"
19
20
"golang.org/x/sync/errgroup"
@@ -383,40 +384,27 @@ func currentBinPath(cmd *cobra.Command) (string, error) {
383
384
384
385
// diffBytes two byte slices as if they were in a file named name.
385
386
// Does best-effort cleanup ignoring non-critical errors.
386
- func diffBytes (name string , b1 , b2 []byte ) (data []byte , err error ) {
387
- f1 , err := os .CreateTemp ("" , "coder_config-ssh." )
388
- if err != nil {
389
- return nil , xerrors .Errorf ("create temp 1 file failed: %w" , err )
390
- }
391
- defer os .Remove (f1 .Name ())
392
- defer f1 .Close ()
393
-
394
- f2 , err := os .CreateTemp ("" , "coder_config-ssh." )
395
- if err != nil {
396
- return nil , xerrors .Errorf ("create temp 2 file failed: %w" , err )
387
+ func diffBytes (name string , b1 , b2 []byte ) ([]byte , error ) {
388
+ var buf bytes.Buffer
389
+ var opts []write.Option
390
+ // TODO(mafredri): Toggle color on/off
391
+ if false {
392
+ opts = append (opts , write .TerminalColor ())
397
393
}
398
- defer os .Remove (f2 .Name ())
399
- defer f2 .Close ()
400
-
401
- _ , err = f1 .Write (b1 )
394
+ err := diff .Text (name , name + ".new" , b1 , b2 , & buf , opts ... )
402
395
if err != nil {
403
- return nil , xerrors .Errorf ("write temp 1 file failed: %w" , err )
404
- }
405
- _ , err = f2 .Write (b2 )
406
- if err != nil {
407
- return nil , xerrors .Errorf ("write temp 2 file failed: %w" , err )
408
- }
409
-
410
- // TODO(mafredri): Ensure diff binary exists, or return useful error when missing.
411
- data , err = exec .Command ("diff" , "-u" , f1 .Name (), f2 .Name ()).Output () // #nosec
412
- if len (data ) == 0 && err != nil { // Ignore non-zero exit when files differ.
413
396
return nil , err
414
397
}
415
- // Replace temp file names with friendly names.
416
- data = bytes .Replace (data , []byte (f1 .Name ()), []byte (name ), 1 )
417
- data = bytes .Replace (data , []byte (f2 .Name ()), []byte (name + ".new" ), 1 )
418
-
419
- return data , err
398
+ b := buf .Bytes ()
399
+ // Check if diff only output two lines, if yes, there's no diff.
400
+ //
401
+ // Example:
402
+ // --- ~/.ssh/config
403
+ // +++ ~/.ssh/config.new
404
+ if bytes .Count (b , []byte {'\n' }) == 2 {
405
+ b = nil
406
+ }
407
+ return b , nil
420
408
}
421
409
422
410
// stripOldConfigBlock is here to migrate users from old config block
0 commit comments