From 867591f3e2ed6546081a9d57716bb1bab2fa0843 Mon Sep 17 00:00:00 2001 From: leoca Date: Wed, 14 Oct 2026 11:05:51 +0000 Subject: [PATCH] fix: normalize playlist:validate file arguments playlist:validate decides which streams belong to the selected files by comparing the raw command-line arguments with the paths returned by Storage.list(). A path such as ./streams/us.m3u never matches streams/us.m3u, so the file's own streams are put in the duplicate buffer and every link is reported as already being in that same file. Resolve the arguments with getStoragePath(), as playlist:format does. --- scripts/commands/playlist/validate.ts | 4 ++-- .../input/playlist_validate_paths/streams/example.m3u | 3 +++ tests/commands/playlist/validate.test.ts | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tests/__data__/input/playlist_validate_paths/streams/example.m3u diff --git a/scripts/commands/playlist/validate.ts b/scripts/commands/playlist/validate.ts index 7e5d0599e5..42a61b9265 100644 --- a/scripts/commands/playlist/validate.ts +++ b/scripts/commands/playlist/validate.ts @@ -4,7 +4,7 @@ import { Storage } from '@freearhey/storage-js' import { PlaylistParser } from '../../core' import { data, loadData } from '../../api' import { ROOT_DIR } from '../../constants' -import { isURI } from '../../utils.js' +import { getStoragePath, isURI } from '../../utils.js' import { Stream } from '../../models' import * as sdk from '@iptv-org/sdk' import chalk from 'chalk' @@ -34,7 +34,7 @@ async function main() { logger.info('loading streams...') const selectedFiles = program.args.length - ? program.args + ? program.args.map((filepath: string) => getStoragePath(filepath, ROOT_DIR)) : await rootStorage.list('streams/**/*.m3u') const selectedStreams = await parser.parse(selectedFiles) logger.info(`found ${selectedStreams.count()} streams`) diff --git a/tests/__data__/input/playlist_validate_paths/streams/example.m3u b/tests/__data__/input/playlist_validate_paths/streams/example.m3u new file mode 100644 index 0000000000..192c54ddfb --- /dev/null +++ b/tests/__data__/input/playlist_validate_paths/streams/example.m3u @@ -0,0 +1,3 @@ +#EXTM3U +#EXTINF:-1 tvg-id="",Example (720p) +https://example.com/playlist.m3u8 diff --git a/tests/commands/playlist/validate.test.ts b/tests/commands/playlist/validate.test.ts index 29595ad853..5d105524d5 100644 --- a/tests/commands/playlist/validate.test.ts +++ b/tests/commands/playlist/validate.test.ts @@ -117,6 +117,14 @@ describe('playlist:validate', () => { expect(stdout).toContain('is missing a channel ID') }) + it('does not report a playlist as a duplicate of itself', () => { + const cmd = + 'cross-env DATA_DIR=tests/__data__/input/data ROOT_DIR=tests/__data__/input/playlist_validate_paths npm run playlist:validate -- ./streams/example.m3u' + const stdout = execSync(cmd, { encoding: 'utf8' }) + if (process.env.DEBUG === 'true') console.log(cmd, stdout) + expect(stdout).not.toContain('is already in') + }) + it('shows only errors if log level is error', () => { const cmd = `${ENV_VAR} npm run playlist:validate -- --log-level=error log_level.m3u` try {