| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cj/music--append-track-to-m3u-file decided whether to prepend a newline by
seeking to a byte offset from file-attributes, which doesn't follow
symlinks. On a stow-deployed playlist that measures the link string instead
of the file.
Two failure modes, and I only went looking for the second. All 100 symlinked
playlists read the wrong byte, so a file already ending in a newline looked
unterminated and gained a blank line on every append. On the 31 whose link
string is longer than their content the range fell outside the file
entirely. Nothing was inserted, and char-after handed nil to a numeric
comparison, so the append died with a wrong-type error.
The probe now reads the file and checks its last character. That takes
file-attributes out of the path, so this class can't come back. The largest
real playlist is 11 KB and the read costs 0.11 ms, so being clever about
offsets bought nothing.
A test per mode, because one fixture can't show both. Seed the blank-line
case with content shorter than the link string and it lands on the error
path instead, going red for the wrong reason and proving nothing.
The cheap patch was guarding char-after against nil. That would have
silenced the crash on 31 playlists and left the blank line live on all 100.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A track under the playlist's own directory still writes relative. Anything
outside it now writes the absolute path instead of a ../ chain. Playlists in
the mpd directory point into ~/music, so the relative form there was four
levels of .. and broke the moment anything moved.
I took the trade knowingly. ambience.m3u is the only playlist anywhere using
../ lines, and it reaches its audio through a sibling directory. So a newly
appended track there writes absolute while its hand-written lines stay
relative, and its header comment needs a matching edit. The alternative was
an exception for tracks inside the deployed tree, which would be a rule
serving exactly one file.
The comment I wrote for the earlier half of this argued one direction only.
Absolute survives the playlist moving, which I said. Relative survives the
library moving, which I didn't, and for a track in the same tree the ../ form
survives strictly more moves rather than fewer. Rewritten to name the trade
instead of implying there isn't one.
The boundary case is a directory whose name begins with two dots. The check
looks for a leading "../", so a real subdirectory called ..hidden sits under
the playlist and must stay relative. It has a test now, because loosening
that check to ".." would break that case and nothing else.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cj/music--append-track-to-m3u-file wrote every relative path against
cj/music-root wherever the playlist actually sat. Both readers resolve
against the playlist's own directory: cj/music--m3u-file-tracks, and EMMS's
emms-source-playlist-parse-m3u. So the writer and the readers disagreed
whenever those two directories were not the same one.
That is not only the playlist-outside-the-music-root case I went looking
for. 39 of the 66 m3u files under ~/music are album playlists sitting beside
their tracks, storing bare filenames. Appending to any of them wrote a line
like Artist/Album/track.flac that resolved to a path which never existed.
The fix is the base: (file-name-directory m3u-file).
Worth recording how the tests went, because the first three I wrote all
passed against the broken writer. I had put cj/music-root and the playlist
directory at the same depth, so file-relative-name returned the same string
for both bases. The fixture reached the bug's code path and still could not
see it. The discriminating cases put the two bases at different depths, and
reverting the one-line fix now fails them.
Eight existing tests moved with it. They built track paths from the real
cj/music-root while the playlist sat in a temp directory, which pinned the
old base and also read my actual music root. Rebinding the root to the
fixture directory restores every assertion verbatim and makes them hermetic.
One thing this does not change: MPD resolves relative playlist entries
against music_directory and rejects entries that escape it, so a ../ line is
for EMMS rather than MPD. That costs nothing today, since EMMS drives mpv
here and MPD is not running.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Major improvements to music player configuration:
Backend Changes:
- Switch from emms-player-mpd to emms-player-mpv
- Remove MPD daemon dependency (no service management required)
- Configure MPV with --quiet, --no-video, --audio-display flags
- Support both local files and streaming URLs (http/https/mms)
Keybinding Enhancements:
- Add C-; m n → next track
- Add C-; m p → previous track
- Add C-; m g → go to playlist
- In playlist: n/P for next/prev, f/b for seek forward/backward
- Update which-key descriptions
Code Quality:
- Use music-dir constant from user-constants.el (not hardcoded path)
- Add (require 'user-constants) for proper dependency
- Update commentary to reflect MPV backend
Test Fixes:
- Fix 8 failing append-track tests
- Update test mock data to use cj/music-root for portability
- All 104 music-config tests now passing
Benefits:
- No daemon to start/stop/manage
- Simpler architecture (one process vs MPD+EMMS)
- Streaming radio URLs work out of the box
- Better path consistency across codebase
|
| |
|
|
| |
This reverts commit d36afc3f277b9a4228eb7b2464ec4e503695b8d4.
|
| | |
|
|
|
Add comprehensive unit tests for various Emacs Lisp functions,
covering M3U file handling, music file validation, and contact
capture template finalization:
- Tests for appending tracks to M3U files Tests for recursive music
- collection Tests for completion table creation Tests for
- extracting M3U basenames and files Tests for M3U file parsing
- Tests for filename sanitization Tests for directory and file
- validity checks Tests for org-contacts capture template
- finalization
Each test validates normal, boundary, and error conditions. These
tests improve code reliability by verifying expected behavior across
a range of scenarios.
|