feat: the library's folders are set in Admin › Library, and changing a folder moves its tracks with it, keeping their plays, likes and playlists (#6129)
release / govulncheck (push) Successful in 15s
release / web (push) Successful in 1m20s
release / go (push) Failing after 1m37s
release / integration (push) Failing after 4m56s
release / android (push) Successful in 5m1s
release / Build signed APK (releases and dev) (push) Successful in 5m13s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Skipped
release / Verify release artifacts (tag releases only) (push) Skipped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 20:37:03 -04:00
co-authored by Claude Opus 5.5
parent 453a977e48
commit edcb3a57ef
25 changed files with 1102 additions and 57 deletions
+10 -8
View File
@@ -63,9 +63,10 @@ type Importer struct {
Scanner Scanner
Catalogue Catalogue
Printer Printer
// Roots are the library's folders (the scan paths). New music is filed
// under the one the settings name, or the first.
Roots []string
// Roots are the library's folders (the scan paths), read on every use
// because they change in Settings (#6129). New music is filed under the
// one the settings name, or the first.
Roots func() []string
// DataDir is where cached art lives, for tidying an artist an upgrade
// leaves with nothing (#5524). Empty skips it.
DataDir string
@@ -79,7 +80,7 @@ type Importer struct {
// New returns an Importer. printer may be nil: the check then rests on
// lengths and tags.
func New(pool *pgxpool.Pool, scanner Scanner, cat Catalogue, printer Printer, roots []string, logger *slog.Logger) *Importer {
func New(pool *pgxpool.Pool, scanner Scanner, cat Catalogue, printer Printer, roots func() []string, logger *slog.Logger) *Importer {
if logger == nil {
logger = slog.Default()
}
@@ -549,14 +550,15 @@ func (im *Importer) editions(ctx context.Context, group string) ([]Edition, erro
// root is the library folder new music is filed into.
func (im *Importer) root(ctx context.Context, q *dbq.Queries) (string, error) {
if len(im.Roots) == 0 {
return "", errors.New("there is no library folder to file new music into (MINSTREL_LIBRARY_SCAN_PATHS)")
roots := im.Roots()
if len(roots) == 0 {
return "", errors.New("there is no library folder to file new music into; add one in Settings → Library")
}
s, err := q.GetAcquisitionSettings(ctx)
if err == nil && s.ImportRoot != "" && slices.Contains(im.Roots, s.ImportRoot) {
if err == nil && s.ImportRoot != "" && slices.Contains(roots, s.ImportRoot) {
return s.ImportRoot, nil
}
return im.Roots[0], nil
return roots[0], nil
}
// held reads which of the planned tracks the library already has: by