build: include X11 override in Snap package configuration

Entire-Checkpoint: 21b9b9f90f23
This commit is contained in:
4gray committed 2026-04-12 18:56:20 +02:00
1 parent 35141bec31
commit e25c137eec
3 files changed
+264 -3

No files matched your search

@@ -15,7 +15,14 @@ if (!platform) {
const workspaceRoot = process.cwd();
const executablesRoot = path.join(workspaceRoot, 'dist', 'executables');
const packageJsonPath = path.join(workspaceRoot, 'package.json');
const electronBuilderConfigPath = path.join(workspaceRoot, 'electron-builder.json');
const electronBuilderConfigPath = path.join(
workspaceRoot,
'electron-builder.json'
);
const builderEffectiveConfigPath = path.join(
executablesRoot,
'builder-effective-config.yaml'
);
const flatpakMetainfoPath = path.join(
workspaceRoot,
'apps',
@@ -28,6 +35,7 @@ const electronBuilderConfig = JSON.parse(
fs.readFileSync(electronBuilderConfigPath, 'utf8')
);
const flatpakFinishArgs = electronBuilderConfig.flatpak?.finishArgs ?? [];
const snapConfigInspection = loadSnapConfigInspection();
const workerRelativeDir = path.join(
'dist',
'apps',
@@ -49,7 +57,9 @@ const nativeModuleRelativeDirs = [
const linuxExecutableName = getLinuxExecutableName();
function directoryExists(directoryPath) {
return fs.existsSync(directoryPath) && fs.statSync(directoryPath).isDirectory();
return (
fs.existsSync(directoryPath) && fs.statSync(directoryPath).isDirectory()
);
}
function fileExists(filePath) {
@@ -133,6 +143,219 @@ function getLinuxExecutableName() {
return packageMetadata.name.toLowerCase();
}
function parseYamlScalar(value) {
const normalizedValue = value.trim();
if (normalizedValue === 'true') {
return true;
}
if (normalizedValue === 'false') {
return false;
}
if (normalizedValue === 'null') {
return null;
}
const singleQuotedMatch = normalizedValue.match(/^'(.*)'$/);
if (singleQuotedMatch) {
return singleQuotedMatch[1].replace(/''/g, "'");
}
const doubleQuotedMatch = normalizedValue.match(/^"(.*)"$/);
if (doubleQuotedMatch) {
return doubleQuotedMatch[1].replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
return normalizedValue;
}
function getYamlSectionLines(yamlContent, sectionName) {
const lines = yamlContent.split(/\r?\n/);
const sectionHeader = `${sectionName}:`;
const sectionLines = [];
let isInsideSection = false;
for (const line of lines) {
if (!isInsideSection) {
if (line === sectionHeader) {
isInsideSection = true;
}
continue;
}
if (line.trim() === '') {
sectionLines.push(line);
continue;
}
const indentation = line.match(/^ */)?.[0].length ?? 0;
if (indentation === 0) {
break;
}
sectionLines.push(line);
}
return isInsideSection ? sectionLines : null;
}
function parseIndentedYamlSequence(lines, startIndex, indentation) {
const values = [];
let nextIndex = startIndex;
while (nextIndex < lines.length) {
const line = lines[nextIndex];
const trimmedLine = line.trim();
if (trimmedLine === '') {
nextIndex += 1;
continue;
}
const currentIndentation = line.match(/^ */)?.[0].length ?? 0;
if (currentIndentation < indentation) {
break;
}
if (currentIndentation > indentation || !trimmedLine.startsWith('- ')) {
break;
}
values.push(parseYamlScalar(trimmedLine.slice(2)));
nextIndex += 1;
}
return {
values,
nextIndex,
};
}
function parseIndentedYamlMapping(lines, startIndex, indentation) {
const values = {};
let nextIndex = startIndex;
while (nextIndex < lines.length) {
const line = lines[nextIndex];
const trimmedLine = line.trim();
if (trimmedLine === '') {
nextIndex += 1;
continue;
}
const currentIndentation = line.match(/^ */)?.[0].length ?? 0;
if (currentIndentation < indentation) {
break;
}
if (currentIndentation > indentation) {
break;
}
const separatorIndex = trimmedLine.indexOf(':');
if (separatorIndex === -1) {
break;
}
const key = trimmedLine.slice(0, separatorIndex).trim();
const rawValue = trimmedLine.slice(separatorIndex + 1).trim();
values[key] = parseYamlScalar(rawValue);
nextIndex += 1;
}
return {
values,
nextIndex,
};
}
function parseEffectiveSnapConfig(yamlContent) {
const sectionLines = getYamlSectionLines(yamlContent, 'snap');
if (!sectionLines) {
return null;
}
const snapConfig = {};
for (let index = 0; index < sectionLines.length; index += 1) {
const line = sectionLines[index];
const trimmedLine = line.trim();
if (trimmedLine === '') {
continue;
}
const indentation = line.match(/^ */)?.[0].length ?? 0;
if (indentation !== 2) {
continue;
}
const separatorIndex = trimmedLine.indexOf(':');
if (separatorIndex === -1) {
continue;
}
const key = trimmedLine.slice(0, separatorIndex).trim();
const rawValue = trimmedLine.slice(separatorIndex + 1).trim();
if (rawValue !== '') {
snapConfig[key] = parseYamlScalar(rawValue);
continue;
}
if (key === 'executableArgs') {
const { values, nextIndex } = parseIndentedYamlSequence(
sectionLines,
index + 1,
4
);
snapConfig[key] = values;
index = nextIndex - 1;
continue;
}
if (key === 'environment') {
const { values, nextIndex } = parseIndentedYamlMapping(
sectionLines,
index + 1,
4
);
snapConfig[key] = values;
index = nextIndex - 1;
}
}
return snapConfig;
}
function loadSnapConfigInspection() {
if (fileExists(builderEffectiveConfigPath)) {
const effectiveConfigContent = fs.readFileSync(
builderEffectiveConfigPath,
'utf8'
);
const effectiveSnapConfig = parseEffectiveSnapConfig(
effectiveConfigContent
);
if (effectiveSnapConfig) {
return {
config: effectiveSnapConfig,
sourcePath: builderEffectiveConfigPath,
};
}
}
return {
config: electronBuilderConfig.snap ?? {},
sourcePath: electronBuilderConfigPath,
};
}
function verifyLinuxLauncher(resourceDir, errors) {
const appDir = path.dirname(resourceDir);
const launcherPath = path.join(appDir, linuxExecutableName);
@@ -186,6 +409,26 @@ function verifyFlatpakPermissions(errors) {
}
}
function verifySnapPackagingConfig(errors) {
const snapExecutableArgs = Array.isArray(
snapConfigInspection.config?.executableArgs
)
? snapConfigInspection.config.executableArgs
: [];
if (!snapExecutableArgs.includes('--ozone-platform=x11')) {
errors.push(
`Snap config in ${snapConfigInspection.sourcePath} must include --ozone-platform=x11 in executableArgs.`
);
}
if (snapConfigInspection.config?.allowNativeWayland === true) {
errors.push(
`Snap config in ${snapConfigInspection.sourcePath} must not enable allowNativeWayland while the X11 startup workaround is required.`
);
}
}
function verifyResourceDir(resourceDir) {
const missingWorkers = workerFiles.filter(
(workerFile) =>
@@ -219,9 +462,12 @@ function verifyResourceDir(resourceDir) {
if (platform === 'linux') {
if (!fileExists(flatpakMetainfoPath)) {
errors.push(`Missing Flatpak metainfo file: ${flatpakMetainfoPath}`);
errors.push(
`Missing Flatpak metainfo file: ${flatpakMetainfoPath}`
);
}
verifyFlatpakPermissions(errors);
verifySnapPackagingConfig(errors);
verifyLinuxLauncher(resourceDir, errors);
}