From 862f83b297bd145b22e7b13ad41f7080cee21cb6 Mon Sep 17 00:00:00 2001 From: Edison Jwa Date: Mon, 25 May 2026 16:02:01 +0900 Subject: [PATCH] fix: parse linux distro metadata --- .../services/startup_dependency_check.dart | 31 +++++++++++++------ .../startup_dependency_check_test.dart | 19 ++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/apps/chanora_flutter/lib/services/startup_dependency_check.dart b/apps/chanora_flutter/lib/services/startup_dependency_check.dart index 16efbd4..b361a17 100644 --- a/apps/chanora_flutter/lib/services/startup_dependency_check.dart +++ b/apps/chanora_flutter/lib/services/startup_dependency_check.dart @@ -233,24 +233,37 @@ Future<_LinuxDistro> _detectLinuxDistro() async { return _LinuxDistro.other; } - final lower = content.toLowerCase(); - if (lower.contains('id=fedora') || - lower.contains('id_like="fedora"') || - lower.contains('id_like=fedora')) { + final fields = _parseOsRelease(content); + final id = fields['id'] ?? ''; + final idLike = (fields['id_like'] ?? '').split(RegExp(r'\s+')); + final ids = {id, ...idLike}; + if (ids.contains('fedora')) { return _LinuxDistro.fedora; } - if (lower.contains('id=ubuntu') || - lower.contains('id=debian') || - lower.contains('id_like=debian') || - lower.contains('id_like="ubuntu debian"')) { + if (ids.contains('ubuntu') || ids.contains('debian')) { return _LinuxDistro.debian; } - if (lower.contains('id=arch') || lower.contains('id_like=arch')) { + if (ids.contains('arch')) { return _LinuxDistro.arch; } return _LinuxDistro.other; } +Map _parseOsRelease(String content) { + final fields = {}; + for (final line in content.split('\n')) { + final separator = line.indexOf('='); + if (separator <= 0) continue; + final key = line.substring(0, separator).trim().toLowerCase(); + var value = line.substring(separator + 1).trim().toLowerCase(); + if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) { + value = value.substring(1, value.length - 1); + } + fields[key] = value; + } + return fields; +} + _LinuxArch _detectLinuxArch() { return switch (_currentAbiProvider()) { Abi.linuxX64 => _LinuxArch.x64, diff --git a/apps/chanora_flutter/test/services/startup_dependency_check_test.dart b/apps/chanora_flutter/test/services/startup_dependency_check_test.dart index 477387d..8b4480a 100644 --- a/apps/chanora_flutter/test/services/startup_dependency_check_test.dart +++ b/apps/chanora_flutter/test/services/startup_dependency_check_test.dart @@ -38,6 +38,25 @@ void main() { expect(sdl.installHints.single.command, 'sudo apt install libsdl2-2.0-0'); }); + test('distro detection parses quoted ID_LIKE lists', () async { + debugResetStartupDependencyCheck( + platformIsLinux: () => true, + libraryProbe: (candidate) => false, + fileExists: (_) async => true, + osReleaseProvider: () async => 'ID=rocky\nID_LIKE="fedora rhel"\n', + resolvedExecutableProvider: () => '/opt/chanora/chanora_flutter', + currentDirectoryProvider: () => '/tmp', + ); + + final result = await checkStartupDependencies(); + + expect(result.platformLabel, 'Fedora'); + final sdl = result.issues.singleWhere( + (issue) => issue.id == 'linux-sdl2-runtime', + ); + expect(sdl.installHints.single.command, 'sudo dnf install SDL2'); + }); + test( 'missing ONNX runtime is reported as recommended when SDL2 is present', () async {