Skip to content

Commit

Permalink
add natefinch/atomic
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanndickson committed Aug 14, 2024
1 parent daea696 commit 64b9c1e
Show file tree
Hide file tree
Showing 9 changed files with 13 additions and 72 deletions.
53 changes: 6 additions & 47 deletions completion/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"text/template"

"github.com/coder/serpent"

"github.com/natefinch/atomic"
)

const (
Expand Down Expand Up @@ -85,7 +87,7 @@ func DetectUserShell(programName string) (Shell, error) {
return nil, fmt.Errorf("default shell not found")
}

func configTemplateWriter(
func writeConfig(
w io.Writer,
cfgTemplate string,
programName string,
Expand Down Expand Up @@ -114,13 +116,13 @@ func InstallShellCompletion(shell Shell) error {
return fmt.Errorf("get install path: %w", err)
}
var headerBuf bytes.Buffer
err = configTemplateWriter(&headerBuf, completionStartTemplate, shell.ProgramName())
err = writeConfig(&headerBuf, completionStartTemplate, shell.ProgramName())
if err != nil {
return fmt.Errorf("generate header: %w", err)
}

var footerBytes bytes.Buffer
err = configTemplateWriter(&footerBytes, completionEndTemplate, shell.ProgramName())
err = writeConfig(&footerBytes, completionEndTemplate, shell.ProgramName())
if err != nil {
return fmt.Errorf("generate footer: %w", err)
}
Expand Down Expand Up @@ -154,7 +156,7 @@ func InstallShellCompletion(shell Shell) error {
_, _ = outBuf.Write([]byte("\n"))
_, _ = outBuf.Write(after)

err = writeWithTempFileAndMove(path, &outBuf)
err = atomic.WriteFile(path, &outBuf)
if err != nil {
return fmt.Errorf("write completion: %w", err)
}
Expand Down Expand Up @@ -194,46 +196,3 @@ func templateConfigSplit(header, footer, data []byte) (before, after []byte, err
}
return data, nil, nil
}

// writeWithTempFileAndMove writes to a temporary file in the same
// directory as path and renames the temp file to the file provided in
// path. This ensure we avoid trashing the file we are writing due to
// unforeseen circumstance like filesystem full, command killed, etc.
func writeWithTempFileAndMove(path string, r io.Reader) (err error) {
dir := filepath.Dir(path)
name := filepath.Base(path)

if err = os.MkdirAll(dir, 0o700); err != nil {
return fmt.Errorf("create directory: %w", err)
}

// Create a tempfile in the same directory for ensuring write
// operation does not fail.
f, err := os.CreateTemp(dir, fmt.Sprintf(".%s.", name))
if err != nil {
return fmt.Errorf("create temp file failed: %w", err)
}
defer func() {
if err != nil {
_ = os.Remove(f.Name()) // Cleanup in case a step failed.
}
}()

_, err = io.Copy(f, r)
if err != nil {
_ = f.Close()
return fmt.Errorf("write temp file failed: %w", err)
}

err = f.Close()
if err != nil {
return fmt.Errorf("close temp file failed: %w", err)
}

err = os.Rename(f.Name(), path)
if err != nil {
return fmt.Errorf("rename temp file failed: %w", err)
}

return nil
}
6 changes: 1 addition & 5 deletions completion/bash.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ func Bash(goos string, programName string) Shell {
return &bash{goos: goos, programName: programName}
}

// Name implements Shell.
func (b *bash) Name() string {
return "bash"
}

// InstallPath implements Shell.
func (b *bash) InstallPath() (string, error) {
homeDir, err := home.Dir()
if err != nil {
Expand All @@ -35,12 +33,10 @@ func (b *bash) InstallPath() (string, error) {
return filepath.Join(homeDir, ".bashrc"), nil
}

// WriteCompletion implements Shell.
func (b *bash) WriteCompletion(w io.Writer) error {
return configTemplateWriter(w, bashCompletionTemplate, b.programName)
return writeConfig(w, bashCompletionTemplate, b.programName)
}

// ProgramName implements Shell.
func (b *bash) ProgramName() string {
return b.programName
}
Expand Down
6 changes: 1 addition & 5 deletions completion/fish.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ func Fish(goos string, programName string) Shell {
return &fish{goos: goos, programName: programName}
}

// Name implements Shell.
func (f *fish) Name() string {
return "fish"
}

// InstallPath implements Shell.
func (f *fish) InstallPath() (string, error) {
homeDir, err := home.Dir()
if err != nil {
Expand All @@ -32,12 +30,10 @@ func (f *fish) InstallPath() (string, error) {
return filepath.Join(homeDir, ".config/fish/completions/", f.programName+".fish"), nil
}

// WriteCompletion implements Shell.
func (f *fish) WriteCompletion(w io.Writer) error {
return configTemplateWriter(w, fishCompletionTemplate, f.programName)
return writeConfig(w, fishCompletionTemplate, f.programName)
}

// ProgramName implements Shell.
func (f *fish) ProgramName() string {
return f.programName
}
Expand Down
6 changes: 1 addition & 5 deletions completion/powershell.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ type powershell struct {

var _ Shell = &powershell{}

// Name implements Shell.
func (p *powershell) Name() string {
return "powershell"
}
Expand All @@ -22,7 +21,6 @@ func Powershell(goos string, programName string) Shell {
return &powershell{goos: goos, programName: programName}
}

// InstallPath implements Shell.
func (p *powershell) InstallPath() (string, error) {
var (
path []byte
Expand All @@ -40,12 +38,10 @@ func (p *powershell) InstallPath() (string, error) {
return strings.TrimSpace(string(path)), nil
}

// WriteCompletion implements Shell.
func (p *powershell) WriteCompletion(w io.Writer) error {
return configTemplateWriter(w, pshCompletionTemplate, p.programName)
return writeConfig(w, pshCompletionTemplate, p.programName)
}

// ProgramName implements Shell.
func (p *powershell) ProgramName() string {
return p.programName
}
Expand Down
6 changes: 1 addition & 5 deletions completion/zsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ func Zsh(goos string, programName string) Shell {
return &zsh{goos: goos, programName: programName}
}

// Name implements Shell.
func (z *zsh) Name() string {
return "zsh"
}

// InstallPath implements Shell.
func (z *zsh) InstallPath() (string, error) {
homeDir, err := home.Dir()
if err != nil {
Expand All @@ -32,12 +30,10 @@ func (z *zsh) InstallPath() (string, error) {
return filepath.Join(homeDir, ".zshrc"), nil
}

// WriteCompletion implements Shell.
func (z *zsh) WriteCompletion(w io.Writer) error {
return configTemplateWriter(w, zshCompletionTemplate, z.programName)
return writeConfig(w, zshCompletionTemplate, z.programName)
}

// ProgramName implements Shell.
func (z *zsh) ProgramName() string {
return z.programName
}
Expand Down
4 changes: 0 additions & 4 deletions completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,24 +321,20 @@ type fakeShell struct {
programName string
}

// ProgramName implements completion.Shell.
func (f *fakeShell) ProgramName() string {
return f.programName
}

var _ completion.Shell = &fakeShell{}

// InstallPath implements completion.Shell.
func (f *fakeShell) InstallPath() (string, error) {
return filepath.Join(f.baseInstallDir, "fake.sh"), nil
}

// Name implements completion.Shell.
func (f *fakeShell) Name() string {
return "Fake"
}

// WriteCompletion implements completion.Shell.
func (f *fakeShell) WriteCompletion(w io.Writer) error {
_, err := w.Write([]byte("\nFAKE_COMPLETION\n"))
return err
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/go-wordwrap v1.0.1
github.com/muesli/termenv v0.15.2
github.com/natefinch/atomic v1.0.1
github.com/pion/udp v0.1.4
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/transport/v2 v2.0.0 h1:bsMYyqHCbkvHwj+eNCFBuxtlKndKfyGI2vaQmM3fIE4=
github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc=
Expand Down
1 change: 0 additions & 1 deletion values.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,6 @@ type EnumArray struct {
Value *[]string
}

// Append implements pflag.SliceValue.
func (e *EnumArray) Append(s string) error {
for _, c := range e.Choices {
if s == c {
Expand Down

0 comments on commit 64b9c1e

Please # to comment.