Add golangci-lint config

This commit is contained in:
2026-02-12 02:54:35 +03:00
parent f22111aa43
commit 9e59fa18e4
14 changed files with 112 additions and 50 deletions

44
.golangci.yml Normal file
View File

@@ -0,0 +1,44 @@
version: "2"
run:
tests: false
linters:
default: all
disable:
- revive
- noinlineerr
- mnd
- tagliatelle
- ireturn
- godox
- exhaustruct
- depguard
settings:
wsl_v5:
allow-first-in-block: true
allow-whole-block: false
branch-max-lines: 2
lll:
line-length: 120
staticcheck:
checks:
- -SA1029
varnamelen:
ignore-decls:
- tx *sqlx.Tx
wrapcheck:
ignore-sig-regexps:
- \.Write\(
- \.WriteString\(
- \.WriteJSON\(
- \.WriteHTML\(
- \.Redirect\(
- \.Error\(
- \.ErrorV0\(
issues:
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- gofmt
- gofumpt
- goimports

View File

@@ -46,7 +46,9 @@ func main() {
// CTRL+C handler. // CTRL+C handler.
interrupt := make(chan os.Signal, 1) interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt) signal.Notify(interrupt)
shutdownDone := make(chan bool, 1) shutdownDone := make(chan bool, 1)
go func() { go func() {
signalThing := <-interrupt signalThing := <-interrupt
if signalThing == syscall.SIGTERM || signalThing == syscall.SIGINT { if signalThing == syscall.SIGTERM || signalThing == syscall.SIGINT {

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"runtime" "runtime"
"strconv"
"sync" "sync"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@@ -34,6 +35,7 @@ func (a *App) Logger() *logrus.Entry {
func New(ctx context.Context) *App { func New(ctx context.Context) *App {
var m runtime.MemStats var m runtime.MemStats
runtime.ReadMemStats(&m) runtime.ReadMemStats(&m)
app := new(App) app := new(App)
@@ -48,7 +50,7 @@ func New(ctx context.Context) *App {
app.logger = logger.WithContext(ctx).WithFields(logrus.Fields{ app.logger = logger.WithContext(ctx).WithFields(logrus.Fields{
"memalloc": fmt.Sprintf("%dMB", m.Alloc/1024/1024), "memalloc": fmt.Sprintf("%dMB", m.Alloc/1024/1024),
"memsys": fmt.Sprintf("%dMB", m.Sys/1024/1024), "memsys": fmt.Sprintf("%dMB", m.Sys/1024/1024),
"numgc": fmt.Sprintf("%d", m.NumGC), "numgc": strconv.FormatUint(uint64(m.NumGC), 10),
}) })
app.ctx = ctx app.ctx = ctx

View File

@@ -40,6 +40,7 @@ func New() (*Config, error) {
} }
config := new(Config) config := new(Config)
err = yaml.Unmarshal(rawConfig, config) err = yaml.Unmarshal(rawConfig, config)
if err != nil { if err != nil {
return nil, fmt.Errorf("%w: %w (%w)", ErrConfiguration, ErrCantParseConfigFile, err) return nil, fmt.Errorf("%w: %w (%w)", ErrConfiguration, ErrCantParseConfigFile, err)

View File

@@ -2,6 +2,7 @@ package cacher
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@@ -31,7 +32,7 @@ func (c *Cacher) getFile(sourcePath string) (*models.CacheItem, error) {
keyData := fmt.Sprintf("%s:%d", sourcePath, sourceFileInfo.ModTime().UnixNano()) keyData := fmt.Sprintf("%s:%d", sourcePath, sourceFileInfo.ModTime().UnixNano())
hash := md5.Sum([]byte(keyData)) hash := md5.Sum([]byte(keyData))
cacheKey := fmt.Sprintf("%x", hash) cacheKey := hex.EncodeToString(hash[:])
cacheFilePath := filepath.Join(c.cacheDir, cacheKey+".m4a") cacheFilePath := filepath.Join(c.cacheDir, cacheKey+".m4a")
c.itemsMutex.Lock() c.itemsMutex.Lock()
@@ -73,6 +74,7 @@ func (c *Cacher) getFile(sourcePath string) (*models.CacheItem, error) {
// File does not exist on disk, need to transcode. // File does not exist on disk, need to transcode.
// Register in the queue // Register in the queue
c.transcoder.QueueChannel() <- struct{}{} c.transcoder.QueueChannel() <- struct{}{}
defer func() { defer func() {
<-c.transcoder.QueueChannel() <-c.transcoder.QueueChannel()
}() }()
@@ -94,7 +96,7 @@ func (c *Cacher) getFile(sourcePath string) (*models.CacheItem, error) {
c.updateCachedStat(sourcePath, size) c.updateCachedStat(sourcePath, size)
// TODO: run cleanup on inotify events. // TODO: run cleanup on inotify events.
// c.cleanup() c.cleanup()
return item, nil return item, nil
} }

View File

@@ -2,6 +2,7 @@ package cacher
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@@ -10,7 +11,7 @@ import (
"source.hodakov.me/hdkv/faketunes/internal/domains/cacher/models" "source.hodakov.me/hdkv/faketunes/internal/domains/cacher/models"
) )
// getStat returns file size without triggering conversion (for ls/stat) // getStat returns file size without triggering conversion (for ls/stat).
func (c *Cacher) GetStat(sourcePath string) (int64, error) { func (c *Cacher) GetStat(sourcePath string) (int64, error) {
c.statMutex.RLock() c.statMutex.RLock()
defer c.statMutex.RUnlock() defer c.statMutex.RUnlock()
@@ -28,7 +29,7 @@ func (c *Cacher) GetStat(sourcePath string) (int64, error) {
keyData := fmt.Sprintf("%s:%d", sourcePath, info.ModTime().UnixNano()) keyData := fmt.Sprintf("%s:%d", sourcePath, info.ModTime().UnixNano())
hash := md5.Sum([]byte(keyData)) hash := md5.Sum([]byte(keyData))
key := fmt.Sprintf("%x", hash) key := hex.EncodeToString(hash[:])
cachePath := filepath.Join(c.cacheDir, key+".m4a") cachePath := filepath.Join(c.cacheDir, key+".m4a")
// Check if converted file exists and is valid // Check if converted file exists and is valid
@@ -44,7 +45,7 @@ func (c *Cacher) GetStat(sourcePath string) (int64, error) {
return info.Size(), nil return info.Size(), nil
} }
// updateCachedStat updates the stat cache // updateCachedStat updates the stat cache.
func (c *Cacher) updateCachedStat(sourcePath string, size int64) { func (c *Cacher) updateCachedStat(sourcePath string, size int64) {
c.statMutex.Lock() c.statMutex.Lock()
defer c.statMutex.Unlock() defer c.statMutex.Unlock()
@@ -55,7 +56,7 @@ func (c *Cacher) updateCachedStat(sourcePath string, size int64) {
} }
} }
// getCachedStat returns cached file stats // getCachedStat returns cached file stats.
func (c *Cacher) getCachedStat(sourcePath string) (int64, bool) { func (c *Cacher) getCachedStat(sourcePath string) (int64, bool) {
c.statMutex.RLock() c.statMutex.RLock()
defer c.statMutex.RUnlock() defer c.statMutex.RUnlock()
@@ -63,5 +64,6 @@ func (c *Cacher) getCachedStat(sourcePath string) (int64, bool) {
if stat, ok := c.stat[sourcePath]; ok { if stat, ok := c.stat[sourcePath]; ok {
return stat.Size, true return stat.Size, true
} }
return 0, false return 0, false
} }

View File

@@ -2,4 +2,4 @@ package domains
const FilesystemName = "filesystem" const FilesystemName = "filesystem"
type Filesystem interface{} type Filesystem any

View File

@@ -35,7 +35,7 @@ func (f *FS) prepareDirectories() error {
// Create the structure for the virtual filesystem. // Create the structure for the virtual filesystem.
for _, dir := range []string{f.destinationDir, f.cacheDir, f.metadataDir} { for _, dir := range []string{f.destinationDir, f.cacheDir, f.metadataDir} {
if err := os.MkdirAll(dir, 0755); err != nil { if err := os.MkdirAll(dir, 0o755); err != nil {
f.app.Logger().WithField("path", dir).Error("Operation on directory was unsuccessful") f.app.Logger().WithField("path", dir).Error("Operation on directory was unsuccessful")
return fmt.Errorf("%w: %w (%w)", ErrFilesystem, ErrFailedToCreateDestinationDirectory, err) return fmt.Errorf("%w: %w (%w)", ErrFilesystem, ErrFailedToCreateDestinationDirectory, err)

View File

@@ -2,6 +2,7 @@ package filesystem
import ( import (
"context" "context"
"errors"
"io" "io"
"os" "os"
"sync" "sync"
@@ -33,7 +34,7 @@ func (fi *File) Read(ctx context.Context, dest []byte, off int64) (fuse.ReadResu
} }
n, err := fi.file.Read(dest) n, err := fi.file.Read(dest)
if err != nil && err != io.EOF { if err != nil && !errors.Is(err, io.EOF) {
return nil, syscall.EIO return nil, syscall.EIO
} }

View File

@@ -30,7 +30,7 @@ var (
func (m *MusicAppMetadataFile) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno { func (m *MusicAppMetadataFile) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
info, err := os.Stat(m.path) info, err := os.Stat(m.path)
if err != nil { if err != nil {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = m.StableAttr().Ino out.Ino = m.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -57,7 +57,7 @@ func (m *MusicAppMetadataFile) Getattr(ctx context.Context, fh fs.FileHandle, ou
func (m *MusicAppMetadataFile) Setattr(ctx context.Context, fh fs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno { func (m *MusicAppMetadataFile) Setattr(ctx context.Context, fh fs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno {
info, err := os.Stat(m.path) info, err := os.Stat(m.path)
if err != nil { if err != nil {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = m.StableAttr().Ino out.Ino = m.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -90,7 +90,7 @@ func (m *MusicAppMetadataFile) Create(ctx context.Context, name string, flags ui
Ino: m.f.nextInode(), Ino: m.f.nextInode(),
}) })
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -104,12 +104,12 @@ func (m *MusicAppMetadataFile) Create(ctx context.Context, name string, flags ui
func (m *MusicAppMetadataFile) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { func (m *MusicAppMetadataFile) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) {
if _, err := os.Stat(m.path); os.IsNotExist(err) { if _, err := os.Stat(m.path); os.IsNotExist(err) {
if err := os.WriteFile(m.path, []byte{}, 0644); err != nil { if err := os.WriteFile(m.path, []byte{}, 0o644); err != nil {
return nil, 0, syscall.EIO return nil, 0, syscall.EIO
} }
} }
file, err := os.OpenFile(m.path, int(flags), 0644) file, err := os.OpenFile(m.path, int(flags), 0o644)
if err != nil { if err != nil {
return nil, 0, syscall.EIO return nil, 0, syscall.EIO
} }
@@ -135,6 +135,7 @@ func (m *MusicAppMetadataFile) Unlink(ctx context.Context, name string) syscall.
if err := os.Remove(m.path); err != nil { if err := os.Remove(m.path); err != nil {
return syscall.ENOENT return syscall.ENOENT
} }
return 0 return 0
} }

View File

@@ -34,7 +34,7 @@ var (
) )
func (d *MusicDir) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) syscall.Errno { func (d *MusicDir) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
out.Mode = fuse.S_IFDIR | 0755 out.Mode = fuse.S_IFDIR | 0o755
out.Nlink = 2 // Minimum . and .. out.Nlink = 2 // Minimum . and ..
out.Ino = d.StableAttr().Ino out.Ino = d.StableAttr().Ino
out.Size = 4096 out.Size = 4096
@@ -77,6 +77,7 @@ func (d *MusicDir) Getxattr(ctx context.Context, attr string, dest []byte) (uint
if len(dest) > 0 { if len(dest) > 0 {
return 0, 0 return 0, 0
} }
return 0, 0 return 0, 0
default: default:
return 0, syscall.ENODATA return 0, syscall.ENODATA
@@ -113,7 +114,7 @@ func (d *MusicDir) Create(ctx context.Context, name string, flags uint32, mode u
}, },
) )
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -144,7 +145,7 @@ func (d *MusicDir) Lookup(ctx context.Context, name string, out *fuse.EntryOut)
}, },
) )
out.Mode = fuse.S_IFREG | 0444 out.Mode = fuse.S_IFREG | 0o444
out.Nlink = 1 out.Nlink = 1
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
@@ -165,6 +166,7 @@ func (d *MusicDir) Lookup(ctx context.Context, name string, out *fuse.EntryOut)
// Check real file or directory // Check real file or directory
fullPath := filepath.Join(d.path, name) fullPath := filepath.Join(d.path, name)
info, err := os.Stat(fullPath) info, err := os.Stat(fullPath)
if err != nil { if err != nil {
return nil, syscall.ENOENT return nil, syscall.ENOENT
@@ -179,7 +181,7 @@ func (d *MusicDir) Lookup(ctx context.Context, name string, out *fuse.EntryOut)
}, },
) )
out.Mode = fuse.S_IFDIR | 0755 out.Mode = fuse.S_IFDIR | 0o755
out.Nlink = 2 out.Nlink = 2
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
out.Size = 4096 out.Size = 4096
@@ -201,9 +203,9 @@ func (d *MusicDir) Lookup(ctx context.Context, name string, out *fuse.EntryOut)
) )
if isMeta { if isMeta {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
} else { } else {
out.Mode = fuse.S_IFREG | 0444 out.Mode = fuse.S_IFREG | 0o444
} }
out.Nlink = 1 out.Nlink = 1
@@ -224,12 +226,12 @@ func (d *MusicDir) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
dirEntries = append(dirEntries, fuse.DirEntry{ dirEntries = append(dirEntries, fuse.DirEntry{
Name: ".", Name: ".",
Mode: fuse.S_IFDIR | 0755, Mode: fuse.S_IFDIR | 0o755,
Ino: d.StableAttr().Ino, Ino: d.StableAttr().Ino,
}) })
dirEntries = append(dirEntries, fuse.DirEntry{ dirEntries = append(dirEntries, fuse.DirEntry{
Name: "..", Name: "..",
Mode: fuse.S_IFDIR | 0755, Mode: fuse.S_IFDIR | 0o755,
Ino: 1, // Parent (root) inode Ino: 1, // Parent (root) inode
}) })
@@ -249,19 +251,19 @@ func (d *MusicDir) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
continue continue
} }
mode := fuse.S_IFREG | 0444 mode := fuse.S_IFREG | 0o444
if entry.IsDir() { if entry.IsDir() {
mode = fuse.S_IFDIR | 0755 mode = fuse.S_IFDIR | 0o755
} }
// Convert .flac to .m4a in directory listing // Convert .flac to .m4a in directory listing
if strings.HasSuffix(strings.ToLower(name), ".flac") { if strings.HasSuffix(strings.ToLower(name), ".flac") {
name = name[:len(name)-5] + ".m4a" name = name[:len(name)-5] + ".m4a"
if !d.f.isiTunesMetadata(name) { if !d.f.isiTunesMetadata(name) {
mode = fuse.S_IFREG | 0644 mode = fuse.S_IFREG | 0o644
} }
} else if !d.f.isiTunesMetadata(name) { } else if !d.f.isiTunesMetadata(name) {
mode = fuse.S_IFREG | 0644 mode = fuse.S_IFREG | 0o644
} }
dirEntries = append(dirEntries, fuse.DirEntry{ dirEntries = append(dirEntries, fuse.DirEntry{

View File

@@ -31,7 +31,7 @@ func (f *MusicFile) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.Att
metaPath := filepath.Join(f.f.metadataDir, f.virtualName) metaPath := filepath.Join(f.f.metadataDir, f.virtualName)
if info, err := os.Stat(metaPath); err == nil { if info, err := os.Stat(metaPath); err == nil {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = f.StableAttr().Ino out.Ino = f.StableAttr().Ino
out.Size = uint64(info.Size()) out.Size = uint64(info.Size())
@@ -40,7 +40,7 @@ func (f *MusicFile) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.Att
out.Ctime = out.Mtime out.Ctime = out.Mtime
out.Blocks = (out.Size + 511) / 512 out.Blocks = (out.Size + 511) / 512
} else { } else {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = f.StableAttr().Ino out.Ino = f.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -53,7 +53,7 @@ func (f *MusicFile) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.Att
return 0 return 0
} }
out.Mode = fuse.S_IFREG | 0444 out.Mode = fuse.S_IFREG | 0o444
out.Nlink = 1 out.Nlink = 1
out.Ino = f.StableAttr().Ino out.Ino = f.StableAttr().Ino
out.Blocks = 1 out.Blocks = 1
@@ -76,7 +76,7 @@ func (f *MusicFile) Setattr(ctx context.Context, fh fs.FileHandle, in *fuse.SetA
if f.isMetaFile { if f.isMetaFile {
metaPath := filepath.Join(f.f.metadataDir, f.virtualName) metaPath := filepath.Join(f.f.metadataDir, f.virtualName)
if info, err := os.Stat(metaPath); err == nil { if info, err := os.Stat(metaPath); err == nil {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = f.StableAttr().Ino out.Ino = f.StableAttr().Ino
out.Size = uint64(info.Size()) out.Size = uint64(info.Size())
@@ -85,7 +85,7 @@ func (f *MusicFile) Setattr(ctx context.Context, fh fs.FileHandle, in *fuse.SetA
out.Ctime = out.Mtime out.Ctime = out.Mtime
out.Blocks = (out.Size + 511) / 512 out.Blocks = (out.Size + 511) / 512
} else { } else {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = f.StableAttr().Ino out.Ino = f.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -105,10 +105,11 @@ func (f *MusicFile) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, f
if f.isMetaFile { if f.isMetaFile {
metaPath := filepath.Join(f.f.metadataDir, f.virtualName) metaPath := filepath.Join(f.f.metadataDir, f.virtualName)
file, err := os.OpenFile(metaPath, int(flags), 0644) file, err := os.OpenFile(metaPath, int(flags), 0o644)
if err != nil && os.IsNotExist(err) { if err != nil && os.IsNotExist(err) {
file, err = os.Create(metaPath) file, err = os.Create(metaPath)
} }
if err != nil { if err != nil {
return nil, 0, syscall.EIO return nil, 0, syscall.EIO
} }

View File

@@ -50,7 +50,7 @@ func (r *RootDirectory) Create(
}, },
) )
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
out.Size = 0 out.Size = 0
@@ -77,7 +77,7 @@ func (r *RootDirectory) Lookup(ctx context.Context, name string, out *fuse.Entry
}, },
) )
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
out.Nlink = 1 out.Nlink = 1
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
@@ -114,7 +114,7 @@ func (r *RootDirectory) Lookup(ctx context.Context, name string, out *fuse.Entry
}, },
) )
out.Mode = fuse.S_IFREG | 0444 out.Mode = fuse.S_IFREG | 0o444
out.Nlink = 1 out.Nlink = 1
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
@@ -135,6 +135,7 @@ func (r *RootDirectory) Lookup(ctx context.Context, name string, out *fuse.Entry
// Check real file or directory // Check real file or directory
fullPath := filepath.Join(r.f.sourceDir, name) fullPath := filepath.Join(r.f.sourceDir, name)
info, err := os.Stat(fullPath) info, err := os.Stat(fullPath)
if err != nil { if err != nil {
return nil, syscall.ENOENT return nil, syscall.ENOENT
@@ -146,7 +147,7 @@ func (r *RootDirectory) Lookup(ctx context.Context, name string, out *fuse.Entry
Ino: r.f.nextInode(), Ino: r.f.nextInode(),
}) })
out.Mode = fuse.S_IFDIR | 0755 out.Mode = fuse.S_IFDIR | 0o755
out.Nlink = 2 // Minimum . and .. out.Nlink = 2 // Minimum . and ..
out.Ino = ch.StableAttr().Ino out.Ino = ch.StableAttr().Ino
out.Size = 4096 out.Size = 4096
@@ -166,9 +167,9 @@ func (r *RootDirectory) Lookup(ctx context.Context, name string, out *fuse.Entry
}) })
if isMeta { if isMeta {
out.Mode = fuse.S_IFREG | 0644 out.Mode = fuse.S_IFREG | 0o644
} else { } else {
out.Mode = fuse.S_IFREG | 0444 out.Mode = fuse.S_IFREG | 0o444
} }
out.Nlink = 1 out.Nlink = 1
@@ -190,12 +191,12 @@ func (r *RootDirectory) Readdir(ctx context.Context) (fs.DirStream, syscall.Errn
// Always include . and .. first // Always include . and .. first
dirEntries = append(dirEntries, fuse.DirEntry{ dirEntries = append(dirEntries, fuse.DirEntry{
Name: ".", Name: ".",
Mode: fuse.S_IFDIR | 0755, Mode: fuse.S_IFDIR | 0o755,
Ino: 1, // Root inode Ino: 1, // Root inode
}) })
dirEntries = append(dirEntries, fuse.DirEntry{ dirEntries = append(dirEntries, fuse.DirEntry{
Name: "..", Name: "..",
Mode: fuse.S_IFDIR | 0755, Mode: fuse.S_IFDIR | 0o755,
Ino: 1, Ino: 1,
}) })
@@ -205,6 +206,7 @@ func (r *RootDirectory) Readdir(ctx context.Context) (fs.DirStream, syscall.Errn
r.f.app.Logger().WithError(err).WithField("path", r.f.sourceDir).Error( r.f.app.Logger().WithError(err).WithField("path", r.f.sourceDir).Error(
"Error reading directory", "Error reading directory",
) )
return fs.NewListDirStream(dirEntries), 0 return fs.NewListDirStream(dirEntries), 0
} }
@@ -215,9 +217,9 @@ func (r *RootDirectory) Readdir(ctx context.Context) (fs.DirStream, syscall.Errn
continue continue
} }
mode := fuse.S_IFREG | 0444 mode := fuse.S_IFREG | 0o444
if entry.IsDir() { if entry.IsDir() {
mode = fuse.S_IFDIR | 0755 mode = fuse.S_IFDIR | 0o755
} }
// Convert .flac to .m4a in directory listing // Convert .flac to .m4a in directory listing
@@ -225,7 +227,7 @@ func (r *RootDirectory) Readdir(ctx context.Context) (fs.DirStream, syscall.Errn
name = name[:len(name)-5] + ".m4a" name = name[:len(name)-5] + ".m4a"
} }
mode = fuse.S_IFREG | 0644 mode = fuse.S_IFREG | 0o644
dirEntries = append(dirEntries, fuse.DirEntry{ dirEntries = append(dirEntries, fuse.DirEntry{
Name: name, Name: name,
@@ -246,7 +248,7 @@ func (r *RootDirectory) Getattr(
ctx context.Context, f fs.FileHandle, out *fuse.AttrOut, ctx context.Context, f fs.FileHandle, out *fuse.AttrOut,
) syscall.Errno { ) syscall.Errno {
// Set basic directory attributes // Set basic directory attributes
out.Mode = fuse.S_IFDIR | 0755 out.Mode = fuse.S_IFDIR | 0o755
// Set nlink to at least 2 (for . and ..) // Set nlink to at least 2 (for . and ..)
out.Nlink = 2 out.Nlink = 2

View File

@@ -52,11 +52,11 @@ func (t *Transcoder) Convert(sourcePath, destinationPath string) (int64, error)
analyzeOutput, err := sourceAnalyzeCmd.Output() analyzeOutput, err := sourceAnalyzeCmd.Output()
if err == nil { if err == nil {
// Investiage bit depth and sample rate from ffprobe output. // Investigate bit depth and sample rate from ffprobe output.
// We need that to make sure we don't oversample files that are lower // We need that to make sure we don't oversample files that are lower
// than the default sample rate and bit depth. // than the default sample rate and bit depth.
lines := strings.Split(strings.TrimSpace(string(analyzeOutput)), "\n") lines := strings.SplitSeq(strings.TrimSpace(string(analyzeOutput)), "\n")
for _, line := range lines { for line := range lines {
if strings.Contains(line, "audio") { if strings.Contains(line, "audio") {
parts := strings.Split(line, ",") parts := strings.Split(line, ",")
if len(parts) >= 6 { if len(parts) >= 6 {
@@ -137,7 +137,7 @@ func (t *Transcoder) Convert(sourcePath, destinationPath string) (int64, error)
"-af", "aresample=48000:resampler=soxr:precision=28", "-af", "aresample=48000:resampler=soxr:precision=28",
) )
} else { } else {
ffmpegArgs = append(ffmpegArgs, "-ar", fmt.Sprintf("%d", sampleRate)) ffmpegArgs = append(ffmpegArgs, "-ar", strconv.Itoa(sampleRate))
} }
if needsBitReduce { if needsBitReduce {
@@ -151,7 +151,7 @@ func (t *Transcoder) Convert(sourcePath, destinationPath string) (int64, error)
// Handle metadata copying and sort_artist filling // Handle metadata copying and sort_artist filling
ffmpegArgs = append(ffmpegArgs, ffmpegArgs = append(ffmpegArgs,
"-map_metadata", "0", "-map_metadata", "0",
"-metadata", fmt.Sprintf("sort_artist=%s", t.escapeMetadata(sortArtist)), "-metadata", "sort_artist="+t.escapeMetadata(sortArtist),
"-write_id3v2", "1", "-write_id3v2", "1",
"-id3v2_version", "3", "-id3v2_version", "3",
destinationPath, destinationPath,
@@ -165,7 +165,9 @@ func (t *Transcoder) Convert(sourcePath, destinationPath string) (int64, error)
).Debug("FFMpeg parameters") ).Debug("FFMpeg parameters")
ffmpeg := exec.Command("ffmpeg", ffmpegArgs...) ffmpeg := exec.Command("ffmpeg", ffmpegArgs...)
var stderr bytes.Buffer var stderr bytes.Buffer
ffmpeg.Stderr = &stderr ffmpeg.Stderr = &stderr
if err := ffmpeg.Run(); err != nil { if err := ffmpeg.Run(); err != nil {