mirror of
https://github.com/octoleo/restic.git
synced 2024-11-29 08:14:03 +00:00
Merge pull request #5122 from restic/bump-golangci-lint
Bump go and golangci lint version
This commit is contained in:
commit
270e7b7679
17
.github/workflows/tests.yml
vendored
17
.github/workflows/tests.yml
vendored
@ -13,7 +13,7 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
latest_go: "1.22.x"
|
latest_go: "1.23.x"
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -23,27 +23,32 @@ jobs:
|
|||||||
# list of jobs to run:
|
# list of jobs to run:
|
||||||
include:
|
include:
|
||||||
- job_name: Windows
|
- job_name: Windows
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
os: windows-latest
|
os: windows-latest
|
||||||
|
|
||||||
- job_name: macOS
|
- job_name: macOS
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
os: macOS-latest
|
os: macOS-latest
|
||||||
test_fuse: false
|
test_fuse: false
|
||||||
|
|
||||||
- job_name: Linux
|
- job_name: Linux
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
test_cloud_backends: true
|
test_cloud_backends: true
|
||||||
test_fuse: true
|
test_fuse: true
|
||||||
check_changelog: true
|
check_changelog: true
|
||||||
|
|
||||||
- job_name: Linux (race)
|
- job_name: Linux (race)
|
||||||
go: 1.22.x
|
go: 1.23.x
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
test_fuse: true
|
test_fuse: true
|
||||||
test_opts: "-race"
|
test_opts: "-race"
|
||||||
|
|
||||||
|
- job_name: Linux
|
||||||
|
go: 1.22.x
|
||||||
|
os: ubuntu-latest
|
||||||
|
test_fuse: true
|
||||||
|
|
||||||
- job_name: Linux
|
- job_name: Linux
|
||||||
go: 1.21.x
|
go: 1.21.x
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@ -254,7 +259,7 @@ jobs:
|
|||||||
uses: golangci/golangci-lint-action@v6
|
uses: golangci/golangci-lint-action@v6
|
||||||
with:
|
with:
|
||||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
version: v1.57.1
|
version: v1.61.0
|
||||||
args: --verbose --timeout 5m
|
args: --verbose --timeout 5m
|
||||||
|
|
||||||
# only run golangci-lint for pull requests, otherwise ALL hints get
|
# only run golangci-lint for pull requests, otherwise ALL hints get
|
||||||
|
@ -365,12 +365,7 @@ func TestBackupExclude(t *testing.T) {
|
|||||||
for _, filename := range backupExcludeFilenames {
|
for _, filename := range backupExcludeFilenames {
|
||||||
fp := filepath.Join(datadir, filename)
|
fp := filepath.Join(datadir, filename)
|
||||||
rtest.OK(t, os.MkdirAll(filepath.Dir(fp), 0755))
|
rtest.OK(t, os.MkdirAll(filepath.Dir(fp), 0755))
|
||||||
|
rtest.OK(t, os.WriteFile(fp, []byte(filename), 0o666))
|
||||||
f, err := os.Create(fp)
|
|
||||||
rtest.OK(t, err)
|
|
||||||
|
|
||||||
fmt.Fprint(f, filename)
|
|
||||||
rtest.OK(t, f.Close())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshots := make(map[string]struct{})
|
snapshots := make(map[string]struct{})
|
||||||
|
@ -39,21 +39,24 @@ func TestCollectTargets(t *testing.T) {
|
|||||||
f1, err := os.Create(filepath.Join(dir, "fromfile"))
|
f1, err := os.Create(filepath.Join(dir, "fromfile"))
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
// Empty lines should be ignored. A line starting with '#' is a comment.
|
// Empty lines should be ignored. A line starting with '#' is a comment.
|
||||||
fmt.Fprintf(f1, "\n%s*\n # here's a comment\n", f1.Name())
|
_, err = fmt.Fprintf(f1, "\n%s*\n # here's a comment\n", f1.Name())
|
||||||
|
rtest.OK(t, err)
|
||||||
rtest.OK(t, f1.Close())
|
rtest.OK(t, f1.Close())
|
||||||
|
|
||||||
f2, err := os.Create(filepath.Join(dir, "fromfile-verbatim"))
|
f2, err := os.Create(filepath.Join(dir, "fromfile-verbatim"))
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
for _, filename := range []string{fooSpace, barStar} {
|
for _, filename := range []string{fooSpace, barStar} {
|
||||||
// Empty lines should be ignored. CR+LF is allowed.
|
// Empty lines should be ignored. CR+LF is allowed.
|
||||||
fmt.Fprintf(f2, "%s\r\n\n", filepath.Join(dir, filename))
|
_, err = fmt.Fprintf(f2, "%s\r\n\n", filepath.Join(dir, filename))
|
||||||
|
rtest.OK(t, err)
|
||||||
}
|
}
|
||||||
rtest.OK(t, f2.Close())
|
rtest.OK(t, f2.Close())
|
||||||
|
|
||||||
f3, err := os.Create(filepath.Join(dir, "fromfile-raw"))
|
f3, err := os.Create(filepath.Join(dir, "fromfile-raw"))
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
for _, filename := range []string{"baz", "quux"} {
|
for _, filename := range []string{"baz", "quux"} {
|
||||||
fmt.Fprintf(f3, "%s\x00", filepath.Join(dir, filename))
|
_, err = fmt.Fprintf(f3, "%s\x00", filepath.Join(dir, filename))
|
||||||
|
rtest.OK(t, err)
|
||||||
}
|
}
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
rtest.OK(t, f3.Close())
|
rtest.OK(t, f3.Close())
|
||||||
|
@ -75,17 +75,17 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type lsPrinter interface {
|
type lsPrinter interface {
|
||||||
Snapshot(sn *restic.Snapshot)
|
Snapshot(sn *restic.Snapshot) error
|
||||||
Node(path string, node *restic.Node, isPrefixDirectory bool)
|
Node(path string, node *restic.Node, isPrefixDirectory bool) error
|
||||||
LeaveDir(path string)
|
LeaveDir(path string) error
|
||||||
Close()
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonLsPrinter struct {
|
type jsonLsPrinter struct {
|
||||||
enc *json.Encoder
|
enc *json.Encoder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) {
|
func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) error {
|
||||||
type lsSnapshot struct {
|
type lsSnapshot struct {
|
||||||
*restic.Snapshot
|
*restic.Snapshot
|
||||||
ID *restic.ID `json:"id"`
|
ID *restic.ID `json:"id"`
|
||||||
@ -94,27 +94,21 @@ func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) {
|
|||||||
StructType string `json:"struct_type"` // "snapshot", deprecated
|
StructType string `json:"struct_type"` // "snapshot", deprecated
|
||||||
}
|
}
|
||||||
|
|
||||||
err := p.enc.Encode(lsSnapshot{
|
return p.enc.Encode(lsSnapshot{
|
||||||
Snapshot: sn,
|
Snapshot: sn,
|
||||||
ID: sn.ID(),
|
ID: sn.ID(),
|
||||||
ShortID: sn.ID().Str(),
|
ShortID: sn.ID().Str(),
|
||||||
MessageType: "snapshot",
|
MessageType: "snapshot",
|
||||||
StructType: "snapshot",
|
StructType: "snapshot",
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print node in our custom JSON format, followed by a newline.
|
// Print node in our custom JSON format, followed by a newline.
|
||||||
func (p *jsonLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) {
|
func (p *jsonLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) error {
|
||||||
if isPrefixDirectory {
|
if isPrefixDirectory {
|
||||||
return
|
return nil
|
||||||
}
|
|
||||||
err := lsNodeJSON(p.enc, path, node)
|
|
||||||
if err != nil {
|
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
return lsNodeJSON(p.enc, path, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error {
|
func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error {
|
||||||
@ -160,8 +154,8 @@ func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error {
|
|||||||
return enc.Encode(n)
|
return enc.Encode(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *jsonLsPrinter) LeaveDir(_ string) {}
|
func (p *jsonLsPrinter) LeaveDir(_ string) error { return nil }
|
||||||
func (p *jsonLsPrinter) Close() {}
|
func (p *jsonLsPrinter) Close() error { return nil }
|
||||||
|
|
||||||
type ncduLsPrinter struct {
|
type ncduLsPrinter struct {
|
||||||
out io.Writer
|
out io.Writer
|
||||||
@ -171,16 +165,17 @@ type ncduLsPrinter struct {
|
|||||||
// lsSnapshotNcdu prints a restic snapshot in Ncdu save format.
|
// lsSnapshotNcdu prints a restic snapshot in Ncdu save format.
|
||||||
// It opens the JSON list. Nodes are added with lsNodeNcdu and the list is closed by lsCloseNcdu.
|
// It opens the JSON list. Nodes are added with lsNodeNcdu and the list is closed by lsCloseNcdu.
|
||||||
// Format documentation: https://dev.yorhel.nl/ncdu/jsonfmt
|
// Format documentation: https://dev.yorhel.nl/ncdu/jsonfmt
|
||||||
func (p *ncduLsPrinter) Snapshot(sn *restic.Snapshot) {
|
func (p *ncduLsPrinter) Snapshot(sn *restic.Snapshot) error {
|
||||||
const NcduMajorVer = 1
|
const NcduMajorVer = 1
|
||||||
const NcduMinorVer = 2
|
const NcduMinorVer = 2
|
||||||
|
|
||||||
snapshotBytes, err := json.Marshal(sn)
|
snapshotBytes, err := json.Marshal(sn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
return err
|
||||||
}
|
}
|
||||||
p.depth++
|
p.depth++
|
||||||
fmt.Fprintf(p.out, "[%d, %d, %s, [{\"name\":\"/\"}", NcduMajorVer, NcduMinorVer, string(snapshotBytes))
|
_, err = fmt.Fprintf(p.out, "[%d, %d, %s, [{\"name\":\"/\"}", NcduMajorVer, NcduMinorVer, string(snapshotBytes))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func lsNcduNode(_ string, node *restic.Node) ([]byte, error) {
|
func lsNcduNode(_ string, node *restic.Node) ([]byte, error) {
|
||||||
@ -232,27 +227,30 @@ func lsNcduNode(_ string, node *restic.Node) ([]byte, error) {
|
|||||||
return json.Marshal(outNode)
|
return json.Marshal(outNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ncduLsPrinter) Node(path string, node *restic.Node, _ bool) {
|
func (p *ncduLsPrinter) Node(path string, node *restic.Node, _ bool) error {
|
||||||
out, err := lsNcduNode(path, node)
|
out, err := lsNcduNode(path, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == restic.NodeTypeDir {
|
if node.Type == restic.NodeTypeDir {
|
||||||
fmt.Fprintf(p.out, ",\n%s[\n%s%s", strings.Repeat(" ", p.depth), strings.Repeat(" ", p.depth+1), string(out))
|
_, err = fmt.Fprintf(p.out, ",\n%s[\n%s%s", strings.Repeat(" ", p.depth), strings.Repeat(" ", p.depth+1), string(out))
|
||||||
p.depth++
|
p.depth++
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(p.out, ",\n%s%s", strings.Repeat(" ", p.depth), string(out))
|
_, err = fmt.Fprintf(p.out, ",\n%s%s", strings.Repeat(" ", p.depth), string(out))
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ncduLsPrinter) LeaveDir(_ string) {
|
func (p *ncduLsPrinter) LeaveDir(_ string) error {
|
||||||
p.depth--
|
p.depth--
|
||||||
fmt.Fprintf(p.out, "\n%s]", strings.Repeat(" ", p.depth))
|
_, err := fmt.Fprintf(p.out, "\n%s]", strings.Repeat(" ", p.depth))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ncduLsPrinter) Close() {
|
func (p *ncduLsPrinter) Close() error {
|
||||||
fmt.Fprint(p.out, "\n]\n]\n")
|
_, err := fmt.Fprint(p.out, "\n]\n]\n")
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
type textLsPrinter struct {
|
type textLsPrinter struct {
|
||||||
@ -261,17 +259,23 @@ type textLsPrinter struct {
|
|||||||
HumanReadable bool
|
HumanReadable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *textLsPrinter) Snapshot(sn *restic.Snapshot) {
|
func (p *textLsPrinter) Snapshot(sn *restic.Snapshot) error {
|
||||||
Verbosef("%v filtered by %v:\n", sn, p.dirs)
|
Verbosef("%v filtered by %v:\n", sn, p.dirs)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
func (p *textLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) {
|
func (p *textLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) error {
|
||||||
if !isPrefixDirectory {
|
if !isPrefixDirectory {
|
||||||
Printf("%s\n", formatNode(path, node, p.ListLong, p.HumanReadable))
|
Printf("%s\n", formatNode(path, node, p.ListLong, p.HumanReadable))
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *textLsPrinter) LeaveDir(_ string) {}
|
func (p *textLsPrinter) LeaveDir(_ string) error {
|
||||||
func (p *textLsPrinter) Close() {}
|
return nil
|
||||||
|
}
|
||||||
|
func (p *textLsPrinter) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []string) error {
|
func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
@ -374,7 +378,9 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.Snapshot(sn)
|
if err := printer.Snapshot(sn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
processNode := func(_ restic.ID, nodepath string, node *restic.Node, err error) error {
|
processNode := func(_ restic.ID, nodepath string, node *restic.Node, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -387,7 +393,9 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
printedDir := false
|
printedDir := false
|
||||||
if withinDir(nodepath) {
|
if withinDir(nodepath) {
|
||||||
// if we're within a target path, print the node
|
// if we're within a target path, print the node
|
||||||
printer.Node(nodepath, node, false)
|
if err := printer.Node(nodepath, node, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
printedDir = true
|
printedDir = true
|
||||||
|
|
||||||
// if recursive listing is requested, signal the walker that it
|
// if recursive listing is requested, signal the walker that it
|
||||||
@ -402,7 +410,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
if approachingMatchingTree(nodepath) {
|
if approachingMatchingTree(nodepath) {
|
||||||
// print node leading up to the target paths
|
// print node leading up to the target paths
|
||||||
if !printedDir {
|
if !printedDir {
|
||||||
printer.Node(nodepath, node, true)
|
return printer.Node(nodepath, node, true)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -412,7 +420,9 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
if node.Type == restic.NodeTypeDir {
|
if node.Type == restic.NodeTypeDir {
|
||||||
// immediately generate leaveDir if the directory is skipped
|
// immediately generate leaveDir if the directory is skipped
|
||||||
if printedDir {
|
if printedDir {
|
||||||
printer.LeaveDir(nodepath)
|
if err := printer.LeaveDir(nodepath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return walker.ErrSkipNode
|
return walker.ErrSkipNode
|
||||||
}
|
}
|
||||||
@ -421,11 +431,12 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
|
|
||||||
err = walker.Walk(ctx, repo, *sn.Tree, walker.WalkVisitor{
|
err = walker.Walk(ctx, repo, *sn.Tree, walker.WalkVisitor{
|
||||||
ProcessNode: processNode,
|
ProcessNode: processNode,
|
||||||
LeaveDir: func(path string) {
|
LeaveDir: func(path string) error {
|
||||||
// the root path `/` has no corresponding node and is thus also skipped by processNode
|
// the root path `/` has no corresponding node and is thus also skipped by processNode
|
||||||
if path != "/" {
|
if path != "/" {
|
||||||
printer.LeaveDir(path)
|
return printer.LeaveDir(path)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -433,6 +444,5 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.Close()
|
return printer.Close()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -134,29 +134,29 @@ func TestLsNcdu(t *testing.T) {
|
|||||||
}
|
}
|
||||||
modTime := time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC)
|
modTime := time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC)
|
||||||
|
|
||||||
printer.Snapshot(&restic.Snapshot{
|
rtest.OK(t, printer.Snapshot(&restic.Snapshot{
|
||||||
Hostname: "host",
|
Hostname: "host",
|
||||||
Paths: []string{"/example"},
|
Paths: []string{"/example"},
|
||||||
})
|
}))
|
||||||
printer.Node("/directory", &restic.Node{
|
rtest.OK(t, printer.Node("/directory", &restic.Node{
|
||||||
Type: restic.NodeTypeDir,
|
Type: restic.NodeTypeDir,
|
||||||
Name: "directory",
|
Name: "directory",
|
||||||
ModTime: modTime,
|
ModTime: modTime,
|
||||||
}, false)
|
}, false))
|
||||||
printer.Node("/directory/data", &restic.Node{
|
rtest.OK(t, printer.Node("/directory/data", &restic.Node{
|
||||||
Type: restic.NodeTypeFile,
|
Type: restic.NodeTypeFile,
|
||||||
Name: "data",
|
Name: "data",
|
||||||
Size: 42,
|
Size: 42,
|
||||||
ModTime: modTime,
|
ModTime: modTime,
|
||||||
}, false)
|
}, false))
|
||||||
printer.LeaveDir("/directory")
|
rtest.OK(t, printer.LeaveDir("/directory"))
|
||||||
printer.Node("/file", &restic.Node{
|
rtest.OK(t, printer.Node("/file", &restic.Node{
|
||||||
Type: restic.NodeTypeFile,
|
Type: restic.NodeTypeFile,
|
||||||
Name: "file",
|
Name: "file",
|
||||||
Size: 12345,
|
Size: 12345,
|
||||||
ModTime: modTime,
|
ModTime: modTime,
|
||||||
}, false)
|
}, false))
|
||||||
printer.Close()
|
rtest.OK(t, printer.Close())
|
||||||
|
|
||||||
rtest.Equals(t, `[1, 2, {"time":"0001-01-01T00:00:00Z","tree":null,"paths":["/example"],"hostname":"host"}, [{"name":"/"},
|
rtest.Equals(t, `[1, 2, {"time":"0001-01-01T00:00:00Z","tree":null,"paths":["/example"],"hostname":"host"}, [{"name":"/"},
|
||||||
[
|
[
|
||||||
|
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -141,7 +140,7 @@ func rewriteSnapshot(ctx context.Context, repo *repository.Repository, sn *resti
|
|||||||
if selectByName(path) {
|
if selectByName(path) {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
Verbosef(fmt.Sprintf("excluding %s\n", path))
|
Verbosef("excluding %s\n", path)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +296,9 @@ func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
fmt.Fprintf(stdout, "snapshots")
|
if _, err := fmt.Fprintf(stdout, "snapshots"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
var infoStrings []string
|
var infoStrings []string
|
||||||
if key.Hostname != "" {
|
if key.Hostname != "" {
|
||||||
infoStrings = append(infoStrings, "host ["+key.Hostname+"]")
|
infoStrings = append(infoStrings, "host ["+key.Hostname+"]")
|
||||||
@ -308,11 +310,13 @@ func PrintSnapshotGroupHeader(stdout io.Writer, groupKeyJSON string) error {
|
|||||||
infoStrings = append(infoStrings, "paths ["+strings.Join(key.Paths, ", ")+"]")
|
infoStrings = append(infoStrings, "paths ["+strings.Join(key.Paths, ", ")+"]")
|
||||||
}
|
}
|
||||||
if infoStrings != nil {
|
if infoStrings != nil {
|
||||||
fmt.Fprintf(stdout, " for (%s)", strings.Join(infoStrings, ", "))
|
if _, err := fmt.Fprintf(stdout, " for (%s)", strings.Join(infoStrings, ", ")); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(stdout, ":\n")
|
}
|
||||||
|
_, err = fmt.Fprintf(stdout, ":\n")
|
||||||
|
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot helps to print Snapshots as JSON with their ID included.
|
// Snapshot helps to print Snapshots as JSON with their ID included.
|
||||||
|
@ -308,7 +308,7 @@ func readPasswordTerminal(ctx context.Context, in *os.File, out *os.File, prompt
|
|||||||
fd := int(out.Fd())
|
fd := int(out.Fd())
|
||||||
state, err := term.GetState(fd)
|
state, err := term.GetState(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "unable to get terminal state: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "unable to get terminal state: %v\n", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,16 +317,22 @@ func readPasswordTerminal(ctx context.Context, in *os.File, out *os.File, prompt
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
fmt.Fprint(out, prompt)
|
_, err = fmt.Fprint(out, prompt)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
buf, err = term.ReadPassword(int(in.Fd()))
|
buf, err = term.ReadPassword(int(in.Fd()))
|
||||||
fmt.Fprintln(out)
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintln(out)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
err := term.Restore(fd, state)
|
err := term.Restore(fd, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err)
|
||||||
}
|
}
|
||||||
return "", ctx.Err()
|
return "", ctx.Err()
|
||||||
case <-done:
|
case <-done:
|
||||||
|
@ -13,17 +13,17 @@ import (
|
|||||||
|
|
||||||
func (e *dirEntry) equals(out io.Writer, other *dirEntry) bool {
|
func (e *dirEntry) equals(out io.Writer, other *dirEntry) bool {
|
||||||
if e.path != other.path {
|
if e.path != other.path {
|
||||||
fmt.Fprintf(out, "%v: path does not match (%v != %v)\n", e.path, e.path, other.path)
|
_, _ = fmt.Fprintf(out, "%v: path does not match (%v != %v)\n", e.path, e.path, other.path)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.fi.Mode() != other.fi.Mode() {
|
if e.fi.Mode() != other.fi.Mode() {
|
||||||
fmt.Fprintf(out, "%v: mode does not match (%v != %v)\n", e.path, e.fi.Mode(), other.fi.Mode())
|
_, _ = fmt.Fprintf(out, "%v: mode does not match (%v != %v)\n", e.path, e.fi.Mode(), other.fi.Mode())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sameModTime(e.fi, other.fi) {
|
if !sameModTime(e.fi, other.fi) {
|
||||||
fmt.Fprintf(out, "%v: ModTime does not match (%v != %v)\n", e.path, e.fi.ModTime(), other.fi.ModTime())
|
_, _ = fmt.Fprintf(out, "%v: ModTime does not match (%v != %v)\n", e.path, e.fi.ModTime(), other.fi.ModTime())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,17 +31,17 @@ func (e *dirEntry) equals(out io.Writer, other *dirEntry) bool {
|
|||||||
stat2, _ := other.fi.Sys().(*syscall.Stat_t)
|
stat2, _ := other.fi.Sys().(*syscall.Stat_t)
|
||||||
|
|
||||||
if stat.Uid != stat2.Uid {
|
if stat.Uid != stat2.Uid {
|
||||||
fmt.Fprintf(out, "%v: UID does not match (%v != %v)\n", e.path, stat.Uid, stat2.Uid)
|
_, _ = fmt.Fprintf(out, "%v: UID does not match (%v != %v)\n", e.path, stat.Uid, stat2.Uid)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if stat.Gid != stat2.Gid {
|
if stat.Gid != stat2.Gid {
|
||||||
fmt.Fprintf(out, "%v: GID does not match (%v != %v)\n", e.path, stat.Gid, stat2.Gid)
|
_, _ = fmt.Fprintf(out, "%v: GID does not match (%v != %v)\n", e.path, stat.Gid, stat2.Gid)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if stat.Nlink != stat2.Nlink {
|
if stat.Nlink != stat2.Nlink {
|
||||||
fmt.Fprintf(out, "%v: Number of links do not match (%v != %v)\n", e.path, stat.Nlink, stat2.Nlink)
|
_, _ = fmt.Fprintf(out, "%v: Number of links do not match (%v != %v)\n", e.path, stat.Nlink, stat2.Nlink)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ func printExitError(code int, message string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(globalOptions.stderr, "%v\n", message)
|
_, _ = fmt.Fprintf(globalOptions.stderr, "%v\n", message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,10 +152,10 @@ func main() {
|
|||||||
log.SetOutput(logBuffer)
|
log.SetOutput(logBuffer)
|
||||||
|
|
||||||
err := feature.Flag.Apply(os.Getenv("RESTIC_FEATURES"), func(s string) {
|
err := feature.Flag.Apply(os.Getenv("RESTIC_FEATURES"), func(s string) {
|
||||||
fmt.Fprintln(os.Stderr, s)
|
_, _ = fmt.Fprintln(os.Stderr, s)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||||
Exit(1)
|
Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ func runRESTServer(ctx context.Context, t testing.TB, dir, reqListenAddr string)
|
|||||||
matched = true
|
matched = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintln(os.Stdout, line) // print all output to console
|
_, _ = fmt.Fprintln(os.Stdout, line) // print all output to console
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ func goroutineNum() int {
|
|||||||
runtime.Stack(b, false)
|
runtime.Stack(b, false)
|
||||||
var num int
|
var num int
|
||||||
|
|
||||||
fmt.Sscanf(string(b), "goroutine %d ", &num)
|
_, _ = fmt.Sscanf(string(b), "goroutine %d ", &num)
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func (rd *eofDetectReader) Close() error {
|
|||||||
msg += fmt.Sprintf(", body: %q", buf)
|
msg += fmt.Sprintf(", body: %q", buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(os.Stderr, msg)
|
_, _ = fmt.Fprintln(os.Stderr, msg)
|
||||||
Log("%s: %+v", msg, errors.New("Close()"))
|
Log("%s: %+v", msg, errors.New("Close()"))
|
||||||
}
|
}
|
||||||
return rd.rd.Close()
|
return rd.rd.Close()
|
||||||
|
@ -212,7 +212,7 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.WriteString(dst, msg.line); err != nil {
|
if _, err := io.WriteString(dst, msg.line); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if flush == nil {
|
if flush == nil {
|
||||||
@ -220,16 +220,18 @@ func (t *Terminal) runWithoutStatus(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := flush(); err != nil {
|
if err := flush(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
case stat := <-t.status:
|
case stat := <-t.status:
|
||||||
for _, line := range stat.lines {
|
for _, line := range stat.lines {
|
||||||
// Ensure that each message ends with exactly one newline.
|
// Ensure that each message ends with exactly one newline.
|
||||||
fmt.Fprintln(t.wr, strings.TrimRight(line, "\n"))
|
if _, err := fmt.Fprintln(t.wr, strings.TrimRight(line, "\n")); err != nil {
|
||||||
|
_, _ = fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := t.wr.Flush(); err != nil {
|
if err := t.wr.Flush(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
_, _ = fmt.Fprintf(os.Stderr, "flush failed: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ type WalkVisitor struct {
|
|||||||
// was returned. This function is mandatory
|
// was returned. This function is mandatory
|
||||||
ProcessNode WalkFunc
|
ProcessNode WalkFunc
|
||||||
// Optional callback
|
// Optional callback
|
||||||
LeaveDir func(path string)
|
LeaveDir func(path string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk calls walkFn recursively for each node in root. If walkFn returns an
|
// Walk calls walkFn recursively for each node in root. If walkFn returns an
|
||||||
@ -100,7 +100,7 @@ func walk(ctx context.Context, repo restic.BlobLoader, prefix string, parentTree
|
|||||||
}
|
}
|
||||||
|
|
||||||
if visitor.LeaveDir != nil {
|
if visitor.LeaveDir != nil {
|
||||||
visitor.LeaveDir(prefix)
|
return visitor.LeaveDir(prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -93,12 +93,12 @@ func (t TreeMap) Connections() uint {
|
|||||||
|
|
||||||
// checkFunc returns a function suitable for walking the tree to check
|
// checkFunc returns a function suitable for walking the tree to check
|
||||||
// something, and a function which will check the final result.
|
// something, and a function which will check the final result.
|
||||||
type checkFunc func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB))
|
type checkFunc func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB))
|
||||||
|
|
||||||
// checkItemOrder ensures that the order of the 'path' arguments is the one passed in as 'want'.
|
// checkItemOrder ensures that the order of the 'path' arguments is the one passed in as 'want'.
|
||||||
func checkItemOrder(want []string) checkFunc {
|
func checkItemOrder(want []string) checkFunc {
|
||||||
pos := 0
|
pos := 0
|
||||||
return func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) {
|
return func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) {
|
||||||
walker = func(treeID restic.ID, path string, node *restic.Node, err error) error {
|
walker = func(treeID restic.ID, path string, node *restic.Node, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error walking %v: %v", path, err)
|
t.Errorf("error walking %v: %v", path, err)
|
||||||
@ -117,8 +117,8 @@ func checkItemOrder(want []string) checkFunc {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
leaveDir = func(path string) {
|
leaveDir = func(path string) error {
|
||||||
_ = walker(restic.ID{}, "leave: "+path, nil, nil)
|
return walker(restic.ID{}, "leave: "+path, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
final = func(t testing.TB) {
|
final = func(t testing.TB) {
|
||||||
@ -134,7 +134,7 @@ func checkItemOrder(want []string) checkFunc {
|
|||||||
// checkParentTreeOrder ensures that the order of the 'parentID' arguments is the one passed in as 'want'.
|
// checkParentTreeOrder ensures that the order of the 'parentID' arguments is the one passed in as 'want'.
|
||||||
func checkParentTreeOrder(want []string) checkFunc {
|
func checkParentTreeOrder(want []string) checkFunc {
|
||||||
pos := 0
|
pos := 0
|
||||||
return func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) {
|
return func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) {
|
||||||
walker = func(treeID restic.ID, path string, node *restic.Node, err error) error {
|
walker = func(treeID restic.ID, path string, node *restic.Node, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error walking %v: %v", path, err)
|
t.Errorf("error walking %v: %v", path, err)
|
||||||
@ -168,7 +168,7 @@ func checkParentTreeOrder(want []string) checkFunc {
|
|||||||
func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc {
|
func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc {
|
||||||
var pos int
|
var pos int
|
||||||
|
|
||||||
return func(t testing.TB) (walker WalkFunc, leaveDir func(path string), final func(testing.TB)) {
|
return func(t testing.TB) (walker WalkFunc, leaveDir func(path string) error, final func(testing.TB)) {
|
||||||
walker = func(treeID restic.ID, path string, node *restic.Node, err error) error {
|
walker = func(treeID restic.ID, path string, node *restic.Node, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("error walking %v: %v", path, err)
|
t.Errorf("error walking %v: %v", path, err)
|
||||||
@ -192,8 +192,8 @@ func checkSkipFor(skipFor map[string]struct{}, wantPaths []string) checkFunc {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
leaveDir = func(path string) {
|
leaveDir = func(path string) error {
|
||||||
_ = walker(restic.ID{}, "leave: "+path, nil, nil)
|
return walker(restic.ID{}, "leave: "+path, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
final = func(t testing.TB) {
|
final = func(t testing.TB) {
|
||||||
|
Loading…
Reference in New Issue
Block a user