mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 01:16:15 -08:00
* docs: design Linux frame-copy packaging * docs: plan Linux frame-copy packaging * feat(packaging): define Linux frame-copy profiles * fix(packaging): reject inherited profile names * feat(embedded-mpv): validate staged Linux runtime * fix(embedded-mpv): require Linux source packages * fix(embedded-mpv): harden Linux runtime staging * feat(embedded-mpv): build LGPL Linux runtime * fix(embedded-mpv): pin Linux runtime inputs * feat(embedded-mpv): build relocatable Linux helper * fix(embedded-mpv): require bundled Linux runtime * fix(embedded-mpv): make Linux runtime portable * feat(packaging): ship Linux frame-copy artifacts * fix(embedded-mpv): verify Linux helper linkage * fix(packaging): enforce Linux frame-copy isolation * fix(embedded-mpv): pin Linux display data * docs(embedded-mpv): document Linux frame-copy packaging * feat(embedded-mpv): probe Linux frame-copy runtime * test(embedded-mpv): smoke packaged Linux frame-copy * docs(embedded-mpv): clarify Linux system runtime baseline * fix(embedded-mpv): harden Linux runtime capability gate * ci: verify Linux frame-copy packages * test(embedded-mpv): harden packaged Linux smoke * test(embedded-mpv): preserve packaged GL mode * test(packaging): harden Linux package probes * fix(embedded-mpv): enable private Snap shared memory * fix(embedded-mpv): sanitize Linux helper environment * fix(packaging): enforce private Snap memory semantics * fix(packaging): reject ambiguous Snap memory metadata * fix(embedded-mpv): prioritize trusted Snap GL * fix(packaging): reject advanced Snap YAML semantics * fix(packaging): reject arbitrary Snap YAML aliases * feat(packaging): ship Linux runtime license notices * docs(embedded-mpv): document Linux runtime distribution * fix(packaging): parse Snap trailing comments safely * fix(release): gate Snap publish on public source release * fix(packaging): strip VCS metadata from source bundle * docs(packaging): clarify Linux source release gate * test(embedded-mpv): smoke missing bundled libmpv * style(embedded-mpv): format final validation inputs * fix(e2e): satisfy fixture index signature typing * fix(ci): declare fontconfig gperf generator * fix(embedded-mpv): hash runtime cache identities * fix(packaging): harden Linux frame-copy delivery * fix(packaging): tighten runtime delivery gates * fix(ci): decouple Linux runtime matrix * fix(packaging): harden Linux frame-copy delivery * fix(packaging): validate Linux frame-copy runtimes * fix(packaging): scope Snap Electron library checks * feat(packaging): ship Linux frame-copy runtimes * fix(packaging): improve Linux runtime smoke diagnostics * fix(packaging): expose bounded helper probe details * test(packaging): trace Snap EGL probe failures * fix(packaging): prefer core22 ABI in Snap helper * fix(packaging): bound helper probe capture * fix(packaging): harden Linux frame-copy releases * fix(packaging): canonicalize libplacebo submodule identity * fix(packaging): make source archive inspection portable * fix(packaging): harden Snap release verification
213 lines
7.1 KiB
JavaScript
213 lines
7.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import { dirname, join } from 'node:path';
|
|
import test from 'node:test';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
import { configureLinuxFrameCopyBuild } from './configure-linux-frame-copy-build.mjs';
|
|
|
|
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
const require = createRequire(import.meta.url);
|
|
const {
|
|
LINUX_FRAME_COPY_PROFILES,
|
|
LINUX_SYSTEM_PACKAGE_DEPENDENCIES,
|
|
resolveLinuxFrameCopyProfile,
|
|
validateLinuxProfileTargets,
|
|
} = require('./linux-frame-copy-profile.cjs');
|
|
const electronBuilderConfig = JSON.parse(
|
|
fs.readFileSync(
|
|
join(currentDir, '..', '..', 'electron-builder.json'),
|
|
'utf8'
|
|
)
|
|
);
|
|
|
|
function hasSystemFrameCopyDependency(config, format, dependency) {
|
|
return (config[format]?.fpm ?? []).some((option) =>
|
|
new RegExp(`^--depends(?:=|\\s+)${dependency}(?:$|\\s|[<>=])`).test(
|
|
option
|
|
)
|
|
);
|
|
}
|
|
|
|
test('defines the exact immutable Linux frame-copy profile matrix', () => {
|
|
assert.deepEqual(LINUX_FRAME_COPY_PROFILES, {
|
|
system: {
|
|
name: 'system',
|
|
runtimeMode: 'system',
|
|
targets: ['deb', 'rpm', 'pacman'],
|
|
manifestOrigin: 'system-libmpv-frame-copy',
|
|
},
|
|
portable: {
|
|
name: 'portable',
|
|
runtimeMode: 'bundled',
|
|
targets: ['appimage', 'snap'],
|
|
manifestOrigin: 'bundled-lgpl-frame-copy',
|
|
},
|
|
flatpak: {
|
|
name: 'flatpak',
|
|
runtimeMode: 'bundled',
|
|
targets: ['flatpak'],
|
|
manifestOrigin: 'bundled-lgpl-frame-copy',
|
|
},
|
|
});
|
|
assert.equal(Object.isFrozen(LINUX_FRAME_COPY_PROFILES), true);
|
|
for (const profile of Object.values(LINUX_FRAME_COPY_PROFILES)) {
|
|
assert.equal(Object.isFrozen(profile), true);
|
|
assert.equal(Object.isFrozen(profile.targets), true);
|
|
}
|
|
});
|
|
|
|
test('defines immutable system-package helper runtime dependencies', () => {
|
|
assert.deepEqual(LINUX_SYSTEM_PACKAGE_DEPENDENCIES, {
|
|
deb: ['libmpv2', 'libegl1', 'libgl1', 'libgbm1'],
|
|
rpm: ['mpv-libs', 'libglvnd-egl', 'libglvnd-glx', 'mesa-libgbm'],
|
|
pacman: ['mpv', 'libglvnd', 'mesa'],
|
|
});
|
|
assert.equal(Object.isFrozen(LINUX_SYSTEM_PACKAGE_DEPENDENCIES), true);
|
|
for (const dependencies of Object.values(
|
|
LINUX_SYSTEM_PACKAGE_DEPENDENCIES
|
|
)) {
|
|
assert.equal(Object.isFrozen(dependencies), true);
|
|
}
|
|
});
|
|
|
|
test('resolves each supported profile as an immutable defensive value', () => {
|
|
const firstSystemProfile = resolveLinuxFrameCopyProfile('system');
|
|
const secondSystemProfile = resolveLinuxFrameCopyProfile('system');
|
|
|
|
assert.deepEqual(firstSystemProfile, {
|
|
name: 'system',
|
|
runtimeMode: 'system',
|
|
targets: ['deb', 'rpm', 'pacman'],
|
|
manifestOrigin: 'system-libmpv-frame-copy',
|
|
});
|
|
assert.deepEqual(resolveLinuxFrameCopyProfile('portable'), {
|
|
name: 'portable',
|
|
runtimeMode: 'bundled',
|
|
targets: ['appimage', 'snap'],
|
|
manifestOrigin: 'bundled-lgpl-frame-copy',
|
|
});
|
|
assert.deepEqual(resolveLinuxFrameCopyProfile('flatpak'), {
|
|
name: 'flatpak',
|
|
runtimeMode: 'bundled',
|
|
targets: ['flatpak'],
|
|
manifestOrigin: 'bundled-lgpl-frame-copy',
|
|
});
|
|
assert.notEqual(firstSystemProfile, LINUX_FRAME_COPY_PROFILES.system);
|
|
assert.notEqual(firstSystemProfile, secondSystemProfile);
|
|
assert.notEqual(
|
|
firstSystemProfile.targets,
|
|
LINUX_FRAME_COPY_PROFILES.system.targets
|
|
);
|
|
assert.notEqual(firstSystemProfile.targets, secondSystemProfile.targets);
|
|
assert.equal(Object.isFrozen(firstSystemProfile), true);
|
|
assert.equal(Object.isFrozen(firstSystemProfile.targets), true);
|
|
assert.throws(() => firstSystemProfile.targets.push('appimage'), TypeError);
|
|
assert.deepEqual(resolveLinuxFrameCopyProfile('system').targets, [
|
|
'deb',
|
|
'rpm',
|
|
'pacman',
|
|
]);
|
|
});
|
|
|
|
test('rejects missing and unsupported profile names with clear errors', () => {
|
|
for (const value of [undefined, null, '', ' ']) {
|
|
assert.throws(
|
|
() => resolveLinuxFrameCopyProfile(value),
|
|
/Linux frame-copy profile is required/
|
|
);
|
|
}
|
|
assert.throws(
|
|
() => resolveLinuxFrameCopyProfile('standard'),
|
|
/Unsupported Linux frame-copy profile "standard"/
|
|
);
|
|
});
|
|
|
|
test('rejects inherited object property names as unsupported profiles', () => {
|
|
for (const value of ['constructor', 'toString', '__proto__']) {
|
|
const unsupportedProfileError = new RegExp(
|
|
`Unsupported Linux frame-copy profile "${value}"`
|
|
);
|
|
|
|
assert.throws(
|
|
() => resolveLinuxFrameCopyProfile(value),
|
|
unsupportedProfileError
|
|
);
|
|
assert.throws(
|
|
() => validateLinuxProfileTargets(value, ['deb']),
|
|
unsupportedProfileError
|
|
);
|
|
}
|
|
});
|
|
|
|
test('validates profile targets case-insensitively with deterministic errors', () => {
|
|
const targets = ['DEB', 'AppImage', 'RPM'];
|
|
|
|
assert.deepEqual(validateLinuxProfileTargets('system', targets), [
|
|
'Linux frame-copy profile "system" cannot build target "appimage".',
|
|
]);
|
|
assert.deepEqual(targets, ['DEB', 'AppImage', 'RPM']);
|
|
assert.deepEqual(
|
|
validateLinuxProfileTargets('portable', ['APPIMAGE', 'sNaP']),
|
|
[]
|
|
);
|
|
assert.deepEqual(validateLinuxProfileTargets('flatpak', ['FlatPak']), []);
|
|
});
|
|
|
|
test('rejects a non-array profile target list', () => {
|
|
assert.throws(
|
|
() => validateLinuxProfileTargets('system', 'deb'),
|
|
/Linux frame-copy targets must be an array/
|
|
);
|
|
});
|
|
|
|
test('keeps frame-copy package dependencies out of the base Electron Builder config', () => {
|
|
for (const [target, dependencies] of Object.entries(
|
|
LINUX_SYSTEM_PACKAGE_DEPENDENCIES
|
|
)) {
|
|
assert.equal(
|
|
electronBuilderConfig[target]?.depends,
|
|
undefined,
|
|
`${target}.depends must remain unset so electron-builder keeps its defaults`
|
|
);
|
|
for (const dependency of dependencies) {
|
|
assert.equal(
|
|
hasSystemFrameCopyDependency(
|
|
electronBuilderConfig,
|
|
target,
|
|
dependency
|
|
),
|
|
false
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('keeps frame-copy package dependencies out of non-system passes', () => {
|
|
const configs = [
|
|
configureLinuxFrameCopyBuild(electronBuilderConfig, {
|
|
profileName: 'portable',
|
|
}),
|
|
configureLinuxFrameCopyBuild(electronBuilderConfig, {
|
|
profileName: 'flatpak',
|
|
}),
|
|
configureLinuxFrameCopyBuild(electronBuilderConfig, {
|
|
foreignDeb: true,
|
|
}),
|
|
];
|
|
|
|
for (const config of configs) {
|
|
for (const [format, dependencies] of Object.entries(
|
|
LINUX_SYSTEM_PACKAGE_DEPENDENCIES
|
|
)) {
|
|
for (const dependency of dependencies) {
|
|
assert.equal(
|
|
hasSystemFrameCopyDependency(config, format, dependency),
|
|
false
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|