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.
This commit is contained in:
leoca committed 2026-10-14 11:05:51 +00:00
1 parent 8d4f4139f4
commit 867591f3e2
3 files changed
+13 -2

No files matched your search

+2 -2
View File
@@ -4,7 +4,7 @@ import { Storage } from '@freearhey/storage-js'
import { PlaylistParser } from '../../core' import { PlaylistParser } from '../../core'
import { data, loadData } from '../../api' import { data, loadData } from '../../api'
import { ROOT_DIR } from '../../constants' import { ROOT_DIR } from '../../constants'
import { isURI } from '../../utils.js' import { getStoragePath, isURI } from '../../utils.js'
import { Stream } from '../../models' import { Stream } from '../../models'
import * as sdk from '@iptv-org/sdk' import * as sdk from '@iptv-org/sdk'
import chalk from 'chalk' import chalk from 'chalk'
@@ -34,7 +34,7 @@ async function main() {
logger.info('loading streams...') logger.info('loading streams...')
const selectedFiles = program.args.length const selectedFiles = program.args.length
? program.args ? program.args.map((filepath: string) => getStoragePath(filepath, ROOT_DIR))
: await rootStorage.list('streams/**/*.m3u') : await rootStorage.list('streams/**/*.m3u')
const selectedStreams = await parser.parse(selectedFiles) const selectedStreams = await parser.parse(selectedFiles)
logger.info(`found ${selectedStreams.count()} streams`) logger.info(`found ${selectedStreams.count()} streams`)
@@ -0,0 +1,3 @@
#EXTM3U
#EXTINF:-1 tvg-id="",Example (720p)
https://example.com/playlist.m3u8
+8
View File
@@ -117,6 +117,14 @@ describe('playlist:validate', () => {
expect(stdout).toContain('is missing a channel ID') 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', () => { it('shows only errors if log level is error', () => {
const cmd = `${ENV_VAR} npm run playlist:validate -- --log-level=error log_level.m3u` const cmd = `${ENV_VAR} npm run playlist:validate -- --log-level=error log_level.m3u`
try { try {