mirror of
https://github.com/nimbold/Firelink.git
synced 2026-08-28 11:37:17 +00:00
fix(release): parse modern Debian package listings
This commit is contained in:
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|||||||
import { collectRegularFiles, sha256 } from './engine-payload-integrity.js';
|
import { collectRegularFiles, sha256 } from './engine-payload-integrity.js';
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const repoRoot = path.resolve(__dirname, '..');
|
const repoRoot = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
function argValue(name) {
|
function argValue(name) {
|
||||||
@@ -87,13 +88,23 @@ function assertPackageRecommendations(packageFile, packageType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseDebianPackagePath(line) {
|
||||||
|
const match = line.match(/^\S+\s+\S+\s+\S+\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+(.*)$/);
|
||||||
|
if (!match) {
|
||||||
|
throw new Error(`Could not parse a Debian package path: ${line}`);
|
||||||
|
}
|
||||||
|
return match[1].replace(/^\.\//, '');
|
||||||
|
}
|
||||||
|
|
||||||
function assertSafePackageListing(listing, packageType) {
|
function assertSafePackageListing(listing, packageType) {
|
||||||
const lines = listing.split('\n').filter(Boolean);
|
const lines = listing.split('\n').filter(Boolean);
|
||||||
const paths = packageType === 'deb'
|
const paths = packageType === 'deb'
|
||||||
? lines.map(line => {
|
? lines.map(line => {
|
||||||
const marker = line.indexOf('./');
|
try {
|
||||||
if (marker < 0) fail(`Could not parse a Debian package path: ${line}`);
|
return parseDebianPackagePath(line);
|
||||||
return line.slice(marker + 2);
|
} catch (error) {
|
||||||
|
fail(error.message);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
: lines.map(line => line.replace(/^\/+/, ''));
|
: lines.map(line => line.replace(/^\/+/, ''));
|
||||||
|
|
||||||
@@ -214,28 +225,34 @@ function verifyExtractedPackage(packageType, packageFile, target, root) {
|
|||||||
], { env: { APPDIR: root } });
|
], { env: { APPDIR: root } });
|
||||||
}
|
}
|
||||||
|
|
||||||
const target = argValue('--target');
|
function main() {
|
||||||
if (!target) fail('Pass --target <Rust target triple>.');
|
const target = argValue('--target');
|
||||||
if (os.platform() !== 'linux') fail('Linux package verification must run on Linux.');
|
if (!target) fail('Pass --target <Rust target triple>.');
|
||||||
|
if (os.platform() !== 'linux') fail('Linux package verification must run on Linux.');
|
||||||
|
|
||||||
const bundleRoot = path.join(repoRoot, 'src-tauri', 'target', target, 'release', 'bundle');
|
const bundleRoot = path.join(repoRoot, 'src-tauri', 'target', target, 'release', 'bundle');
|
||||||
const deb = findSingle(path.join(bundleRoot, 'deb'), '.deb', 'Debian package');
|
const deb = findSingle(path.join(bundleRoot, 'deb'), '.deb', 'Debian package');
|
||||||
const rpm = findSingle(path.join(bundleRoot, 'rpm'), '.rpm', 'RPM package');
|
const rpm = findSingle(path.join(bundleRoot, 'rpm'), '.rpm', 'RPM package');
|
||||||
const extractionRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'firelink-linux-packages-'));
|
const extractionRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'firelink-linux-packages-'));
|
||||||
const debRoot = path.join(extractionRoot, 'deb');
|
const debRoot = path.join(extractionRoot, 'deb');
|
||||||
const rpmRoot = path.join(extractionRoot, 'rpm');
|
const rpmRoot = path.join(extractionRoot, 'rpm');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertPackageListing(deb, 'deb', 'usr/share/metainfo/com.nimbold.firelink.metainfo.xml');
|
assertPackageListing(deb, 'deb', 'usr/share/metainfo/com.nimbold.firelink.metainfo.xml');
|
||||||
assertPackageRecommendations(deb, 'deb');
|
assertPackageRecommendations(deb, 'deb');
|
||||||
extractDeb(deb, debRoot);
|
extractDeb(deb, debRoot);
|
||||||
verifyExtractedPackage('deb', deb, target, debRoot);
|
verifyExtractedPackage('deb', deb, target, debRoot);
|
||||||
|
|
||||||
assertPackageListing(rpm, 'rpm', 'usr/share/metainfo/com.nimbold.firelink.metainfo.xml');
|
assertPackageListing(rpm, 'rpm', 'usr/share/metainfo/com.nimbold.firelink.metainfo.xml');
|
||||||
assertPackageRecommendations(rpm, 'rpm');
|
assertPackageRecommendations(rpm, 'rpm');
|
||||||
extractRpm(rpm, rpmRoot);
|
extractRpm(rpm, rpmRoot);
|
||||||
verifyExtractedPackage('rpm', rpm, target, rpmRoot);
|
verifyExtractedPackage('rpm', rpm, target, rpmRoot);
|
||||||
console.log('Linux .deb and .rpm payload and launch verification passed.');
|
console.log('Linux .deb and .rpm payload and launch verification passed.');
|
||||||
} finally {
|
} finally {
|
||||||
fs.rmSync(extractionRoot, { recursive: true, force: true });
|
fs.rmSync(extractionRoot, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] && path.resolve(process.argv[1]) === __filename) {
|
||||||
|
main();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
|
||||||
|
import { parseDebianPackagePath } from './verify-linux-packages.js';
|
||||||
|
|
||||||
|
test('parses current dpkg-deb listings without a ./ prefix', () => {
|
||||||
|
assert.equal(
|
||||||
|
parseDebianPackagePath('drwxr-xr-x 0/0 0 2026-07-12 07:24 usr/share/'),
|
||||||
|
'usr/share/'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('parses legacy dpkg-deb listings with a ./ prefix', () => {
|
||||||
|
assert.equal(
|
||||||
|
parseDebianPackagePath('-rwxr-xr-x root/root 123 2026-07-12 07:24 ./usr/bin/firelink'),
|
||||||
|
'usr/bin/firelink'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rejects malformed dpkg-deb listing lines', () => {
|
||||||
|
assert.throws(
|
||||||
|
() => parseDebianPackagePath('not a dpkg-deb listing'),
|
||||||
|
/Could not parse a Debian package path/
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user