Files
dcf/pkg/dcf/helpers.go
clawbot ed95e66f7d bring the repo up to org standards
Adopt the standard tooling: a Makefile of thin shims over a full
scripts-to-rule-them-all `script/` set, the canonical `.golangci.yml`
vendored byte-identical from `sneak/prompts`, docker-only linting via
`Dockerfile.lint`, a `Dockerfile` and Gitea workflow that gate every
push, and prettier/editorconfig/dockerignore config.

`make build` pointed at a `cmd/dcfinfo` that is not in the tree and
could never have succeeded; this repo is a library, so `build` is now
the compile check over every package.

Clear the 57 findings the canonical linter config reports on `pkg/dcf`.
Two were real: `findDCFMountPoints` checked a never-assigned `erro`
instead of the error from `findAllMountPoints`, discarding it, and
`privatePath` was computed twice so the first computation was dead.
Mountpoint selection otherwise behaves exactly as before; the defects
that survive are filed as issue #6, not fixed here.

Rename `DCFStore` to `Store` and `DCFObject` to `Object` (with its
`DCFStoreRoot` field to `StoreRoot`), which revive's stutter rule
requires and which the `fs.FS` rework in issue #4 will build on.

Replace the placeholder test with tests over the exported surface.
The filesystem walk stays uncovered: it is reachable only through
`GetDCFStores`, which needs real mounted media.

README keeps its content, reorganised into the required sections and
gaining Entrypoints.

(closes #1)
2026-08-30 11:36:58 +00:00

85 lines
1.9 KiB
Go

package dcf
import (
"log/slog"
"os"
"path/filepath"
"slices"
"github.com/shirou/gopsutil/disk"
)
// dcfMarkerDirectories are the directory names whose presence in a
// filesystem root identifies that filesystem as a DCF store.
func dcfMarkerDirectories() []string {
return []string{"DCIM", "M4ROOT"}
}
// findAllMountPoints returns the distinct mountpoints of the system's
// physical filesystems.
func findAllMountPoints() ([]string, error) {
partitions, err := disk.Partitions(false) // physical devices only
if err != nil {
return nil, err
}
mountpoints := []string{}
for _, partition := range partitions {
if !slices.Contains(mountpoints, partition.Mountpoint) {
mountpoints = append(mountpoints, partition.Mountpoint)
}
}
return mountpoints, nil
}
// findDCFMountPoints returns the paths of the mountpoints that contain
// one of the marker directories a DCF store is identified by. Its only
// argument is how many mountpoints to return; 0 returns all of them.
func findDCFMountPoints(requestedCount int) ([]string, error) {
mountpoints, err := findAllMountPoints()
if err != nil {
return nil, err
}
filteredMountpoints := []string{}
for _, mountpoint := range mountpoints {
if !isDCFMountPoint(mountpoint) {
continue
}
slog.Debug("keeping mountpoint", "mountpoint", mountpoint)
filteredMountpoints = append(filteredMountpoints, mountpoint)
if requestedCount > 0 && len(filteredMountpoints)+1 >= requestedCount {
break
}
}
return filteredMountpoints, nil
}
// isDCFMountPoint reports whether mountpoint holds any of the marker
// directories a DCF store is identified by.
func isDCFMountPoint(mountpoint string) bool {
found := false
for _, marker := range dcfMarkerDirectories() {
markerPath := filepath.Join(mountpoint, marker)
_, err := os.Stat(markerPath)
if err != nil {
continue
}
slog.Debug("found marker directory", "path", markerPath)
found = true
}
return found
}