scan created a missing database directory from filepath.Dir of the path. That cleans the path as text, dropping each .. together with the name before it, so after a symlinked directory it named another directory than the one the system reaches when it opens the file. With /srv/link a symlink to /data/x, SFDUPES_DATABASE=/srv/link/../new/db.sqlite made scan create /srv/new and then fail to create the database at /data/new/db.sqlite.
lockScanDatabase and openScanDatabase now both call createDatabaseDirectory, beside databasePath in db.go. It cuts the last element off the path as text with filepath.Split and passes the rest to os.MkdirAll, which also works on the text, so each .. is followed through any symlink before it. This is the rule #118 set for databasePath.
What the diff does not show:
A missing directory before a .. is now created on the way: for /a/missing/../b/db.sqlite, both /a/missing and /a/b. Before, scan created only /a/b and then failed to open the file.
A comment in databasePath said scan cleans the path; it now gives only the README "Database" reason for resolving the working directory's symlinks.
The new test runs the symlink case through each function separately, since in a real scan the first one creates the directory before the second runs. The plain missing directory stays covered by TestOpenScanDatabaseCreates.
Unverified item: the /a/missing case follows from reading os.MkdirAll; no test covers it.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/sfdupes/issues/119.
`scan` created a missing database directory from `filepath.Dir` of the path. That cleans the path as text, dropping each `..` together with the name before it, so after a symlinked directory it named another directory than the one the system reaches when it opens the file. With `/srv/link` a symlink to `/data/x`, `SFDUPES_DATABASE=/srv/link/../new/db.sqlite` made `scan` create `/srv/new` and then fail to create the database at `/data/new/db.sqlite`.
`lockScanDatabase` and `openScanDatabase` now both call `createDatabaseDirectory`, beside `databasePath` in `db.go`. It cuts the last element off the path as text with `filepath.Split` and passes the rest to `os.MkdirAll`, which also works on the text, so each `..` is followed through any symlink before it. This is the rule https://git.eeqj.de/sneak/sfdupes/pulls/118 set for `databasePath`.
What the diff does not show:
- A missing directory before a `..` is now created on the way: for `/a/missing/../b/db.sqlite`, both `/a/missing` and `/a/b`. Before, `scan` created only `/a/b` and then failed to open the file.
- A comment in `databasePath` said `scan` cleans the path; it now gives only the README "Database" reason for resolving the working directory's symlinks.
- The new test runs the symlink case through each function separately, since in a real scan the first one creates the directory before the second runs. The plain missing directory stays covered by `TestOpenScanDatabaseCreates`.
Unverified item: the `/a/missing` case follows from reading `os.MkdirAll`; no test covers it.
Model: opus-5-5
scan created a missing database directory from filepath.Dir of the
path, which cleans it as text and drops each ".." together with the
name before it. After a symlinked directory that is another directory
than the one the system reaches when it opens the file, so scan left an
empty directory beside the symlink and then failed to create the
database. lockScanDatabase and openScanDatabase now both call
createDatabaseDirectory, beside databasePath, which cuts the last
element off the path as text and creates what is missing along it. A
comment in databasePath that described scan cleaning the path now says
why the working directory has its symlinks resolved.
Model: opus-5-5
Review passed: #129 meets the definition of done of #119.
Model: opus-5-5
Review passed: https://git.eeqj.de/sneak/sfdupes/pulls/129 meets the definition of done of https://git.eeqj.de/sneak/sfdupes/issues/119.
Model: opus-5-5
clawbot
merged commit 4e4a94db2b into next2026-10-17 04:44:54 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #119.
scancreated a missing database directory fromfilepath.Dirof the path. That cleans the path as text, dropping each..together with the name before it, so after a symlinked directory it named another directory than the one the system reaches when it opens the file. With/srv/linka symlink to/data/x,SFDUPES_DATABASE=/srv/link/../new/db.sqlitemadescancreate/srv/newand then fail to create the database at/data/new/db.sqlite.lockScanDatabaseandopenScanDatabasenow both callcreateDatabaseDirectory, besidedatabasePathindb.go. It cuts the last element off the path as text withfilepath.Splitand passes the rest toos.MkdirAll, which also works on the text, so each..is followed through any symlink before it. This is the rule #118 set fordatabasePath.What the diff does not show:
..is now created on the way: for/a/missing/../b/db.sqlite, both/a/missingand/a/b. Before,scancreated only/a/band then failed to open the file.databasePathsaidscancleans the path; it now gives only the README "Database" reason for resolving the working directory's symlinks.TestOpenScanDatabaseCreates.Unverified item: the
/a/missingcase follows from readingos.MkdirAll; no test covers it.Model: opus-5-5
Review passed: #129 meets the definition of done of #119.
Model: opus-5-5