Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

save: Save files atomically #3273

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
27190ca
actions: SaveAs: Print the error of `os.Stat()` to the `InfoBar`
JoeKar Apr 29, 2024
9b4f4ee
save: Convert `os.IsNotExist()` into `errors.Is()`
JoeKar May 1, 2024
870f2fb
open & write: Process regular files only
JoeKar May 12, 2024
3edf31d
buffer: Convert `os.Is()` into `errors.Is()`
JoeKar May 29, 2024
9595862
backup: Convert `os.IsNotExist()` into `errors.Is()`
JoeKar May 12, 2024
322ee18
backup: Store the file with the endings of the buffer
JoeKar May 23, 2024
e9027da
backup: Lock the buffer lines in `Backup()`
JoeKar May 24, 2024
30a7c62
bindings: Convert `os.IsNotExist()` into `errors.Is()`
JoeKar May 12, 2024
84b9c79
clean: Inform about all failed write steps
JoeKar May 12, 2024
9c21055
clean: Remove some unneeded `filepath.Join()` calls
JoeKar May 12, 2024
0e56940
util: Improve and rename `EscapePath()` to `DetermineEscapePath()`
JoeKar May 24, 2024
d79b665
util: Generalize the file mode of 0666 with `util.FileMode`
JoeKar May 30, 2024
4513796
ioutil: Remove deprecated functions where possible
JoeKar May 30, 2024
a00c7f7
save: Perform write process atomic
JoeKar May 29, 2024
d192c34
util: Provide `AppendBackupSuffix()` for further transformations
JoeKar Sep 3, 2024
a570ed4
backup: Perform write process atomic
JoeKar May 31, 2024
d687dca
util: Provide `SafeWrite()` to generalize the internal file write pro…
JoeKar Aug 29, 2024
d3e8ba5
serialize: Perform write process atomic
JoeKar Jun 1, 2024
a74a982
bindings: Perform write process atomic
JoeKar Jun 1, 2024
3675890
settings: Perform write process atomic
JoeKar Jun 1, 2024
c37d7de
micro: Generalize exit behavior
JoeKar Sep 8, 2024
d4601cd
micro: Provide recovery of `settings.json` & `bindings.json`
JoeKar Sep 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions cmd/micro/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bufio"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO:
Replace them in the plugin interfaces in the future!

Done in #3393?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, was already done as interface compatible interface extension.
I removed this TODO from the commit message locally now.

