Strider report

Strider corpus: restic

171 msformat978 mscheck 5843total 785errors 2426warnings 2632notes

Showing 1000 of 5843 detailed findings. The summary includes all 5843 findings.

build.go1

251:27add-constantstring literal "go" appears more than twice; define a constant

build.go:251:27

250func ParseGoVersion(s string) (v GoVersion) {
251 if !strings.HasPrefix(s, "go") {
252 return

internal/ui/backup/text.go1

68:17append-to-sized-slicelines already has a positive length; use make with length zero and capacity, or reslice to zero before append

internal/ui/backup/text.go:68:17

67 for filename := range currentFiles {
68 lines = append(lines, filename)
69 }

internal/global/global_debug.go1

9:2blank-importsblank import should be justified by a comment

internal/global/global_debug.go:9:2

8 "net/http"
9 _ "net/http/pprof"
10

internal/fs/stat_darwin_test.go1

31:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/fs/stat_darwin_test.go:31:18

30 rtest.Assert(t, err == nil, "err should be nil", err)
31 rtest.Assert(t, recall == false, "RecallOnDataAccess should be false")
32}

cmd/restic/cmd_prune.go1

243:2call-to-gcavoid explicit garbage collection

cmd/restic/cmd_prune.go:243:2

242 // Trigger GC to reset garbage collection threshold
243 runtime.GC()
244

build.go1

250:6cognitive-complexityfunction has cognitive complexity 11; maximum is 7

build.go:250:6

249// ParseGoVersion parses the Go version s. If s cannot be parsed, the returned GoVersion is null.
250func ParseGoVersion(s string) (v GoVersion) {
251 if !strings.HasPrefix(s, "go") {

cmd/restic/cmd_backup_integration_test.go1

60:6confusing-namingname testBackup differs from TestBackup only by capitalization

cmd/restic/cmd_backup_integration_test.go:60:6

59
60func testBackup(t *testing.T, useFsSnapshot bool) {
61 env, cleanup := withTestEnvironment(t)

cmd/restic/cmd_check_integration_test.go1

28:88confusing-resultsadjacent unnamed results of the same type should be named

cmd/restic/cmd_check_integration_test.go:28:88

27
28func testRunCheckOutput(t testing.TB, gopts global.Options, checkUnused bool) (string, string, error) {
29 stdout, stderr, err := withCaptureStdoutStderr(t, gopts, func(ctx context.Context, gopts global.Options) error {

internal/backend/limiter/static_limiter.go1

25:6constructor-interface-returnNewStaticLimiter returns interface Limiter although its concrete result is consistently staticLimiter; return the concrete type

internal/backend/limiter/static_limiter.go:25:6

24// download rate cap
25func NewStaticLimiter(l Limits) Limiter {
26 var (

internal/data/testing.go1

113:38context-as-argumentcontext.Context should be the first parameter

internal/data/testing.go:113:38

112//nolint:revive // as this is a test helper, t should go first
113func TestSaveNodes(t testing.TB, ctx context.Context, uploader restic.BlobSaver, nodes []*Node) restic.ID {
114 slices.SortFunc(nodes, func(a, b *Node) int {

internal/backend/readerat.go1

12:2context-stored-in-structdo not store context.Context in a struct; pass it explicitly to each operation

internal/backend/readerat.go:12:2

11type backendReaderAt struct {
12 ctx context.Context
13 be Backend

internal/fuse/dir.go1

53:16copy-lock-valuecomposite literal copies fuse.treeCache by value; it contains sync.Mutex

internal/fuse/dir.go:53:16

52 parentInode: parentInode,
53 cache: *newTreeCache(),
54 }, nil

build.go2

323:6cyclomatic-complexityfunction complexity is 29; maximum is 10

build.go:323:6

322
323func main() {
324 if !goVersion.AtLeast(config.MinVersion) {
87:2deep-exitprocess-exit calls should be confined to main or init

build.go:87:2

86 fmt.Fprintf(os.Stderr, message, args...)
87 os.Exit(1)
88}

internal/repository/crypto/crypto.go1

12:2deprecated-api-usagegolang.org/x/crypto/poly1305 is deprecated: Poly1305 as implemented by this package is a cryptographic building block that is not safe for general purpose use. For encryption, use the full ChaCha20-Poly1305 construction implemented by golang.org/x/crypto/chacha20poly1305. For authentication, use a general purpose MAC such as HMAC implemented by crypto/hmac.

internal/repository/crypto/crypto.go:12:2

11
12 "golang.org/x/crypto/poly1305"
13)

cmd/restic/cleanup.go1

32:10discarded-error-resulterror result returned by stderr.Write is discarded

cmd/restic/cleanup.go:32:10

31 if val, _ := os.LookupEnv("RESTIC_DEBUG_STACKTRACE_SIGINT"); val != "" {
32 _, _ = stderr.Write([]byte("\n--- STACKTRACE START ---\n\n"))
33 _, _ = stderr.Write([]byte(debug.DumpStacktrace()))

cmd/restic/cmd_backup.go1

176:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_backup.go:176:1

175
176// ErrInvalidSourceData is used to report an incomplete backup
177var ErrInvalidSourceData = errors.New("at least one source file could not be read")

internal/restorer/restorer_windows_test.go1

22:2duplicated-importspackage github.com/restic/restic/internal/test is imported more than once

internal/restorer/restorer_windows_test.go:22:2

21 "github.com/restic/restic/internal/test"
22 rtest "github.com/restic/restic/internal/test"
23 "golang.org/x/sys/windows"

cmd/restic/cmd_backup.go1

522:3early-returninvert the condition and return early to reduce nesting

cmd/restic/cmd_backup.go:522:3

521 if err != nil {
522 if errors.Is(err, ErrInvalidSourceData) {
523 success = false

cmd/restic/cmd_check_test.go1

216:15error-stringserror string should not be capitalized or end with punctuation

cmd/restic/cmd_check_test.go:216:15

215 if !found {
216 t.Errorf("Expected temporary directory to exist, but it does not")
217 }

internal/repository/checker.go1

26:6error-type-namingerror implementation type should have an Error suffix

internal/repository/checker.go:26:6

25// ErrIncompletePackEntry is returned when indexes contain different data for a pack.
26type ErrIncompletePackEntry struct {
27 PackID restic.ID

internal/archiver/archiver_test.go1

2402:4excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/archiver/archiver_test.go:2402:4

2401
2402 _, _, _, err := arch.Snapshot(ctx, []string{"."}, SnapshotOptions{Time: time.Now()})
2403 if !errors.Is(err, testErr) {

build.go1

229:6exported-declaration-commentexported type should have a comment beginning with its name

build.go:229:6

228// the given value via compiler flags.
229type Constants map[string]string
230

cmd/restic/cmd_backup.go1

1:1file-length-limitfile has 720 lines; maximum is 500

cmd/restic/cmd_backup.go:1:1

1package main
2

cmd/restic/cmd_check.go1

441:2flag-parameterboolean parameter filteredStatus controls function flow

cmd/restic/cmd_check.go:441:2

440func buildPacksFilter(opts CheckOptions, printer restic.Printer,
441 filteredStatus bool) (func(packs map[restic.ID]int64) map[restic.ID]int64, error) {
442 typeData := ""

build.go2

1:1formatfile is not formatted

build.go:1:1

1// Description
2//
  • Fix (safe): run `strider fmt build.go`
323:6function-lengthfunction has 77 statements and 142 lines; maximum is 50 statements or 75 lines

build.go:323:6

322
323func main() {
324 if !goVersion.AtLeast(config.MinVersion) {

cmd/restic/cmd_diff_integration_test.go1

81:6function-result-limitfunction returns 4 values; maximum is 3

cmd/restic/cmd_diff_integration_test.go:81:6

80
81func setupDiffRepo(t *testing.T) (*testEnvironment, func(), string, string) {
82 env, cleanup := withTestEnvironment(t)

internal/backend/sema/semaphore.go1

25:20get-function-return-valueGet-prefixed function should return a value

internal/backend/sema/semaphore.go:25:20

24// GetToken blocks until a Token is available.
25func (s semaphore) GetToken() {
26 s.ch <- struct{}{}

cmd/restic/main.go1

226:2identical-switch-branchesswitch repeats a case body

cmd/restic/main.go:226:2

225 exitCode = 3
226 case errors.Is(err, ErrFailedToRemoveOneOrMoreSnapshots):
227 exitCode = 3

cmd/restic/cmd_mount.go1

29:2import-alias-namingimport alias should contain lower-case letters and digits

cmd/restic/cmd_mount.go:29:2

28
29 systemFuse "github.com/anacrolix/fuse"
30 fusefs "github.com/anacrolix/fuse/fs"

cmd/restic/cmd_backup.go1

174:27import-shadowingidentifier fs shadows an imported package

cmd/restic/cmd_backup.go:174:27

173
174var backupFSTestHook func(fs fs.FS) fs.FS
175

cmd/restic/cmd_find.go1

435:6inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

cmd/restic/cmd_find.go:435:6

434 // Replace the short ID with the long one
435 f.blobIDs[idStr] = struct{}{}
436 delete(f.blobIDs, id.Str())

internal/backend/cache/cache.go1

128:65inefficient-sprintffmt.Sprintf is unnecessary for this conversion; use strconv.Itoa

internal/backend/cache/cache.go:128:65

127 if v < cacheVersion {
128 err = os.WriteFile(filepath.Join(cachedir, "version"), []byte(fmt.Sprintf("%d", cacheVersion)), fileMode)
129 if err != nil {

internal/backend/rclone/backend.go1

232:21insecure-url-schemeURL uses insecure http scheme

internal/backend/rclone/backend.go:232:21

231 // rclone is able to accept HTTP requests.
232 url := fmt.Sprintf("http://localhost/file-%d", rand.Uint64())
233

internal/backend/backend.go1

19:14interface-method-limitinterface has 13 methods, exceeding the configured design limit of 10

internal/backend/backend.go:19:14

18// separately by the retrying logic.
19type Backend interface {
20 // Properties returns information about the backend

internal/data/node.go1

187:7marshal-receivermarshal and unmarshal methods should use a consistent receiver type

internal/data/node.go:187:7

186
187func (node *Node) UnmarshalJSON(data []byte) error {
188 type nodeJSON Node

cmd/restic/cmd_migrate.go1

93:7max-control-nestingcontrol-flow nesting exceeds 5 levels

cmd/restic/cmd_migrate.go:93:7

92 if !opts.Force {
93 if reason == "" {
94 reason = "check failed"

cmd/restic/cmd_rewrite.go1

193:6max-parametersfunction has 10 parameters; maximum is 8

cmd/restic/cmd_rewrite.go:193:6

192
193func filterAndReplaceSnapshot(ctx context.Context, repo restic.Repository, sn *data.Snapshot,
194 filter rewriteFilterFunc, dryRun bool, forget bool, newMetadata *snapshotMetadata, addTag string, printer restic.Printer,

internal/archiver/archiver.go1

830:6max-public-structsfile declares more than 5 exported structs

internal/archiver/archiver.go:830:6

829// SnapshotOptions collect attributes for a new snapshot.
830type SnapshotOptions struct {
831 Tags data.TagList

build.go1

158:2modifies-parameterassignment modifies parameter args

build.go:158:2

157func test(cwd string, env map[string]string, args ...string) error {
158 args = append([]string{"test", "-count", "1"}, args...)
159 cmd := exec.Command("go", args...)

internal/archiver/archiver.go1

162:3modifies-value-receiverassignment modifies value receiver o

internal/archiver/archiver.go:162:3

161 // https://github.com/borgbackup/borg/issues/3500
162 o.ReadConcurrency = 2
163 }

cmd/restic/cmd_backup_integration_test.go1

392:31nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_backup_integration_test.go:392:31

391
392 snapshots := make(map[string]struct{})
393

cmd/restic/cmd_backup.go2

167:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_backup.go:167:4

166 debug.Log("os.Hostname() returned err: %v", err)
167 return nil
168 }
472:3nil-value-with-nil-errornil payload is returned with a nil error; return a meaningful value or a descriptive error

cmd/restic/cmd_backup.go:472:3

471 if opts.Force {
472 return nil, nil
473 }

internal/data/tree_test.go1

45:3no-defer-in-loopdefer inside a loop runs at function exit, not iteration exit

internal/data/tree_test.go:45:3

44 f, err := os.Create(file)
45 defer func() {
46 rtest.OK(t, f.Close())

cmd/restic/cmd_backup.go1

201:4no-else-after-returnremove else and unindent its body after the return

cmd/restic/cmd_backup.go:201:4

200 return nil, ErrNoSourceData
201 } else if len(result) < len(items) {
202 return result, ErrInvalidSourceData

cmd/restic/main.go1

26:6no-initreplace init with explicit initialization

cmd/restic/main.go:26:6

25
26func init() {
27 // don't import `go.uber.org/automaxprocs` to disable the log output

build.go3

252:3no-naked-returnreturn values must be explicit

build.go:252:3

251 if !strings.HasPrefix(s, "go") {
252 return
253 }
54:5no-package-varpackage variables introduce mutable global state

build.go:54:5

53// config contains the configuration for the program to build.
54var config = Config{
55 Name: "restic", // name of the program executable and directory
40:9package-commentspackage should have a documentation comment

build.go:40:9

39
40package main
41

cmd/restic/cmd_forget_test.go1

87:30range-value-addresstaking the address of range value testCase can be misleading

cmd/restic/cmd_forget_test.go:87:30

86 for _, testCase := range testCases {
87 err := verifyForgetOptions(&testCase.input)
88 if testCase.errorMsg != "" {

cmd/restic/integration_helpers_test.go1

362:24redefines-builtin-ididentifier new shadows a predeclared identifier

cmd/restic/integration_helpers_test.go:362:24

361
362func lastSnapshot(old, new map[string]struct{}) (map[string]struct{}, string) {
363 for k := range new {

cmd/restic/cmd_check.go1

474:15redundant-conversionconversion from int64 to the identical type is redundant

cmd/restic/cmd_check.go:474:15

473
474 repoSize := int64(0)
475 return func(packs map[restic.ID]int64) map[restic.ID]int64 {

internal/data/find.go1

34:4single-case-switchswitch with one case can be replaced by an if statement

internal/data/find.go:34:4

33 lock.Lock()
34 switch item.Node.Type {
35 case NodeTypeFile:

cmd/restic/cmd_backup_test.go1

27:6slice-preallocationpreallocate expect with capacity len(range source) before appending once per iteration

cmd/restic/cmd_backup_test.go:27:6

26
27 var expect []string
28 for _, filename := range []string{

internal/backend/rest/rest.go1

225:46standard-http-method-constantreplace the HTTP method literal with http.MethodGet

internal/backend/rest/rest.go:225:46

224func (b *Backend) openReader(ctx context.Context, h backend.Handle, length int, offset int64) (io.ReadCloser, error) {
225 req, err := http.NewRequestWithContext(ctx, "GET", b.Filename(h), nil)
226 if err != nil {

cmd/restic/lock.go1

35:2task-commentTODO comment should be resolved or linked to an owned work item

cmd/restic/lock.go:35:2

34func openWithReadLock(ctx context.Context, gopts global.Options, noLock bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
35 // TODO enforce read-only operations once the locking code has moved to the repository
36 // As in-depth hardening, put the repository into read-only mode if noLock is true

internal/fs/node_unix_test.go1

69:5time-value-equalitycompare time.Time values with Time.Equal instead of == or !=

internal/fs/node_unix_test.go:69:5

68 s := ExtendedStat(fi)
69 if node.ModTime != s.ModTime {
70 t.Errorf("ModTime does not match, want %v, got %v", s.ModTime, node.ModTime)

build.go1

75:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

build.go:75:1

74
75var (
76 verbose bool

cmd/restic/cmd_mount.go1

250:46unchecked-type-assertionuse the checked two-result form of the type assertion

cmd/restic/cmd_mount.go:250:46

249 if loc.Scheme == "local" {
250 if err := checkMountpointOverlap(loc.Config.(*local.Config).Path, mountpoint); err != nil {
251 return err

internal/backend/httpuseragent_roundtripper_test.go1

36:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/httpuseragent_roundtripper_test.go:36:2

35 // Make a request to the test server
36 resp, err := client.Get(server.URL)
37 if err != nil {

internal/fs/ea_windows.go1

144:6unexported-namingunexported identifier should not begin with an underscore

internal/fs/ea_windows.go:144:6

143func getFileEA(handle windows.Handle, iosb *ioStatusBlock, buf *uint8, bufLen uint32, returnSingleEntry bool, eaList uintptr, eaListLen uint32, eaIndex *uint32, restartScan bool) (status ntStatus) {
144 var _p0 uint32
145 if returnSingleEntry {

internal/archiver/buffer.go1

45:31unexported-returnexported function returns an unexported type

internal/archiver/buffer.go:45:31

44// Get returns a new buffer, either from the pool or newly allocated.
45func (pool *bufferPool) Get() *buffer {
46 return pool.pool.Get().(*buffer)

cmd/restic/cmd_self_update.go1

62:87unused-parameterparameter args is unused

cmd/restic/cmd_self_update.go:62:87

61
62func runSelfUpdate(ctx context.Context, opts SelfUpdateOptions, gopts global.Options, args []string, term ui.Terminal) error {
63 if opts.Output == "" {

cmd/restic/cmd_forget.go1

97:7unused-receiverreceiver c is unused

cmd/restic/cmd_forget.go:97:7

96
97func (c *ForgetPolicyCount) Type() string {
98 return "n"

build.go1

85:34use-anyuse any instead of interface{}

build.go:85:34

84// code.
85func die(message string, args ...interface{}) {
86 fmt.Fprintf(os.Stderr, message, args...)

cmd/restic/cmd_debug.go1

165:10use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_debug.go:165:10

164 if opts.ExtractPack && gopts.NoLock {
165 return fmt.Errorf("--extract-pack and --no-lock are mutually exclusive")
166 }

internal/ui/table/table.go1

105:10use-fmt-printuse fmt.Print or fmt.Println instead of the builtin

internal/ui/table/table.go:105:10

104
105 err := print(w, strings.TrimRight(s, " "))
106 if err != nil {

cmd/restic/cmd_cache.go1

134:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

cmd/restic/cmd_cache.go:134:2

133
134 sort.Slice(dirs, func(i, j int) bool {
135 return dirs[i].ModTime().Before(dirs[j].ModTime())

internal/fs/vss_windows.go1

646:21var-declarationomit the explicit zero value from the variable declaration

internal/fs/vss_windows.go:646:21

645func (vssAsync *IVSSAsync) QueryStatus() (HRESULT, uint32) {
646 var state uint32 = 0
647 result, _, _ := syscall.Syscall(vssAsync.getVTable().queryStatus, 3,

internal/fs/const.go1

8:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:8:2

7const (
8 O_RDONLY int = syscall.O_RDONLY // open the file read-only.
9 O_WRONLY int = syscall.O_WRONLY // open the file write-only.

internal/backend/azure/azure.go1

223:9weak-cryptographydeprecated cryptographic primitive crypto/md5.New should not protect new data

internal/backend/azure/azure.go:223:9

222func (be *Backend) Hasher() hash.Hash {
223 return md5.New()
224}

build.go1

405:10add-constantstring literal "GOOS" appears more than twice; define a constant

build.go:405:10

404 outputFilename = config.Name
405 if env["GOOS"] == "windows" {
406 outputFilename += ".exe"

internal/fs/stat_darwin_test.go1

79:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/fs/stat_darwin_test.go:79:18

78 rtest.Assert(t, err == nil, "err should be nil", err)
79 rtest.Assert(t, recall == false, "RecallOnDataAccess should be false")
80}

internal/repository/index/master_index.go1

402:2call-to-gcavoid explicit garbage collection

internal/repository/index/master_index.go:402:2

401 mi.clear()
402 runtime.GC()
403

build.go1

323:6cognitive-complexityfunction has cognitive complexity 26; maximum is 7

build.go:323:6

322
323func main() {
324 if !goVersion.AtLeast(config.MinVersion) {

cmd/restic/cmd_list_integration_test.go1

84:6confusing-namingname TestListBlobs differs from testListBlobs only by capitalization

cmd/restic/cmd_list_integration_test.go:84:6

83
84func TestListBlobs(t *testing.T) {
85

cmd/restic/cmd_diff_integration_test.go1

81:69confusing-resultsadjacent unnamed results of the same type should be named

cmd/restic/cmd_diff_integration_test.go:81:69

80
81func setupDiffRepo(t *testing.T) (*testEnvironment, func(), string, string) {
82 env, cleanup := withTestEnvironment(t)

internal/backend/location/registry.go1

68:6constructor-interface-returnNewHTTPBackendFactory returns interface Factory although its concrete result is consistently *genericBackendFactory[C, T]; return the concrete type

internal/backend/location/registry.go:68:6

67
68func NewHTTPBackendFactory[C any, T backend.Backend](
69 scheme string,

internal/fuse/dir.go1

99:10copy-lock-valuecomposite literal copies fuse.treeCache by value; it contains sync.Mutex

internal/fuse/dir.go:99:10

98 inode: inode,
99 cache: *newTreeCache(),
100 }, nil

cmd/restic/cmd_backup.go1

300:27cyclomatic-complexityfunction complexity is 13; maximum is 10

cmd/restic/cmd_backup.go:300:27

299// Check returns an error when an invalid combination of options was set.
300func (opts BackupOptions) Check(gopts global.Options, args []string) error {
301 if gopts.Password == "" && !gopts.InsecureNoPassword {

cmd/restic/cleanup.go1

43:2deep-exitprocess-exit calls should be confined to main or init

cmd/restic/cleanup.go:43:2

42 debug.Log("exiting with status code %d", code)
43 os.Exit(code)
44}

internal/selfupdate/verify.go1

7:2deprecated-api-usagegolang.org/x/crypto/openpgp is deprecated: this package is unsafe by design, and has numerous known security issues. It is not maintained, and should not be used. New applications should consider a more focused, modern alternative to OpenPGP for their specific task. If you are required to interoperate with OpenPGP systems and need a maintained package, consider github.com/ProtonMail/go-crypto/openpgp, which is a maintained fork that aims to be a drop-in replacement for this package.

internal/selfupdate/verify.go:7:2

6
7 "golang.org/x/crypto/openpgp"
8)

cmd/restic/cleanup.go1

33:10discarded-error-resulterror result returned by stderr.Write is discarded

cmd/restic/cleanup.go:33:10

32 _, _ = stderr.Write([]byte("\n--- STACKTRACE START ---\n\n"))
33 _, _ = stderr.Write([]byte(debug.DumpStacktrace()))
34 _, _ = stderr.Write([]byte("\n--- STACKTRACE END ---\n"))

cmd/restic/cmd_backup.go1

179:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_backup.go:179:1

178
179// ErrNoSourceData is used to report that no source data was found
180var ErrNoSourceData = errors.Fatal("all source directories/files do not exist")

cmd/restic/cmd_forget.go1

244:4early-returninvert the condition and return early to reduce nesting

cmd/restic/cmd_forget.go:244:4

243 if policy.Empty() {
244 if opts.UnsafeAllowRemoveAll {
245 if opts.SnapshotFilter.Empty() {

cmd/restic/cmd_copy.go1

302:22error-stringserror string should not be capitalized or end with punctuation

cmd/restic/cmd_copy.go:302:22

301 if err != nil {
302 return fmt.Errorf("LoadTree(%v) returned error %v", treeID.Str(), err)
303 }

internal/repository/checker.go1

36:6error-type-namingerror implementation type should have an Error suffix

internal/repository/checker.go:36:6

35// ErrDuplicatePacks is returned when a pack is found in more than one index.
36type ErrDuplicatePacks struct {
37 PackID restic.ID

internal/checker/checker_test.go1

498:3excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/checker/checker_test.go:498:3

497 var err error
498 _, _, _, err = uploader.SaveBlob(ctx, restic.DataBlob, buf, id, false)
499 return err

cmd/restic/cmd_backup_integration_test.go2

768:8exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_backup_integration_test.go:768:8

767
768 type MessageType struct {
769 MessageType string `json:"message_type"` // any
1:1file-length-limitfile has 785 lines; maximum is 500

cmd/restic/cmd_backup_integration_test.go:1:1

1package main
2

cmd/restic/cmd_key_add.go1

98:88flag-parameterboolean parameter insecureNoPassword controls function flow

cmd/restic/cmd_key_add.go:98:88

97
98func getNewPassword(ctx context.Context, gopts global.Options, newPasswordFile string, insecureNoPassword bool) (string, error) {
99 if testKeyNewPassword != "" {

cmd/restic/cmd_backup.go2

1:1formatfile is not formatted

cmd/restic/cmd_backup.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_backup.go`
498:6function-lengthfunction has 115 statements and 222 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_backup.go:498:6

497
498func runBackup(ctx context.Context, opts BackupOptions, gopts global.Options, term ui.Terminal, args []string) error {
499 var vsscfg fs.VSSConfig

cmd/restic/lock.go1

11:6function-result-limitfunction returns 4 values; maximum is 3

cmd/restic/lock.go:11:6

10
11func internalOpenWithLocked(ctx context.Context, gopts global.Options, dryRun bool, exclusive bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
12 repo, err := global.OpenRepository(ctx, gopts, printer)

internal/archiver/archiver.go1

639:2identical-switch-branchesswitch repeats a case body

internal/archiver/archiver.go:639:2

638 return true
639 case node.Type != data.NodeTypeFile:
640 // We're only called for regular files, so this is a type change.

cmd/restic/cmd_mount_integration_test.go1

15:2import-alias-namingimport alias should contain lower-case letters and digits

cmd/restic/cmd_mount_integration_test.go:15:2

14
15 systemFuse "github.com/anacrolix/fuse"
16 "github.com/restic/restic/internal/data"

cmd/restic/cmd_backup.go1

220:3import-shadowingidentifier data shadows an imported package

cmd/restic/cmd_backup.go:220:3

219 var (
220 data []byte
221 err error

cmd/restic/cmd_find.go1

482:4inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

cmd/restic/cmd_find.go:482:4

481 delete(packIDs, id.Str())
482 packIDs[idStr] = struct{}{}
483 }

internal/backend/rest/rest_int_test.go1

101:41inefficient-sprintffmt.Sprintf is unnecessary for this conversion; use strconv.FormatInt with base 10

internal/backend/rest/rest_int_test.go:101:41

100
101 res.Header().Set("Content-Length", fmt.Sprintf("%d", length))
102 res.WriteHeader(http.StatusOK)

internal/backend/rclone/backend.go1

279:24insecure-url-schemeURL uses insecure http scheme

internal/backend/rclone/backend.go:279:24

278
279 url, err := url.Parse("http://localhost/")
280 if err != nil {

internal/backend/backend.go1

126:20interface-method-limitinterface has 15 methods, exceeding the configured design limit of 10

internal/backend/backend.go:126:20

125
126type FreezeBackend interface {
127 Backend

internal/restic/blob.go1

80:7marshal-receivermarshal and unmarshal methods should use a consistent receiver type

internal/restic/blob.go:80:7

79// UnmarshalJSON decodes the BlobType from JSON.
80func (t *BlobType) UnmarshalJSON(buf []byte) error {
81 switch string(buf) {

cmd/restic/cmd_stats.go1

284:8max-control-nestingcontrol-flow nesting exceeds 5 levels

cmd/restic/cmd_stats.go:284:8

283 blobSize, found := repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: blobID})
284 if !found {
285 return fmt.Errorf("blob %s not found for tree %s", blobID, parentTreeID)

internal/archiver/file_saver.go1

160:21max-parametersfunction has 9 parameters; maximum is 8

internal/archiver/file_saver.go:160:21

159// saveFile stores the file f in the repo, then closes it.
160func (s *fileSaver) saveFile(ctx context.Context, chnker restic.Chunker, chunkState *fileChunkState, snPath string, target string, f fs.File, start func(), finishReading func(), finish func(res futureNodeResult)) {
161 start()

internal/fs/vss_windows.go1

700:6max-public-structsfile declares more than 5 exported structs

internal/fs/vss_windows.go:700:6

699// IVSSAdmin VSS api interface.
700type IVSSAdmin struct {
701 ole.IUnknown

build.go1

255:2modifies-parameterassignment modifies parameter s

build.go:255:2

254
255 s = s[2:]
256 data := strings.Split(s, ".")

internal/archiver/archiver.go1

171:3modifies-value-receiverassignment modifies value receiver o

internal/archiver/archiver.go:171:3

170 // more files to read.
171 o.SaveTreeConcurrency = uint(runtime.GOMAXPROCS(0)) + o.ReadConcurrency
172 }

cmd/restic/cmd_cat_test.go1

11:25nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_cat_test.go:11:25

10func TestCatArgsValidation(t *testing.T) {
11 for _, test := range []struct {
12 args []string

cmd/restic/cmd_check.go1

468:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_check.go:468:4

467 }
468 return func(packs map[restic.ID]int64) map[restic.ID]int64 {
469 printer.P("read %.1f%% of %spackfiles", percentage, typeData)

cmd/restic/cmd_init.go1

130:2nil-value-with-nil-errornil payload is returned with a nil error; return a meaningful value or a descriptive error

cmd/restic/cmd_init.go:130:2

129 }
130 return nil, nil
131}

internal/fs/node_windows_test.go1

478:3no-defer-in-loopdefer inside a loop runs at function exit, not iteration exit

internal/fs/node_windows_test.go:478:3

477 test.OK(t, errors.Wrapf(err, "Error opening file/directory for: %s", testPath))
478 defer func() {
479 err := windows.Close(handle)

cmd/restic/cmd_check.go1

463:5no-else-after-returnremove else and unindent its body after the return

cmd/restic/cmd_check.go:463:5

462 }, nil
463 } else if strings.HasSuffix(opts.ReadDataSubset, "%") {
464 percentage, err := parsePercentage(opts.ReadDataSubset)

helpers/build-release-binaries/main.go1

30:6no-initreplace init with explicit initialization

helpers/build-release-binaries/main.go:30:6

29
30func init() {
31 pflag.BoolVarP(&opts.Verbose, "verbose", "v", false, "be verbose")

build.go2

290:2no-naked-returnreturn values must be explicit

build.go:290:2

289
290 return
291}
76:2no-package-varpackage variables introduce mutable global state

build.go:76:2

75var (
76 verbose bool
77 runTests bool

cmd/restic/cleanup.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cleanup.go:1:9

1package main
2

cmd/restic/cmd_snapshots_integration_test.go1

32:13range-value-addresstaking the address of range value sn can be misleading

cmd/restic/cmd_snapshots_integration_test.go:32:13

31 if newest == nil || sn.Time.After(newest.Time) {
32 newest = &sn
33 }

internal/backend/cache/cache.go1

206:32redefines-builtin-ididentifier max shadows a predeclared identifier

internal/backend/cache/cache.go:206:32

205// OlderThan returns the list of cache directories older than max.
206func OlderThan(basedir string, max time.Duration) ([]os.FileInfo, error) {
207 entries, err := listCacheDirs(basedir)

cmd/restic/cmd_check_test.go1

87:11redundant-conversionconversion from uint to the identical type is redundant

cmd/restic/cmd_check_test.go:87:11

86
87 for i := uint(1); i <= 5; i++ {
88 selectedPacks = selectPacksByBucket(testPacks, i, 5)

cmd/restic/cmd_check.go1

522:6slice-preallocationpreallocate keys with capacity len(range source) before appending once per iteration

cmd/restic/cmd_check.go:522:6

521
522 var keys []restic.ID
523 for k := range allPacks {

internal/backend/rest/rest.go1

290:46standard-http-method-constantreplace the HTTP method literal with http.MethodDelete

internal/backend/rest/rest.go:290:46

289func (b *Backend) Remove(ctx context.Context, h backend.Handle) error {
290 req, err := http.NewRequestWithContext(ctx, "DELETE", b.Filename(h), nil)
291 if err != nil {

cmd/restic/lock.go1

42:2task-commentTODO comment should be resolved or linked to an owned work item

cmd/restic/lock.go:42:2

41func openWithAppendLock(ctx context.Context, gopts global.Options, dryRun bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
42 // TODO enforce non-exclusive operations once the locking code has moved to the repository
43 return internalOpenWithLocked(ctx, gopts, dryRun, false, printer)

internal/fs/node_unix_test.go1

72:5time-value-equalitycompare time.Time values with Time.Equal instead of == or !=

internal/fs/node_unix_test.go:72:5

71 }
72 if node.ChangeTime != s.ChangeTime {
73 t.Errorf("ChangeTime does not match, want %v, got %v", s.ChangeTime, node.ChangeTime)

cmd/restic/cmd_backup.go1

70:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_backup.go:70:1

69// BackupOptions bundles all options for the backup command.
70type BackupOptions struct {
71 filter.ExcludePatternOptions

internal/archiver/archiver_test.go1

2578:91unchecked-type-assertionuse the checked two-result form of the type assertion

internal/archiver/archiver_test.go:2578:91

2577 // make sure the content matches
2578 TestEnsureFileContent(context.Background(), t, repo, "testfile", node3, files["testfile"].(TestFile))
2579

internal/backend/limiter/static_limiter.go1

80:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/limiter/static_limiter.go:80:2

79
80 res, err := rt.RoundTrip(req)
81

internal/fs/ea_windows.go1

148:6unexported-namingunexported identifier should not begin with an underscore

internal/fs/ea_windows.go:148:6

147 }
148 var _p1 uint32
149 if restartScan {

internal/archiver/file_saver.go1

69:156unexported-returnexported function returns an unexported type

internal/archiver/file_saver.go:69:156

68// this will always happen before calling complete. The callbacks must not block.
69func (s *fileSaver) Save(ctx context.Context, snPath string, target string, file fs.File, start func(), completeReading func(), complete fileCompleteFunc) futureNode {
70 fn, ch := newFutureNode()

cmd/restic/integration_helpers_test.go1

426:30unused-parameterparameter t is unused

cmd/restic/integration_helpers_test.go:426:30

425
426func withCaptureStdoutStderr(t testing.TB, gopts global.Options, callback func(ctx context.Context, gopts global.Options) error) (*bytes.Buffer, *bytes.Buffer, error) {
427 bufStdout := bytes.NewBuffer(nil)

cmd/restic/cmd_ls.go1

188:7unused-receiverreceiver p is unused

cmd/restic/cmd_ls.go:188:7

187
188func (p *jsonLsPrinter) LeaveDir(_ string) error { return nil }
189func (p *jsonLsPrinter) Close() error { return nil }

build.go1

105:44use-anyuse any instead of interface{}

build.go:105:44

104
105func verbosePrintf(message string, args ...interface{}) {
106 if !verbose {

cmd/restic/cmd_dump.go1

208:32use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_dump.go:208:32

207 if term.OutputIsTerminal() {
208 return func() error { return fmt.Errorf("stdout is the terminal, please redirect output") }
209 }

cmd/restic/cmd_find.go1

689:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

cmd/restic/cmd_find.go:689:2

688
689 sort.Slice(filteredSnapshots, func(i, j int) bool {
690 if opts.Reverse {

internal/restorer/restorer_windows_test.go1

324:32var-declarationomit the explicit zero value from the variable declaration

internal/restorer/restorer_windows_test.go:324:32

323
324 var attr *FileAttributes = nil
325 if mainNodeName == stream.name {

internal/fs/const.go1

9:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:9:2

8 O_RDONLY int = syscall.O_RDONLY // open the file read-only.
9 O_WRONLY int = syscall.O_WRONLY // open the file write-only.
10 O_RDWR int = syscall.O_RDWR // open the file read-write.

internal/backend/azure/azure.go1

309:8weak-cryptographydeprecated cryptographic primitive crypto/md5.Sum should not protect new data

internal/backend/azure/azure.go:309:8

308 // upload it as a new "block", use the base64 hash for the ID
309 h := md5.Sum(buf)
310 id := base64.StdEncoding.EncodeToString(h[:])

build.go1

444:36add-constantstring literal " " appears more than twice; define a constant

build.go:444:36

443 buildArgs = append(buildArgs,
444 "-tags", strings.Join(buildTags, " "),
445 "-ldflags", ldflags,

internal/fs/stat_darwin_test.go1

90:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/fs/stat_darwin_test.go:90:18

89 rtest.Assert(t, err.Error() == "could not determine file attributes: test-file-name", "err message not correct", err)
90 rtest.Assert(t, recall == false, "RecallOnDataAccess should be false")
91}

internal/repository/index/master_index_test.go1

406:3call-to-gcavoid explicit garbage collection

internal/repository/index/master_index_test.go:406:3

405 for b.Loop() {
406 runtime.GC()
407 }

cmd/restic/cmd_backup.go1

184:6cognitive-complexityfunction has cognitive complexity 9; maximum is 7

cmd/restic/cmd_backup.go:184:6

183// ErrNoSourceData if none remain, or ErrInvalidSourceData if some were skipped.
184func filterExisting(items []string, warnf func(msg string, args ...interface{})) (result []string, err error) {
185 for _, item := range items {

cmd/restic/cmd_prune_integration_test.go1

112:6confusing-namingname testPrune differs from TestPrune only by capitalization

cmd/restic/cmd_prune_integration_test.go:112:6

111
112func testPrune(t *testing.T, pruneOpts PruneOptions, checkOpts CheckOptions) {
113 env, cleanup := withTestEnvironment(t)

cmd/restic/cmd_repair_packs_integration_test.go1

17:85confusing-resultsadjacent unnamed results of the same type should be named

cmd/restic/cmd_repair_packs_integration_test.go:17:85

16// testRunRepairPacks runs `restic repair packs` with capturing stdout and stderr
17func testRunRepairPacks(t testing.TB, gopts global.Options, args []string) (string, string, error) {
18 bufStdout, bufStderr, err := withCaptureStdoutStderr(t, gopts, func(ctx context.Context, gopts global.Options) error {

internal/backend/location/registry.go1

88:6constructor-interface-returnNewLimitedBackendFactory returns interface Factory although its concrete result is consistently *genericBackendFactory[C, T]; return the concrete type

internal/backend/location/registry.go:88:6

87
88func NewLimitedBackendFactory[C any, T backend.Backend](
89 scheme string,

internal/fuse/snapshots_dir.go1

44:16copy-lock-valuecomposite literal copies fuse.treeCache by value; it contains sync.Mutex

internal/fuse/snapshots_dir.go:44:16

43 prefix: prefix,
44 cache: *newTreeCache(),
45 }

cmd/restic/cmd_backup.go1

359:6cyclomatic-complexityfunction complexity is 17; maximum is 10

cmd/restic/cmd_backup.go:359:6

358// from being saved in a snapshot based on path and file info
359func collectRejectFuncs(opts BackupOptions, targets []string, fs fs.FS, warnf func(msg string, args ...interface{})) (funcs []archiver.RejectFunc, err error) {
360 // allowed devices

helpers/build-release-binaries/main.go1

48:2deep-exitprocess-exit calls should be confined to main or init

helpers/build-release-binaries/main.go:48:2

47 fmt.Fprintf(os.Stderr, f, args...)
48 os.Exit(1)
49}

cmd/restic/cleanup.go1

34:10discarded-error-resulterror result returned by stderr.Write is discarded

cmd/restic/cleanup.go:34:10

33 _, _ = stderr.Write([]byte(debug.DumpStacktrace()))
34 _, _ = stderr.Write([]byte("\n--- STACKTRACE END ---\n"))
35 }

cmd/restic/cmd_find_integration_test.go1

150:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_find_integration_test.go:150:1

149
150// JsonOutput is the struct `restic find --json` produces
151type JSONOutput struct {

cmd/restic/cmd_init.go1

89:2early-returninvert the condition and return early to reduce nesting

cmd/restic/cmd_init.go:89:2

88
89 if !gopts.JSON {
90 printer.P("created restic repository %v at %s", s.Config().ID[:10], location.StripPassword(gopts.Backends, gopts.Repo))

cmd/restic/cmd_mount_integration_test.go1

126:13error-stringserror string should not be capitalized or end with punctuation

cmd/restic/cmd_mount_integration_test.go:126:13

125 if !ok {
126 t.Errorf("Symlink latest isn't present in fuse dir")
127 } else {

internal/repository/checker.go1

46:6error-type-namingerror implementation type should have an Error suffix

internal/repository/checker.go:46:6

45// ErrMixedPack is returned when a pack is found that contains both tree and data blobs.
46type ErrMixedPack struct {
47 PackID restic.ID

internal/fs/vss_windows.go1

546:2excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/fs/vss_windows.go:546:2

545 // this function always succeeds and returns no value
546 _, _, _ = proc.Call(uintptr(unsafe.Pointer(properties)))
547 return nil

cmd/restic/cmd_debug.go1

82:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_debug.go:82:6

81
82type DebugExamineOptions struct {
83 TryRepair bool

cmd/restic/cmd_check.go1

1:1file-length-limitfile has 585 lines; maximum is 500

cmd/restic/cmd_check.go:1:1

1package main
2

cmd/restic/cmd_ls.go1

181:52flag-parameterboolean parameter isPrefixDirectory controls function flow

cmd/restic/cmd_ls.go:181:52

180
181func (p *jsonLsPrinter) NodeOutput(n lsNodeOutput, isPrefixDirectory bool) error {
182 if isPrefixDirectory {

cmd/restic/cmd_backup_integration_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_backup_integration_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_backup_integration_test.go`

cmd/restic/cmd_cache.go1

60:6function-lengthfunction has 55 statements and 111 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_cache.go:60:6

59
60func runCache(opts CacheOptions, gopts global.Options, args []string, term ui.Terminal) error {
61 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

cmd/restic/lock.go1

34:6function-result-limitfunction returns 4 values; maximum is 3

cmd/restic/lock.go:34:6

33
34func openWithReadLock(ctx context.Context, gopts global.Options, noLock bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
35 // TODO enforce read-only operations once the locking code has moved to the repository

internal/archiver/archiver.go1

642:2identical-switch-branchesswitch repeats a case body

internal/archiver/archiver.go:642:2

641 return true
642 case uint64(fi.Size) != node.Size:
643 return true

internal/backend/azure/azure.go1

29:2import-alias-namingimport alias should contain lower-case letters and digits

internal/backend/azure/azure.go:29:2

28 "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob"
29 azContainer "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
30)

cmd/restic/cmd_backup.go1

335:126import-shadowingidentifier fs shadows an imported package

cmd/restic/cmd_backup.go:335:126

334// from being saved in a snapshot based on path only
335func collectRejectByNameFuncs(opts BackupOptions, repo *repository.Repository, warnf func(msg string, args ...interface{})) (fs []archiver.RejectByNameFunc, err error) {
336 // exclude restic cache

cmd/restic/cmd_stats.go1

262:5inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

cmd/restic/cmd_stats.go:262:5

261 // mark the file as visited
262 stats.uniqueFiles[fid] = struct{}{}
263

internal/backend/watchdog_roundtriper_test.go1

49:9inefficient-sprintffmt.Sprintf is unnecessary for this conversion; use strconv.Itoa

internal/backend/watchdog_roundtriper_test.go:49:9

48 for _, delay := range []int{0, 1, 10, 20} {
49 t.Run(fmt.Sprintf("%v", delay), func(t *testing.T) {
50 msg := []byte("ping-pong-data")

internal/backend/rclone/backend.go1

308:24insecure-url-schemeURL uses insecure http scheme

internal/backend/rclone/backend.go:308:24

307
308 url, err := url.Parse("http://localhost/")
309 if err != nil {

internal/checker/checker.go1

37:24interface-method-limitinterface has 20 methods, exceeding the configured design limit of 10

internal/checker/checker.go:37:24

36
37type checkerRepository interface {
38 restic.Repository

internal/restic/id.go1

80:7marshal-receivermarshal and unmarshal methods should use a consistent receiver type

internal/restic/id.go:80:7

79// UnmarshalJSON parses the JSON-encoded data and stores the result in id.
80func (id *ID) UnmarshalJSON(b []byte) error {
81 // check string length

cmd/restic/integration_helpers_test.go1

128:11max-control-nestingcontrol-flow nesting exceeds 5 levels

cmd/restic/integration_helpers_test.go:128:11

127 continue
128 } else if a.path > b.path {
129 fmt.Fprintf(&out, "+%v\n", b.path)

internal/fs/ea_windows.go1

143:6max-parametersfunction has 9 parameters; maximum is 8

internal/fs/ea_windows.go:143:6

142
143func getFileEA(handle windows.Handle, iosb *ioStatusBlock, buf *uint8, bufLen uint32, returnSingleEntry bool, eaList uintptr, eaListLen uint32, eaIndex *uint32, restartScan bool) (status ntStatus) {
144 var _p0 uint32

internal/fs/vss_windows.go1

706:6max-public-structsfile declares more than 5 exported structs

internal/fs/vss_windows.go:706:6

705// nolint:structcheck
706type IVSSAdminVTable struct {
707 ole.IUnknownVtbl

build.go1

271:29modifies-parameterassignment modifies parameter s

build.go:271:29

270 // "rc2" or so)
271 for s := data[1]; s != ""; s = s[:len(s)-1] {
272 v.Minor, err = strconv.Atoi(s)

internal/archiver/archiver_test.go1

1845:3modifies-value-receiverassignment modifies value receiver f

internal/archiver/archiver_test.go:1845:3

1844 f.fs.m.Lock()
1845 f.fs.bytesRead[f.filename] += n
1846 f.fs.m.Unlock()

cmd/restic/cmd_check_integration_test.go1

50:17nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_check_integration_test.go:50:17

49func TestCheckWithSnaphotFilter(t *testing.T) {
50 testCases := []struct {
51 opts CheckOptions

cmd/restic/cmd_copy.go1

89:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_copy.go:89:5

88 }
89 return nil
90 }

cmd/restic/cmd_rewrite.go1

90:3nil-value-with-nil-errornil payload is returned with a nil error; return a meaningful value or a descriptive error

cmd/restic/cmd_rewrite.go:90:3

89 if sma.empty() {
90 return nil, nil
91 }

internal/terminal/terminal_windows_test.go1

25:3no-defer-in-loopdefer inside a loop runs at function exit, not iteration exit

internal/terminal/terminal_windows_test.go:25:3

24 rtest.OK(t, err)
25 defer windows.CloseHandle(handle)
26

cmd/restic/cmd_mount.go1

231:4no-else-after-returnremove else and unindent its body after the return

cmd/restic/cmd_mount.go:231:4

230 return errors.Fatal(fmt.Sprintf("mountpoint %s does not exist", mountpoint))
231 } else if err != nil {
232 return errors.Fatal(fmt.Sprintf("mountpoint %s is inaccessible: %v", mountpoint, err))

helpers/prepare-release/main.go1

33:6no-initreplace init with explicit initialization

helpers/prepare-release/main.go:33:6

32
33func init() {
34 pflag.BoolVar(&opts.IgnoreBranchName, "ignore-branch-name", false, "allow releasing from other branches than 'master'")

cmd/restic/cmd_generate.go1

84:4no-naked-returnreturn values must be explicit

cmd/restic/cmd_generate.go:84:4

83 if err != nil {
84 return
85 }

build.go1

77:2no-package-varpackage variables introduce mutable global state

build.go:77:2

76 verbose bool
77 runTests bool
78 enableCGO bool

cmd/restic/cmd_backup.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_backup.go:1:9

1package main
2

cmd/restic/format_test.go1

58:27range-value-addresstaking the address of range value c can be misleading

cmd/restic/format_test.go:58:27

57 } {
58 r := formatNode(c.path, &c.Node, c.long, c.human)
59 rtest.Equals(t, c.expect, r)

internal/backend/test/tests.go1

768:73redefines-builtin-ididentifier max shadows a predeclared identifier

internal/backend/test/tests.go:768:73

767
768func delayedList(t testing.TB, b backend.Backend, tpe backend.FileType, max int, maxwait time.Duration) restic.IDs {
769 list := restic.NewIDSet()

cmd/restic/cmd_copy.go1

223:16redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_copy.go:223:16

222 var batch []*data.Snapshot
223 batchSize := uint64(0)
224 startTime := time.Now()

cmd/restic/cmd_forget.go1

373:6slice-preallocationpreallocate resultList with capacity len(range source) before appending once per iteration

cmd/restic/cmd_forget.go:373:6

372func asJSONSnapshots(list data.Snapshots) []Snapshot {
373 var resultList []Snapshot
374 for _, sn := range list {

internal/backend/watchdog_roundtriper_test.go1

71:59standard-http-method-constantreplace the HTTP method literal with http.MethodGet

internal/backend/watchdog_roundtriper_test.go:71:59

70 rt := newWatchdogRoundtripper(http.DefaultTransport, 100*time.Millisecond, 2)
71 req, err := http.NewRequestWithContext(context.TODO(), "GET", srv.URL, io.NopCloser(newSlowReader(bytes.NewReader(msg), time.Duration(delay)*time.Millisecond)))
72 rtest.OK(t, err)

internal/backend/retry/backend_retry.go1

139:4task-commentTODO comment should be resolved or linked to an owned work item

internal/backend/retry/backend_retry.go:139:4

138 // don't retry permanent errors as those very likely cannot be fixed by retrying
139 // TODO remove IsNotExist(err) special cases when removing the feature flag
140 if feature.Flag.Enabled(feature.BackendErrorRedesign) && !errors.Is(err, &backoff.PermanentError{}) && be.Backend.IsPermanentError(err) {

internal/fs/node_unix_test.go1

75:5time-value-equalitycompare time.Time values with Time.Equal instead of == or !=

internal/fs/node_unix_test.go:75:5

74 }
75 if node.AccessTime != s.AccessTime {
76 t.Errorf("AccessTime does not match, want %v, got %v", s.AccessTime, node.AccessTime)

cmd/restic/cmd_backup_integration_test.go1

145:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_backup_integration_test.go:145:1

144
145type vssDeleteOriginalFS struct {
146 fs.FS

internal/archiver/buffer.go1

46:24unchecked-type-assertionuse the checked two-result form of the type assertion

internal/archiver/buffer.go:46:24

45func (pool *bufferPool) Get() *buffer {
46 return pool.pool.Get().(*buffer)
47}

internal/backend/limiter/static_limiter_test.go1

129:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/limiter/static_limiter_test.go:129:2

128
129 res, err := rt.RoundTrip(&http.Request{})
130 test.OK(t, err)

internal/archiver/tree_saver.go1

46:141unexported-returnexported function returns an unexported type

internal/archiver/tree_saver.go:46:141

45// Save stores the dir d and returns the data once it has been completed.
46func (s *treeSaver) Save(ctx context.Context, snPath string, target string, node *data.Node, nodes []futureNode, complete fileCompleteFunc) futureNode {
47 fn, ch := newFutureNode()

internal/archiver/tree_saver_test.go1

22:85unused-parameterparameter id is unused

internal/archiver/tree_saver_test.go:22:85

21
22func (m *mockSaver) SaveBlobAsync(_ context.Context, _ restic.BlobType, buf []byte, id restic.ID, storeDuplicate bool, cb func(newID restic.ID, known bool, sizeInRepo int, err error)) {
23 // Fake async operation

cmd/restic/cmd_ls.go1

189:7unused-receiverreceiver p is unused

cmd/restic/cmd_ls.go:189:7

188func (p *jsonLsPrinter) LeaveDir(_ string) error { return nil }
189func (p *jsonLsPrinter) Close() error { return nil }
190

cmd/restic/cmd_backup.go1

184:68use-anyuse any instead of interface{}

cmd/restic/cmd_backup.go:184:68

183// ErrNoSourceData if none remain, or ErrInvalidSourceData if some were skipped.
184func filterExisting(items []string, warnf func(msg string, args ...interface{})) (result []string, err error) {
185 for _, item := range items {

cmd/restic/cmd_key_add.go1

61:10use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_key_add.go:61:10

60 if len(args) > 0 {
61 return fmt.Errorf("the key add command expects no arguments, only options - please see `restic help key add` for usage and flags")
62 }

cmd/restic/cmd_snapshots.go1

174:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

cmd/restic/cmd_snapshots.go:174:2

173 // Sort the snapshots so that the newer ones are listed first
174 sort.SliceStable(list, func(i, j int) bool {
175 return list[i].Time.After(list[j].Time)

internal/fs/const.go1

10:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:10:2

9 O_WRONLY int = syscall.O_WRONLY // open the file write-only.
10 O_RDWR int = syscall.O_RDWR // open the file read-write.
11 O_APPEND int = syscall.O_APPEND // append data to the file when writing.

internal/backend/gs/gs.go1

187:9weak-cryptographydeprecated cryptographic primitive crypto/md5.New should not protect new data

internal/backend/gs/gs.go:187:9

186func (be *gs) Hasher() hash.Hash {
187 return md5.New()
188}

cmd/restic/cmd_backup.go1

128:62add-constantstring literal "read the files to backup from `file` (can be combined with file args; can be specified multiple times)" appears more than twice; define a constant

cmd/restic/cmd_backup.go:128:62

127 f.StringArrayVar(&opts.FilesFromVerbatim, "files-from-verbatim", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
128 f.StringArrayVar(&opts.FilesFromRaw, "files-from-raw", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
129 f.StringVar(&opts.TimeStamp, "time", "", "`time` of the backup (ex. '2012-11-01 22:08:41') (default: now)")

internal/fs/stat_windows_test.go1

31:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/fs/stat_windows_test.go:31:18

30 rtest.Assert(t, err == nil, "err should be nil", err)
31 rtest.Assert(t, recall == false, "RecallOnDataAccess should be false")
32}

internal/repository/repository.go1

733:2call-to-gcavoid explicit garbage collection

internal/repository/repository.go:733:2

732 // Trigger GC to reset garbage collection threshold
733 runtime.GC()
734

cmd/restic/cmd_backup.go1

273:6cognitive-complexityfunction has cognitive complexity 8; maximum is 7

cmd/restic/cmd_backup.go:273:6

272
273func readFilenamesRaw(r io.Reader) (names []string, err error) {
274 br := bufio.NewReader(r)

cmd/restic/cmd_repair_index_integration_test.go1

61:6confusing-namingname TestRebuildIndex differs from testRebuildIndex only by capitalization

cmd/restic/cmd_repair_index_integration_test.go:61:6

60
61func TestRebuildIndex(t *testing.T) {
62 testRebuildIndex(t, nil)

cmd/restic/integration_helpers_test.go1

426:146confusing-resultsadjacent unnamed results of the same type should be named

cmd/restic/integration_helpers_test.go:426:146

425
426func withCaptureStdoutStderr(t testing.TB, gopts global.Options, callback func(ctx context.Context, gopts global.Options) error) (*bytes.Buffer, *bytes.Buffer, error) {
427 bufStdout := bytes.NewBuffer(nil)

internal/fs/fs_local.go1

21:6constructor-interface-returnNewLocal returns interface FS although its concrete result is consistently local; return the concrete type

internal/fs/fs_local.go:21:6

20// NewLocal returns an FS for the local file system. Most methods are just passed on to the stdlib.
21func NewLocal() FS {
22 return local{}

cmd/restic/cmd_backup.go1

407:6cyclomatic-complexityfunction complexity is 18; maximum is 10

cmd/restic/cmd_backup.go:407:6

406// collectTargets returns a list of target files/dirs from several sources.
407func collectTargets(opts BackupOptions, args []string, warnf func(msg string, args ...interface{}), stdin io.ReadCloser) (targets []string, err error) {
408 if opts.Stdin || opts.StdinCommand {

helpers/prepare-release/main.go1

52:2deep-exitprocess-exit calls should be confined to main or init

helpers/prepare-release/main.go:52:2

51 fmt.Fprintf(os.Stderr, f, args...)
52 os.Exit(1)
53}

cmd/restic/cmd_backup.go1

146:24discarded-error-resulterror result returned by strconv.ParseBool is discarded

cmd/restic/cmd_backup.go:146:24

145 // parse read inode and ctime from env, on error the default value will be used
146 opts.IgnoreInode, _ = strconv.ParseBool(os.Getenv("RESTIC_IGNORE_INODE"))
147 opts.IgnoreCtime, _ = strconv.ParseBool(os.Getenv("RESTIC_IGNORE_CTIME"))

cmd/restic/cmd_ls.go1

198:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_ls.go:198:1

197// It opens the JSON list. Nodes are added with lsNodeNcdu and the list is closed by lsCloseNcdu.
198// Format documentation: https://dev.yorhel.nl/ncdu/jsonfmt
199func (p *ncduLsPrinter) Snapshot(sn *data.Snapshot) error {

internal/archiver/file_saver.go1

148:3early-returninvert the condition and return early to reduce nesting

internal/archiver/file_saver.go:148:3

147 split := chnker.NextSplitPoint(s.readBuf[s.bpos:s.bmax])
148 if split == -1 {
149 data = append(data, s.readBuf[s.bpos:s.bmax]...)

cmd/restic/cmd_mount_integration_test.go1

147:14error-stringserror string should not be capitalized or end with punctuation

cmd/restic/cmd_mount_integration_test.go:147:14

146 if !ok {
147 t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts)
148 }

internal/repository/checker.go1

56:6error-type-namingerror implementation type should have an Error suffix

internal/repository/checker.go:56:6

55// Errors of the actual pack data are returned as ErrPackData.
56type ErrPackMetadata struct {
57 ID restic.ID

internal/repository/debug.go1

356:5excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/debug.go:356:5

355 if opts.ReuploadBlobs {
356 _, _, _, err := uploader.SaveBlob(ctx, blob.Type, plaintext, id, true)
357 if err != nil {

cmd/restic/cmd_diff.go1

90:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_diff.go:90:6

89
90type Change struct {
91 MessageType string `json:"message_type"` // "change"

cmd/restic/cmd_find.go1

1:1file-length-limitfile has 715 lines; maximum is 500

cmd/restic/cmd_find.go:1:1

1package main
2

cmd/restic/cmd_ls.go1

302:55flag-parameterboolean parameter isPrefixDirectory controls function flow

cmd/restic/cmd_ls.go:302:55

301}
302func (p *textLsPrinter) NodeOutput(node lsNodeOutput, isPrefixDirectory bool) error {
303 if !isPrefixDirectory {

cmd/restic/cmd_backup_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_backup_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_backup_test.go`

cmd/restic/cmd_cat.go1

70:6function-lengthfunction has 88 statements and 152 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_cat.go:70:6

69
70func runCat(ctx context.Context, gopts global.Options, args []string, term ui.Terminal) error {
71 printer := progress.NewTerminalPrinter(gopts.JSON, gopts.Verbosity, term)

cmd/restic/lock.go1

41:6function-result-limitfunction returns 4 values; maximum is 3

cmd/restic/lock.go:41:6

40
41func openWithAppendLock(ctx context.Context, gopts global.Options, dryRun bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
42 // TODO enforce non-exclusive operations once the locking code has moved to the repository

internal/archiver/archiver.go1

644:2identical-switch-branchesswitch repeats a case body

internal/archiver/archiver.go:644:2

643 return true
644 case !fi.ModTime.Equal(node.ModTime):
645 return true

cmd/restic/cmd_backup.go1

359:63import-shadowingidentifier fs shadows an imported package

cmd/restic/cmd_backup.go:359:63

358// from being saved in a snapshot based on path and file info
359func collectRejectFuncs(opts BackupOptions, targets []string, fs fs.FS, warnf func(msg string, args ...interface{})) (funcs []archiver.RejectFunc, err error) {
360 // allowed devices

cmd/restic/cmd_stats.go1

278:8inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

cmd/restic/cmd_stats.go:278:8

277 if _, ok := stats.fileBlobs[nodePath]; !ok {
278 stats.fileBlobs[nodePath] = restic.NewIDSet()
279 stats.TotalFileCount++

internal/backend/rest/config_test.go1

23:26insecure-url-schemeURL uses insecure http scheme

internal/backend/rest/config_test.go:23:26

22 Cfg: Config{
23 URL: parseURL("http://localhost:1234/"),
24 Connections: 5,

internal/restic/repository.go1

15:17interface-method-limitinterface has 19 methods, exceeding the configured design limit of 10

internal/restic/repository.go:15:17

14// transparently encrypts/decrypts data.
15type Repository interface {
16 // Connections returns the maximum number of concurrent backend operations

internal/data/snapshot_find.go1

170:12max-control-nestingcontrol-flow nesting exceeds 5 levels

internal/data/snapshot_find.go:170:12

169 err = ErrInvalidSnapshotSyntax
170 } else if err == nil {
171 if ids.Has(*sn.ID()) {

internal/global/global.go1

561:6max-parametersfunction has 9 parameters; maximum is 8

internal/global/global.go:561:6

560// createOrOpenBackend creates or opens a backend using the appropriate factory method.
561func createOrOpenBackend(ctx context.Context, scheme string, cfg interface{}, rt http.RoundTripper, lim limiter.Limiter, gopts Options, s string, create bool, printer restic.Printer) (backend.Backend, error) {
562 factory := gopts.Backends.Lookup(scheme)

internal/fs/vss_windows.go1

730:6max-public-structsfile declares more than 5 exported structs

internal/fs/vss_windows.go:730:6

729// IVssEnumObject VSS api interface.
730type IVssEnumObject struct {
731 ole.IUnknown

cmd/restic/cmd_backup.go1

391:3modifies-parameterassignment modifies parameter opts

cmd/restic/cmd_backup.go:391:3

390 if opts.ExcludeCaches {
391 opts.ExcludeIfPresent = append(opts.ExcludeIfPresent, "CACHEDIR.TAG:Signature: 8a477f597d28d172789f06886806bc55")
392 }

internal/archiver/archiver_test.go1

2479:3modifies-value-receiverassignment modifies value receiver f

internal/archiver/archiver_test.go:2479:3

2478 if f.ofs.resetFIOnRead {
2479 f.ofs.overrideFI = nil
2480 }

cmd/restic/cmd_check_test.go1

18:17nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_check_test.go:18:17

17func TestParsePercentage(t *testing.T) {
18 testCases := []struct {
19 input string

cmd/restic/cmd_find.go1

488:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_find.go:488:4

487 // ignore error to allow fallback to index
488 return nil
489 }

internal/data/tree.go1

172:3nil-value-with-nil-errornil payload is returned with a nil error; return a meaningful value or a descriptive error

internal/data/tree.go:172:3

171 if t.next == nil {
172 return nil, nil
173 }

cmd/restic/cmd_mount.go1

233:4no-else-after-returnremove else and unindent its body after the return

cmd/restic/cmd_mount.go:233:4

232 return errors.Fatal(fmt.Sprintf("mountpoint %s is inaccessible: %v", mountpoint, err))
233 } else if !stat.IsDir() {
234 return errors.Fatal(fmt.Sprintf("mountpoint %s is not a directory", mountpoint))

internal/backend/azure/config.go1

36:6no-initreplace init with explicit initialization

internal/backend/azure/config.go:36:6

35
36func init() {
37 options.Register("azure", Config{})

cmd/restic/cmd_generate.go1

93:2no-naked-returnreturn values must be explicit

cmd/restic/cmd_generate.go:93:2

92 err = generate(outWriter)
93 return
94}

build.go1

78:2no-package-varpackage variables introduce mutable global state

build.go:78:2

77 runTests bool
78 enableCGO bool
79 enablePIE bool

cmd/restic/cmd_cache.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_cache.go:1:9

1package main
2

internal/archiver/archiver_test.go1

2387:16range-value-addresstaking the address of range value test can be misleading

internal/archiver/archiver_test.go:2387:16

2386 testErr := context.Canceled
2387 testRepo := &failSaveRepo{
2388 archiverRepo: repo,

internal/backend/watchdog_roundtriper.go1

80:74redefines-builtin-ididentifier close shadows a predeclared identifier

internal/backend/watchdog_roundtriper.go:80:74

79
80func newWatchdogReadCloser(rc io.ReadCloser, chunkSize int, kick func(), close func(), isTimeout func(err error) bool) *watchdogReadCloser {
81 return &watchdogReadCloser{

cmd/restic/cmd_copy.go1

337:15redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_copy.go:337:15

336 countBlobs := 0
337 sizeBlobs := uint64(0)
338 for blob := range copyBlobs.Keys() {

cmd/restic/cmd_forget.go1

392:6slice-preallocationpreallocate resultList with capacity len(range source) before appending once per iteration

cmd/restic/cmd_forget.go:392:6

391func asJSONKeeps(list []data.KeepReason) []KeepReason {
392 var resultList []KeepReason
393 for _, keep := range list {

internal/backend/watchdog_roundtriper_test.go1

91:46standard-http-method-constantreplace the HTTP method literal with http.MethodGet

internal/backend/watchdog_roundtriper_test.go:91:46

90 cancel()
91 req, err := http.NewRequestWithContext(ctx, "GET", "http://some.random.url.dfdgsfg", nil)
92 rtest.OK(t, err)

internal/dump/tar.go1

109:3task-commentTODO comment should be resolved or linked to an owned work item

internal/dump/tar.go:109:3

108 //
109 // TODO support ACLs from other operating systems.
110 // FreeBSD ACLs have names "posix1e.acl_(access|default)",

cmd/restic/cmd_cache.go1

48:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_cache.go:48:1

47// CacheOptions bundles all options for the snapshots command.
48type CacheOptions struct {
49 Cleanup bool

internal/archiver/testing_test.go1

334:38unchecked-type-assertionuse the checked two-result form of the type assertion

internal/archiver/testing_test.go:334:38

333
334 if test.expectFailure && !subtestT.(*MockT).HasFailed {
335 t.Fatal("expected failure of TestEnsureFiles not found")

internal/backend/rest/rest.go1

103:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/rest/rest.go:103:2

102
103 resp, err := be.client.Post(url.String(), "binary/octet-stream", strings.NewReader(""))
104 if err != nil {

internal/repository/index/indexmap.go1

278:36unexported-returnexported function returns an unexported type

internal/repository/index/indexmap.go:278:36

277
278func (h *hashedArrayTree) Alloc() (*indexEntry, uint) {
279 h.grow()

internal/archiver/tree_saver_test.go1

22:99unused-parameterparameter storeDuplicate is unused

internal/archiver/tree_saver_test.go:22:99

21
22func (m *mockSaver) SaveBlobAsync(_ context.Context, _ restic.BlobType, buf []byte, id restic.ID, storeDuplicate bool, cb func(newID restic.ID, known bool, sizeInRepo int, err error)) {
23 // Fake async operation

cmd/restic/cmd_ls.go1

309:7unused-receiverreceiver p is unused

cmd/restic/cmd_ls.go:309:7

308
309func (p *textLsPrinter) LeaveDir(_ string) error {
310 return nil

cmd/restic/cmd_backup.go1

335:111use-anyuse any instead of interface{}

cmd/restic/cmd_backup.go:335:111

334// from being saved in a snapshot based on path only
335func collectRejectByNameFuncs(opts BackupOptions, repo *repository.Repository, warnf func(msg string, args ...interface{})) (fs []archiver.RejectByNameFunc, err error) {
336 // exclude restic cache

cmd/restic/cmd_key_add.go1

105:15use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_key_add.go:105:15

104 if newPasswordFile != "" {
105 return "", fmt.Errorf("only either --new-password-file or --new-insecure-no-password may be specified")
106 }

cmd/restic/cmd_snapshots.go1

195:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

cmd/restic/cmd_snapshots.go:195:2

194 // Sort the snapshots so that the newer ones are listed first
195 sort.SliceStable(list, func(i, j int) bool {
196 return list[i].Time.After(list[j].Time)

internal/fs/const.go1

11:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:11:2

10 O_RDWR int = syscall.O_RDWR // open the file read-write.
11 O_APPEND int = syscall.O_APPEND // append data to the file when writing.
12 O_CREATE int = syscall.O_CREAT // create a new file if none exists.

internal/backend/rewind_reader_test.go1

19:42weak-cryptographydeprecated cryptographic primitive crypto/md5.New should not protect new data

internal/backend/rewind_reader_test.go:19:42

18 buf := []byte("foobar")
19 for _, hasher := range []hash.Hash{nil, md5.New()} {
20 fn := func() RewindReader {

cmd/restic/cmd_backup.go1

308:19add-constantstring literal "-" appears more than twice; define a constant

cmd/restic/cmd_backup.go:308:19

307 for _, filename := range filesFrom {
308 if filename == "-" {
309 return errors.Fatal("unable to read password from stdin when data is to be read from stdin, use --password-file or $RESTIC_PASSWORD")

internal/fs/stat_windows_test.go1

79:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/fs/stat_windows_test.go:79:18

78 rtest.Assert(t, err == nil, "err should be nil", err)
79 rtest.Assert(t, recall == false, "RecallOnDataAccess should be false")
80}

cmd/restic/cmd_backup.go1

300:27cognitive-complexityfunction has cognitive complexity 17; maximum is 7

cmd/restic/cmd_backup.go:300:27

299// Check returns an error when an invalid combination of options was set.
300func (opts BackupOptions) Check(gopts global.Options, args []string) error {
301 if gopts.Password == "" && !gopts.InsecureNoPassword {

cmd/restic/cmd_rewrite_integration_test.go1

182:6confusing-namingname TestRewriteMetadata differs from testRewriteMetadata only by capitalization

cmd/restic/cmd_rewrite_integration_test.go:182:6

181
182func TestRewriteMetadata(t *testing.T) {
183 newHost := "new host"

internal/archiver/archiver_unix_test.go1

14:81confusing-resultsadjacent unnamed results of the same type should be named

internal/archiver/archiver_unix_test.go:14:81

13
14func statAndSnapshot(t *testing.T, repo archiverRepo, name string) (*data.Node, *data.Node) {
15 want := nodeFromFile(t, fs.NewLocal(), name)

internal/fs/fs_reader.go1

45:6constructor-interface-returnNewReader returns interface FS although its concrete result is consistently *reader; return the concrete type

internal/fs/fs_reader.go:45:6

44// the provided FileInfo is returned.
45func NewReader(name string, r io.ReadCloser, opts ReaderOptions) (FS, error) {
46 items := make(map[string]readerItem)

cmd/restic/cmd_backup.go1

498:6cyclomatic-complexityfunction complexity is 37; maximum is 10

cmd/restic/cmd_backup.go:498:6

497
498func runBackup(ctx context.Context, opts BackupOptions, gopts global.Options, term ui.Terminal, args []string) error {
499 var vsscfg fs.VSSConfig

internal/debug/debug.go1

50:3deep-exitprocess-exit calls should be confined to main or init

internal/debug/debug.go:50:3

49 fmt.Fprintf(os.Stderr, "unable to open debug log file: %v\n", err)
50 os.Exit(2)
51 }

cmd/restic/cmd_backup.go1

147:24discarded-error-resulterror result returned by strconv.ParseBool is discarded

cmd/restic/cmd_backup.go:147:24

146 opts.IgnoreInode, _ = strconv.ParseBool(os.Getenv("RESTIC_IGNORE_INODE"))
147 opts.IgnoreCtime, _ = strconv.ParseBool(os.Getenv("RESTIC_IGNORE_CTIME"))
148

cmd/restic/cmd_ls.go1

579:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_ls.go:579:1

578
579// SortMode defines the allowed sorting modes
580type SortMode uint

internal/backend/backend.go1

115:3early-returninvert the condition and return early to reduce nesting

internal/backend/backend.go:115:3

114
115 if be, ok := b.(Unwrapper); ok {
116 b = be.Unwrap()

cmd/restic/cmd_mount_integration_test.go1

154:15error-stringserror string should not be capitalized or end with punctuation

cmd/restic/cmd_mount_integration_test.go:154:15

153 if !ok {
154 t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts)
155 }

internal/repository/checker.go1

69:6error-type-namingerror implementation type should have an Error suffix

internal/repository/checker.go:69:6

68// ErrPackData is returned if errors are discovered while verifying a packfile
69type ErrPackData struct {
70 PackID restic.ID

internal/repository/fuzz_test.go1

24:4excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/fuzz_test.go:24:4

23 rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error {
24 _, _, _, err := uploader.SaveBlob(ctx, restic.DataBlob, blob, id, false)
25 return err

cmd/restic/cmd_diff.go1

150:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_diff.go:150:6

149
150type DiffStatsContainer struct {
151 MessageType string `json:"message_type"` // "statistics"

cmd/restic/cmd_ls.go2

1:1file-length-limitfile has 638 lines; maximum is 500

cmd/restic/cmd_ls.go:1:1

1package main
2
507:55flag-parameterboolean parameter isPrefixDirectory controls function flow

cmd/restic/cmd_ls.go:507:55

506}
507func (p *sortedPrinter) NodeOutput(node lsNodeOutput, isPrefixDirectory bool) error {
508 if !isPrefixDirectory {

cmd/restic/cmd_cache.go1

1:1formatfile is not formatted

cmd/restic/cmd_cache.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_cache.go`

cmd/restic/cmd_check.go1

229:6function-lengthfunction has 126 statements and 210 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_check.go:229:6

228
229func runCheck(ctx context.Context, opts CheckOptions, gopts global.Options, args []string, term ui.Terminal) (checkSummary, error) {
230 summary := checkSummary{MessageType: "summary"}

cmd/restic/lock.go1

46:6function-result-limitfunction returns 4 values; maximum is 3

cmd/restic/lock.go:46:6

45
46func openWithExclusiveLock(ctx context.Context, gopts global.Options, dryRun bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
47 return internalOpenWithLocked(ctx, gopts, dryRun, true, printer)

internal/archiver/archiver.go1

654:2identical-switch-branchesswitch repeats a case body

internal/archiver/archiver.go:654:2

653 return true
654 case checkInode && node.Inode != fi.Inode:
655 return true

cmd/restic/cmd_backup_integration_test.go1

186:26import-shadowingidentifier fs shadows an imported package

cmd/restic/cmd_backup_integration_test.go:186:26

185 var testFS *vssDeleteOriginalFS
186 backupFSTestHook = func(fs fs.FS) fs.FS {
187 testFS = &vssDeleteOriginalFS{

cmd/restic/integration_helpers_test.go1

365:4inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

cmd/restic/integration_helpers_test.go:365:4

364 if _, ok := old[k]; !ok {
365 old[k] = struct{}{}
366 return old, k

internal/backend/rest/config_test.go1

30:26insecure-url-schemeURL uses insecure http scheme

internal/backend/rest/config_test.go:30:26

29 Cfg: Config{
30 URL: parseURL("http://localhost:1234/"),
31 Connections: 5,

internal/ui/backup/progress.go1

14:22interface-method-limitinterface has 16 methods, exceeding the configured design limit of 10

internal/ui/backup/progress.go:14:22

13// It must be safe to call its methods from concurrent goroutines.
14type ProgressPrinter interface {
15 Update(total, processed Counter, errors uint, currentFiles map[string]struct{}, start time.Time, secs uint64)

internal/data/snapshot_find.go1

171:6max-control-nestingcontrol-flow nesting exceeds 5 levels

internal/data/snapshot_find.go:171:6

170 } else if err == nil {
171 if ids.Has(*sn.ID()) {
172 continue

internal/restorer/filerestorer.go1

67:6max-parametersfunction has 9 parameters; maximum is 8

internal/restorer/filerestorer.go:67:6

66
67func newFileRestorer(dst string,
68 blobsLoader blobsLoaderFn,

internal/fs/vss_windows.go1

736:6max-public-structsfile declares more than 5 exported structs

internal/fs/vss_windows.go:736:6

735// nolint:structcheck
736type IVssEnumObjectVTable struct {
737 ole.IUnknownVtbl

cmd/restic/cmd_backup_integration_test.go1

33:3modifies-parameterassignment modifies parameter opts

cmd/restic/cmd_backup_integration_test.go:33:3

32
33 opts.GroupBy = data.SnapshotGroupByOptions{Host: true, Path: true}
34 return runBackup(ctx, opts, gopts, gopts.Term, target)

internal/backend/retry/backend_retry_test.go1

236:2modifies-value-receiverassignment modifies value receiver r

internal/backend/retry/backend_retry_test.go:236:2

235 }
236 r.pos += i
237 if r.pos >= r.limit {

cmd/restic/cmd_check_test.go1

49:17nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_check_test.go:49:17

48func TestStringToIntSlice(t *testing.T) {
49 testCases := []struct {
50 input string

cmd/restic/cmd_key_list.go1

76:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_key_list.go:76:4

75 printer.E("LoadKey() failed: %v", err)
76 return nil
77 }

internal/data/tree.go1

185:4nil-value-with-nil-errornil payload is returned with a nil error; return a meaningful value or a descriptive error

internal/data/tree.go:185:4

184 if !ok {
185 return nil, nil
186 }

cmd/restic/cmd_prune.go1

155:5no-else-after-returnremove else and unindent its body after the return

cmd/restic/cmd_prune.go:155:5

154 return errors.Fatalf("invalid number of bytes %q for --repack-smaller-than: %v", opts.SmallPackSize, err)
155 } else if size <= 0 {
156 return errors.Fatalf("--repack-smaller-than must be larger than zero")

internal/backend/b2/config.go1

32:6no-initreplace init with explicit initialization

internal/backend/b2/config.go:32:6

31
32func init() {
33 options.Register("b2", Config{})

cmd/restic/cmd_snapshots_integration_test.go1

35:2no-naked-returnreturn values must be explicit

cmd/restic/cmd_snapshots_integration_test.go:35:2

34 }
35 return
36}

build.go1

79:2no-package-varpackage variables introduce mutable global state

build.go:79:2

78 enableCGO bool
79 enablePIE bool
80 goVersion = ParseGoVersion(runtime.Version())

cmd/restic/cmd_cat.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_cat.go:1:9

1package main
2

internal/archiver/archiver_test.go1

2773:34range-value-addresstaking the address of range value errorOnOpen can be misleading

internal/archiver/archiver_test.go:2773:34

2772 for _, errorOnOpen := range []bool{false, true} {
2773 arch := New(repo, fs.Track{FS: &missingFS{FS: fs.NewLocal(), errorOnOpen: errorOnOpen}}, Options{})
2774 _, excluded, err := arch.save(ctx, "/", filepath.Join(tempdir, "testdir"), nil, false)

internal/backend/watchdog_roundtriper.go1

94:2redefines-builtin-ididentifier close shadows a predeclared identifier

internal/backend/watchdog_roundtriper.go:94:2

93 kick func()
94 close func()
95 isTimeout func(err error) bool

cmd/restic/cmd_copy.go1

347:30redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_copy.go:347:30

346 printer.V(" copy %d blobs with disk size %s in %d packfiles\n",
347 countBlobs, ui.FormatBytes(uint64(sizeBlobs)), len(packList))
348 return sizeBlobs

cmd/restic/cmd_snapshots.go1

378:3slice-preallocationpreallocate snapshotGroups with capacity len(range source) before appending once per iteration

cmd/restic/cmd_snapshots.go:378:3

377 if grouped {
378 snapshotGroups := []SnapshotGroup{}
379

internal/backend/watchdog_roundtriper_test.go1

134:57standard-http-method-constantreplace the HTTP method literal with http.MethodGet

internal/backend/watchdog_roundtriper_test.go:134:57

133 rt := newWatchdogRoundtripper(http.DefaultTransport, 10*time.Millisecond, 1024)
134 req, err := http.NewRequestWithContext(context.TODO(), "GET", srv.URL, io.NopCloser(newSlowReader(bytes.NewReader(msg), 100*time.Millisecond)))
135 rtest.OK(t, err)

internal/fs/const_windows.go1

5:1task-commentTODO comment should be resolved or linked to an owned work item

internal/fs/const_windows.go:5:1

4
5// TODO honor flags when opening files
6

cmd/restic/cmd_check.go1

75:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_check.go:75:1

74// CheckOptions bundles all options for the 'check' command.
75type CheckOptions struct {
76 ReadData bool

internal/archiver/testing_test.go1

490:38unchecked-type-assertionuse the checked two-result form of the type assertion

internal/archiver/testing_test.go:490:38

489
490 if test.expectFailure && !subtestT.(*MockT).HasFailed {
491 t.Fatal("expected failure of TestEnsureSnapshot not found")

internal/backend/rest/rest.go1

156:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/rest/rest.go:156:2

155
156 resp, err := b.client.Do(req)
157 if err != nil {

internal/repository/index/indexmap.go1

292:41unexported-returnexported function returns an unexported type

internal/repository/index/indexmap.go:292:41

291
292func (h *hashedArrayTree) Ref(pos uint) *indexEntry {
293 if pos >= h.size {

internal/backend/layout/testing.go1

7:29unused-parameterparameter t is unused

internal/backend/layout/testing.go:7:29

6
7func TestDisablePackSubdirs(t testing.TB) {
8 disablePackSubdirs = true

cmd/restic/cmd_ls.go1

312:7unused-receiverreceiver p is unused

cmd/restic/cmd_ls.go:312:7

311}
312func (p *textLsPrinter) Close() error {
313 return nil

cmd/restic/cmd_backup.go1

359:104use-anyuse any instead of interface{}

cmd/restic/cmd_backup.go:359:104

358// from being saved in a snapshot based on path and file info
359func collectRejectFuncs(opts BackupOptions, targets []string, fs fs.FS, warnf func(msg string, args ...interface{})) (funcs []archiver.RejectFunc, err error) {
360 // allowed devices

cmd/restic/cmd_key_add.go1

116:15use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_key_add.go:116:15

115 if password == "" {
116 return "", fmt.Errorf("an empty password is not allowed by default. Pass the flag `--new-insecure-no-password` to restic to disable this check")
117 }

cmd/restic/cmd_snapshots.go1

220:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

cmd/restic/cmd_snapshots.go:220:2

219 // always sort the snapshots so that the newer ones are listed last
220 sort.SliceStable(list, func(i, j int) bool {
221 return list[i].Time.Before(list[j].Time)

internal/fs/const.go1

12:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:12:2

11 O_APPEND int = syscall.O_APPEND // append data to the file when writing.
12 O_CREATE int = syscall.O_CREAT // create a new file if none exists.
13 O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist

internal/backend/rewind_reader_test.go1

49:42weak-cryptographydeprecated cryptographic primitive crypto/md5.New should not protect new data

internal/backend/rewind_reader_test.go:49:42

48
49 for _, hasher := range []hash.Hash{nil, md5.New()} {
50 fn := func() RewindReader {

cmd/restic/cmd_backup.go1

508:21add-constantstring literal "windows" appears more than twice; define a constant

cmd/restic/cmd_backup.go:508:21

507 }
508 if runtime.GOOS == "windows" {
509 if vsscfg, err = fs.ParseVSSConfig(gopts.Extended); err != nil {

internal/repository/lock_test.go1

344:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/repository/lock_test.go:344:18

343
344 rtest.Assert(t, lockExists(repo, t, id1) == false,
345 "stale lock still exists after RemoveStaleLocks was called")

cmd/restic/cmd_backup.go1

359:6cognitive-complexityfunction has cognitive complexity 15; maximum is 7

cmd/restic/cmd_backup.go:359:6

358// from being saved in a snapshot based on path and file info
359func collectRejectFuncs(opts BackupOptions, targets []string, fs fs.FS, warnf func(msg string, args ...interface{})) (funcs []archiver.RejectFunc, err error) {
360 // allowed devices

internal/archiver/scanner.go1

100:19confusing-namingname scan differs from Scan only by capitalization

internal/archiver/scanner.go:100:19

99// explicit is true when this path was an explicit backup target (same meaning as tree.Explicit on a leaf).
100func (s *Scanner) scan(ctx context.Context, stats ScanStats, target string, explicit bool) (ScanStats, error) {
101 if ctx.Err() != nil {

internal/archiver/exclude.go1

72:50confusing-resultsadjacent unnamed results of the same type should be named

internal/archiver/exclude.go:72:50

71// method, otherwise data races may occur.
72func (rc *rejectionCache) Get(dir string) (bool, bool) {
73 v, ok := rc.m[dir]

internal/restic/progress.go1

70:6constructor-interface-returnNewNoopPrinter returns interface Printer although its concrete result is consistently *noopPrinter; return the concrete type

internal/restic/progress.go:70:6

69// NewNoopPrinter returns a Printer that discards all messages.
70func NewNoopPrinter() Printer {
71 return &noopPrinter{}

cmd/restic/cmd_cache.go1

60:6cyclomatic-complexityfunction complexity is 19; maximum is 10

cmd/restic/cmd_cache.go:60:6

59
60func runCache(opts CacheOptions, gopts global.Options, args []string, term ui.Terminal) error {
61 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

internal/debug/debug.go1

80:4deep-exitprocess-exit calls should be confined to main or init

internal/debug/debug.go:80:4

79 fmt.Fprintf(os.Stderr, "error: invalid pattern %q: %v\n", t, err)
80 os.Exit(5)
81 }

cmd/restic/cmd_backup.go1

261:7discarded-error-resulterror result returned by f.Close is discarded

cmd/restic/cmd_backup.go:261:7

260 // ignore subsequent errors
261 _ = f.Close()
262 return nil, err

cmd/restic/cmd_ls.go1

582:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_ls.go:582:1

581
582// Allowed sort modes
583const (

internal/backend/retry/backend_retry.go1

207:3early-returninvert the condition and return early to reduce nesting

internal/backend/retry/backend_retry.go:207:3

206 if v, ok := be.failedLoads.Load(key); ok {
207 if time.Since(v.(time.Time)) > failedLoadExpiry {
208 be.failedLoads.Delete(key)

cmd/restic/cmd_repair_index_integration_test.go1

111:23error-stringserror string should not be capitalized or end with punctuation

cmd/restic/cmd_repair_index_integration_test.go:111:23

110func (b *appendOnlyBackend) Remove(_ context.Context, h backend.Handle) error {
111 return errors.Errorf("Failed to remove %v", h)
112}

internal/repository/index_list_test.go1

49:4excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/index_list_test.go:49:4

48 for range 5 {
49 _, _, _, err := uploader.SaveBlob(ctx, restic.DataBlob, []byte("test"), restic.ID{}, false)
50 rtest.OK(t, err)

cmd/restic/cmd_find_integration_test.go1

151:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_find_integration_test.go:151:6

150// JsonOutput is the struct `restic find --json` produces
151type JSONOutput struct {
152 ObjectType string `json:"object_type"`

cmd/restic/cmd_stats.go1

1:1file-length-limitfile has 531 lines; maximum is 500

cmd/restic/cmd_stats.go:1:1

1package main
2

cmd/restic/cmd_prune_integration_test.go1

42:38flag-parameterboolean parameter unsafeNoSpaceRecovery controls function flow

cmd/restic/cmd_prune_integration_test.go:42:38

41
42func testPruneVariants(t *testing.T, unsafeNoSpaceRecovery bool) {
43 suffix := ""

cmd/restic/cmd_cat.go1

1:1formatfile is not formatted

cmd/restic/cmd_cat.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_cat.go`

cmd/restic/cmd_diff.go1

243:20function-lengthfunction has 65 statements and 113 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_diff.go:243:20

242
243func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, prefix string, id1, id2 restic.ID) error {
244 debug.Log("diffing %v to %v", id1, id2)

internal/archiver/archiver.go1

883:23function-result-limitfunction returns 4 values; maximum is 3

internal/archiver/archiver.go:883:23

882// Snapshot saves several targets and returns a snapshot.
883func (arch *Archiver) Snapshot(ctx context.Context, targets []string, opts SnapshotOptions) (*data.Snapshot, restic.ID, *Summary, error) {
884 arch.summary = &Summary{

internal/fs/node.go1

95:2identical-switch-branchesswitch repeats a case body

internal/fs/node.go:95:2

94 node.Links = stat.Links
95 case data.NodeTypeCharDev:
96 node.Device = stat.Device

cmd/restic/cmd_diff.go1

96:16import-shadowingidentifier path shadows an imported package

cmd/restic/cmd_diff.go:96:16

95
96func NewChange(path string, mode string) *Change {
97 return &Change{MessageType: "change", Path: path, Modifier: mode}

internal/archiver/tree.go1

249:6inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/archiver/tree.go:249:6

248 node.Path = f.Join(t.Path, entry)
249 t.Nodes[entry] = node
250 continue

internal/backend/rest/rest_test.go1

136:33insecure-url-schemeURL uses insecure http scheme

internal/backend/rest/rest_test.go:136:33

135 // while we may listen on 0.0.0.0, we connect to localhost
136 addrToConnectTo = fmt.Sprintf("http://%s/restic-test/", strings.Replace(actualListenAddr, "0.0.0.0", "localhost", 1))
137 }

internal/ui/restore/progress.go1

40:22interface-method-limitinterface has 12 methods, exceeding the configured design limit of 10

internal/ui/restore/progress.go:40:22

39
40type ProgressPrinter interface {
41 Update(progress State, duration time.Duration)

internal/data/snapshot_policy.go1

281:7max-control-nestingcontrol-flow nesting exceeds 5 levels

internal/data/snapshot_policy.go:281:7

280 keepSnap = true
281 if val == b.Last && nr == len(list)-1 {
282 b.reason = fmt.Sprintf("oldest %v", b.reason)

internal/repository/checker.go1

79:6max-public-structsfile declares more than 5 exported structs

internal/repository/checker.go:79:6

78// Checker handles index-related operations for repository checking.
79type Checker struct {
80 repo *Repository

cmd/restic/cmd_backup_integration_test.go1

119:3modifies-parameterassignment modifies parameter path

cmd/restic/cmd_backup_integration_test.go:119:3

118 }
119 path = vol[:len(vol)-1] + string(filepath.Separator) + path[len(vol)+1:]
120 path = filepath.ToSlash(path)

internal/data/node.go1

168:2modifies-value-receiverassignment modifies value receiver node

internal/data/node.go:168:2

167 // something we can actually save.
168 node.ModTime = fixTime(node.ModTime)
169 node.AccessTime = fixTime(node.AccessTime)

cmd/restic/cmd_check_test.go1

189:17nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_check_test.go:189:17

188
189 testCases := []struct {
190 opts CheckOptions

cmd/restic/cmd_mount.go1

294:3nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_mount.go:294:3

293 if err != nil {
294 return abs, nil
295 }

internal/data/tree.go1

197:2nil-value-with-nil-errornil payload is returned with a nil error; return a meaningful value or a descriptive error

internal/data/tree.go:197:2

196 // we have already passed the name
197 return nil, nil
198}

cmd/restic/cmd_rewrite.go1

297:4no-else-after-returnremove else and unindent its body after the return

cmd/restic/cmd_rewrite.go:297:4

296 return errors.Fatal("Nothing to do: no excludes/includes provided and no new metadata provided")
297 } else if hasExcludes && hasIncludes {
298 return errors.Fatal("exclude and include patterns are mutually exclusive")

internal/backend/gs/config.go1

33:6no-initreplace init with explicit initialization

internal/backend/gs/config.go:33:6

32
33func init() {
34 options.Register("gs", Config{})

internal/backend/layout/layout_default.go1

91:2no-naked-returnreturn values must be explicit

internal/backend/layout/layout_default.go:91:2

90 dirname = l.join(l.path, defaultLayoutPaths[t])
91 return
92}

build.go1

80:2no-package-varpackage variables introduce mutable global state

build.go:80:2

79 enablePIE bool
80 goVersion = ParseGoVersion(runtime.Version())
81)

cmd/restic/cmd_check.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_check.go:1:9

1package main
2

internal/archiver/tree.go1

266:24range-value-addresstaking the address of range value subtree can be misleading

internal/archiver/tree.go:266:24

265 for i, subtree := range t.Nodes {
266 err := unrollTree(f, &subtree)
267 if err != nil {

internal/data/tree_stream.go1

54:29redefines-builtin-ididentifier error shadows a predeclared identifier

internal/data/tree_stream.go:54:29

53 in <-chan trackedID,
54 process func(id restic.ID, error error, nodes TreeNodeIterator) error,
55 out chan<- trackedTreeItem,

cmd/restic/cmd_forget_test.go1

17:9redundant-conversionconversion from ForgetPolicyCount to the identical type is redundant

cmd/restic/cmd_forget_test.go:17:9

16 }{
17 {"0", ForgetPolicyCount(0), ""},
18 {"1", ForgetPolicyCount(1), ""},

cmd/restic/cmd_snapshots.go1

383:8slice-preallocationpreallocate snapshots with capacity len(range source) before appending once per iteration

cmd/restic/cmd_snapshots.go:383:8

382 var err error
383 var snapshots []Snapshot
384

internal/backend/watchdog_roundtriper_test.go1

161:57standard-http-method-constantreplace the HTTP method literal with http.MethodGet

internal/backend/watchdog_roundtriper_test.go:161:57

160 rt := newWatchdogRoundtripper(http.DefaultTransport, 10*time.Millisecond, 1024)
161 req, err := http.NewRequestWithContext(context.TODO(), "GET", srv.URL, io.NopCloser(bytes.NewReader(msg)))
162 rtest.OK(t, err)

internal/fs/fs_local_vss.go1

258:3task-commentTODO comment should be resolved or linked to an owned work item

internal/fs/fs_local_vss.go:258:3

257 // -> try to backup without a snapshot
258 // TODO: log warning?
259 snapshotPath = path

cmd/restic/cmd_copy.go1

65:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_copy.go:65:1

64// CopyOptions bundles all options for the copy command.
65type CopyOptions struct {
66 global.SecondaryRepoOptions

internal/backend/location/location_test.go1

56:42unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/location/location_test.go:56:42

55 test.Equals(t, "local", u.Scheme)
56 test.Equals(t, "local:"+path, u.Config.(*testConfig).loc)
57 })

internal/backend/rest/rest.go1

263:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/rest/rest.go:263:2

262
263 resp, err := b.client.Do(req)
264 if err != nil {

internal/repository/repository.go1

1287:36unexported-returnexported function returns an unexported type

internal/repository/repository.go:1287:36

1286// Next returns the next blob, an error or ErrPackEOF if all blobs were read
1287func (b *packBlobIterator) Next() (packBlobValue, error) {
1288 if len(b.blobs) == 0 {

internal/fs/node_freebsd.go1

10:35unused-parameterparameter path is unused

internal/fs/node_freebsd.go:10:35

9
10func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error {
11 return nil

cmd/restic/cmd_ls.go1

514:7unused-receiverreceiver p is unused

cmd/restic/cmd_ls.go:514:7

513
514func (p *sortedPrinter) LeaveDir(_ string) error {
515 return nil

cmd/restic/cmd_backup.go1

407:87use-anyuse any instead of interface{}

cmd/restic/cmd_backup.go:407:87

406// collectTargets returns a list of target files/dirs from several sources.
407func collectTargets(opts BackupOptions, args []string, warnf func(msg string, args ...interface{}), stdin io.ReadCloser) (targets []string, err error) {
408 if opts.Stdin || opts.StdinCommand {

cmd/restic/cmd_key_list.go1

46:10use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_key_list.go:46:10

45 if len(args) > 0 {
46 return fmt.Errorf("the key list command expects no arguments, only options - please see `restic help key list` for usage and flags")
47 }

internal/feature/features.go1

135:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

internal/feature/features.go:135:2

134
135 sort.Slice(help, func(i, j int) bool {
136 return strings.Compare(help[i].Name, help[j].Name) < 0

internal/fs/const.go1

13:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:13:2

12 O_CREATE int = syscall.O_CREAT // create a new file if none exists.
13 O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
14 O_SYNC int = syscall.O_SYNC // open for synchronous I/O.

internal/backend/rewind_reader_test.go1

121:15weak-cryptographydeprecated cryptographic primitive crypto/md5.New should not protect new data

internal/backend/rewind_reader_test.go:121:15

120 if rd.Hash() != nil {
121 hasher := md5.New()
122 // must never fail according to interface

cmd/restic/cmd_backup_integration_test.go1

137:56add-constantstring literal "testdata" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:137:56

136 // second backup, implicit incremental
137 testRunBackup(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, env.gopts)
138

internal/repository/lock_test.go1

346:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/repository/lock_test.go:346:18

345 "stale lock still exists after RemoveStaleLocks was called")
346 rtest.Assert(t, lockExists(repo, t, id2) == true,
347 "non-stale lock was removed by RemoveStaleLocks")

cmd/restic/cmd_backup.go1

407:6cognitive-complexityfunction has cognitive complexity 29; maximum is 7

cmd/restic/cmd_backup.go:407:6

406// collectTargets returns a list of target files/dirs from several sources.
407func collectTargets(opts BackupOptions, args []string, warnf func(msg string, args ...interface{}), stdin io.ReadCloser) (targets []string, err error) {
408 if opts.Stdin || opts.StdinCommand {

internal/archiver/tree.go1

158:16confusing-namingname add differs from Add only by capitalization

internal/archiver/tree.go:158:16

157// add adds a new target path into the tree.
158func (t *tree) add(fs fs.FS, target, root string, pc []string, explicit bool) error {
159 if len(pc) == 0 {

internal/restic/parallel_test.go1

34:38confusing-resultsadjacent unnamed results of the same type should be named

internal/restic/parallel_test.go:34:38

33func (c *testCounter) SetMax(_ uint64) {}
34func (c *testCounter) Get() (uint64, uint64) { return c.value.Load(), 0 }
35func (c *testCounter) Done() {}

internal/ui/backup/json.go1

25:6constructor-interface-returnNewJSONProgress returns interface ProgressPrinter although its concrete result is consistently *jsonProgress; return the concrete type

internal/ui/backup/json.go:25:6

24// NewJSONProgress returns a new backup progress reporter.
25func NewJSONProgress(term ui.Terminal, verbosity uint) ProgressPrinter {
26 return &jsonProgress{

cmd/restic/cmd_cat.go1

70:6cyclomatic-complexityfunction complexity is 36; maximum is 10

cmd/restic/cmd_cat.go:70:6

69
70func runCat(ctx context.Context, gopts global.Options, args []string, term ui.Terminal) error {
71 printer := progress.NewTerminalPrinter(gopts.JSON, gopts.Verbosity, term)

cmd/restic/cmd_backup.go1

589:8discarded-error-resulterror result returned by progressReporter.Error is discarded

cmd/restic/cmd_backup.go:589:8

588 errorHandler := func(item string, err error) {
589 _ = progressReporter.Error(item, err)
590 }

cmd/restic/cmd_ls_integration_test.go1

109:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_ls_integration_test.go:109:1

108
109// JSON lines test
110func TestRunLsJson(t *testing.T) {

internal/backend/test/tests.go1

183:3early-returninvert the condition and return early to reduce nesting

internal/backend/test/tests.go:183:3

182 d := data
183 if o < len(d) {
184 d = d[o:]

internal/archiver/archiver.go1

673:42error-stringserror string should not be capitalized or end with punctuation

internal/archiver/archiver.go:673:42

672 if atree.FileInfoPath == "" {
673 return futureNode{}, 0, errors.Errorf("FileInfoPath for %v is empty", snPath)
674 }

internal/repository/prune_test.go1

32:4excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/prune_test.go:32:4

31 rtest.OK(t, err)
32 _, _, _, err = uploader.SaveBlob(ctx, blob.Type, buf, blob.ID, true)
33 rtest.OK(t, err)

cmd/restic/cmd_forget.go1

65:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_forget.go:65:6

64
65type ForgetPolicyCount int
66

internal/archiver/archiver.go1

1:1file-length-limitfile has 991 lines; maximum is 500

internal/archiver/archiver.go:1:1

1package archiver
2

cmd/restic/cmd_prune_integration_test.go1

217:107flag-parameterboolean parameter checkOK controls function flow

cmd/restic/cmd_prune_integration_test.go:217:107

216
217func testEdgeCaseRepo(t *testing.T, tarfile string, optionsCheck CheckOptions, optionsPrune PruneOptions, checkOK, pruneOK bool) {
218 env, cleanup := withTestEnvironment(t)

cmd/restic/cmd_cat_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_cat_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_cat_test.go`

cmd/restic/cmd_diff.go1

357:6function-lengthfunction has 58 statements and 114 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_diff.go:357:6

356
357func runDiff(ctx context.Context, opts DiffOptions, gopts global.Options, args []string, term ui.Terminal) error {
358 if len(args) != 2 {

internal/archiver/archiver_test.go1

438:32function-result-limitfunction returns 4 values; maximum is 3

internal/archiver/archiver_test.go:438:32

437
438func (repo *blobCountingSaver) SaveBlob(ctx context.Context, t restic.BlobType, buf []byte, id restic.ID, storeDuplicate bool) (restic.ID, bool, int, error) {
439 id, exists, size, err := repo.saver.SaveBlob(ctx, t, buf, id, storeDuplicate)

internal/repository/prune.go1

522:3identical-switch-branchesswitch repeats a case body

internal/repository/prune.go:522:3

521 return false
522 case pi.unusedSize+pi.usedSize < uint64(targetPackSize) && pj.unusedSize+pj.usedSize >= uint64(targetPackSize):
523 return true

cmd/restic/cmd_ls_integration_test.go1

31:38import-shadowingidentifier data shadows an imported package

cmd/restic/cmd_ls_integration_test.go:31:38

30
31func assertIsValidJSON(t *testing.T, data []byte) {
32 // Sanity check: output must be valid JSON.

internal/repository/checker.go1

135:5inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/repository/checker.go:135:5

134 if _, ok := packToIndex[packID]; !ok {
135 packToIndex[packID] = restic.NewIDSet()
136 }

internal/backend/watchdog_roundtriper_test.go1

91:53insecure-url-schemeURL uses insecure http scheme

internal/backend/watchdog_roundtriper_test.go:91:53

90 cancel()
91 req, err := http.NewRequestWithContext(ctx, "GET", "http://some.random.url.dfdgsfg", nil)
92 rtest.OK(t, err)

internal/fs/fs_local_vss.go1

204:7max-control-nestingcontrol-flow nesting exceeds 5 levels

internal/fs/fs_local_vss.go:204:7

203 fs.msgMessage("mountpoints in snapshot volume [%s]:\n", vssVolume)
204 for mp, mpInfo := range snapshot.mountPointInfo {
205 info := ""

internal/restorer/restorer_test.go1

535:6max-public-structsfile declares more than 5 exported structs

internal/restorer/restorer_test.go:535:6

534
535type TreeVisit struct {
536 funcName string // name of the function

cmd/restic/cmd_backup_integration_test.go1

120:3modifies-parameterassignment modifies parameter path

cmd/restic/cmd_backup_integration_test.go:120:3

119 path = vol[:len(vol)-1] + string(filepath.Separator) + path[len(vol)+1:]
120 path = filepath.ToSlash(path)
121 }

internal/data/node.go1

169:2modifies-value-receiverassignment modifies value receiver node

internal/data/node.go:169:2

168 node.ModTime = fixTime(node.ModTime)
169 node.AccessTime = fixTime(node.AccessTime)
170 node.ChangeTime = fixTime(node.ChangeTime)

cmd/restic/cmd_copy_integration_test.go1

66:34nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_copy_integration_test.go:66:34

65 // Check that the copied snapshots have the same tree contents as the old ones (= identical tree hash)
66 origRestores := make(map[string]struct{})
67 for i, snapshotID := range snapshotIDs {

cmd/restic/cmd_tag.go1

169:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/cmd_tag.go:169:4

168 printer.E("unable to modify the tags for snapshot ID %q, ignoring: %v", sn.ID(), err)
169 return nil
170 }

internal/backend/b2/b2.go1

83:4no-else-after-returnremove else and unindent its body after the return

internal/backend/b2/b2.go:83:4

82 return nil, errors.New("connection to B2 failed")
83 } else if err != nil {
84 return nil, errors.Wrap(err, "b2.NewClient")

internal/backend/local/config.go1

24:6no-initreplace init with explicit initialization

internal/backend/local/config.go:24:6

23
24func init() {
25 options.Register("local", Config{})

internal/backend/s3/s3.go1

573:5no-naked-returnreturn values must be explicit

internal/backend/s3/s3.go:573:5

572 objectInfo, err = be.client.StatObject(ctx, be.cfg.Bucket, filename, minio.StatObjectOptions{})
573 return
574 },

cmd/restic/cmd_backup.go1

174:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_backup.go:174:5

173
174var backupFSTestHook func(fs fs.FS) fs.FS
175

cmd/restic/cmd_copy.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_copy.go:1:9

1package main
2

internal/archiver/tree_test.go1

471:18range-value-addresstaking the address of range value test can be misleading

internal/archiver/tree_test.go:471:18

470
471 if !cmp.Equal(&test.want, tree) {
472 t.Error(cmp.Diff(&test.want, tree))

internal/data/tree_stream.go1

192:29redefines-builtin-ididentifier error shadows a predeclared identifier

internal/data/tree_stream.go:192:29

191 skip func(tree restic.ID) bool,
192 process func(id restic.ID, error error, nodes TreeNodeIterator) error,
193) error {

cmd/restic/cmd_forget_test.go1

18:9redundant-conversionconversion from ForgetPolicyCount to the identical type is redundant

cmd/restic/cmd_forget_test.go:18:9

17 {"0", ForgetPolicyCount(0), ""},
18 {"1", ForgetPolicyCount(1), ""},
19 {"unlimited", ForgetPolicyCount(-1), ""},

internal/archiver/archiver_test.go1

1479:8slice-preallocationpreallocate targets with capacity len(range source) before appending once per iteration

internal/archiver/archiver_test.go:1479:8

1478
1479 var targets []string
1480 for _, target := range test.targets {

internal/backend/watchdog_roundtriper_test.go1

194:57standard-http-method-constantreplace the HTTP method literal with http.MethodGet

internal/backend/watchdog_roundtriper_test.go:194:57

193 rt := newWatchdogRoundtripper(http.DefaultTransport, 25*time.Millisecond, 1024)
194 req, err := http.NewRequestWithContext(context.TODO(), "GET", srv.URL, io.NopCloser(bytes.NewReader(msg)))
195 rtest.OK(t, err)

internal/fs/vss_windows.go1

826:3task-commentTODO comment should be resolved or linked to an owned work item

internal/fs/vss_windows.go:826:3

825 ); err != nil {
826 // TODO warn for expected event logs for VSS IVssWriterCallback failure
827 return nil, newVssError(

cmd/restic/cmd_debug.go1

82:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_debug.go:82:1

81
82type DebugExamineOptions struct {
83 TryRepair bool

internal/backend/location/registry.go1

62:29unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/location/registry.go:62:29

61func (f *genericBackendFactory[C, T]) Create(ctx context.Context, cfg interface{}, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...interface{})) (backend.Backend, error) {
62 return f.createFn(ctx, *cfg.(*C), rt, lim, errorLog)
63}

internal/backend/rest/rest.go1

296:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/rest/rest.go:296:2

295
296 resp, err := b.client.Do(req)
297 if err != nil {

internal/fs/node_freebsd.go1

10:48unused-parameterparameter utimes is unused

internal/fs/node_freebsd.go:10:48

9
10func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error {
11 return nil

cmd/restic/cmd_ls.go1

635:7unused-receiverreceiver c is unused

cmd/restic/cmd_ls.go:635:7

634
635func (c *SortMode) Type() string {
636 return "mode"

cmd/restic/cmd_backup.go1

592:46use-anyuse any instead of interface{}

cmd/restic/cmd_backup.go:592:46

591
592 messageHandler := func(msg string, args ...interface{}) {
593 if !gopts.JSON {

cmd/restic/cmd_key_passwd.go1

56:10use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_key_passwd.go:56:10

55 if len(args) > 0 {
56 return fmt.Errorf("the key passwd command expects no arguments, only options - please see `restic help key passwd` for usage and flags")
57 }

internal/fuse/snapshots_dirstruct.go1

314:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

internal/fuse/snapshots_dirstruct.go:314:2

313 // This needs to be done before hashing.
314 sort.Slice(snapshots, func(i, j int) bool {
315 si, sj := snapshots[i], snapshots[j]

internal/fs/const.go1

14:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:14:2

13 O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
14 O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
15 O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.

internal/backend/swift/swift.go1

123:9weak-cryptographydeprecated cryptographic primitive crypto/md5.New should not protect new data

internal/backend/swift/swift.go:123:9

122func (be *beSwift) Hasher() hash.Hash {
123 return md5.New()
124}

cmd/restic/cmd_backup_integration_test.go1

175:21add-constantstring literal "windows" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:175:21

174func TestBackupVSS(t *testing.T) {
175 if runtime.GOOS != "windows" || fs.HasSufficientPrivilegesForVSS() != nil {
176 t.Skip("vss fs test can only be run on windows with admin privileges")

internal/repository/lock_test.go1

348:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/repository/lock_test.go:348:18

347 "non-stale lock was removed by RemoveStaleLocks")
348 rtest.Assert(t, lockExists(repo, t, id3) == false,
349 "stale lock still exists after RemoveStaleLocks was called")

cmd/restic/cmd_backup.go1

498:6cognitive-complexityfunction has cognitive complexity 47; maximum is 7

cmd/restic/cmd_backup.go:498:6

497
498func runBackup(ctx context.Context, opts BackupOptions, gopts global.Options, term ui.Terminal, args []string) error {
499 var vsscfg fs.VSSConfig

internal/archiver/tree_saver.go1

76:21confusing-namingname save differs from Save only by capitalization

internal/archiver/tree_saver.go:76:21

75// save stores the nodes as a tree in the repo.
76func (s *treeSaver) save(ctx context.Context, job *saveTreeJob) (*data.Node, ItemStats, error) {
77 var stats ItemStats

internal/restic/progress.go1

15:35confusing-resultsadjacent unnamed results of the same type should be named

internal/restic/progress.go:15:35

14func (noopCounter) SetMax(uint64) {}
15func (noopCounter) Get() (uint64, uint64) { return 0, 0 }
16func (noopCounter) Done() {}

internal/ui/backup/text.go1

26:6constructor-interface-returnNewTextProgress returns interface ProgressPrinter although its concrete result is consistently *textProgress; return the concrete type

internal/ui/backup/text.go:26:6

25// NewTextProgress returns a new backup progress reporter.
26func NewTextProgress(term ui.Terminal, verbosity uint) ProgressPrinter {
27 return &textProgress{

cmd/restic/cmd_check.go1

97:6cyclomatic-complexityfunction complexity is 16; maximum is 10

cmd/restic/cmd_check.go:97:6

96
97func checkFlags(opts CheckOptions) error {
98 if opts.ReadData && opts.ReadDataSubset != "" {

cmd/restic/cmd_backup_integration_test.go1

154:10discarded-error-resulterror result returned by f.FS.Lstat is discarded

cmd/restic/cmd_backup_integration_test.go:154:10

153 // call Lstat to trigger snapshot creation
154 _, _ = f.FS.Lstat(name)
155 // nuke testdata

cmd/restic/cmd_prune_integration_test.go1

159:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_prune_integration_test.go:159:1

158
159// Test repos for edge cases
160func TestEdgeCaseRepos(t *testing.T) {

internal/fs/node_windows.go1

270:4early-returninvert the condition and return early to reduce nesting

internal/fs/node_windows.go:270:4

269 if err != nil {
270 if IsAccessDenied(err) || errors.Is(err, windows.ERROR_FILE_READ_ONLY) {
271 // If existing file already has readonly or system flag, encrypt file call fails.

internal/archiver/archiver_test.go1

232:15error-stringserror string should not be capitalized or end with punctuation

internal/archiver/archiver_test.go:232:15

231 if excluded {
232 t.Errorf("Save() excluded the node, that's unexpected")
233 }

internal/repository/repack.go1

129:5excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/repack.go:129:5

128 // We do want to save already saved blobs!
129 _, _, _, err = uploader.SaveBlob(wgCtx, blob.Type, buf, blob.ID, true)
130 if err != nil {

cmd/restic/cmd_forget.go1

67:5exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_forget.go:67:5

66
67var ErrNegativePolicyCount = errors.New("negative values not allowed, use 'unlimited' instead")
68var ErrFailedToRemoveOneOrMoreSnapshots = errors.New("failed to remove one or more snapshots")

internal/archiver/archiver_test.go1

1:1file-length-limitfile has 2779 lines; maximum is 500

internal/archiver/archiver_test.go:1:1

1package archiver
2

cmd/restic/cmd_prune_integration_test.go1

217:116flag-parameterboolean parameter pruneOK controls function flow

cmd/restic/cmd_prune_integration_test.go:217:116

216
217func testEdgeCaseRepo(t *testing.T, tarfile string, optionsCheck CheckOptions, optionsPrune PruneOptions, checkOK, pruneOK bool) {
218 env, cleanup := withTestEnvironment(t)

cmd/restic/cmd_check.go1

1:1formatfile is not formatted

cmd/restic/cmd_check.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_check.go`

cmd/restic/cmd_find.go1

290:18function-lengthfunction has 5 statements and 78 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_find.go:290:18

289
290func (f *Finder) findInSnapshot(ctx context.Context, sn *data.Snapshot) error {
291 debug.Log("searching in snapshot %s\n for entries within [%s %s]", sn.ID(), f.pat.oldest, f.pat.newest)

internal/archiver/archiver_test.go1

2293:25function-result-limitfunction returns 4 values; maximum is 3

internal/archiver/archiver_test.go:2293:25

2292
2293func (f *failSaveSaver) SaveBlob(ctx context.Context, t restic.BlobType, buf []byte, id restic.ID, storeDuplicate bool) (restic.ID, bool, int, error) {
2294 val := f.failSaveRepo.cnt.Add(1)

internal/repository/prune.go1

524:3identical-switch-branchesswitch repeats a case body

internal/repository/prune.go:524:3

523 return true
524 case pj.unusedSize+pj.usedSize < uint64(targetPackSize) && pi.unusedSize+pi.usedSize >= uint64(targetPackSize):
525 return false

cmd/restic/cmd_rewrite.go1

155:6import-shadowingidentifier filter shadows an imported package

cmd/restic/cmd_rewrite.go:155:6

154 condExclude := len(rejectByNameFuncs) > 0
155 var filter rewriteFilterFunc
156

internal/repository/checker.go1

143:5inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/repository/checker.go:143:5

142 if _, ok := packToPackBlobHash[pbs.PackID]; !ok {
143 packToPackBlobHash[pbs.PackID] = restic.NewIDSet()
144 }

internal/fs/fs_local_vss.go1

206:8max-control-nestingcontrol-flow nesting exceeds 5 levels

internal/fs/fs_local_vss.go:206:8

205 info := ""
206 if !mpInfo.IsSnapshotted() {
207 info = " (not snapshotted)"

cmd/restic/cmd_check.go1

167:2modifies-parameterassignment modifies parameter s

cmd/restic/cmd_check.go:167:2

166 }
167 s = s[:len(s)-1]
168

internal/data/node.go1

170:2modifies-value-receiverassignment modifies value receiver node

internal/data/node.go:170:2

169 node.AccessTime = fixTime(node.AccessTime)
170 node.ChangeTime = fixTime(node.ChangeTime)
171

cmd/restic/cmd_copy_integration_test.go1

69:30nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_copy_integration_test.go:69:30

68 restoredir := filepath.Join(env.base, fmt.Sprintf("restore%d", i))
69 origRestores[restoredir] = struct{}{}
70 testRunRestore(t, env.gopts, restoredir, snapshotID.String())

cmd/restic/integration_helpers_test.go1

43:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/integration_helpers_test.go:43:5

42 t.Logf("error: %v\n", err)
43 return nil
44 }

internal/backend/b2/b2.go1

104:4no-else-after-returnremove else and unindent its body after the return

internal/backend/b2/b2.go:104:4

103 return nil, backend.ErrNoRepository
104 } else if err != nil {
105 return nil, errors.Wrap(err, "Bucket")

internal/backend/rclone/config.go1

27:6no-initreplace init with explicit initialization

internal/backend/rclone/config.go:27:6

26
27func init() {
28 options.Register("rclone", Config{})

internal/bloblru/cache.go1

54:3no-naked-returnreturn values must be explicit

internal/bloblru/cache.go:54:3

53 if size > c.size {
54 return
55 }

cmd/restic/cmd_backup.go1

177:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_backup.go:177:5

176// ErrInvalidSourceData is used to report an incomplete backup
177var ErrInvalidSourceData = errors.New("at least one source file could not be read")
178

cmd/restic/cmd_debug.go1

3:9package-commentspackage should have a documentation comment

cmd/restic/cmd_debug.go:3:9

2
3package main
4

internal/archiver/tree_test.go1

472:22range-value-addresstaking the address of range value test can be misleading

internal/archiver/tree_test.go:472:22

471 if !cmp.Equal(&test.want, tree) {
472 t.Error(cmp.Diff(&test.want, tree))
473 }

internal/repository/index/master_index_test.go1

524:5redefines-builtin-ididentifier max shadows a predeclared identifier

internal/repository/index/master_index_test.go:524:5

523 rtest.OK(t, master.Load(context.TODO(), repo, p, nil))
524 v, max := p.Get()
525 rtest.Equals(t, uint64(indexCount), v)

cmd/restic/cmd_forget_test.go1

19:17redundant-conversionconversion from ForgetPolicyCount to the identical type is redundant

cmd/restic/cmd_forget_test.go:19:17

18 {"1", ForgetPolicyCount(1), ""},
19 {"unlimited", ForgetPolicyCount(-1), ""},
20 {"", ForgetPolicyCount(0), "strconv.ParseInt: parsing \"\": invalid syntax"},

internal/archiver/file_saver_test.go1

60:6slice-preallocationpreallocate results with capacity len(range source) before appending once per iteration

internal/archiver/file_saver_test.go:60:6

59
60 var results []futureNode
61

internal/fuse/root.go1

41:1task-commentTODO comment should be resolved or linked to an owned work item

internal/fuse/root.go:41:1

40
41// Size of the blob cache. TODO: make this configurable.
42const blobCacheSize = 64 << 20

cmd/restic/cmd_diff.go1

66:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_diff.go:66:1

65// DiffOptions collects all options for the diff command.
66type DiffOptions struct {
67 ShowMetadata bool

internal/backend/location/registry.go1

65:27unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/location/registry.go:65:27

64func (f *genericBackendFactory[C, T]) Open(ctx context.Context, cfg interface{}, rt http.RoundTripper, lim limiter.Limiter, errorLog func(string, ...interface{})) (backend.Backend, error) {
65 return f.openFn(ctx, *cfg.(*C), rt, lim, errorLog)
66}

internal/backend/rest/rest.go1

326:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/rest/rest.go:326:2

325
326 resp, err := b.client.Do(req)
327 if err != nil {

internal/repository/index/index_test.go1

328:15unused-parameterparameter t is unused

internal/repository/index/index_test.go:328:15

327
328func listPack(t testing.TB, idx *index.Index, id restic.ID) (pbs []*pack.PackedBlob) {
329 for pb := range idx.Values() {

cmd/restic/cmd_repair_index_integration_test.go1

110:7unused-receiverreceiver b is unused

cmd/restic/cmd_repair_index_integration_test.go:110:7

109// called via repo.Backend().Remove()
110func (b *appendOnlyBackend) Remove(_ context.Context, h backend.Handle) error {
111 return errors.Errorf("Failed to remove %v", h)

cmd/restic/cmd_check.go1

573:50use-anyuse any instead of interface{}

cmd/restic/cmd_check.go:573:50

572
573func (p *jsonErrorPrinter) E(msg string, args ...interface{}) {
574 status := checkError{

cmd/restic/cmd_key_remove.go1

43:10use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/cmd_key_remove.go:43:10

42 if len(args) != 1 {
43 return fmt.Errorf("key remove expects one argument as the key id")
44 }

internal/repository/prune.go1

514:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

internal/repository/prune.go:514:2

513 debug.Log("%d candidate packfiles to repack", len(repackCandidates))
514 sort.Slice(repackCandidates, func(i, j int) bool {
515 pi := repackCandidates[i].packInfo

internal/fs/const.go1

15:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:15:2

14 O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
15 O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
16 O_NONBLOCK int = syscall.O_NONBLOCK // don't block open on fifos etc.

cmd/restic/cmd_backup_integration_test.go1

254:44add-constantstring literal "packs" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:254:44

253 rtest.Equals(t, snapshotIDs, snapshotIDsAfter)
254 dataIDsAfter := testRunList(t, env.gopts, "packs")
255 rtest.Equals(t, packIDs, dataIDsAfter)

internal/repository/lock_test.go1

372:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/repository/lock_test.go:372:18

371
372 rtest.Assert(t, lockExists(repo, t, id1) == false,
373 "lock still exists after RemoveAllLocks was called")

cmd/restic/cmd_backup_integration_test.go1

151:31cognitive-complexityfunction has cognitive complexity 9; maximum is 7

cmd/restic/cmd_backup_integration_test.go:151:31

150
151func (f *vssDeleteOriginalFS) Lstat(name string) (*fs.ExtendedFileInfo, error) {
152 if !f.hasRemoved {

internal/backend/azure/azure.go1

161:6confusing-namingname Open differs from open only by capitalization

internal/backend/azure/azure.go:161:6

160// Open opens the Azure backend at specified container.
161func Open(_ context.Context, cfg Config, rt http.RoundTripper, _ func(string, ...interface{})) (*Backend, error) {
162 return open(cfg, rt)

internal/ui/restore/json.go1

19:6constructor-interface-returnNewJSONProgress returns interface ProgressPrinter although its concrete result is consistently *jsonPrinter; return the concrete type

internal/ui/restore/json.go:19:6

18
19func NewJSONProgress(terminal ui.Terminal, verbosity uint) ProgressPrinter {
20 return &jsonPrinter{

cmd/restic/cmd_check.go1

229:6cyclomatic-complexityfunction complexity is 43; maximum is 10

cmd/restic/cmd_check.go:229:6

228
229func runCheck(ctx context.Context, opts CheckOptions, gopts global.Options, args []string, term ui.Terminal) (checkSummary, error) {
230 summary := checkSummary{MessageType: "summary"}

cmd/restic/cmd_cache.go1

166:6discarded-error-resulterror result returned by tab.Write is discarded

cmd/restic/cmd_cache.go:166:6

165
166 _ = tab.Write(gopts.Term.OutputWriter())
167 printer.S("%d cache dirs in %s", len(dirs), cachedir)

cmd/restic/cmd_repair_index_integration_test.go1

109:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_repair_index_integration_test.go:109:1

108
109// called via repo.Backend().Remove()
110func (b *appendOnlyBackend) Remove(_ context.Context, h backend.Handle) error {

internal/fs/node_windows.go1

298:5early-returninvert the condition and return early to reduce nesting

internal/fs/node_windows.go:298:5

297 if err != nil {
298 if IsAccessDenied(err) || errors.Is(err, windows.ERROR_FILE_READ_ONLY) {
299 // If existing file already has readonly or system flag, decrypt file call fails.

internal/archiver/archiver_test.go1

310:15error-stringserror string should not be capitalized or end with punctuation

internal/archiver/archiver_test.go:310:15

309 if excluded {
310 t.Errorf("Save() excluded the node, that's unexpected")
311 }

internal/repository/repack_test.go1

73:3excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/repack_test.go:73:3

72 rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error {
73 _, _, _, err := uploader.SaveBlob(ctx, restic.DataBlob, buf, id, false)
74 return err

cmd/restic/cmd_forget.go1

68:5exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_forget.go:68:5

67var ErrNegativePolicyCount = errors.New("negative values not allowed, use 'unlimited' instead")
68var ErrFailedToRemoveOneOrMoreSnapshots = errors.New("failed to remove one or more snapshots")
69

internal/backend/retry/backend_retry_test.go1

1:1file-length-limitfile has 635 lines; maximum is 500

internal/backend/retry/backend_retry_test.go:1:1

1package retry
2

cmd/restic/cmd_rewrite.go1

194:28flag-parameterboolean parameter dryRun controls function flow

cmd/restic/cmd_rewrite.go:194:28

193func filterAndReplaceSnapshot(ctx context.Context, repo restic.Repository, sn *data.Snapshot,
194 filter rewriteFilterFunc, dryRun bool, forget bool, newMetadata *snapshotMetadata, addTag string, printer restic.Printer,
195 keepEmptySnapshot bool) (bool, error) {

cmd/restic/cmd_check_integration_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_check_integration_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_check_integration_test.go`

cmd/restic/cmd_find.go1

596:6function-lengthfunction has 57 statements and 119 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_find.go:596:6

595
596func runFind(ctx context.Context, opts FindOptions, gopts global.Options, args []string, term ui.Terminal) error {
597 if len(args) == 0 {

internal/archiver/file_saver_test.go1

33:6function-result-limitfunction returns 4 values; maximum is 3

internal/archiver/file_saver_test.go:33:6

32
33func startFileSaver(ctx context.Context, t testing.TB, _ fs.FS) (*fileSaver, *mockSaver, context.Context, *errgroup.Group) {
34 wg, ctx := errgroup.WithContext(ctx)

internal/repository/prune.go1

559:3identical-switch-branchesswitch repeats a case body

internal/repository/prune.go:559:3

558
559 case reachedUnusedSizeAfter && packIsLargeEnough:
560 // for all other packs stop repacking if tolerated unused size is reached.

cmd/restic/cmd_rewrite.go1

194:2import-shadowingidentifier filter shadows an imported package

cmd/restic/cmd_rewrite.go:194:2

193func filterAndReplaceSnapshot(ctx context.Context, repo restic.Repository, sn *data.Snapshot,
194 filter rewriteFilterFunc, dryRun bool, forget bool, newMetadata *snapshotMetadata, addTag string, printer restic.Printer,
195 keepEmptySnapshot bool) (bool, error) {

internal/repository/index/associated_data.go1

79:3inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/repository/index/associated_data.go:79:3

78 if _, ok := a.overflow[bh]; ok {
79 a.overflow[bh] = val
80 return

internal/restorer/filerestorer.go1

294:6max-control-nestingcontrol-flow nesting exceeds 5 levels

internal/restorer/filerestorer.go:294:6

293 for _, idxPack := range idxPacks {
294 if idxPack.PackID().Equal(pack.id) {
295 addBlob(idxPack.Handle(), blob.offset)

cmd/restic/cmd_check.go1

204:4modifies-parameterassignment modifies parameter gopts

cmd/restic/cmd_check.go:204:4

203 printer.E("unable to create cache directory %s, disabling cache: %v", cachedir, err)
204 gopts.NoCache = true
205 return cleanup

internal/data/snapshot.go1

267:2modifies-value-receiverassignment modifies value receiver sn

internal/data/snapshot.go:267:2

266func (sn Snapshots) Swap(i, j int) {
267 sn[i], sn[j] = sn[j], sn[i]
268}

cmd/restic/cmd_diff_integration_test.go1

104:31nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_diff_integration_test.go:104:31

103
104 snapshots := make(map[string]struct{})
105 opts := BackupOptions{}

cmd/restic/integration_helpers_test.go1

49:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

cmd/restic/integration_helpers_test.go:49:5

48 t.Logf("error: %v\n", err)
49 return nil
50 }

internal/backend/s3/s3.go1

142:5no-else-after-returnremove else and unindent its body after the return

internal/backend/s3/s3.go:142:5

141 return nil, errors.Fatalf("no credentials found. $AWS_SECRET_ACCESS_KEY is set but $AWS_ACCESS_KEY_ID is empty")
142 } else if keyID != "" && secret == "" {
143 return nil, errors.Fatalf("no credentials found. $AWS_ACCESS_KEY_ID is set but $AWS_SECRET_ACCESS_KEY is empty")

internal/backend/rest/config.go1

19:6no-initreplace init with explicit initialization

internal/backend/rest/config.go:19:6

18
19func init() {
20 options.Register("rest", Config{})

internal/bloblru/cache.go1

61:3no-naked-returnreturn values must be explicit

internal/bloblru/cache.go:61:3

60 if c.c.Contains(id) { // Doesn't update the recency list.
61 return
62 }

cmd/restic/cmd_backup.go1

180:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_backup.go:180:5

179// ErrNoSourceData is used to report that no source data was found
180var ErrNoSourceData = errors.Fatal("all source directories/files do not exist")
181

cmd/restic/cmd_debug_disabled.go1

3:9package-commentspackage should have a documentation comment

cmd/restic/cmd_debug_disabled.go:3:9

2
3package main
4

internal/backend/layout/layout_test.go1

129:9range-value-addresstaking the address of range value test can be misleading

internal/backend/layout/layout_test.go:129:9

128 t.Run(fmt.Sprintf("%v/%v", test.Type, test.Handle.Name), func(t *testing.T) {
129 l := &DefaultLayout{
130 path: test.path,

internal/repository/packer_manager.go1

151:16redefines-builtin-ididentifier max shadows a predeclared identifier

internal/repository/packer_manager.go:151:16

150
151func randomInt(max int) (int, error) {
152 rangeSize := big.NewInt(int64(max))

cmd/restic/cmd_forget_test.go1

20:8redundant-conversionconversion from ForgetPolicyCount to the identical type is redundant

cmd/restic/cmd_forget_test.go:20:8

19 {"unlimited", ForgetPolicyCount(-1), ""},
20 {"", ForgetPolicyCount(0), "strconv.ParseInt: parsing \"\": invalid syntax"},
21 {"-1", ForgetPolicyCount(0), ErrNegativePolicyCount.Error()},

internal/archiver/testing.go1

83:6slice-preallocationpreallocate names with capacity len(range source) before appending once per iteration

internal/archiver/testing.go:83:6

82 // ensure a stable order such that it can be guaranteed that a hardlink target already exists
83 var names []string
84 for name := range dir {

internal/restorer/fileswriter.go1

20:1task-commentTODO comment should be resolved or linked to an owned work item

internal/restorer/fileswriter.go:20:1

19// multiple blobs can be concurrently written to the same file.
20// TODO I am not 100% convinced this is necessary, i.e. it may be okay
21// to use multiple os.File to write to the same target file

cmd/restic/cmd_diff_integration_test.go1

64:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_diff_integration_test.go:64:1

63
64var diffOutputRegexPatterns = []string{
65 "-.+modfile",

internal/backend/rclone/internal_test.go1

31:10unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/rclone/internal_test.go:31:10

30
31 err = be.(*rclone).cmd.Process.Kill()
32 rtest.OK(t, err)

internal/backend/watchdog_roundtriper.go1

66:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/backend/watchdog_roundtriper.go:66:2

65
66 resp, err := w.rt.RoundTrip(req)
67 if err != nil {

internal/repository/pack/blobs_test.go1

21:28unused-parameterparameter t is unused

internal/repository/pack/blobs_test.go:21:28

20
21func TestBlobsSortNilSlice(t *testing.T) {
22 var blobs Blobs

cmd/restic/integration_test.go1

110:7unused-receiverreceiver r is unused

cmd/restic/integration_test.go:110:7

109
110func (r *writeToOnly) Read(_ []byte) (n int, err error) {
111 return 0, fmt.Errorf("should have called WriteTo instead")

cmd/restic/cmd_check.go1

580:43use-anyuse any instead of interface{}

cmd/restic/cmd_check.go:580:43

579}
580func (*jsonErrorPrinter) S(_ string, _ ...interface{}) {}
581func (*jsonErrorPrinter) P(_ string, _ ...interface{}) {}

cmd/restic/integration_test.go1

111:12use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/integration_test.go:111:12

110func (r *writeToOnly) Read(_ []byte) (n int, err error) {
111 return 0, fmt.Errorf("should have called WriteTo instead")
112}

internal/repository/repository_internal_test.go1

50:2use-slices-sortuse slices.Sort or slices.SortFunc when possible

internal/repository/repository_internal_test.go:50:2

49 copy(sorted[:], blobs[:])
50 sort.SliceStable(sorted[:], func(i, j int) bool {
51 hi := backend.Handle{Type: backend.PackFile, Name: sorted[i].PackID().String()}

internal/fs/const.go1

16:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const.go:16:2

15 O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
16 O_NONBLOCK int = syscall.O_NONBLOCK // don't block open on fifos etc.
17)

cmd/restic/cmd_backup_integration_test.go1

256:45add-constantstring literal "index" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:256:45

255 rtest.Equals(t, packIDs, dataIDsAfter)
256 indexIDsAfter := testRunList(t, env.gopts, "index")
257 rtest.Equals(t, indexIDs, indexIDsAfter)

internal/repository/lock_test.go1

374:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/repository/lock_test.go:374:18

373 "lock still exists after RemoveAllLocks was called")
374 rtest.Assert(t, lockExists(repo, t, id2) == false,
375 "lock still exists after RemoveAllLocks was called")

cmd/restic/cmd_backup_integration_test.go1

600:6cognitive-complexityfunction has cognitive complexity 9; maximum is 7

cmd/restic/cmd_backup_integration_test.go:600:6

599
600func linksEqual(source, dest map[uint64][]string) bool {
601 for _, vs := range source {

internal/backend/gs/gs.go1

117:6confusing-namingname Open differs from open only by capitalization

internal/backend/gs/gs.go:117:6

116// Open opens the gs backend at the specified bucket.
117func Open(_ context.Context, cfg Config, rt http.RoundTripper, _ func(string, ...interface{})) (backend.Backend, error) {
118 return open(cfg, rt)

internal/ui/restore/text.go1

19:6constructor-interface-returnNewTextProgress returns interface ProgressPrinter although its concrete result is consistently *textPrinter; return the concrete type

internal/ui/restore/text.go:19:6

18
19func NewTextProgress(terminal ui.Terminal, verbosity uint) ProgressPrinter {
20 return &textPrinter{

cmd/restic/cmd_copy.go1

120:6cyclomatic-complexityfunction complexity is 11; maximum is 10

cmd/restic/cmd_copy.go:120:6

119
120func runCopy(ctx context.Context, opts CopyOptions, gopts global.Options, args []string, term ui.Terminal) error {
121 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

cmd/restic/cmd_check.go1

479:21discarded-error-resulterror result returned by ui.ParseBytes is discarded

cmd/restic/cmd_check.go:479:21

478 }
479 subsetSize, _ := ui.ParseBytes(opts.ReadDataSubset)
480 if subsetSize > repoSize {

cmd/restic/cmd_rewrite_integration_test.go1

334:1doc-comment-perioddocumentation comment should end with punctuation

cmd/restic/cmd_rewrite_integration_test.go:334:1

333
334// TestRewriteIncludeNothing makes sure when nothing is included, the original snapshot stays untouched
335func TestRewriteIncludeNothing(t *testing.T) {

internal/repository/debug.go1

317:5early-returninvert the condition and return early to reduce nesting

internal/repository/debug.go:317:5

316 }
317 if plaintext != nil {
318 outputPrefix = "repaired "

internal/archiver/archiver_test.go1

2731:12error-stringserror string should not be capitalized or end with punctuation

internal/archiver/archiver_test.go:2731:12

2730 if excluded {
2731 t.Errorf("Save() excluded the node, that's unexpected")
2732 }

internal/repository/repack_test.go1

345:3excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/repack_test.go:345:3

344 rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error {
345 _, _, _, err := uploader.SaveBlob(ctx, restic.DataBlob, modbuf, id, false)
346 return err

cmd/restic/cmd_key_add.go1

45:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_key_add.go:45:6

44
45type KeyAddOptions struct {
46 NewPasswordFile string

internal/backend/s3/s3.go1

1:1file-length-limitfile has 598 lines; maximum is 500

internal/backend/s3/s3.go:1:1

1package s3
2

cmd/restic/cmd_rewrite.go1

194:41flag-parameterboolean parameter forget controls function flow

cmd/restic/cmd_rewrite.go:194:41

193func filterAndReplaceSnapshot(ctx context.Context, repo restic.Repository, sn *data.Snapshot,
194 filter rewriteFilterFunc, dryRun bool, forget bool, newMetadata *snapshotMetadata, addTag string, printer restic.Printer,
195 keepEmptySnapshot bool) (bool, error) {

cmd/restic/cmd_check_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_check_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_check_test.go`

cmd/restic/cmd_find_integration_test.go1

215:6function-lengthfunction has 35 statements and 86 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_find_integration_test.go:215:6

214
215func TestFindPackID(t *testing.T) {
216 env, cleanup := withTestEnvironment(t)

internal/archiver/tree_saver_test.go1

33:6function-result-limitfunction returns 4 values; maximum is 3

internal/archiver/tree_saver_test.go:33:6

32
33func setupTreeSaver() (context.Context, context.CancelFunc, *treeSaver, func() error) {
34 ctx, cancel := context.WithCancel(context.Background())

internal/repository/prune.go1

563:3identical-switch-branchesswitch repeats a case body

internal/repository/prune.go:563:3

562
563 default:
564 repack(p.ID, p.packInfo)

cmd/restic/cmd_snapshots.go1

273:3import-shadowingidentifier data shadows an imported package

cmd/restic/cmd_snapshots.go:273:3

272 for _, sn := range list {
273 data := snapshot{
274 ID: sn.ID().Str(),

internal/repository/repository_test.go1

430:5inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/repository/repository_test.go:430:5

429 if _, ok := packEntries[packID]; !ok {
430 packEntries[packID] = make(map[restic.ID]struct{})
431 }

cmd/restic/cmd_check.go1

212:3modifies-parameterassignment modifies parameter gopts

cmd/restic/cmd_check.go:212:3

211 printer.E("unable to create temporary directory for cache during check, disabling cache: %v\n", err)
212 gopts.NoCache = true
213 return cleanup

internal/data/snapshot.go1

267:9modifies-value-receiverassignment modifies value receiver sn

internal/data/snapshot.go:267:9

266func (sn Snapshots) Swap(i, j int) {
267 sn[i], sn[j] = sn[j], sn[i]
268}

cmd/restic/cmd_dump_test.go1

10:17nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_dump_test.go:10:17

9func TestDumpSplitPath(t *testing.T) {
10 testPaths := []struct {
11 path string

internal/backend/cache/cache.go1

58:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/cache/cache.go:58:4

57 if errors.Is(err, os.ErrExist) {
58 return nil
59 }

internal/checker/checker.go1

131:5no-else-after-returnremove else and unindent its body after the return

internal/checker/checker.go:131:5

130 return nil
131 } else if sn != nil {
132 trees = append(trees, *sn.Tree)

internal/backend/s3/config.go1

54:6no-initreplace init with explicit initialization

internal/backend/s3/config.go:54:6

53
54func init() {
55 options.Register("s3", Config{})

internal/data/snapshot.go1

154:2no-naked-returnreturn values must be explicit

internal/data/snapshot.go:154:2

153 }
154 return
155}

cmd/restic/cmd_backup_integration_test.go1

371:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_backup_integration_test.go:371:5

370
371var backupExcludeFilenames = []string{
372 "testfile1",

cmd/restic/cmd_diff.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_diff.go:1:9

1package main
2

internal/checker/checker.go1

209:24range-value-addresstaking the address of range value item can be misleading

internal/checker/checker.go:209:24

208 if item.Error != nil {
209 errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("failed to decode tree %v: %w", id, item.Error)})
210 break

internal/repository/repack_test.go1

15:36redefines-builtin-ididentifier min shadows a predeclared identifier

internal/repository/repack_test.go:15:36

14
15func randomSize(random *rand.Rand, min, max int) int {
16 return random.Intn(max-min) + min

cmd/restic/cmd_forget_test.go1

21:10redundant-conversionconversion from ForgetPolicyCount to the identical type is redundant

cmd/restic/cmd_forget_test.go:21:10

20 {"", ForgetPolicyCount(0), "strconv.ParseInt: parsing \"\": invalid syntax"},
21 {"-1", ForgetPolicyCount(0), ErrNegativePolicyCount.Error()},
22 {"abc", ForgetPolicyCount(0), "strconv.ParseInt: parsing \"abc\": invalid syntax"},

internal/backend/cache/cache.go1

212:6slice-preallocationpreallocate oldCacheDirs with capacity len(range source) before appending once per iteration

internal/backend/cache/cache.go:212:6

211
212 var oldCacheDirs []os.FileInfo
213 for _, fi := range entries {

internal/restorer/restorer.go1

318:2task-commentTODO comment should be resolved or linked to an owned work item

internal/restorer/restorer.go:318:2

317 res.opts.Progress.AddProgress(location, ActionOtherRestored, 0, 0)
318 // TODO investigate if hardlinks have separate metadata on any supported system
319 return res.restoreNodeMetadataTo(node, path, location)

cmd/restic/cmd_dump.go1

63:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_dump.go:63:1

62// DumpOptions collects all options for the dump command.
63type DumpOptions struct {
64 data.SnapshotFilter

internal/backend/retry/backend_retry.go1

207:18unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/retry/backend_retry.go:207:18

206 if v, ok := be.failedLoads.Load(key); ok {
207 if time.Since(v.(time.Time)) > failedLoadExpiry {
208 be.failedLoads.Delete(key)

internal/debug/round_tripper.go1

52:2unclosed-http-response-bodylocally acquired HTTP response body is not directly closed or transferred before replacement or function exit

internal/debug/round_tripper.go:52:2

51func (tr eofDetectRoundTripper) RoundTrip(req *http.Request) (res *http.Response, err error) {
52 res, err = tr.RoundTripper.RoundTrip(req)
53 if res != nil && res.Body != nil {

internal/archiver/archiver_test.go1

2752:7unused-receiverreceiver f is unused

internal/archiver/archiver_test.go:2752:7

2751
2752func (f *missingFile) Stat() (*fs.ExtendedFileInfo, error) {
2753 return nil, os.ErrNotExist

cmd/restic/cmd_check.go1

581:43use-anyuse any instead of interface{}

cmd/restic/cmd_check.go:581:43

580func (*jsonErrorPrinter) S(_ string, _ ...interface{}) {}
581func (*jsonErrorPrinter) P(_ string, _ ...interface{}) {}
582func (*jsonErrorPrinter) PT(_ string, _ ...interface{}) {}

cmd/restic/integration_test.go1

213:10use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/integration_test.go:213:10

212 be.failedOnce = true
213 return fmt.Errorf("oops")
214 }

internal/fs/const_unix.go1

8:7var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const_unix.go:8:7

7// O_NOFOLLOW instructs the kernel to not follow symlinks when opening a file.
8const O_NOFOLLOW int = syscall.O_NOFOLLOW
9

cmd/restic/cmd_backup_integration_test.go1

283:20add-constantstring literal "0" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:283:20

282 dirs := []string{
283 filepath.Join(p, "0"),
284 filepath.Join(p, "1"),

internal/repository/lock_test.go1

376:18boolean-literal-comparisonomit the boolean literal from the logical expression

internal/repository/lock_test.go:376:18

375 "lock still exists after RemoveAllLocks was called")
376 rtest.Assert(t, lockExists(repo, t, id3) == false,
377 "lock still exists after RemoveAllLocks was called")

cmd/restic/cmd_backup_integration_test.go1

618:6cognitive-complexityfunction has cognitive complexity 12; maximum is 7

cmd/restic/cmd_backup_integration_test.go:618:6

617
618func linkEqual(source, dest []string) bool {
619 // equal if sliced are equal without considering order

internal/backend/limiter/static_limiter.go1

45:24confusing-namingname Upstream differs from upstream only by capitalization

internal/backend/limiter/static_limiter.go:45:24

44
45func (l staticLimiter) Upstream(r io.Reader) io.Reader {
46 return l.limitReader(r, l.upstream)

cmd/restic/cmd_copy.go1

187:6cyclomatic-complexityfunction complexity is 14; maximum is 10

cmd/restic/cmd_copy.go:187:6

186
187func similarSnapshots(sna *data.Snapshot, snb *data.Snapshot) bool {
188 // everything except Parent and Original must match

cmd/restic/cmd_diff_integration_test.go1

37:7discarded-error-resulterror result returned by srcFile.Close is discarded

cmd/restic/cmd_diff_integration_test.go:37:7

36 // ignore subsequent errors
37 _ = srcFile.Close()
38 return err

internal/archiver/exclude.go1

320:1doc-comment-perioddocumentation comment should end with punctuation

internal/archiver/exclude.go:320:1

319
320// RejectCloudFiles returns a func which rejects files which are online-only cloud files
321func RejectCloudFiles(warnf func(msg string, args ...interface{})) (RejectFunc, error) {

internal/repository/lock.go1

64:3early-returninvert the condition and return early to reduce nesting

internal/repository/lock.go:64:3

63 lock, err = newLock(ctx, repo, exclusive)
64 if err != nil && IsAlreadyLocked(err) {
65

internal/archiver/exclude.go1

191:26error-stringserror string should not be capitalized or end with punctuation

internal/archiver/exclude.go:191:26

190 if runtime.GOOS == "windows" {
191 return nil, errors.New("Device IDs are not supported on Windows")
192 }

internal/repository/repack_test.go1

355:3excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/repack_test.go:355:3

354 rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error {
355 _, _, _, err := uploader.SaveBlob(ctx, restic.DataBlob, buf, id, true)
356 return err

cmd/restic/cmd_key_passwd.go1

46:6exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_key_passwd.go:46:6

45
46type KeyPasswdOptions struct {
47 KeyAddOptions

internal/backend/sftp/sftp.go1

1:1file-length-limitfile has 678 lines; maximum is 500

internal/backend/sftp/sftp.go:1:1

1package sftp
2

cmd/restic/cmd_rewrite.go1

195:2flag-parameterboolean parameter keepEmptySnapshot controls function flow

cmd/restic/cmd_rewrite.go:195:2

194 filter rewriteFilterFunc, dryRun bool, forget bool, newMetadata *snapshotMetadata, addTag string, printer restic.Printer,
195 keepEmptySnapshot bool) (bool, error) {
196

cmd/restic/cmd_copy.go1

1:1formatfile is not formatted

cmd/restic/cmd_copy.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_copy.go`

cmd/restic/cmd_forget.go1

178:6function-lengthfunction has 89 statements and 183 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_forget.go:178:6

177
178func runForget(ctx context.Context, opts ForgetOptions, pruneOptions PruneOptions, gopts global.Options, term ui.Terminal, args []string) error {
179 err := verifyForgetOptions(&opts)

internal/backend/rclone/backend.go1

47:6function-result-limitfunction returns 5 values; maximum is 3

internal/backend/rclone/backend.go:47:6

46// run starts command with args and initializes the StdioConn.
47func run(errorLog func(string, ...interface{}), command string, args ...string) (*StdioConn, *sync.WaitGroup, chan struct{}, func() error, error) {
48 cmd := exec.Command(command, args...)

internal/restorer/restorer_test.go1

829:3identical-switch-branchesswitch repeats a case body

internal/restorer/restorer_test.go:829:3

828 childMayBeSelected = true
829 case "/dir/subdir/file2":
830 selectedForRestore = true

cmd/restic/cmd_stats.go1

248:127import-shadowingidentifier progress shadows an imported package

cmd/restic/cmd_stats.go:248:127

247
248func statsWalkTree(repo restic.Loader, opts StatsOptions, stats *statsContainer, hardLinkIndex *data.HardlinkIndex[struct{}], progress *statsui.Progress) walker.WalkFunc {
249 return func(parentTreeID restic.ID, npath string, node *data.Node, nodeErr error) error {

internal/restorer/filerestorer_test.go1

128:5inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/restorer/filerestorer_test.go:128:5

127 n := uint(len(blobData))
128 pack.blobs[blobID] = packBlobLayout{
129 offset: uint(len(pack.data)),

cmd/restic/cmd_check.go1

216:2modifies-parameterassignment modifies parameter gopts

cmd/restic/cmd_check.go:216:2

215
216 gopts.CacheDir = tempdir
217 printer.P("using temporary cache in %v\n", tempdir)

internal/data/testing.go1

238:2modifies-value-receiverassignment modifies value receiver t

internal/data/testing.go:238:2

237
238 t.TestTreeMap[id] = append([]byte{}, buf...)
239 return id, true, len(buf), nil

cmd/restic/cmd_find.go1

148:25nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:148:25

147 type findNode data.Node
148 b, err := json.Marshal(struct {
149 // Add these attributes

internal/backend/cache/file.go1

201:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/cache/file.go:201:5

200 if errors.Is(err, os.ErrNotExist) {
201 return nil
202 }

internal/data/node.go1

311:4no-else-after-returnremove else and unindent its body after the return

internal/data/node.go:311:4

310 return false
311 } else if ln == 0 {
312 // This means lo is also of length 0

internal/backend/sftp/config.go1

29:6no-initreplace init with explicit initialization

internal/backend/sftp/config.go:29:6

28
29func init() {
30 options.Register("sftp", Config{})

internal/data/snapshot.go1

173:2no-naked-returnreturn values must be explicit

internal/data/snapshot.go:173:2

172 }
173 return
174}

cmd/restic/cmd_cat.go1

19:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_cat.go:19:5

18
19var catAllowedCmds = []string{"config", "index", "snapshot", "key", "masterkey", "lock", "pack", "blob", "tree"}
20

cmd/restic/cmd_dump.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_dump.go:1:9

1package main
2

internal/checker/checker.go1

221:26range-value-addresstaking the address of range value b can be misleading

internal/checker/checker.go:221:26

220 if blobID.IsNull() {
221 errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("file %q blob %d has null ID", node.Name, b)})
222 continue

internal/repository/repack_test.go1

15:41redefines-builtin-ididentifier max shadows a predeclared identifier

internal/repository/repack_test.go:15:41

14
15func randomSize(random *rand.Rand, min, max int) int {
16 return random.Intn(max-min) + min

cmd/restic/cmd_forget_test.go1

22:11redundant-conversionconversion from ForgetPolicyCount to the identical type is redundant

cmd/restic/cmd_forget_test.go:22:11

21 {"-1", ForgetPolicyCount(0), ErrNegativePolicyCount.Error()},
22 {"abc", ForgetPolicyCount(0), "strconv.ParseInt: parsing \"abc\": invalid syntax"},
23 }

internal/backend/test/tests.go1

874:4slice-preallocationpreallocate IDs with capacity len(range source) before appending once per iteration

internal/backend/test/tests.go:874:4

873 // list items
874 IDs := restic.IDs{}
875

internal/restorer/restorer.go1

520:3task-commentTODO comment should be resolved or linked to an owned work item

internal/restorer/restorer.go:520:3

519
520 // TODO pass a proper value to the isDir parameter once this becomes relevant for the filters
521 selectedForRestore, _ := res.SelectFilter(nodeLocation, false)

cmd/restic/cmd_find.go1

71:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_find.go:71:1

70// FindOptions bundles all options for the find command.
71type FindOptions struct {
72 Oldest string

internal/backend/sema/backend_test.go1

74:17unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/sema/backend_test.go:74:17

73
74 unwrapper := be.(backend.Unwrapper)
75 test.Assert(t, unwrapper.Unwrap() == m, "Unwrap() returned wrong backend")

internal/archiver/archiver_test.go1

2756:7unused-receiverreceiver f is unused

internal/archiver/archiver_test.go:2756:7

2755
2756func (f *missingFile) Close() error {
2757 // prevent segfault in test

cmd/restic/cmd_check.go1

582:44use-anyuse any instead of interface{}

cmd/restic/cmd_check.go:582:44

581func (*jsonErrorPrinter) P(_ string, _ ...interface{}) {}
582func (*jsonErrorPrinter) PT(_ string, _ ...interface{}) {}
583func (*jsonErrorPrinter) V(_ string, _ ...interface{}) {}

cmd/restic/integration_test.go1

221:30use-errors-newreplace fmt.Errorf with errors.New for a static message

cmd/restic/integration_test.go:221:30

220 be.failedOnce = true
221 return backend.FileInfo{}, fmt.Errorf("oops")
222 }

internal/fs/const_unix.go1

11:7var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const_unix.go:11:7

10// O_DIRECTORY instructs the kernel to only open directories.
11const O_DIRECTORY int = syscall.O_DIRECTORY
12

cmd/restic/cmd_backup_integration_test.go1

413:35add-constantstring literal "/testdata/foo.tar.gz" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:413:35

412 files = testRunLs(t, env.gopts, snapshotID)
413 rtest.Assert(t, !includes(files, "/testdata/foo.tar.gz"),
414 "expected file %q not in first snapshot, but it's included", "foo.tar.gz")

cmd/restic/cmd_cache.go1

60:6cognitive-complexityfunction has cognitive complexity 28; maximum is 7

cmd/restic/cmd_cache.go:60:6

59
60func runCache(opts CacheOptions, gopts global.Options, args []string, term ui.Terminal) error {
61 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

internal/backend/limiter/static_limiter.go1

53:24confusing-namingname Downstream differs from downstream only by capitalization

internal/backend/limiter/static_limiter.go:53:24

52
53func (l staticLimiter) Downstream(r io.Reader) io.Reader {
54 return l.limitReader(r, l.downstream)

cmd/restic/cmd_debug.go1

161:6cyclomatic-complexityfunction complexity is 12; maximum is 10

cmd/restic/cmd_debug.go:161:6

160
161func runDebugExamine(ctx context.Context, gopts global.Options, opts DebugExamineOptions, args []string, term ui.Terminal) error {
162 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

cmd/restic/cmd_diff_integration_test.go1

44:7discarded-error-resulterror result returned by srcFile.Close is discarded

cmd/restic/cmd_diff_integration_test.go:44:7

43 // ignore subsequent errors
44 _ = srcFile.Close()
45 _ = dstFile.Close()

internal/archiver/exclude_test.go1

138:1doc-comment-perioddocumentation comment should end with punctuation

internal/archiver/exclude_test.go:138:1

137// TestIsExcludedByFileSize is for testing the instance of
138// --exclude-larger-than parameters
139func TestIsExcludedByFileSize(t *testing.T) {

internal/restic/backend_find.go1

36:4early-returninvert the condition and return early to reduce nesting

internal/restic/backend_find.go:36:4

35 if len(name) >= len(prefix) && prefix == name[:len(prefix)] {
36 if match.IsNull() {
37 match = id

internal/backend/cache/backend_test.go1

117:12error-stringserror string should not be capitalized or end with punctuation

internal/backend/cache/backend_test.go:117:12

116 if !wbe.IsNotExist(err) {
117 t.Errorf("Stat() returned error that does not match IsNotExist(): %v", err)
118 }

internal/repository/repository_test.go1

177:4excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/repository_test.go:177:4

176 for i := 0; i < t.N; i++ {
177 _, _, _, err = uploader.SaveBlob(ctx, restic.DataBlob, data, id, true)
178 rtest.OK(t, err)

cmd/restic/cmd_ls.go1

200:8exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:200:8

199func (p *ncduLsPrinter) Snapshot(sn *data.Snapshot) error {
200 const NcduMajorVer = 1
201 const NcduMinorVer = 2

internal/backend/test/tests.go1

1:1file-length-limitfile has 927 lines; maximum is 500

internal/backend/test/tests.go:1:1

1package test
2

cmd/restic/cmd_snapshots.go1

203:87flag-parameterboolean parameter compact controls function flow

cmd/restic/cmd_snapshots.go:203:87

202// PrintSnapshots prints a text table of the snapshots in list to stdout.
203func PrintSnapshots(stdout io.Writer, list data.Snapshots, reasons []data.KeepReason, compact bool) error {
204 // keep the reasons a snasphot is being kept in a map, so that it doesn't

cmd/restic/cmd_copy_integration_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_copy_integration_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_copy_integration_test.go`

cmd/restic/cmd_ls.go1

316:6function-lengthfunction has 46 statements and 180 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_ls.go:316:6

315
316func runLs(ctx context.Context, opts LsOptions, gopts global.Options, args []string, term ui.Terminal) error {
317 termPrinter := progress.NewTerminalPrinter(gopts.JSON, gopts.Verbosity, term)

internal/data/testing.go1

225:30function-result-limitfunction returns 4 values; maximum is 3

internal/data/testing.go:225:30

224
225func (t TestWritableTreeMap) SaveBlob(_ context.Context, tpe restic.BlobType, buf []byte, id restic.ID, _ bool) (newID restic.ID, known bool, size int, err error) {
226 if tpe != restic.TreeBlob {

internal/restorer/restorer_test.go1

1436:5identical-switch-branchesswitch repeats a case body

internal/restorer/restorer_test.go:1436:5

1435 selectedForRestore = true
1436 case filepath.FromSlash("/dir2"):
1437 selectedForRestore = true

cmd/restic/integration_helpers_test.go1

388:40import-shadowingidentifier bytes shadows an imported package

cmd/restic/integration_helpers_test.go:388:40

387
388func appendRandomData(filename string, bytes uint) error {
389 f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0666)

internal/restorer/fileswriter.go1

191:4inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/restorer/fileswriter.go:191:4

190 if wr, ok := bucket.files[path]; ok {
191 bucket.files[path].users++
192 return wr, nil

cmd/restic/cmd_check_integration_test.go1

42:3modifies-parameterassignment modifies parameter gopts

cmd/restic/cmd_check_integration_test.go:42:3

41 buf, err := withCaptureStdout(t, gopts, func(ctx context.Context, gopts global.Options) error {
42 gopts.Verbosity = 2
43 _, err := runCheck(ctx, opts, gopts, args, gopts.Term)

internal/filter/exclude.go1

131:3modifies-value-receiverassignment modifies value receiver opts

internal/filter/exclude.go:131:3

130
131 opts.Excludes = append(opts.Excludes, excludePatterns...)
132 }

cmd/restic/cmd_find.go1

210:25nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:210:25

209func (s *statefulOutput) PrintObjectJSON(kind, id, nodepath, treeID string, sn *data.Snapshot) {
210 b, err := json.Marshal(struct {
211 // Add these attributes

internal/backend/gs/gs.go1

138:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/gs/gs.go:138:4

137 // however, the client doesn't have storage.bucket.get permission
138 return be, nil
139 }

internal/fs/node_windows.go1

429:5no-else-after-returnremove else and unindent its body after the return

internal/fs/node_windows.go:429:5

428 return false, nil
429 } else {
430 debug.Log("Checking extended attributes. Prepared volume name: %s, actual volume name: %s, isEASupportedVolume: %v, err: %v", volumeName, volumeNameActual, isEASupportedVolume, err)

internal/backend/swift/config.go1

42:6no-initreplace init with explicit initialization

internal/backend/swift/config.go:42:6

41
42func init() {
43 options.Register("swift", Config{})

internal/data/snapshot_find.go1

89:2no-naked-returnreturn values must be explicit

internal/data/snapshot_find.go:89:2

88 id, subfolder, _ = strings.Cut(s, ":")
89 return
90}

cmd/restic/cmd_copy.go1

75:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_copy.go:75:5

74
75var errSentinelEndIteration = errors.New("end iteration")
76

cmd/restic/cmd_features.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_features.go:1:9

1package main
2

internal/checker/checker.go1

232:26range-value-addresstaking the address of range value blobID can be misleading

internal/checker/checker.go:232:26

231 debug.Log("tree %v references blob %v which isn't contained in index", id, blobID)
232 errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("file %q blob %v not found in index", node.Name, blobID)})
233 }

internal/restic/progress_test.go1

14:5redefines-builtin-ididentifier max shadows a predeclared identifier

internal/restic/progress_test.go:14:5

13 c.Done()
14 v, max := c.Get()
15 if v != 0 || max != 0 {

cmd/restic/cmd_list.go1

113:13redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_list.go:113:13

112 bar := printer.NewCounter("snapshot")
113 bar.SetMax(uint64(1))
114 err = data.FindUsedBlobs(ctx, repo, []restic.ID{*sn.Tree}, usedBlobs, bar)

internal/backend/test/tests.go1

894:8slice-preallocationpreallocate handles with capacity len(range source) before appending once per iteration

internal/backend/test/tests.go:894:8

893
894 var handles []backend.Handle
895 for _, ts := range testStrings {

internal/terminal/terminal_unix.go1

38:2task-commentTODO comment should be resolved or linked to an owned work item

internal/terminal/terminal_unix.go:38:2

37 }
38 // TODO actually read termcap db and detect if terminal supports what we need
39 return term != "dumb"

cmd/restic/cmd_find_integration_test.go1

50:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_find_integration_test.go:50:1

49
50type testMatch struct {
51 Path string `json:"path,omitempty"`

internal/backend/sema/backend_test.go1

221:10unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/sema/backend_test.go:221:10

220 be := sema.NewBackend(m)
221 fb := be.(backend.FreezeBackend)
222

internal/archiver/testing.go1

46:7unused-receiverreceiver d is unused

internal/archiver/testing.go:46:7

45
46func (d TestDir) String() string {
47 return "<Dir>"

cmd/restic/cmd_check.go1

583:43use-anyuse any instead of interface{}

cmd/restic/cmd_check.go:583:43

582func (*jsonErrorPrinter) PT(_ string, _ ...interface{}) {}
583func (*jsonErrorPrinter) V(_ string, _ ...interface{}) {}
584func (*jsonErrorPrinter) VV(_ string, _ ...interface{}) {}

internal/archiver/archiver_test.go1

2666:20use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/archiver/archiver_test.go:2666:20

2665 var filteredErr error
2666 replacementErr := fmt.Errorf("replacement")
2667 arch.Error = func(item string, err error) error {

internal/fs/const_windows.go1

10:7var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const_windows.go:10:7

9// It must not conflict with the other O_* values from go/src/syscall/types_windows.go
10const O_NOFOLLOW int = 0x40000000
11

cmd/restic/cmd_backup_integration_test.go1

414:64add-constantstring literal "foo.tar.gz" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:414:64

413 rtest.Assert(t, !includes(files, "/testdata/foo.tar.gz"),
414 "expected file %q not in first snapshot, but it's included", "foo.tar.gz")
415 rtest.Assert(t, !includes(files, "/testdata/private/secret/passwords.txt"),

cmd/restic/cmd_cat.go1

70:6cognitive-complexityfunction has cognitive complexity 47; maximum is 7

cmd/restic/cmd_cat.go:70:6

69
70func runCat(ctx context.Context, gopts global.Options, args []string, term ui.Terminal) error {
71 printer := progress.NewTerminalPrinter(gopts.JSON, gopts.Verbosity, term)

internal/backend/local/local.go1

55:6confusing-namingname Open differs from open only by capitalization

internal/backend/local/local.go:55:6

54// Open opens the local backend as specified by config.
55func Open(_ context.Context, cfg Config, _ func(string, ...interface{})) (*Local, error) {
56 debug.Log("open local backend at %v", cfg.Path)

cmd/restic/cmd_diff.go1

243:20cyclomatic-complexityfunction complexity is 35; maximum is 10

cmd/restic/cmd_diff.go:243:20

242
243func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, prefix string, id1, id2 restic.ID) error {
244 debug.Log("diffing %v to %v", id1, id2)

cmd/restic/cmd_diff_integration_test.go1

45:7discarded-error-resulterror result returned by dstFile.Close is discarded

cmd/restic/cmd_diff_integration_test.go:45:7

44 _ = srcFile.Close()
45 _ = dstFile.Close()
46 return err

internal/backend/azure/azure.go1

221:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/azure/azure.go:221:1

220
221// Hasher may return a hash function for calculating a content hash for the backend
222func (be *Backend) Hasher() hash.Hash {

internal/restorer/filerestorer.go1

147:4early-returninvert the condition and return early to reduce nesting

internal/restorer/filerestorer.go:147:4

146 packID := blob.PackID()
147 if !file.state.HasMatchingBlob(idx) {
148 if largeFile {

internal/backend/cache/file.go1

78:21error-stringserror string should not be capitalized or end with punctuation

internal/backend/cache/file.go:78:21

77 if rd == nil {
78 return errors.New("Save() called with nil reader")
79 }

internal/repository/repository_test.go1

401:4excessive-blank-identifiersassignment discards three or more results; name meaningful results or simplify the return contract

internal/repository/repository_test.go:401:4

400
401 _, _, _, err = uploader.SaveBlob(ctx, restic.DataBlob, buf, restic.ID{}, false)
402 rtest.OK(t, err)

cmd/restic/cmd_ls.go1

201:8exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:201:8

200 const NcduMajorVer = 1
201 const NcduMinorVer = 2
202

internal/checker/checker_test.go1

1:1file-length-limitfile has 642 lines; maximum is 500

internal/checker/checker_test.go:1:1

1package checker_test
2

cmd/restic/cmd_snapshots.go1

376:83flag-parameterboolean parameter grouped controls function flow

cmd/restic/cmd_snapshots.go:376:83

375// printSnapshotGroupJSON writes the JSON representation of list to stdout.
376func printSnapshotGroupJSON(stdout io.Writer, snGroups map[string]data.Snapshots, grouped bool) error {
377 if grouped {

cmd/restic/cmd_debug.go1

1:1formatfile is not formatted

cmd/restic/cmd_debug.go:1:1

1//go:build debug
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_debug.go`

cmd/restic/cmd_mount.go1

123:6function-lengthfunction has 48 statements and 101 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_mount.go:123:6

122
123func runMount(ctx context.Context, opts MountOptions, gopts global.Options, args []string, term ui.Terminal) error {
124 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

internal/debug/debug.go1

129:6function-result-limitfunction returns 4 values; maximum is 3

internal/debug/debug.go:129:6

128// taken from https://github.com/VividCortex/trace
129func getPosition() (fn, dir, file string, line int) {
130 pc, file, line, ok := runtime.Caller(2)

internal/ui/backup/json.go1

134:2identical-switch-branchesswitch repeats a case body

internal/ui/backup/json.go:134:2

133 })
134 case "file unchanged":
135 b.print(verboseUpdate{

helpers/build-release-binaries/main.go1

310:3import-shadowingidentifier os shadows an imported package

helpers/build-release-binaries/main.go:310:3

309 for _, platform := range platforms {
310 os, arch, _ := strings.Cut(platform, "/")
311 targets[os] = append(targets[os], arch)

internal/walker/walker_test.go1

71:3inefficient-map-lookupreuse the map value obtained by the comma-ok lookup

internal/walker/walker_test.go:71:3

70 if _, ok := m[id]; !ok {
71 m[id] = buf
72 }

cmd/restic/cmd_copy.go1

128:3modifies-parameterassignment modifies parameter gopts

cmd/restic/cmd_copy.go:128:3

127 // swap global options, if the secondary repo was set via from-repo
128 gopts, secondaryGopts = secondaryGopts, gopts
129 }

internal/filter/exclude.go1

144:3modifies-value-receiverassignment modifies value receiver opts

internal/filter/exclude.go:144:3

143
144 opts.InsensitiveExcludes = append(opts.InsensitiveExcludes, excludes...)
145 }

cmd/restic/cmd_find.go1

280:24nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:280:24

279 out statefulOutput
280 blobIDs map[string]struct{}
281 treeIDs map[string]struct{}

internal/backend/limiter/limiter_backend_test.go1

32:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/limiter/limiter_backend_test.go:32:4

31 if err != nil {
32 return nil
33 }

internal/fs/sd_windows.go1

54:5no-else-after-returnremove else and unindent its body after the return

internal/fs/sd_windows.go:54:5

53 return getSecurityDescriptor(filePath)
54 } else if errors.Is(err, windows.ERROR_NOT_SUPPORTED) {
55 return nil, nil

internal/data/node.go1

54:6no-initreplace init with explicit initialization

internal/data/node.go:54:6

53// init is called when the package is initialized. Any new GenericAttributeTypes being created must be added here as well.
54func init() {
55 storeGenericAttributeType(TypeCreationTime, TypeFileAttributes, TypeSecurityDescriptor)

internal/fs/ea_windows.go1

78:2no-naked-returnreturn values must be explicit

internal/fs/ea_windows.go:78:2

77 }
78 return
79}

cmd/restic/cmd_diff_integration_test.go1

64:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_diff_integration_test.go:64:5

63
64var diffOutputRegexPatterns = []string{
65 "-.+modfile",

cmd/restic/cmd_find.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_find.go:1:9

1package main
2

internal/data/snapshot_policy_test.go1

260:17range-value-addresstaking the address of range value p can be misleading

internal/data/snapshot_policy_test.go:260:17

259
260 if policySum(&p) > 0 && len(keep) > policySum(&p) {
261 t.Errorf("not enough snapshots removed: policy allows %v snapshots to remain, but ended up with %v",

internal/ui/progress/counter.go1

22:9redefines-builtin-ididentifier max shadows a predeclared identifier

internal/ui/progress/counter.go:22:9

21 Updater
22 value, max atomic.Uint64
23}

cmd/restic/cmd_ls_integration_test.go1

59:18redundant-conversionconversion from SortMode to the identical type is redundant

cmd/restic/cmd_ls_integration_test.go:59:18

58func TestRunLsSort(t *testing.T) {
59 rtest.Equals(t, SortMode(0), SortModeName, "unexpected default sort mode")
60

internal/data/find_test.go1

58:6slice-preallocationpreallocate hs with capacity len(range source) before appending once per iteration

internal/data/find_test.go:58:6

57
58 var hs restic.BlobHandles
59 for h := range s {

cmd/restic/cmd_forget.go1

65:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_forget.go:65:1

64
65type ForgetPolicyCount int
66

internal/backend/sftp/sftp.go1

460:27unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/sftp/sftp.go:460:27

459 _, rderr := rd.Read([]byte{0})
460 if rderr == io.EOF && rd.(*util.LimitedReadCloser).N != 0 {
461 // file is too short

internal/archiver/testing.go1

55:7unused-receiverreceiver f is unused

internal/archiver/testing.go:55:7

54
55func (f TestFile) String() string {
56 return "<File>"

cmd/restic/cmd_check.go1

584:44use-anyuse any instead of interface{}

cmd/restic/cmd_check.go:584:44

583func (*jsonErrorPrinter) V(_ string, _ ...interface{}) {}
584func (*jsonErrorPrinter) VV(_ string, _ ...interface{}) {}
585

internal/archiver/archiver_test.go1

2674:9use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/archiver/archiver_test.go:2674:9

2673 node: &data.Node{Type: data.NodeTypeFile},
2674 err: fmt.Errorf("not found"),
2675 }

internal/fs/const_windows.go1

13:7var-namingidentifier should use MixedCaps rather than underscores

internal/fs/const_windows.go:13:7

12// O_DIRECTORY is a noop on Windows.
13const O_DIRECTORY int = 0
14

cmd/restic/cmd_backup_integration_test.go1

416:3add-constantstring literal "expected file %q not in first snapshot, but it's included" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:416:3

415 rtest.Assert(t, !includes(files, "/testdata/private/secret/passwords.txt"),
416 "expected file %q not in first snapshot, but it's included", "passwords.txt")
417}

cmd/restic/cmd_check.go1

97:6cognitive-complexityfunction has cognitive complexity 31; maximum is 7

cmd/restic/cmd_check.go:97:6

96
97func checkFlags(opts CheckOptions) error {
98 if opts.ReadData && opts.ReadDataSubset != "" {

internal/backend/retry/backend_retry_test.go1

324:6confusing-namingname TestBackendLoadNotExists differs from testBackendLoadNotExists only by capitalization

internal/backend/retry/backend_retry_test.go:324:6

323
324func TestBackendLoadNotExists(t *testing.T) {
325 // Without HasFlakyErrors, should fail after 1 attempt

cmd/restic/cmd_diff.go1

357:6cyclomatic-complexityfunction complexity is 17; maximum is 10

cmd/restic/cmd_diff.go:357:6

356
357func runDiff(ctx context.Context, opts DiffOptions, gopts global.Options, args []string, term ui.Terminal) error {
358 if len(args) != 2 {

cmd/restic/cmd_diff_integration_test.go1

52:7discarded-error-resulterror result returned by dstFile.Close is discarded

cmd/restic/cmd_diff_integration_test.go:52:7

51 // ignore subsequent errors
52 _ = dstFile.Close()
53 return err

internal/backend/azure/azure.go1

461:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/azure/azure.go:461:1

460
461// Close does nothing
462func (be *Backend) Close() error { return nil }

internal/backend/cache/file_test.go1

127:14error-stringserror string should not be capitalized or end with punctuation

internal/backend/cache/file_test.go:127:14

126 if !maps.Equal(list2, want) {
127 t.Errorf("ClearIndexes removed indexes, want:\n %v\ngot:\n %v", list2, want)
128 }

cmd/restic/cmd_ls.go1

213:7exported-declaration-commentexported type should have a comment beginning with its name

cmd/restic/cmd_ls.go:213:7

212func lsNcduOutput(node lsNodeOutput) ([]byte, error) {
213 type NcduNode struct {
214 Name string `json:"name"`

internal/data/tree_test.go1

1:1file-length-limitfile has 604 lines; maximum is 500

internal/data/tree_test.go:1:1

1package data_test
2

cmd/restic/cmd_snapshots_integration_test.go1

38:65flag-parameterboolean parameter keepPath controls function flow

cmd/restic/cmd_snapshots_integration_test.go:38:65

37
38func snapshotsGroupTestData(t *testing.T, env *testEnvironment, keepPath bool) string {
39 testSetupBackupData(t, env)

cmd/restic/cmd_debug_disabled.go1

1:1formatfile is not formatted

cmd/restic/cmd_debug_disabled.go:1:1

1//go:build !debug
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_debug_disabled.go`

cmd/restic/cmd_mount_integration_test.go1

94:6function-lengthfunction has 26 statements and 78 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_mount_integration_test.go:94:6

93
94func checkSnapshots(t testing.TB, gopts global.Options, mountpoint string, snapshotIDs restic.IDs, expectedSnapshotsInFuseDir int) {
95 t.Logf("checking for %d snapshots: %v", len(snapshotIDs), snapshotIDs)

internal/repository/repository.go1

624:25function-result-limitfunction returns 4 values; maximum is 3

internal/repository/repository.go:624:25

623
624func (r *blobSaverRepo) SaveBlob(ctx context.Context, t restic.BlobType, buf []byte, id restic.ID, storeDuplicate bool) (newID restic.ID, known bool, size int, err error) {
625 return r.repo.saveBlob(ctx, t, buf, id, storeDuplicate)

internal/ui/backup/text.go1

109:2identical-switch-branchesswitch repeats a case body

internal/ui/backup/text.go:109:2

108 d.Seconds(), ui.FormatBytes(s.DataSize), ui.FormatBytes(s.DataSizeInRepo))
109 case "file unchanged":
110 b.VV("unchanged %v", item)

internal/archiver/archiver.go1

29:60import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver.go:29:60

28// dirs). If false is returned, files are ignored and dirs are not even walked.
29type SelectFunc func(item string, fi *fs.ExtendedFileInfo, fs fs.FS) bool
30

cmd/restic/cmd_copy.go1

352:2modifies-parameterassignment modifies parameter sn

cmd/restic/cmd_copy.go:352:2

351func copySaveSnapshot(ctx context.Context, sn *data.Snapshot, dstRepo restic.Repository, printer restic.Printer) error {
352 sn.Parent = nil // Parent does not have relevance in the new repo.
353 // Use Original as a persistent snapshot ID

internal/filter/include.go1

44:3modifies-value-receiverassignment modifies value receiver opts

internal/filter/include.go:44:3

43
44 opts.Includes = append(opts.Includes, includePatterns...)
45 }

cmd/restic/cmd_find.go1

281:24nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:281:24

280 blobIDs map[string]struct{}
281 treeIDs map[string]struct{}
282 itemsFound int

internal/backend/s3/s3.go1

499:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/s3/s3.go:499:5

498 case "InvalidObjectState":
499 return false, nil
500 case "RestoreAlreadyInProgress":

internal/fs/sd_windows.go1

56:5no-else-after-returnremove else and unindent its body after the return

internal/fs/sd_windows.go:56:5

55 return nil, nil
56 } else {
57 return nil, fmt.Errorf("get named security info failed with: %w", err)

internal/feature/registry.go1

17:6no-initreplace init with explicit initialization

internal/feature/registry.go:17:6

16
17func init() {
18 Flag.SetFlags(map[FlagName]FlagDesc{

internal/fs/ea_windows.go1

154:2no-naked-returnreturn values must be explicit

internal/fs/ea_windows.go:154:2

153 status = ntStatus(r0)
154 return
155}

cmd/restic/cmd_find.go1

27:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_find.go:27:5

26// errFindDone is returned from the tree walk when all requested tree IDs were found.
27var errFindDone = errors.New("find: all tree IDs found")
28

cmd/restic/cmd_forget.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_forget.go:1:9

1package main
2

internal/data/snapshot_policy_test.go1

260:50range-value-addresstaking the address of range value p can be misleading

internal/data/snapshot_policy_test.go:260:50

259
260 if policySum(&p) > 0 && len(keep) > policySum(&p) {
261 t.Errorf("not enough snapshots removed: policy allows %v snapshots to remain, but ended up with %v",

internal/ui/progress/counter.go1

46:26redefines-builtin-ididentifier max shadows a predeclared identifier

internal/ui/progress/counter.go:46:26

45// SetMax sets the maximum expected counter value. This method is concurrency-safe.
46func (c *Counter) SetMax(max uint64) {
47 c.max.Store(max)

cmd/restic/cmd_repair_packs_integration_test.go1

62:35redundant-conversionconversion from string to the identical type is redundant

cmd/restic/cmd_repair_packs_integration_test.go:62:35

61 rtest.Assert(t, err != nil, "expected check errors, got none")
62 rtest.Assert(t, strings.Contains(string(outError), packIDString), "expected mention of %q", packIDString)
63

internal/feature/features.go1

124:6slice-preallocationpreallocate help with capacity len(range source) before appending once per iteration

internal/feature/features.go:124:6

123func (f *FlagSet) List() []Help {
124 var help []Help
125

cmd/restic/cmd_generate.go1

43:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_generate.go:43:1

42
43type generateOptions struct {
44 ManDir string

internal/backend/watchdog_roundtriper_test.go1

62:7unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/watchdog_roundtriper_test.go:62:7

61 _, _ = w.Write(data[:2])
62 w.(http.Flusher).Flush()
63 data = data[2:]

internal/archiver/testing.go1

64:7unused-receiverreceiver s is unused

internal/archiver/testing.go:64:7

63
64func (s TestSymlink) String() string {
65 return "<Symlink>"

cmd/restic/cmd_debug.go1

96:41use-anyuse any instead of interface{}

cmd/restic/cmd_debug.go:96:41

95
96func prettyPrintJSON(wr io.Writer, item interface{}) error {
97 buf, err := json.MarshalIndent(item, "", " ")

internal/archiver/archiver_test.go1

2687:9use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/archiver/archiver_test.go:2687:9

2686 node: &data.Node{Type: data.NodeTypeIrregular},
2687 err: fmt.Errorf(`unsupported file type "irregular"`),
2688 }

internal/fs/ea_windows.go1

92:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/ea_windows.go:92:2

91 // Windows NTSTATUS value: STATUS_NO_EAS_ON_FILE=0xC0000052
92 STATUS_NO_EAS_ON_FILE = -1073741742
93)

cmd/restic/cmd_backup_integration_test.go1

472:9add-constantstring literal "repository grown by %d bytes" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:472:9

471 }
472 t.Logf("repository grown by %d bytes", stat2.size-stat1.size)
473

cmd/restic/cmd_check.go1

229:6cognitive-complexityfunction has cognitive complexity 54; maximum is 7

cmd/restic/cmd_check.go:229:6

228
229func runCheck(ctx context.Context, opts CheckOptions, gopts global.Options, args []string, term ui.Terminal) (checkSummary, error) {
230 summary := checkSummary{MessageType: "summary"}

internal/backend/s3/s3.go1

200:6confusing-namingname Open differs from open only by capitalization

internal/backend/s3/s3.go:200:6

199// does not exist yet.
200func Open(_ context.Context, cfg Config, rt http.RoundTripper, _ func(string, ...interface{})) (backend.Backend, error) {
201 return open(cfg, rt)

cmd/restic/cmd_diff_integration_test.go1

151:6cyclomatic-complexityfunction complexity is 17; maximum is 10

cmd/restic/cmd_diff_integration_test.go:151:6

150
151func TestDiffJSON(t *testing.T) {
152 env, cleanup, firstSnapshotID, secondSnapshotID := setupDiffRepo(t)

cmd/restic/cmd_dump.go1

190:8discarded-error-resulterror result returned by file.Close is discarded

cmd/restic/cmd_dump.go:190:8

189 defer func() {
190 _ = file.Close()
191 }()

internal/backend/azure/azure.go1

464:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/azure/azure.go:464:1

463
464// Warmup not implemented
465func (be *Backend) Warmup(_ context.Context, _ []backend.Handle) ([]backend.Handle, error) {

internal/backend/cache/file_test.go1

134:14error-stringserror string should not be capitalized or end with punctuation

internal/backend/cache/file_test.go:134:14

133 if !maps.Equal(list3, want) {
134 t.Errorf("ClearIndexes returned a wrong list, want:\n %v\ngot:\n %v", want, list3)
135 }

cmd/restic/cmd_ls.go1

584:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:584:2

583const (
584 SortModeName SortMode = iota
585 SortModeSize

internal/fs/node_windows_test.go1

1:1file-length-limitfile has 747 lines; maximum is 500

internal/fs/node_windows_test.go:1:1

1//go:build windows
2

cmd/restic/find.go1

13:79flag-parameterboolean parameter addHostShorthand controls function flow

cmd/restic/find.go:13:79

12// MUST be followed by finalizeSnapshotFilter after flag parsing
13func initMultiSnapshotFilter(flags *pflag.FlagSet, filt *data.SnapshotFilter, addHostShorthand bool) {
14 hostShorthand := "H"

cmd/restic/cmd_diff.go1

1:1formatfile is not formatted

cmd/restic/cmd_diff.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_diff.go`

cmd/restic/cmd_recover.go1

45:6function-lengthfunction has 61 statements and 131 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_recover.go:45:6

44
45func runRecover(ctx context.Context, gopts global.Options, term ui.Terminal) error {
46 hostname, err := os.Hostname()

internal/repository/repository.go1

1021:22function-result-limitfunction returns 4 values; maximum is 3

internal/repository/repository.go:1021:22

1020// occupies in the repo (compressed or not, including encryption overhead).
1021func (r *Repository) saveBlob(ctx context.Context, t restic.BlobType, buf []byte, id restic.ID, storeDuplicate bool) (newID restic.ID, known bool, size int, err error) {
1022

internal/ui/restore/json.go1

74:2identical-switch-branchesswitch repeats a case body

internal/ui/restore/json.go:74:2

73 action = "restored"
74 case restorer.ActionFileRestored:
75 action = "restored"

internal/archiver/archiver.go1

134:20import-shadowingidentifier path shadows an imported package

internal/archiver/archiver.go:134:20

133 // for excluded items
134 ExcludedItem func(path string)
135}

cmd/restic/cmd_copy.go1

355:3modifies-parameterassignment modifies parameter sn

cmd/restic/cmd_copy.go:355:3

354 if sn.Original == nil {
355 sn.Original = sn.ID()
356 }

internal/filter/include.go1

57:3modifies-value-receiverassignment modifies value receiver opts

internal/filter/include.go:57:3

56
57 opts.InsensitiveIncludes = append(opts.InsensitiveIncludes, includePatterns...)
58 }

cmd/restic/cmd_find.go1

435:25nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:435:25

434 // Replace the short ID with the long one
435 f.blobIDs[idStr] = struct{}{}
436 delete(f.blobIDs, id.Str())

internal/backend/s3/s3.go1

501:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/s3/s3.go:501:5

500 case "RestoreAlreadyInProgress":
501 return true, nil
502 }

internal/fs/sd_windows.go1

124:5no-else-after-returnremove else and unindent its body after the return

internal/fs/sd_windows.go:124:5

123 return setSecurityDescriptor(filePath, securityDescriptor)
124 } else {
125 return fmt.Errorf("set named security info failed with: %w", err)

internal/fs/fs_local.go1

11:6no-initreplace init with explicit initialization

internal/fs/fs_local.go:11:6

10
11func init() {
12 if err := enableProcessPrivileges(); err != nil {

internal/fs/ea_windows.go1

160:2no-naked-returnreturn values must be explicit

internal/fs/ea_windows.go:160:2

159 status = ntStatus(r0)
160 return
161}

cmd/restic/cmd_find.go1

106:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_find.go:106:5

105
106var timeFormats = []string{
107 "2006-01-02",

cmd/restic/cmd_generate.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_generate.go:1:9

1package main
2

internal/data/snapshot_policy_test.go1

262:16range-value-addresstaking the address of range value p can be misleading

internal/data/snapshot_policy_test.go:262:16

261 t.Errorf("not enough snapshots removed: policy allows %v snapshots to remain, but ended up with %v",
262 policySum(&p), len(keep))
263 }

internal/ui/progress/counter.go1

52:29redefines-builtin-ididentifier max shadows a predeclared identifier

internal/ui/progress/counter.go:52:29

51// This method is concurrency-safe.
52func (c *Counter) Get() (v, max uint64) {
53 return c.value.Load(), c.max.Load()

cmd/restic/cmd_restore_integration_test.go1

297:90redundant-conversionconversion from int64 to the identical type is redundant

cmd/restic/cmd_restore_integration_test.go:297:90

296 testRunRestoreLatest(t, env.gopts, filepath.Join(env.base, "restore0"), nil, nil)
297 rtest.OK(t, testFileSize(filepath.Join(env.base, "restore0", "testdata", "testfile.c"), int64(101)))
298

internal/filter/filter.go1

259:2slice-preallocationpreallocate patpat with capacity len(range source) before appending once per iteration

internal/filter/filter.go:259:2

258func ParsePatterns(pattern []string) []Pattern {
259 patpat := make([]Pattern, 0)
260 for _, pat := range pattern {

cmd/restic/cmd_init.go1

46:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_init.go:46:1

45// InitOptions bundles all options for the init command.
46type InitOptions struct {
47 global.SecondaryRepoOptions

internal/backend/watchdog_roundtriper_test.go1

184:4unchecked-type-assertionuse the checked two-result form of the type assertion

internal/backend/watchdog_roundtriper_test.go:184:4

183 _, _ = w.Write(data[:2])
184 w.(http.Flusher).Flush()
185 data = data[2:]

internal/archiver/testing.go1

73:7unused-receiverreceiver s is unused

internal/archiver/testing.go:73:7

72
73func (s TestHardlink) String() string {
74 return "<Hardlink>"

cmd/restic/cmd_diff.go1

87:30use-anyuse any instead of interface{}

cmd/restic/cmd_diff.go:87:30

86 printChange func(change *Change)
87 printError func(string, ...interface{})
88}

internal/archiver/archiver_test.go1

2717:16use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/archiver/archiver_test.go:2717:16

2716 },
2717 overrideErr: fmt.Errorf(`unsupported file type "irregular"`),
2718 }

internal/fs/ea_windows.go1

144:6var-namingidentifier should use MixedCaps rather than underscores

internal/fs/ea_windows.go:144:6

143func getFileEA(handle windows.Handle, iosb *ioStatusBlock, buf *uint8, bufLen uint32, returnSingleEntry bool, eaList uintptr, eaListLen uint32, eaIndex *uint32, restartScan bool) (status ntStatus) {
144 var _p0 uint32
145 if returnSingleEntry {

cmd/restic/cmd_backup_integration_test.go1

529:11add-constantstring literal "expected a backup, got nil" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:529:11

528 if newest == nil {
529 t.Fatal("expected a backup, got nil")
530 }

cmd/restic/cmd_check.go1

440:6cognitive-complexityfunction has cognitive complexity 10; maximum is 7

cmd/restic/cmd_check.go:440:6

439
440func buildPacksFilter(opts CheckOptions, printer restic.Printer,
441 filteredStatus bool) (func(packs map[restic.ID]int64) map[restic.ID]int64, error) {

internal/backend/sftp/sftp.go1

162:6confusing-namingname open differs from Open only by capitalization

internal/backend/sftp/sftp.go:162:6

161
162func open(sftp *SFTP, cfg Config) (*SFTP, error) {
163 fi, err := sftp.c.Stat(sftp.Layout.Filename(backend.Handle{Type: backend.ConfigFile}))

cmd/restic/cmd_dump.go1

84:6cyclomatic-complexityfunction complexity is 17; maximum is 10

cmd/restic/cmd_dump.go:84:6

83
84func printFromTree(ctx context.Context, tree data.TreeNodeIterator, repo restic.BlobLoader, prefix string, pathComponents []string, d *dump.Dumper, canWriteArchiveFunc func() error) error {
85 // If we print / we need to assume that there are multiple nodes at that

cmd/restic/cmd_find.go1

172:10discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:172:10

171 if !s.inuse {
172 _, _ = s.stdout.Write([]byte("["))
173 s.inuse = true

internal/backend/b2/b2.go1

156:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/b2/b2.go:156:1

155
156// Hasher may return a hash function for calculating a content hash for the backend
157func (be *b2Backend) Hasher() hash.Hash {

internal/backend/httpuseragent_roundtripper_test.go1

14:13error-stringserror string should not be capitalized or end with punctuation

internal/backend/httpuseragent_roundtripper_test.go:14:13

13 if userAgent != "TestUserAgent" {
14 t.Errorf("Expected User-Agent: TestUserAgent, got: %s", userAgent)
15 }

cmd/restic/cmd_ls.go1

585:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:585:2

584 SortModeName SortMode = iota
585 SortModeSize
586 SortModeAtime

internal/fs/vss_windows.go1

1:1file-length-limitfile has 1308 lines; maximum is 500

internal/fs/vss_windows.go:1:1

1//go:build windows
2

cmd/restic/format.go1

12:39flag-parameterboolean parameter long controls function flow

cmd/restic/format.go:12:39

11
12func formatNodeOutput(n lsNodeOutput, long bool, human bool) string {
13 if !long {

cmd/restic/cmd_diff_integration_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_diff_integration_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_diff_integration_test.go`

cmd/restic/cmd_repair_snapshots.go1

112:6function-lengthfunction has 24 statements and 114 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_repair_snapshots.go:112:6

111
112func runRepairSnapshots(ctx context.Context, gopts global.Options, opts RepairOptions, args []string, term ui.Terminal) error {
113 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

internal/ui/restore/json.go1

76:2identical-switch-branchesswitch repeats a case body

internal/ui/restore/json.go:76:2

75 action = "restored"
76 case restorer.ActionOtherRestored:
77 action = "restored"

internal/archiver/archiver_test.go1

451:50import-shadowingidentifier data shadows an imported package

internal/archiver/archiver_test.go:451:50

450
451func appendToFile(t testing.TB, filename string, data []byte) {
452 f, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)

cmd/restic/cmd_diff.go1

165:4modifies-parameterassignment modifies parameter stats

cmd/restic/cmd_diff.go:165:4

164 case restic.DataBlob:
165 stats.DataBlobs++
166 case restic.TreeBlob:

internal/options/options.go1

90:2modifies-value-receiverassignment modifies value receiver h

internal/options/options.go:90:2

89func (h helpList) Swap(i, j int) {
90 h[i], h[j] = h[j], h[i]
91}

cmd/restic/cmd_find.go1

451:30nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:451:30

450 case restic.DataBlob:
451 f.blobIDs[h.ID.String()] = struct{}{}
452 case restic.TreeBlob:

internal/backend/sftp/sftp.go1

219:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/backend/sftp/sftp.go:219:4

218 if fi, statErr := r.c.Lstat(dir); statErr == nil && fi.IsDir() {
219 return nil
220 }

internal/fs/vss_windows.go1

969:4no-else-after-returnremove else and unindent its body after the return

internal/fs/vss_windows.go:969:4

968 return vssSnapshot{}, err
969 } else if !isSupported {
970 iVssBackupComponents.Release()

internal/fs/fs_local_vss.go2

22:6no-initreplace init with explicit initialization

internal/fs/fs_local_vss.go:22:6

21
22func init() {
23 if runtime.GOOS == "windows" {
73:3no-naked-returnreturn values must be explicit

internal/fs/fs_local_vss.go:73:3

72 if list == "" {
73 return
74 }

cmd/restic/cmd_find.go1

446:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_find.go:446:5

445
446var errAllPacksFound = errors.New("all packs found")
447

cmd/restic/cmd_init.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_init.go:1:9

1package main
2

internal/data/tree_test.go1

77:33range-value-addresstaking the address of range value n can be misleading

internal/data/tree_test.go:77:33

76 for i, n := range testNodes {
77 nodeData, err := json.Marshal(&n)
78 rtest.OK(t, err)

internal/ui/progress/terminal.go1

31:32redefines-builtin-ididentifier max shadows a predeclared identifier

internal/ui/progress/terminal.go:31:32

30// newProgressMax returns a progress.Counter that prints to terminal if provided.
31func newProgressMax(show bool, max uint64, description string, term ui.Terminal) restic.Counter {
32 if !show {

cmd/restic/cmd_restore_integration_test.go1

318:35redundant-conversionconversion from int64 to the identical type is redundant

cmd/restic/cmd_restore_integration_test.go:318:35

317 testRunRestoreLatest(t, env.gopts, filepath.Join(env.base, "restore1"), []string{filepath.Dir(p1)}, nil)
318 rtest.OK(t, testFileSize(p1rAbs, int64(102)))
319 if _, err := os.Stat(p2rAbs); os.IsNotExist(err) {

internal/filter/filter_patterns_test.go1

25:2slice-preallocationpreallocate patterns with capacity len(range source) before appending once per iteration

internal/filter/filter_patterns_test.go:25:2

24 // Test all patterns defined in matchTests are valid
25 patterns := make([]string, 0)
26

cmd/restic/cmd_key_add.go1

45:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_key_add.go:45:1

44
45type KeyAddOptions struct {
46 NewPasswordFile string

internal/fs/node_unix_test.go1

37:18unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/node_unix_test.go:37:18

36
37 stat := fi.Sys().(*syscall.Stat_t)
38

internal/backend/azure/azure.go1

196:7unused-receiverreceiver be is unused

internal/backend/azure/azure.go:196:7

195// IsNotExist returns true if the error is caused by a not existing file.
196func (be *Backend) IsNotExist(err error) bool {
197 return bloberror.HasCode(err, bloberror.BlobNotFound)

cmd/restic/cmd_diff.go1

161:114use-anyuse any instead of interface{}

cmd/restic/cmd_diff.go:161:114

160// updateBlobs updates the blob counters in the stats struct.
161func updateBlobs(repo restic.Loader, blobs restic.AssociatedBlobSet, stats *DiffStat, printError func(string, ...interface{})) {
162 for h := range blobs.Keys() {

internal/archiver/exclude.go1

97:15use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/archiver/exclude.go:97:15

96 if colon == 0 {
97 return nil, fmt.Errorf("no name for exclusion tagfile provided")
98 }

internal/fs/ea_windows.go1

148:6var-namingidentifier should use MixedCaps rather than underscores

internal/fs/ea_windows.go:148:6

147 }
148 var _p1 uint32
149 if restartScan {

cmd/restic/cmd_backup_integration_test.go1

694:76add-constantstring literal "python" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:694:76

693
694 err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"python", "-c", "import sys; print('test'); sys.exit(1)"}, opts, env.gopts)
695 rtest.Assert(t, err != nil, "Expected error while backing up")

cmd/restic/cmd_copy.go1

120:6cognitive-complexityfunction has cognitive complexity 10; maximum is 7

cmd/restic/cmd_copy.go:120:6

119
120func runCopy(ctx context.Context, opts CopyOptions, gopts global.Options, args []string, term ui.Terminal) error {
121 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

internal/data/snapshot.go1

125:20confusing-namingname ID differs from id only by capitalization

internal/data/snapshot.go:125:20

124// ID returns the snapshot's ID.
125func (sn Snapshot) ID() *restic.ID {
126 return sn.id

cmd/restic/cmd_dump.go1

135:6cyclomatic-complexityfunction complexity is 11; maximum is 10

cmd/restic/cmd_dump.go:135:6

134
135func runDump(ctx context.Context, opts DumpOptions, gopts global.Options, args []string, term ui.Terminal) error {
136 if len(args) != 2 {

cmd/restic/cmd_find.go1

179:10discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:179:10

178 }
179 _, _ = s.stdout.Write([]byte(`{"matches":[`))
180 s.oldsn = s.newsn

internal/backend/b2/b2.go1

327:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/b2/b2.go:327:1

326
327// Close does nothing
328func (be *b2Backend) Close() error { return nil }

internal/backend/httpuseragent_roundtripper_test.go1

48:12error-stringserror string should not be capitalized or end with punctuation

internal/backend/httpuseragent_roundtripper_test.go:48:12

47 if resp.StatusCode != http.StatusOK {
48 t.Errorf("Expected status code: %d, got: %d", http.StatusOK, resp.StatusCode)
49 }

cmd/restic/cmd_ls.go1

586:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:586:2

585 SortModeSize
586 SortModeAtime
587 SortModeCtime

internal/global/global.go1

1:1file-length-limitfile has 627 lines; maximum is 500

internal/global/global.go:1:1

1package global
2

cmd/restic/format.go1

12:50flag-parameterboolean parameter human controls function flow

cmd/restic/format.go:12:50

11
12func formatNodeOutput(n lsNodeOutput, long bool, human bool) string {
13 if !long {

cmd/restic/cmd_dump.go1

1:1formatfile is not formatted

cmd/restic/cmd_dump.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_dump.go`

cmd/restic/cmd_restore.go1

99:6function-lengthfunction has 74 statements and 183 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_restore.go:99:6

98
99func runRestore(ctx context.Context, opts RestoreOptions, gopts global.Options,
100 term ui.Terminal, args []string) error {

internal/ui/restore/text.go1

53:2identical-switch-branchesswitch repeats a case body

internal/ui/restore/text.go:53:2

52 action = "restored"
53 case restorer.ActionFileRestored:
54 action = "restored"

internal/archiver/archiver_test.go1

477:2import-shadowingidentifier data shadows an imported package

internal/archiver/archiver_test.go:477:2

476
477 data := rtest.Random(23, 512*1024+887898)
478 testfile := filepath.Join(tempdir, "testfile")

cmd/restic/cmd_diff.go1

167:4modifies-parameterassignment modifies parameter stats

cmd/restic/cmd_diff.go:167:4

166 case restic.TreeBlob:
167 stats.TreeBlobs++
168 }

internal/options/options.go1

90:8modifies-value-receiverassignment modifies value receiver h

internal/options/options.go:90:8

89func (h helpList) Swap(i, j int) {
90 h[i], h[j] = h[j], h[i]
91}

cmd/restic/cmd_find.go1

453:30nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:453:30

452 case restic.TreeBlob:
453 f.treeIDs[h.ID.String()] = struct{}{}
454 default:

internal/checker/checker.go1

105:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/checker/checker.go:105:4

104 errs = append(errs, &SnapshotError{ID: id.String(), Message: err})
105 return nil
106 }

internal/fs/vss_windows.go1

989:5no-else-after-returnremove else and unindent its body after the return

internal/fs/vss_windows.go:989:5

988 return vssSnapshot{}, err
989 } else {
990 break

internal/migrations/upgrade_repo_v2.go1

11:6no-initreplace init with explicit initialization

internal/migrations/upgrade_repo_v2.go:11:6

10
11func init() {
12 register(&UpgradeRepoV2{})

internal/fs/fs_local_vss.go1

86:2no-naked-returnreturn values must be explicit

internal/fs/fs_local_vss.go:86:2

85
86 return
87}

cmd/restic/cmd_forget.go1

67:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_forget.go:67:5

66
67var ErrNegativePolicyCount = errors.New("negative values not allowed, use 'unlimited' instead")
68var ErrFailedToRemoveOneOrMoreSnapshots = errors.New("failed to remove one or more snapshots")

cmd/restic/cmd_key.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_key.go:1:9

1package main
2

internal/data/tree_test.go1

202:26range-value-addresstaking the address of range value i can be misleading

internal/data/tree_test.go:202:26

201 for i := range nodes {
202 rtest.OK(b, t.AddNode(&nodes[i]))
203 }

internal/ui/progress/terminal.go1

37:50redefines-builtin-ididentifier max shadows a predeclared identifier

internal/ui/progress/terminal.go:37:50

36
37 return NewCounter(interval, max, func(v uint64, max uint64, d time.Duration, final bool) {
38 var status string

cmd/restic/cmd_restore_integration_test.go1

325:35redundant-conversionconversion from int64 to the identical type is redundant

cmd/restic/cmd_restore_integration_test.go:325:35

324 testRunRestoreLatest(t, env.gopts, filepath.Join(env.base, "restore2"), []string{filepath.Dir(p2)}, nil)
325 rtest.OK(t, testFileSize(p2rAbs, int64(103)))
326 if _, err := os.Stat(p1rAbs); os.IsNotExist(err) {

internal/filter/filter_patterns_test.go1

40:2slice-preallocationpreallocate childPatterns with capacity len(range source) before appending once per iteration

internal/filter/filter_patterns_test.go:40:2

39 // Test all patterns defined in childMatchTests are valid
40 childPatterns := make([]string, 0)
41

cmd/restic/cmd_key_integration_test.go1

214:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_key_integration_test.go:214:1

213
214type emptySaveBackend struct {
215 backend.Backend

internal/fs/node_unix_test.go1

81:18unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/node_unix_test.go:81:18

80func checkDevice(t testing.TB, fi fs.FileInfo, node *data.Node) {
81 stat := fi.Sys().(*syscall.Stat_t)
82 if node.Device != uint64(stat.Rdev) {

internal/backend/azure/azure.go1

222:7unused-receiverreceiver be is unused

internal/backend/azure/azure.go:222:7

221// Hasher may return a hash function for calculating a content hash for the backend
222func (be *Backend) Hasher() hash.Hash {
223 return md5.New()

cmd/restic/cmd_find.go1

139:16use-anyuse any instead of interface{}

cmd/restic/cmd_find.go:139:16

138 printer interface {
139 S(string, ...interface{})
140 P(string, ...interface{})

internal/backend/b2/b2.go1

34:19use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/b2/b2.go:34:19

33
34var errTooShort = fmt.Errorf("file is too short")
35

internal/fs/vss_windows.go1

27:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:27:2

26const (
27 S_OK HRESULT = 0x00000000
28 S_FALSE HRESULT = 0x00000001

cmd/restic/cmd_backup_integration_test.go1

694:86add-constantstring literal "-c" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:694:86

693
694 err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"python", "-c", "import sys; print('test'); sys.exit(1)"}, opts, env.gopts)
695 rtest.Assert(t, err != nil, "Expected error while backing up")

cmd/restic/cmd_copy.go1

208:6cognitive-complexityfunction has cognitive complexity 13; maximum is 7

cmd/restic/cmd_copy.go:208:6

207// data equivalent to at least 10 packfiles was written.
208func copyTreeBatched(ctx context.Context, srcRepo *repository.Repository, dstRepo restic.Repository,
209 selectedSnapshots iter.Seq2[*data.Snapshot, error], printer restic.Printer) error {

internal/data/snapshot_find.go1

112:26confusing-namingname FindLatest differs from findLatest only by capitalization

internal/data/snapshot_find.go:112:26

111// or a snapshot specified by `snapshotID`.
112func (f *SnapshotFilter) FindLatest(ctx context.Context, be restic.Lister, loader restic.LoaderUnpacked, snapshotID string) (*Snapshot, string, error) {
113 id, subfolder := splitSnapshotID(snapshotID)

cmd/restic/cmd_find.go2

596:6cyclomatic-complexityfunction complexity is 36; maximum is 10

cmd/restic/cmd_find.go:596:6

595
596func runFind(ctx context.Context, opts FindOptions, gopts global.Options, args []string, term ui.Terminal) error {
597 if len(args) == 0 {
184:10discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:184:10

183 if s.hits > 0 {
184 _, _ = s.stdout.Write([]byte(","))
185 }

internal/backend/b2/b2.go1

330:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/b2/b2.go:330:1

329
330// Warmup not implemented
331func (be *b2Backend) Warmup(_ context.Context, _ []backend.Handle) ([]backend.Handle, error) {

internal/backend/limiter/limiter_backend_test.go1

77:28error-stringserror string should not be capitalized or end with punctuation

internal/backend/limiter/limiter_backend_test.go:77:28

76 if length != 0 || offset != 0 {
77 return nil, fmt.Errorf("Not supported")
78 }

cmd/restic/cmd_ls.go1

587:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:587:2

586 SortModeAtime
587 SortModeCtime
588 SortModeMtime

internal/repository/checker.go1

1:1file-length-limitfile has 533 lines; maximum is 500

internal/repository/checker.go:1:1

1package repository
2

cmd/restic/integration_helpers_test.go1

312:79flag-parameterboolean parameter removeTreePacks controls function flow

cmd/restic/integration_helpers_test.go:312:79

311
312func removePacksExcept(gopts global.Options, t testing.TB, keep restic.IDSet, removeTreePacks bool) {
313 be := captureBackend(&gopts)

cmd/restic/cmd_dump_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_dump_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_dump_test.go`

cmd/restic/cmd_rewrite.go1

193:6function-lengthfunction has 54 statements and 96 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_rewrite.go:193:6

192
193func filterAndReplaceSnapshot(ctx context.Context, repo restic.Repository, sn *data.Snapshot,
194 filter rewriteFilterFunc, dryRun bool, forget bool, newMetadata *snapshotMetadata, addTag string, printer restic.Printer,

internal/ui/restore/text.go1

55:2identical-switch-branchesswitch repeats a case body

internal/ui/restore/text.go:55:2

54 action = "restored"
55 case restorer.ActionOtherRestored:
56 action = "restored"

internal/archiver/archiver_test.go1

494:42import-shadowingidentifier data shadows an imported package

internal/archiver/archiver_test.go:494:42

493
494func save(t testing.TB, filename string, data []byte) {
495 f, err := os.Create(filename)

cmd/restic/cmd_diff.go1

176:3modifies-parameterassignment modifies parameter stats

cmd/restic/cmd_diff.go:176:3

175
176 stats.Bytes += uint64(size)
177 }

internal/restic/blob.go1

113:2modifies-value-receiverassignment modifies value receiver h

internal/restic/blob.go:113:2

112func (h BlobHandles) Swap(i, j int) {
113 h[i], h[j] = h[j], h[i]
114}

cmd/restic/cmd_find.go1

462:29nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:462:29

461func (f *Finder) packsToBlobs(ctx context.Context, packs []string) error {
462 packIDs := make(map[string]struct{})
463 for _, p := range packs {

internal/checker/checker.go1

130:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/checker/checker.go:130:4

129 errs = append(errs, &SnapshotError{ID: id, Message: err})
130 return nil
131 } else if sn != nil {

internal/fuse/snapshots_dir.go1

67:4no-else-after-returnremove else and unindent its body after the return

internal/fuse/snapshots_dir.go:67:4

66 return nil, unwrapCtxCanceled(err)
67 } else if meta == nil {
68 return nil, syscall.ENOENT

internal/repository/lock_file_unix.go1

17:6no-initreplace init with explicit initialization

internal/repository/lock_file_unix.go:17:6

16
17func init() {
18 ignoreSIGHUP.Do(func() {

internal/repository/crypto/crypto.go1

233:2no-naked-returnreturn values must be explicit

internal/repository/crypto/crypto.go:233:2

232 tail = head[len(in):]
233 return
234}

cmd/restic/cmd_forget.go1

68:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_forget.go:68:5

67var ErrNegativePolicyCount = errors.New("negative values not allowed, use 'unlimited' instead")
68var ErrFailedToRemoveOneOrMoreSnapshots = errors.New("failed to remove one or more snapshots")
69

cmd/restic/cmd_key_add.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_key_add.go:1:9

1package main
2

internal/fs/node_test.go1

220:30range-value-addresstaking the address of range value test can be misleading

internal/fs/node_test.go:220:30

219 }
220 rtest.OK(t, NodeCreateAt(&test, nodePath))
221 // Restore metadata, restoring all xattrs

internal/ui/table/table.go1

70:29redefines-builtin-ididentifier print shadows a predeclared identifier

internal/ui/table/table.go:70:29

69
70func printLine(w io.Writer, print func(io.Writer, string) error, sep string, data []string, widths []int) error {
71 var fields [][]string

cmd/restic/cmd_stats.go1

256:25redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_stats.go:256:25

255 }
256 progress.Update(1, 0, uint64(node.Size))
257 if opts.countMode == countModeUniqueFilesByContents || opts.countMode == countModeBlobsPerFile {

internal/fs/node_xattr_all_test.go1

111:3slice-preallocationpreallocate out with capacity len(range source) before appending once per iteration

internal/fs/node_xattr_all_test.go:111:3

110 if runtime.GOOS == "windows" {
111 out := []string{}
112 for _, pattern := range patterns {

cmd/restic/cmd_key_passwd.go1

46:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_key_passwd.go:46:1

45
46type KeyPasswdOptions struct {
47 KeyAddOptions

internal/fs/node_windows.go1

369:19unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/node_windows.go:369:19

368
369 winFI := stat.sys.(*syscall.Win32FileAttributeData)
370

internal/backend/azure/azure.go1

462:7unused-receiverreceiver be is unused

internal/backend/azure/azure.go:462:7

461// Close does nothing
462func (be *Backend) Close() error { return nil }
463

cmd/restic/cmd_find.go1

140:16use-anyuse any instead of interface{}

cmd/restic/cmd_find.go:140:16

139 S(string, ...interface{})
140 P(string, ...interface{})
141 E(string, ...interface{})

internal/backend/backend.go1

10:23use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/backend.go:10:23

9
10var ErrNoRepository = fmt.Errorf("repository does not exist")
11

internal/fs/vss_windows.go1

28:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:28:2

27 S_OK HRESULT = 0x00000000
28 S_FALSE HRESULT = 0x00000001
29 E_ACCESSDENIED HRESULT = 0x80070005

cmd/restic/cmd_backup_integration_test.go1

709:18add-constantstring literal "stdin" appears more than twice; define a constant

cmd/restic/cmd_backup_integration_test.go:709:18

708 StdinCommand: true,
709 StdinFilename: "stdin",
710 }

cmd/restic/cmd_copy_integration_test.go1

33:6cognitive-complexityfunction has cognitive complexity 8; maximum is 7

cmd/restic/cmd_copy_integration_test.go:33:6

32
33func TestCopy(t *testing.T) {
34 env, cleanup := withTestEnvironment(t)

internal/data/snapshot_test.go1

34:6confusing-namingname testLoadJSONUnpacked differs from TestLoadJSONUnpacked only by capitalization

internal/data/snapshot_test.go:34:6

33
34func testLoadJSONUnpacked(t *testing.T, version uint) {
35 repo, _, _ := repository.TestRepositoryWithVersion(t, version)

cmd/restic/cmd_forget.go1

162:6cyclomatic-complexityfunction complexity is 12; maximum is 10

cmd/restic/cmd_forget.go:162:6

161
162func verifyForgetOptions(opts *ForgetOptions) error {
163 if opts.Last < -1 || opts.Hourly < -1 || opts.Daily < -1 || opts.Weekly < -1 ||

cmd/restic/cmd_find.go1

186:9discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:186:9

185 }
186 _, _ = s.stdout.Write(b)
187 s.hits++

internal/backend/backend.go1

140:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/backend.go:140:1

139
140// ApplyEnvironmenter fills in a backend configuration from the environment
141type ApplyEnvironmenter interface {

internal/backend/local/layout_test.go1

55:14error-stringserror string should not be capitalized or end with punctuation

internal/backend/local/layout_test.go:55:14

54 if len(packs) == 0 {
55 t.Errorf("List() returned zero pack files")
56 }

cmd/restic/cmd_ls.go1

588:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:588:2

587 SortModeCtime
588 SortModeMtime
589 SortModeExt

internal/repository/index/index.go1

1:1file-length-limitfile has 590 lines; maximum is 500

internal/repository/index/index.go:1:1

1package index
2

cmd/restic/lock.go1

11:72flag-parameterboolean parameter dryRun controls function flow

cmd/restic/lock.go:11:72

10
11func internalOpenWithLocked(ctx context.Context, gopts global.Options, dryRun bool, exclusive bool, printer restic.Printer) (context.Context, *repository.Repository, func(), error) {
12 repo, err := global.OpenRepository(ctx, gopts, printer)

cmd/restic/cmd_features.go1

1:1formatfile is not formatted

cmd/restic/cmd_features.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_features.go`

cmd/restic/cmd_snapshots.go1

203:6function-lengthfunction has 54 statements and 122 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_snapshots.go:203:6

202// PrintSnapshots prints a text table of the snapshots in list to stdout.
203func PrintSnapshots(stdout io.Writer, list data.Snapshots, reasons []data.KeepReason, compact bool) error {
204 // keep the reasons a snasphot is being kept in a map, so that it doesn't

internal/archiver/archiver_test.go1

688:4import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver_test.go:688:4

687
688 fs := fs.NewLocal()
689 fiBefore, err := fs.Lstat(filename)

cmd/restic/cmd_diff.go1

293:5modifies-parameterassignment modifies parameter stats

cmd/restic/cmd_diff.go:293:5

292 mod += "M"
293 stats.ChangedFiles++
294

internal/restic/blob.go1

113:8modifies-value-receiverassignment modifies value receiver h

internal/restic/blob.go:113:8

112func (h BlobHandles) Swap(i, j int) {
113 h[i], h[j] = h[j], h[i]
114}

cmd/restic/cmd_find.go1

464:16nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:464:16

463 for _, p := range packs {
464 packIDs[p] = struct{}{}
465 }

internal/data/snapshot.go1

132:3nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/data/snapshot.go:132:3

131 if err != nil {
132 return nil
133 }

internal/fuse/snapshots_dir.go1

110:4no-else-after-returnremove else and unindent its body after the return

internal/fuse/snapshots_dir.go:110:4

109 return nil, unwrapCtxCanceled(err)
110 } else if meta == nil {
111 return nil, syscall.ENOENT

internal/repository/crypto/crypto_int_test.go1

86:2no-naked-returnreturn values must be explicit

internal/repository/crypto/crypto_int_test.go:86:2

85 copy(dst[:], data)
86 return
87}

cmd/restic/cmd_key_add.go1

96:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_key_add.go:96:5

95// testKeyNewPassword is used to set a new password during integration testing.
96var testKeyNewPassword string
97

cmd/restic/cmd_key_list.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_key_list.go:1:9

1package main
2

internal/fs/node_test.go1

222:37range-value-addresstaking the address of range value test can be misleading

internal/fs/node_test.go:222:37

221 // Restore metadata, restoring all xattrs
222 rtest.OK(t, NodeRestoreMetadata(&test, nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) },
223 func(_ string) bool { return true }, ownershipByName))

internal/ui/termstatus/stdio_wrapper.go1

12:2redefines-builtin-ididentifier print shadows a predeclared identifier

internal/ui/termstatus/stdio_wrapper.go:12:2

11 buf bytes.Buffer
12 print func(string)
13}

cmd/restic/cmd_stats.go1

445:16redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_stats.go:445:16

444
445 lowerBound := uint64(1)
446 growthFactor := uint64(10)

internal/repository/pack/pack_test.go1

46:2slice-preallocationpreallocate bufs with capacity len(range source) before appending once per iteration

internal/repository/pack/pack_test.go:46:2

45func createBuffers(t testing.TB, lengths []int) []Buf {
46 bufs := []Buf{}
47 for _, l := range lengths {

cmd/restic/cmd_ls.go1

75:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_ls.go:75:1

74// LsOptions collects all options for the ls command.
75type LsOptions struct {
76 ListLong bool

internal/fs/node_windows.go1

394:27unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/node_windows.go:394:27

393 // Cache hit, immediately return the cached value
394 return eaSupportedValue.(bool), nil
395 }

internal/backend/azure/azure.go1

465:7unused-receiverreceiver be is unused

internal/backend/azure/azure.go:465:7

464// Warmup not implemented
465func (be *Backend) Warmup(_ context.Context, _ []backend.Handle) ([]backend.Handle, error) {
466 return []backend.Handle{}, nil

cmd/restic/cmd_find.go1

141:16use-anyuse any instead of interface{}

cmd/restic/cmd_find.go:141:16

140 P(string, ...interface{})
141 E(string, ...interface{})
142 }

internal/backend/limiter/limiter_backend_test.go1

35:11use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/limiter/limiter_backend_test.go:35:11

34 if !bytes.Equal(data, buf.Bytes()) {
35 return fmt.Errorf("data mismatch")
36 }

internal/fs/vss_windows.go1

29:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:29:2

28 S_FALSE HRESULT = 0x00000001
29 E_ACCESSDENIED HRESULT = 0x80070005
30 E_OUTOFMEMORY HRESULT = 0x8007000E

cmd/restic/cmd_backup_test.go1

76:60add-constantstring literal "cmdline arg" appears more than twice; define a constant

cmd/restic/cmd_backup_test.go:76:60

75
76 _, err = collectTargets(opts, []string{filepath.Join(dir, "cmdline arg"), filepath.Join(dir, "non-existing-file")}, t.Logf, nil)
77 rtest.Assert(t, err == ErrInvalidSourceData, "expected error when not all targets exist")

cmd/restic/cmd_debug.go1

161:6cognitive-complexityfunction has cognitive complexity 17; maximum is 7

cmd/restic/cmd_debug.go:161:6

160
161func runDebugExamine(ctx context.Context, gopts global.Options, opts DebugExamineOptions, args []string, term ui.Terminal) error {
162 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

internal/data/tree_test.go1

213:6confusing-namingname testLoadTree differs from TestLoadTree only by capitalization

internal/data/tree_test.go:213:6

212
213func testLoadTree(t *testing.T, version uint) {
214 if rtest.BenchArchiveDirectory == "" {

cmd/restic/cmd_forget.go1

178:6cyclomatic-complexityfunction complexity is 42; maximum is 10

cmd/restic/cmd_forget.go:178:6

177
178func runForget(ctx context.Context, opts ForgetOptions, pruneOptions PruneOptions, gopts global.Options, term ui.Terminal, args []string) error {
179 err := verifyForgetOptions(&opts)

cmd/restic/cmd_find.go1

231:10discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:231:10

230 if !s.inuse {
231 _, _ = s.stdout.Write([]byte("["))
232 s.inuse = true

internal/backend/cache/dir.go1

9:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/cache/dir.go:9:1

8
9// EnvDir return $RESTIC_CACHE_DIR env
10func EnvDir() string {

internal/backend/local/layout_test.go1

73:14error-stringserror string should not be capitalized or end with punctuation

internal/backend/local/layout_test.go:73:14

72 if err = be.Close(); err != nil {
73 t.Errorf("Close() returned error %v", err)
74 }

cmd/restic/cmd_ls.go1

589:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:589:2

588 SortModeMtime
589 SortModeExt
590 SortModeInvalid

internal/repository/index/index_test.go1

1:1file-length-limitfile has 632 lines; maximum is 500

internal/repository/index/index_test.go:1:1

1package index_test
2

internal/archiver/archiver.go1

463:93flag-parameterboolean parameter explicit controls function flow

internal/archiver/archiver.go:463:93

462// set); Excludes (`SelectByName` and `Select`) are skipped for that path only.
463func (arch *Archiver) save(ctx context.Context, snPath, target string, previous *data.Node, explicit bool) (fn futureNode, excluded bool, err error) {
464 start := time.Now()

cmd/restic/cmd_find.go1

1:1formatfile is not formatted

cmd/restic/cmd_find.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_find.go`

cmd/restic/cmd_stats.go1

98:6function-lengthfunction has 70 statements and 124 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_stats.go:98:6

97
98func runStats(ctx context.Context, opts StatsOptions, gopts global.Options, args []string, term ui.Terminal) error {
99 err := verifyStatsInput(opts)

internal/archiver/archiver_test.go1

1668:54import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver_test.go:1668:54

1667 },
1668 selFn: func(item string, fi *fs.ExtendedFileInfo, fs fs.FS) bool {
1669 return fs.Base(item) != "subdir"

cmd/restic/cmd_diff.go1

326:5modifies-parameterassignment modifies parameter prefix

cmd/restic/cmd_diff.go:326:5

325 if node1.Type == data.NodeTypeDir {
326 prefix += "/"
327 }

internal/restic/blob_set.go1

30:2modifies-value-receiverassignment modifies value receiver s

internal/restic/blob_set.go:30:2

29func (s BlobSet) Insert(h BlobHandle) {
30 s[h] = struct{}{}
31}

cmd/restic/cmd_find.go1

467:31nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:467:31

466 if f.blobIDs == nil {
467 f.blobIDs = make(map[string]struct{})
468 }

internal/fs/node.go1

305:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/fs/node.go:305:4

304 path, err)
305 return nil
306 }

internal/fuse/snapshots_dir.go1

123:5no-else-after-returnremove else and unindent its body after the return

internal/fuse/snapshots_dir.go:123:5

122 return newSnapshotLink(d.root, forget, inode, entry.linkTarget, entry.snapshot)
123 } else if entry.snapshot != nil {
124 return newDirFromSnapshot(d.root, forget, inode, entry.snapshot)

internal/repository/crypto/crypto_int_test.go1

95:2no-naked-returnreturn values must be explicit

internal/repository/crypto/crypto_int_test.go:95:2

94 copy(dst[:], data)
95 return
96}

cmd/restic/cmd_ls_test.go1

19:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_ls_test.go:19:5

18
19var lsTestNodes = []lsTestNode{
20 // Mode is omitted when zero.

cmd/restic/cmd_key_passwd.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_key_passwd.go:1:9

1package main
2

internal/fs/node_windows_test.go1

358:51range-value-addresstaking the address of range value testNode can be misleading

internal/fs/node_windows_test.go:358:51

357 for _, testNode := range expectedNodes {
358 testPath, node := restoreAndGetNode(t, tempDir, &testNode, warningExpected)
359 rawMessage := node.GenericAttributes[genericAttr]

internal/ui/termstatus/stdio_wrapper.go1

17:20redefines-builtin-ididentifier print shadows a predeclared identifier

internal/ui/termstatus/stdio_wrapper.go:17:20

16
17func newLineWriter(print func(string)) *lineWriter {
18 return &lineWriter{print: print}

cmd/restic/cmd_stats.go1

446:18redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_stats.go:446:18

445 lowerBound := uint64(1)
446 growthFactor := uint64(10)
447

internal/restorer/filerestorer_test.go1

158:6slice-preallocationpreallocate files with capacity len(range source) before appending once per iteration

internal/restorer/filerestorer_test.go:158:6

157
158 var files []*fileInfo
159 for _, file := range content {

cmd/restic/cmd_ls_test.go1

19:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_ls_test.go:19:1

18
19var lsTestNodes = []lsTestNode{
20 // Mode is omitted when zero.

internal/fs/node_windows.go1

419:27unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/node_windows.go:419:27

418 // Cache hit, immediately return the cached value
419 return eaSupportedValue.(bool), nil
420 }

internal/backend/azure/azure.go1

468:7unused-receiverreceiver be is unused

internal/backend/azure/azure.go:468:7

467}
468func (be *Backend) WarmupWait(_ context.Context, _ []backend.Handle) error { return nil }
469

cmd/restic/cmd_find.go1

284:16use-anyuse any instead of interface{}

cmd/restic/cmd_find.go:284:16

283 printer interface {
284 S(string, ...interface{})
285 P(string, ...interface{})

internal/backend/limiter/limiter_backend_test.go1

77:17use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/limiter/limiter_backend_test.go:77:17

76 if length != 0 || offset != 0 {
77 return nil, fmt.Errorf("Not supported")
78 }

internal/fs/vss_windows.go1

30:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:30:2

29 E_ACCESSDENIED HRESULT = 0x80070005
30 E_OUTOFMEMORY HRESULT = 0x8007000E
31 E_INVALIDARG HRESULT = 0x80070057

cmd/restic/cmd_cat.go1

94:7add-constantstring literal "config" appears more than twice; define a constant

cmd/restic/cmd_cat.go:94:7

93 switch tpe {
94 case "config":
95 buf, err := json.MarshalIndent(repo.Config(), "", " ")

cmd/restic/cmd_diff.go1

180:20cognitive-complexityfunction has cognitive complexity 13; maximum is 7

cmd/restic/cmd_diff.go:180:20

179
180func (c *Comparer) printDir(ctx context.Context, mode string, stats *DiffStat, blobs restic.AssociatedBlobSet, prefix string, id restic.ID) error {
181 debug.Log("print %v tree %v", mode, id)

internal/data/tree_test.go1

302:6confusing-namingname benchmarkLoadTree differs from BenchmarkLoadTree only by capitalization

internal/data/tree_test.go:302:6

301
302func benchmarkLoadTree(t *testing.B, version uint) {
303 if rtest.BenchArchiveDirectory == "" {

cmd/restic/cmd_generate.go1

115:6cyclomatic-complexityfunction complexity is 14; maximum is 10

cmd/restic/cmd_generate.go:115:6

114
115func runGenerate(opts generateOptions, gopts global.Options, args []string, term ui.Terminal) error {
116 if len(args) > 0 {

cmd/restic/cmd_find.go1

235:10discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:235:10

234 if s.hits > 0 {
235 _, _ = s.stdout.Write([]byte(","))
236 }

internal/backend/gs/gs.go1

185:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/gs/gs.go:185:1

184
185// Hasher may return a hash function for calculating a content hash for the backend
186func (be *gs) Hasher() hash.Hash {

internal/backend/sftp/layout_test.go1

59:14error-stringserror string should not be capitalized or end with punctuation

internal/backend/sftp/layout_test.go:59:14

58 if len(packs) == 0 {
59 t.Errorf("List() returned zero pack files")
60 }

cmd/restic/cmd_ls.go1

590:2exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/cmd_ls.go:590:2

589 SortModeExt
590 SortModeInvalid
591)

internal/repository/index/master_index.go1

1:1file-length-limitfile has 723 lines; maximum is 500

internal/repository/index/master_index.go:1:1

1package index
2

internal/archiver/archiver_test.go1

429:38flag-parameterboolean parameter exists controls function flow

internal/archiver/archiver_test.go:429:38

428
429func (repo *blobCountingSaver) count(exists bool, h restic.BlobHandle) {
430 if exists {

cmd/restic/cmd_find_integration_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_find_integration_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_find_integration_test.go`

cmd/restic/cmd_tag_integration_test.go1

18:6function-lengthfunction has 52 statements and 80 lines; maximum is 50 statements or 75 lines

cmd/restic/cmd_tag_integration_test.go:18:6

17
18func TestTag(t *testing.T) {
19 env, cleanup := withTestEnvironment(t)

internal/archiver/archiver_test.go1

1677:54import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver_test.go:1677:54

1676 },
1677 selFn: func(item string, fi *fs.ExtendedFileInfo, fs fs.FS) bool {
1678 return fs.IsAbs(item)

cmd/restic/cmd_diff.go1

340:5modifies-parameterassignment modifies parameter prefix

cmd/restic/cmd_diff.go:340:5

339 if node2.Type == data.NodeTypeDir {
340 prefix += "/"
341 }

internal/restic/ids.go1

20:2modifies-value-receiverassignment modifies value receiver ids

internal/restic/ids.go:20:2

19func (ids IDs) Swap(i, j int) {
20 ids[i], ids[j] = ids[j], ids[i]
21}

cmd/restic/cmd_find.go1

470:31nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:470:31

469 if f.treeIDs == nil {
470 f.treeIDs = make(map[string]struct{})
471 }

internal/fs/node_xattr.go1

103:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/fs/node_xattr.go:103:4

102 if ignoreListError && isListxattrPermissionError(err) {
103 return nil
104 }

internal/repository/lock_file.go1

333:4no-else-after-returnremove else and unindent its body after the return

internal/repository/lock_file.go:333:4

332 return err
333 } else if !exists {
334 return errRemovedLock

internal/repository/index/indexmap.go1

289:2no-naked-returnreturn values must be explicit

internal/repository/index/indexmap.go:289:2

288 idx = pos >> h.maskShift
289 return
290}

cmd/restic/cmd_prune_integration_test.go1

124:5no-package-varpackage variables introduce mutable global state

cmd/restic/cmd_prune_integration_test.go:124:5

123
124var pruneDefaultOptions = PruneOptions{MaxUnused: "5%"}
125

cmd/restic/cmd_key_remove.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_key_remove.go:1:9

1package main
2

internal/fs/node_windows_test.go1

433:51range-value-addresstaking the address of range value testNode can be misleading

internal/fs/node_windows_test.go:433:51

432 for _, testNode := range expectedNodes {
433 testPath, node := restoreAndGetNode(t, tempDir, &testNode, true)
434 _, ua, err := genericAttributesToWindowsAttrs(node.GenericAttributes)

cmd/restic/cmd_stats_test.go1

27:11redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/cmd_stats_test.go:27:11

26 h := newSizeHistogram(42)
27 for i := uint64(0); i < 45; i++ {
28 h.Add(i)

internal/restorer/filerestorer_test.go1

160:3slice-preallocationpreallocate content with capacity len(range source) before appending once per iteration

internal/restorer/filerestorer_test.go:160:3

159 for _, file := range content {
160 content := restic.IDs{}
161 for _, blob := range file.blobs {

cmd/restic/cmd_migrate.go1

48:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_migrate.go:48:1

47// MigrateOptions bundles all options for the 'check' command.
48type MigrateOptions struct {
49 Force bool

internal/fs/node_windows_test.go1

252:18unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/node_windows_test.go:252:18

251 test.OK(t, errors.Wrapf(err, "Could not Lstat for path: %s", path))
252 attr := fi.Sys().(*syscall.Win32FileAttributeData)
253 creationTimeAttribute := attr.CreationTime

internal/backend/b2/b2.go1

157:7unused-receiverreceiver be is unused

internal/backend/b2/b2.go:157:7

156// Hasher may return a hash function for calculating a content hash for the backend
157func (be *b2Backend) Hasher() hash.Hash {
158 return nil

cmd/restic/cmd_find.go1

285:16use-anyuse any instead of interface{}

cmd/restic/cmd_find.go:285:16

284 S(string, ...interface{})
285 P(string, ...interface{})
286 E(string, ...interface{})

internal/backend/limiter/limiter_backend_test.go1

99:12use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/limiter/limiter_backend_test.go:99:12

98 if !bytes.Equal(data, dataRead.Bytes()) {
99 return fmt.Errorf("read broken data")
100 }

internal/fs/vss_windows.go1

31:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:31:2

30 E_OUTOFMEMORY HRESULT = 0x8007000E
31 E_INVALIDARG HRESULT = 0x80070057
32 VSS_E_BAD_STATE HRESULT = 0x80042301

cmd/restic/cmd_cat.go1

129:44add-constantstring literal " " appears more than twice; define a constant

cmd/restic/cmd_cat.go:129:44

128
129 buf, err := json.MarshalIndent(&key, "", " ")
130 if err != nil {

cmd/restic/cmd_diff.go1

214:20cognitive-complexityfunction has cognitive complexity 11; maximum is 7

cmd/restic/cmd_diff.go:214:20

213
214func (c *Comparer) collectDir(ctx context.Context, blobs restic.AssociatedBlobSet, id restic.ID) error {
215 debug.Log("print tree %v", id)

internal/dump/common.go1

115:18confusing-namingname writeNode differs from WriteNode only by capitalization

internal/dump/common.go:115:18

114
115func (d *Dumper) writeNode(ctx context.Context, w io.Writer, node *data.Node) error {
116 wg, ctx := errgroup.WithContext(ctx)

cmd/restic/cmd_list.go1

50:6cyclomatic-complexityfunction complexity is 17; maximum is 10

cmd/restic/cmd_list.go:50:6

49
50func runList(ctx context.Context, gopts global.Options, args []string, term ui.Terminal, listAllowedArgsUseString string) error {
51 printer := progress.NewTerminalPrinter(false, gopts.Verbosity, term)

cmd/restic/cmd_find.go1

237:9discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:237:9

236 }
237 _, _ = s.stdout.Write(b)
238 s.hits++

internal/backend/gs/gs.go1

349:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/gs/gs.go:349:1

348
349// Warmup not implemented
350func (be *gs) Warmup(_ context.Context, _ []backend.Handle) ([]backend.Handle, error) {

internal/backend/sftp/layout_test.go1

77:14error-stringserror string should not be capitalized or end with punctuation

internal/backend/sftp/layout_test.go:77:14

76 if err = be.Close(); err != nil {
77 t.Errorf("Close() returned error %v", err)
78 }

cmd/restic/main.go1

31:5exported-declaration-commentexported declaration should have a comment beginning with its name

cmd/restic/main.go:31:5

30
31var ErrOK = errors.New("ok")
32

internal/repository/index/master_index_test.go1

1:1file-length-limitfile has 758 lines; maximum is 500

internal/repository/index/master_index_test.go:1:1

1package index_test
2

internal/archiver/scanner.go1

100:77flag-parameterboolean parameter explicit controls function flow

internal/archiver/scanner.go:100:77

99// explicit is true when this path was an explicit backup target (same meaning as tree.Explicit on a leaf).
100func (s *Scanner) scan(ctx context.Context, stats ScanStats, target string, explicit bool) (ScanStats, error) {
101 if ctx.Err() != nil {

cmd/restic/cmd_forget.go1

1:1formatfile is not formatted

cmd/restic/cmd_forget.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_forget.go`

cmd/restic/main.go1

36:6function-lengthfunction has 10 statements and 78 lines; maximum is 50 statements or 75 lines

cmd/restic/main.go:36:6

35
36func newRootCommand(globalOptions *global.Options) *cobra.Command {
37 cmd := &cobra.Command{

internal/archiver/archiver_test.go1

1838:2import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver_test.go:1838:2

1837
1838 fs *MockFS
1839}

cmd/restic/cmd_find.go1

544:5modifies-parameterassignment modifies parameter packIDs

cmd/restic/cmd_find.go:544:5

543 delete(packIDs, packID.Str())
544 packIDs[idStr] = struct{}{}
545 matchingID = true

internal/restic/ids.go1

20:10modifies-value-receiverassignment modifies value receiver ids

internal/restic/ids.go:20:10

19func (ids IDs) Swap(i, j int) {
20 ids[i], ids[j] = ids[j], ids[i]
21}

cmd/restic/cmd_find.go1

482:21nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:482:21

481 delete(packIDs, id.Str())
482 packIDs[idStr] = struct{}{}
483 }

internal/repository/checker.go1

122:4nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/repository/checker.go:122:4

121 errs = append(errs, err)
122 return nil
123 }

internal/repository/repository.go1

136:4no-else-after-returnremove else and unindent its body after the return

internal/repository/repository.go:136:4

135 return nil, fmt.Errorf("pack size larger than limit of %v MiB", MaxPackSize/1024/1024)
136 } else if opts.PackSize < MinPackSize {
137 return nil, fmt.Errorf("pack size smaller than minimum of %v MiB", MinPackSize/1024/1024)

internal/restorer/restorer_test.go1

1439:5no-naked-returnreturn values must be explicit

internal/restorer/restorer_test.go:1439:5

1438 }
1439 return
1440 },

cmd/restic/main.go1

31:5no-package-varpackage variables introduce mutable global state

cmd/restic/main.go:31:5

30
31var ErrOK = errors.New("ok")
32

cmd/restic/cmd_list.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_list.go:1:9

1package main
2

internal/fs/node_windows_test.go1

469:51range-value-addresstaking the address of range value testNode can be misleading

internal/fs/node_windows_test.go:469:51

468 for _, testNode := range expectedNodes {
469 testPath, node := restoreAndGetNode(t, tempDir, &testNode, false)
470

cmd/restic/integration_helpers_unix_test.go1

67:13redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/integration_helpers_unix_test.go:67:13

66 }
67 linkTests[uint64(stat.Ino)] = append(linkTests[uint64(stat.Ino)], f.Name())
68 }

internal/ui/table/table.go1

71:6slice-preallocationpreallocate fields with capacity len(range source) before appending once per iteration

internal/ui/table/table.go:71:6

70func printLine(w io.Writer, print func(io.Writer, string) error, sep string, data []string, widths []int) error {
71 var fields [][]string
72

cmd/restic/cmd_mount.go1

101:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_mount.go:101:1

100// MountOptions collects all options for the mount command.
101type MountOptions struct {
102 OwnerRoot bool

internal/fs/stat_bsd.go1

13:15unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/stat_bsd.go:13:15

12func extendedStat(fi os.FileInfo) *ExtendedFileInfo {
13 s := fi.Sys().(*syscall.Stat_t)
14

internal/backend/b2/b2.go1

162:7unused-receiverreceiver be is unused

internal/backend/b2/b2.go:162:7

161// IsNotExist returns true if the error is caused by a non-existing file.
162func (be *b2Backend) IsNotExist(err error) bool {
163 // blazer/b2 does not export its error types and values,

cmd/restic/cmd_find.go1

286:16use-anyuse any instead of interface{}

cmd/restic/cmd_find.go:286:16

285 P(string, ...interface{})
286 E(string, ...interface{})
287 }

internal/backend/limiter/static_limiter_test.go1

134:15use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/limiter/static_limiter_test.go:134:15

133 rt = limiter.Transport(roundTripper(func(req *http.Request) (*http.Response, error) {
134 return nil, fmt.Errorf("error")
135 }))

internal/fs/vss_windows.go1

32:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:32:2

31 E_INVALIDARG HRESULT = 0x80070057
32 VSS_E_BAD_STATE HRESULT = 0x80042301
33 VSS_E_UNEXPECTED HRESULT = 0x80042302

cmd/restic/cmd_cat.go1

136:7add-constantstring literal "masterkey" appears more than twice; define a constant

cmd/restic/cmd_cat.go:136:7

135 return nil
136 case "masterkey":
137 buf, err := json.MarshalIndent(repo.Key(), "", " ")

cmd/restic/cmd_diff.go1

243:20cognitive-complexityfunction has cognitive complexity 61; maximum is 7

cmd/restic/cmd_diff.go:243:20

242
243func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, prefix string, id1, id2 restic.ID) error {
244 debug.Log("diffing %v to %v", id1, id2)

internal/filter/filter.go1

120:6confusing-namingname childMatch differs from ChildMatch only by capitalization

internal/filter/filter.go:120:6

119
120func childMatch(pattern Pattern, strs []string) (matched bool, err error) {
121 if pattern.parts[0].pattern != "/" {

cmd/restic/cmd_ls.go1

316:6cyclomatic-complexityfunction complexity is 22; maximum is 10

cmd/restic/cmd_ls.go:316:6

315
316func runLs(ctx context.Context, opts LsOptions, gopts global.Options, args []string, term ui.Terminal) error {
317 termPrinter := progress.NewTerminalPrinter(gopts.JSON, gopts.Verbosity, term)

cmd/restic/cmd_find.go1

267:11discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:267:11

266 if s.inuse {
267 _, _ = s.stdout.Write([]byte("]\n"))
268 } else {

internal/backend/layout/layout_rest.go1

51:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/layout/layout_rest.go:51:1

50
51// Paths returns all directory names
52func (l *RESTLayout) Paths() (dirs []string) {

internal/backend/sftp/sftp.go1

397:24error-stringserror string should not be capitalized or end with punctuation

internal/backend/sftp/sftp.go:397:24

396 _ = f.Close()
397 return errors.Errorf("Write %v: wrote %d bytes instead of the expected %d bytes", tmpFilename, wbytes, rd.Length())
398 }

helpers/build-release-binaries/main.go1

216:7exported-declaration-commentexported type should have a comment beginning with its name

helpers/build-release-binaries/main.go:216:7

215
216 type Job struct{ GOOS, GOARCH string }
217

internal/repository/prune.go1

1:1file-length-limitfile has 709 lines; maximum is 500

internal/repository/prune.go:1:1

1package repository
2

internal/archiver/tree.go1

34:41flag-parameterboolean parameter includeRelative controls function flow

internal/archiver/tree.go:34:41

33// tests for examples.
34func pathComponents(fs fs.FS, p string, includeRelative bool) (components []string, virtualPrefix bool) {
35 volume := fs.VolumeName(p)

cmd/restic/cmd_forget_integration_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_forget_integration_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_forget_integration_test.go`

cmd/restic/main.go1

161:6function-lengthfunction has 36 statements and 84 lines; maximum is 50 statements or 75 lines

cmd/restic/main.go:161:6

160
161func main() {
162 tweakGoGC()

internal/archiver/archiver_test.go1

2420:48import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver_test.go:2420:48

2419
2420func snapshot(t testing.TB, repo archiverRepo, fs fs.FS, parent *data.Snapshot, filename string) (*data.Snapshot, *data.Node) {
2421 ctx, cancel := context.WithCancel(context.Background())

cmd/restic/cmd_find_integration_test.go1

21:3modifies-parameterassignment modifies parameter gopts

cmd/restic/cmd_find_integration_test.go:21:3

20 buf, err := withCaptureStdout(t, gopts, func(ctx context.Context, gopts global.Options) error {
21 gopts.JSON = wantJSON
22

internal/restic/idset.go1

29:2modifies-value-receiverassignment modifies value receiver s

internal/restic/idset.go:29:2

28func (s IDSet) Insert(id ID) {
29 s[id] = struct{}{}
30}

cmd/restic/cmd_find.go1

527:76nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:527:76

526
527func (f *Finder) indexPacksToBlobs(ctx context.Context, packIDs map[string]struct{}) (map[string]struct{}, error) {
528 wctx, cancel := context.WithCancel(ctx)

internal/repository/index/master_index_test.go1

443:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/repository/index/master_index_test.go:443:5

442 if err != nil {
443 return nil
444 }

internal/restorer/restorer.go1

495:4no-else-after-returnremove else and unindent its body after the return

internal/restorer/restorer.go:495:4

494 return nil
495 } else if err != nil {
496 return err

internal/restorer/restorer_windows_test.go1

257:4no-naked-returnreturn values must be explicit

internal/restorer/restorer_windows_test.go:257:4

256 if attr == nil {
257 return
258 }

cmd/restic/main.go1

33:5no-package-varpackage variables introduce mutable global state

cmd/restic/main.go:33:5

32
33var cmdGroupDefault = "default"
34var cmdGroupAdvanced = "advanced"

cmd/restic/cmd_ls.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_ls.go:1:9

1package main
2

internal/fs/node_windows_test.go1

491:21range-value-addresstaking the address of range value ea can be misleading

internal/fs/node_windows_test.go:491:21

490 if strings.EqualFold(ea.Name, expectedExtAttr.Name) {
491 foundExtAttr = &ea
492 break

cmd/restic/integration_helpers_unix_test.go1

67:50redundant-conversionconversion from uint64 to the identical type is redundant

cmd/restic/integration_helpers_unix_test.go:67:50

66 }
67 linkTests[uint64(stat.Ino)] = append(linkTests[uint64(stat.Ino)], f.Name())
68 }

internal/walker/walker_test.go1

30:6slice-preallocationpreallocate names with capacity len(range source) before appending once per iteration

internal/walker/walker_test.go:30:6

29 tb := data.NewTreeJSONBuilder()
30 var names []string
31 for name := range tree {

cmd/restic/cmd_prune.go1

54:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_prune.go:54:1

53// PruneOptions collects all options for the cleanup command.
54type PruneOptions struct {
55 DryRun bool

internal/fs/stat_darwin.go1

16:15unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/stat_darwin.go:16:15

15func extendedStat(fi os.FileInfo) *ExtendedFileInfo {
16 s := fi.Sys().(*syscall.Stat_t)
17

internal/backend/b2/b2.go1

328:7unused-receiverreceiver be is unused

internal/backend/b2/b2.go:328:7

327// Close does nothing
328func (be *b2Backend) Close() error { return nil }
329

cmd/restic/cmd_ls.go1

293:25use-anyuse any instead of interface{}

cmd/restic/cmd_ls.go:293:25

292 termPrinter interface {
293 P(msg string, args ...interface{})
294 S(msg string, args ...interface{})

internal/backend/local/local.go1

34:19use-errors-newreplace fmt.Errorf with errors.New for a static message

internal/backend/local/local.go:34:19

33
34var errTooShort = fmt.Errorf("file is too short")
35

internal/fs/vss_windows.go1

33:2var-namingidentifier should use MixedCaps rather than underscores

internal/fs/vss_windows.go:33:2

32 VSS_E_BAD_STATE HRESULT = 0x80042301
33 VSS_E_UNEXPECTED HRESULT = 0x80042302
34 VSS_E_PROVIDER_ALREADY_REGISTERED HRESULT = 0x80042303

cmd/restic/cmd_check.go1

277:14add-constantstring literal "%s" appears more than twice; define a constant

cmd/restic/cmd_check.go:277:14

276 case *repository.ErrMixedPack:
277 printer.S("%s", hint.Error())
278 summary.HintPrune = true

cmd/restic/cmd_diff.go1

357:6cognitive-complexityfunction has cognitive complexity 17; maximum is 7

cmd/restic/cmd_diff.go:357:6

356
357func runDiff(ctx context.Context, opts DiffOptions, gopts global.Options, args []string, term ui.Terminal) error {
358 if len(args) != 2 {

internal/filter/filter.go1

152:6confusing-namingname match differs from Match only by capitalization

internal/filter/filter.go:152:6

151
152func match(pattern Pattern, strs []string) (matched bool, err error) {
153 if ok, pos := hasDoubleWildcard(pattern); ok {

cmd/restic/cmd_ls.go1

517:25cyclomatic-complexityfunction complexity is 12; maximum is 10

cmd/restic/cmd_ls.go:517:25

516}
517func (p *sortedPrinter) Close() error {
518 var comparator func(a, b lsNodeOutput) int

cmd/restic/cmd_find.go1

269:11discarded-error-resulterror result returned by s.stdout.Write is discarded

cmd/restic/cmd_find.go:269:11

268 } else {
269 _, _ = s.stdout.Write([]byte("[]\n"))
270 }

internal/backend/limiter/static_limiter.go1

24:1doc-comment-perioddocumentation comment should end with punctuation

internal/backend/limiter/static_limiter.go:24:1

23// NewStaticLimiter constructs a Limiter with a fixed (static) upload and
24// download rate cap
25func NewStaticLimiter(l Limits) Limiter {

internal/backend/test/tests.go1

210:13error-stringserror string should not be capitalized or end with punctuation

internal/backend/test/tests.go:210:13

209 t.Logf("Load, l %v, o %v, len(d) %v, getlen %v", l, o, len(d), getlen)
210 t.Errorf("Load(%d, %d) returned unexpected error: %+v", l, o, err)
211 continue

internal/archiver/archiver.go1

25:6exported-declaration-commentexported type should have a comment beginning with its name

internal/archiver/archiver.go:25:6

24// dirs). If false is returned, files are ignored and dirs are not even walked.
25type SelectByNameFunc func(item string) bool
26

internal/repository/repository.go1

1:1file-length-limitfile has 1356 lines; maximum is 500

internal/repository/repository.go:1:1

1package repository
2

internal/backend/local/local.go1

310:83flag-parameterboolean parameter ignoreNotADirectory controls function flow

internal/backend/local/local.go:310:83

309
310func visitFiles(ctx context.Context, dir string, fn func(backend.FileInfo) error, ignoreNotADirectory bool) error {
311 d, err := os.Open(dir)

cmd/restic/cmd_forget_test.go1

1:1formatfile is not formatted

cmd/restic/cmd_forget_test.go:1:1

1package main
2
  • Fix (safe): run `strider fmt cmd/restic/cmd_forget_test.go`

internal/archiver/archiver.go1

463:23function-lengthfunction has 76 statements and 168 lines; maximum is 50 statements or 75 lines

internal/archiver/archiver.go:463:23

462// set); Excludes (`SelectByName` and `Select`) are skipped for that path only.
463func (arch *Archiver) save(ctx context.Context, snPath, target string, previous *data.Node, explicit bool) (fn futureNode, excluded bool, err error) {
464 start := time.Now()

internal/archiver/archiver_test.go1

2522:2import-shadowingidentifier fs shadows an imported package

internal/archiver/archiver_test.go:2522:2

2521
2522 fs := &overrideFS{
2523 FS: localFS,

cmd/restic/cmd_forget.go1

159:2modifies-parameterassignment modifies parameter f

cmd/restic/cmd_forget.go:159:2

158
159 f.SortFlags = false
160}

cmd/restic/cmd_find.go1

527:98nested-structsmove nested anonymous struct types to named declarations

cmd/restic/cmd_find.go:527:98

526
527func (f *Finder) indexPacksToBlobs(ctx context.Context, packIDs map[string]struct{}) (map[string]struct{}, error) {
528 wctx, cancel := context.WithCancel(ctx)

internal/repository/key.go1

168:5nil-error-returnthis branch proves an error is non-nil but returns nil in an error result

internal/repository/key.go:168:5

167 if errors.Is(err, crypto.ErrUnauthenticated) {
168 return nil
169 }

internal/restorer/restorer.go1

567:4no-else-after-returnremove else and unindent its body after the return

internal/restorer/restorer.go:567:4

566 return buf, err
567 } else if !overwrite {
568 size := node.Size

cmd/restic/main.go1

34:5no-package-varpackage variables introduce mutable global state

cmd/restic/main.go:34:5

33var cmdGroupDefault = "default"
34var cmdGroupAdvanced = "advanced"
35

cmd/restic/cmd_migrate.go1

1:9package-commentspackage should have a documentation comment

cmd/restic/cmd_migrate.go:1:9

1package main
2

internal/fs/vss_windows.go1

1072:4range-value-addresstaking the address of range value info can be misleading

internal/fs/vss_windows.go:1072:4

1071 err := iVssBackupComponents.GetSnapshotProperties(info.snapshotSetID,
1072 &info.snapshotProperties)
1073 if err != nil {

cmd/restic/integration_test.go1

33:36redundant-conversionconversion from os.FileMode to the identical type is redundant

cmd/restic/integration_test.go:33:36

32 }
33 return os.Chmod(p, fi.Mode() & ^(os.FileMode(0222)))
34 })

cmd/restic/cmd_prune_integration_test.go1

124:1top-level-declaration-ordertop-level declarations should be ordered as const, var, type, then func

cmd/restic/cmd_prune_integration_test.go:124:1

123
124var pruneDefaultOptions = PruneOptions{MaxUnused: "5%"}
125

internal/fs/stat_unix.go1

13:15unchecked-type-assertionuse the checked two-result form of the type assertion

internal/fs/stat_unix.go:13:15

12func extendedStat(fi os.FileInfo) *ExtendedFileInfo {
13 s := fi.Sys().(*syscall.Stat_t)
14

internal/backend/b2/b2.go1

331:7unused-receiverreceiver be is unused

internal/backend/b2/b2.go:331:7

330// Warmup not implemented
331func (be *b2Backend) Warmup(_ context.Context, _ []backend.Handle) ([]backend.Handle, error) {
332 return []backend.Handle{}, nil