"encoding/gob"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
Expand Down Expand Up @@ -91,7 +90,7 @@ func CleanConfig() {

// detect incorrectly formatted buffer/ files
buffersPath := filepath.Join(config.ConfigDir, "buffers")
files, err := ioutil.ReadDir(buffersPath)
files, err := os.ReadDir(buffersPath)
if err == nil {
var badFiles []string
var buffer buffer.SerializedBuffer
Expand Down
3 changes: 1 addition & 2 deletions cmd/micro/micro.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/signal"
Expand Down Expand Up @@ -209,7 +208,7 @@ func LoadInput(args []string) []*buffer.Buffer {
// Option 2
// The input is not a terminal, so something is being piped in
// and we should read from stdin
input, err = ioutil.ReadAll(os.Stdin)
input, err = io.ReadAll(os.Stdin)
if err != nil {
screen.TermMessage("Error reading from stdin: ", err)
input = []byte{}
Expand Down
13 changes: 6 additions & 7 deletions internal/action/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"regexp"
Expand All @@ -27,7 +26,7 @@ var Binder = map[string]func(e Event, action string){

func createBindingsIfNotExist(fname string) {
if _, e := os.Stat(fname); errors.Is(e, fs.ErrNotExist) {
ioutil.WriteFile(fname, []byte("{}"), util.FileMode)
os.WriteFile(fname, []byte("{}"), util.FileMode)
}
}

Expand All @@ -39,7 +38,7 @@ func InitBindings() {
createBindingsIfNotExist(filename)

if _, e := os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
input, err := os.ReadFile(filename)
if err != nil {
screen.TermMessage("Error reading bindings.json file: " + err.Error())
return
Expand Down Expand Up @@ -267,7 +266,7 @@ func TryBindKey(k, v string, overwrite bool) (bool, error) {
filename := filepath.Join(config.ConfigDir, "bindings.json")
createBindingsIfNotExist(filename)
if _, e = os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
input, err := os.ReadFile(filename)
if err != nil {
return false, errors.New("Error reading bindings.json file: " + err.Error())
}
Expand Down Expand Up @@ -306,7 +305,7 @@ func TryBindKey(k, v string, overwrite bool) (bool, error) {
BindKey(k, v, Binder["buffer"])

txt, _ := json.MarshalIndent(parsed, "", " ")
return true, ioutil.WriteFile(filename, append(txt, '\n'), util.FileMode)
return true, os.WriteFile(filename, append(txt, '\n'), util.FileMode)
}
return false, e
}
Expand All @@ -319,7 +318,7 @@ func UnbindKey(k string) error {
filename := filepath.Join(config.ConfigDir, "bindings.json")
createBindingsIfNotExist(filename)
if _, e = os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
input, err := os.ReadFile(filename)
if err != nil {
return errors.New("Error reading bindings.json file: " + err.Error())
}
Expand Down Expand Up @@ -356,7 +355,7 @@ func UnbindKey(k string) error {
}

txt, _ := json.MarshalIndent(parsed, "", " ")
return ioutil.WriteFile(filename, append(txt, '\n'), util.FileMode)
return os.WriteFile(filename, append(txt, '\n'), util.FileMode)
}
return e
}
Expand Down
8 changes: 4 additions & 4 deletions internal/buffer/autocomplete.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package buffer

import (
"bytes"
"io/ioutil"
"io/fs"
"os"
"sort"
"strings"
Expand Down Expand Up @@ -109,15 +109,15 @@ func FileComplete(b *Buffer) ([]string, []string) {
sep := string(os.PathSeparator)
dirs := strings.Split(input, sep)

var files []os.FileInfo
var files []fs.DirEntry
var err error
if len(dirs) > 1 {
directories := strings.Join(dirs[:len(dirs)-1], sep) + sep

directories, _ = util.ReplaceHome(directories)
files, err = ioutil.ReadDir(directories)
files, err = os.ReadDir(directories)
} else {
files, err = ioutil.ReadDir(".")
files, err = os.ReadDir(".")
}

if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions internal/buffer/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -550,7 +549,7 @@ func (b *Buffer) ReOpen() error {
}

reader := bufio.NewReader(transform.NewReader(file, enc.NewDecoder()))
data, err := ioutil.ReadAll(reader)
data, err := io.ReadAll(reader)
txt := string(data)

if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions internal/config/plugin_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
Expand Down Expand Up @@ -396,7 +395,7 @@ func (pv *PluginVersion) DownloadAndInstall(out io.Writer) error {
return err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
Expand Down
11 changes: 5 additions & 6 deletions internal/config/rtfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package config

import (
"errors"
"io/ioutil"
"log"
"os"
"path"
Expand Down Expand Up @@ -87,7 +86,7 @@ func (rf realFile) Name() string {
}

func (rf realFile) Data() ([]byte, error) {
return ioutil.ReadFile(string(rf))
return os.ReadFile(string(rf))
}

func (af assetFile) Name() string {
Expand Down Expand Up @@ -117,7 +116,7 @@ func AddRealRuntimeFile(fileType RTFiletype, file RuntimeFile) {
// AddRuntimeFilesFromDirectory registers each file from the given directory for
// the filetype which matches the file-pattern
func AddRuntimeFilesFromDirectory(fileType RTFiletype, directory, pattern string) {
files, _ := ioutil.ReadDir(directory)
files, _ := os.ReadDir(directory)
for _, f := range files {
if ok, _ := filepath.Match(pattern, f.Name()); !f.IsDir() && ok {
fullPath := filepath.Join(directory, f.Name())
Expand Down Expand Up @@ -204,22 +203,22 @@ func InitPlugins() {

// Search ConfigDir for plugin-scripts
plugdir := filepath.Join(ConfigDir, "plug")
files, _ := ioutil.ReadDir(plugdir)
files, _ := os.ReadDir(plugdir)

isID := regexp.MustCompile(`^[_A-Za-z0-9]+$`).MatchString

for _, d := range files {
plugpath := filepath.Join(plugdir, d.Name())
if stat, err := os.Stat(plugpath); err == nil && stat.IsDir() {
srcs, _ := ioutil.ReadDir(plugpath)
srcs, _ := os.ReadDir(plugpath)
p := new(Plugin)
p.Name = d.Name()
p.DirName = d.Name()
for _, f := range srcs {
if strings.HasSuffix(f.Name(), ".lua") {
p.Srcs = append(p.Srcs, realFile(filepath.Join(plugdir, d.Name(), f.Name())))
} else if strings.HasSuffix(f.Name(), ".json") {
data, err := ioutil.ReadFile(filepath.Join(plugdir, d.Name(), f.Name()))
data, err := os.ReadFile(filepath.Join(plugdir, d.Name(), f.Name()))
if err != nil {
continue
}
Expand Down
7 changes: 3 additions & 4 deletions internal/config/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -217,7 +216,7 @@ func ReadSettings() error {
parsedSettings = make(map[string]interface{})
filename := filepath.Join(ConfigDir, "settings.json")
if _, e := os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
input, err := os.ReadFile(filename)
if err != nil {
settingsParseError = true
return errors.New("Error reading settings.json file: " + err.Error())
Expand Down Expand Up @@ -342,7 +341,7 @@ func WriteSettings(filename string) error {
}

txt, _ := json.MarshalIndent(parsedSettings, "", " ")
err = ioutil.WriteFile(filename, append(txt, '\n'), util.FileMode)
err = os.WriteFile(filename, append(txt, '\n'), util.FileMode)
}
return err
}
Expand All @@ -364,7 +363,7 @@ func OverwriteSettings(filename string) error {
}

txt, _ := json.MarshalIndent(settings, "", " ")
err = ioutil.WriteFile(filename, append(txt, '\n'), util.FileMode)
err = os.WriteFile(filename, append(txt, '\n'), util.FileMode)
}
return err
}
Expand Down
7 changes: 3 additions & 4 deletions runtime/syntax/make_headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
Expand Down Expand Up @@ -34,7 +33,7 @@ func main() {
if len(os.Args) > 1 {
os.Chdir(os.Args[1])
}
files, _ := ioutil.ReadDir(".")
files, _ := os.ReadDir(".")
for _, f := range files {
fname := f.Name()
if strings.HasSuffix(fname, ".yaml") {
Expand All @@ -46,7 +45,7 @@ func main() {
func convert(name string) {
filename := name + ".yaml"
var hdr HeaderYaml
source, err := ioutil.ReadFile(filename)
source, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
Expand All @@ -68,7 +67,7 @@ func encode(name string, c HeaderYaml) {

func decode(name string) Header {
start := time.Now()
data, _ := ioutil.ReadFile(name + ".hdr")
data, _ := os.ReadFile(name + ".hdr")
strs := bytes.Split(data, []byte{'\n'})
var hdr Header
hdr.FileType = string(strs[0])
Expand Down
3 changes: 1 addition & 2 deletions runtime/syntax/syntax_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package main

import (
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
Expand Down Expand Up @@ -161,6 +160,6 @@ func main() {
return
}

data, _ := ioutil.ReadFile(os.Args[1])
data, _ := os.ReadFile(os.Args[1])
fmt.Print(generateFile(parseFile(string(data), os.Args[1])))
}
4 changes: 2 additions & 2 deletions tools/remove-nightly-assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package main

import (
"fmt"
"io/ioutil"
"io"
"net/http"
"os/exec"
"strings"
Expand All @@ -19,7 +19,7 @@ func main() {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)

var data interface{}

Expand Down
3 changes: 1 addition & 2 deletions tools/testgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package main

import (
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
Expand Down Expand Up @@ -210,7 +209,7 @@ func main() {
var tests []test

for _, filename := range os.Args[1:] {
source, err := ioutil.ReadFile(filename)
source, err := os.ReadFile(filename)
if err != nil {
log.Fatalln(err)
}
Expand Down