Updated Flatpak scripts

This commit is contained in:
Miroslav Mazel
2024-01-10 18:41:59 +01:00
parent 95ea711e97
commit 79522575f6
6 changed files with 208 additions and 134 deletions

View File

@@ -63,7 +63,7 @@ jobs:
flutter build linux --release
cd flatpak/scripts
dart pub get
dart flatpak_packager.dart --meta ../flatpak_meta.json --github
dart flatpak_packager.dart --meta ../flatpak_meta.json --github --addTodaysVersion ${{ env.VERSION }}
- name: Build AAB
run: flutter build appbundle --release

View File

@@ -3,14 +3,8 @@
"lowercaseAppName": "wger",
"githubReleaseOrganization": "wger-project",
"githubReleaseProject": "flutter",
"localReleases": [
],
"localReleaseAssets": [
],
"localLinuxBuildDir": "../build/linux",
"appDataPath": "de.wger.flutter.appdata.xml",
"appStreamPath": "de.wger.flutter.metainfo.xml",
"desktopPath": "de.wger.flutter.desktop",
"icons": {
"64x64": "logo64.png",

View File

@@ -1,17 +1,27 @@
// ignore_for_file: avoid_print
import 'dart:io';
import 'flatpak_shared.dart';
/// Creates an archive containing all the sources for the Flatpak package for a
/// specific architecture.
///
/// arguments:
/// --meta [file]
/// Required argument for providing the metadata file for this script.
/// --github
/// Use this option to pull release info from Github rather than the metadata file.
/// --addTodaysVersion [version]
/// If pulling data from Github, this provides a way to specify the release to be released today.
void main(List<String> arguments) async {
if (Platform.isWindows) {
throw Exception('Must be run under a UNIX-like operating system.');
if (!Platform.isLinux) {
throw Exception('Must be run under Linux');
}
// PARSE ARGUMENTS
final metaIndex = arguments.indexOf('--meta');
if (metaIndex == -1) {
throw Exception(
@@ -22,123 +32,136 @@ void main(List<String> arguments) async {
}
final metaFile = File(arguments[metaIndex + 1]);
if (!metaFile.existsSync()) {
if (!(await metaFile.exists())) {
throw Exception('The provided metadata file does not exist.');
}
final meta = FlatpakMeta.fromJson(metaFile);
final fetchFromGithub = arguments.contains('--github');
final addTodaysVersionIndex = arguments.indexOf('--addTodaysVersion');
if (addTodaysVersionIndex != -1 && arguments.length == addTodaysVersionIndex + 1) {
throw Exception('The --addTodaysVersion flag must be followed by the version name.');
}
final addedTodaysVersion =
addTodaysVersionIndex != -1 ? arguments[addTodaysVersionIndex + 1] : null;
// GENERATE PACKAGE
final meta = FlatpakMeta.fromJson(metaFile, skipLocalReleases: fetchFromGithub);
final outputDir = Directory('${Directory.current.path}/flatpak_generator_exports');
outputDir.createSync();
await outputDir.create();
final packageGenerator = PackageGenerator(inputDir: metaFile.parent, meta: meta);
final packageGenerator = PackageGenerator(
inputDir: metaFile.parent, meta: meta, addedTodaysVersion: addedTodaysVersion);
packageGenerator.generatePackage(
outputDir,
PackageGenerator.runningOnARM() ? CPUArchitecture.aarch64 : CPUArchitecture.x86_64,
fetchFromGithub,
);
await packageGenerator.generatePackage(
outputDir,
await PackageGenerator.runningOnARM() ? CPUArchitecture.aarch64 : CPUArchitecture.x86_64,
fetchFromGithub);
}
class PackageGenerator {
final Directory inputDir;
final FlatpakMeta meta;
final Map<CPUArchitecture, String> shaByArch = {};
final String? addedTodaysVersion;
PackageGenerator({required this.inputDir, required this.meta});
PackageGenerator({required this.inputDir, required this.meta, required this.addedTodaysVersion});
Future<void> generatePackage(
Directory outputDir, CPUArchitecture arch, bool fetchReleasesFromGithub) async {
final tempDir = outputDir.createTempSync('flutter_generator_temp');
final tempDir = await outputDir.createTemp('flutter_generator_temp');
final appId = meta.appId;
// desktop file
final desktopFile = File('${inputDir.path}/${meta.desktopPath}');
if (!desktopFile.existsSync()) {
if (!(await desktopFile.exists())) {
throw Exception(
'The desktop file does not exist under the specified path: ${desktopFile.path}');
}
desktopFile.copySync('${tempDir.path}/$appId.desktop');
await desktopFile.copy('${tempDir.path}/$appId.desktop');
// icons
final iconTempDir = Directory('${tempDir.path}/icons');
for (final icon in meta.icons) {
final iconFile = File('${inputDir.path}/${icon.path}');
if (!iconFile.existsSync()) {
if (!(await iconFile.exists())) {
throw Exception('The icon file ${iconFile.path} does not exist.');
}
final iconSubdir = Directory('${iconTempDir.path}/${icon.type}');
iconSubdir.createSync(recursive: true);
iconFile.copySync('${iconSubdir.path}/${icon.getFilename(appId)}');
await iconSubdir.create(recursive: true);
await iconFile.copy('${iconSubdir.path}/${icon.getFilename(appId)}');
}
// appdata file
final origAppDataFile = File('${inputDir.path}/${meta.appDataPath}');
if (!origAppDataFile.existsSync()) {
// AppStream metainfo file
final origAppStreamFile = File('${inputDir.path}/${meta.appStreamPath}');
if (!(await origAppStreamFile.exists())) {
throw Exception(
'The app data file does not exist under the specified path: ${origAppDataFile.path}');
'The app data file does not exist under the specified path: ${origAppStreamFile.path}');
}
final editedAppDataContent = AppDataModifier.replaceVersions(
origAppDataFile.readAsStringSync(), await meta.getReleases(fetchReleasesFromGithub));
final editedAppStreamContent = AppStreamModifier.replaceVersions(
await origAppStreamFile.readAsString(),
await meta.getReleases(fetchReleasesFromGithub, addedTodaysVersion));
final editedAppDataFile = File('${tempDir.path}/$appId.appdata.xml');
editedAppDataFile.writeAsStringSync(editedAppDataContent);
final editedAppStreamFile = File('${tempDir.path}/$appId.metainfo.xml');
await editedAppStreamFile.writeAsString(editedAppStreamContent);
// build files
final bundlePath =
'${inputDir.path}/${meta.localLinuxBuildDir}/${arch.flutterDirName}/release/bundle';
final buildDir = Directory(bundlePath);
if (!buildDir.existsSync()) {
if (!(await buildDir.exists())) {
throw Exception(
'The linux build directory does not exist under the specified path: ${buildDir.path}');
}
final destDir = Directory('${tempDir.path}/bin');
destDir.createSync();
await destDir.create();
final baseFileName = '${meta.lowercaseAppName}-linux-${arch.flatpakArchCode}';
final baseFilename = '${meta.lowercaseAppName}-linux-${arch.flatpakArchCode}';
final packagePath = '${outputDir.absolute.path}/$baseFilename.tar.gz';
final shaPath = '${outputDir.absolute.path}/$baseFilename.sha256';
await Process.run('cp', ['-r', '${buildDir.absolute.path}/.', destDir.absolute.path]);
await Process.run('tar', ['-czvf', packagePath, '.'], workingDirectory: tempDir.absolute.path);
final packagePath = '${outputDir.absolute.path}/$baseFileName.tar.gz';
Process.runSync('cp', ['-r', '${buildDir.absolute.path}/.', destDir.absolute.path]);
Process.runSync('tar', ['-czvf', packagePath, '.'], workingDirectory: tempDir.absolute.path);
print('Generated $packagePath');
final preShasum = Process.runSync('shasum', ['-a', '256', packagePath]);
final sha256 = preShasum.stdout.toString().split(' ').first;
final preShasum = await Process.run('shasum', ['-a', '256', packagePath]);
final shasum = preShasum.stdout.toString().split(' ').first;
final shaFile = await File('${outputDir.path}/$baseFileName.sha256').writeAsString(sha256);
print('Generated ${shaFile.path}');
await File(shaPath).writeAsString(shasum);
shaByArch.putIfAbsent(arch, () => sha256);
print('Generated $shaPath');
tempDir.deleteSync(recursive: true);
await tempDir.delete(recursive: true);
}
static bool runningOnARM() {
final unameRes = Process.runSync('uname', ['-m']);
static Future<bool> runningOnARM() async {
final unameRes = await Process.run('uname', ['-m']);
final unameString = unameRes.stdout.toString().trimLeft();
return unameString.startsWith('arm') || unameString.startsWith('aarch');
}
}
// updates releases in ${appName}.appdata.xml
class AppDataModifier {
static String replaceVersions(String origAppDataContent, List<Release> versions) {
// updates releases in ${appName}.metainfo.xml
class AppStreamModifier {
static String replaceVersions(String origAppStreamContent, List<Release> versions) {
final joinedReleases =
versions.map((v) => '\t\t<release version="${v.version}" date="${v.date}" />').join('\n');
final releasesSection = '<releases>\n$joinedReleases\n\t</releases>'; //todo check this
if (origAppDataContent.contains('<releases')) {
return origAppDataContent
final releasesSection = '<releases>\n$joinedReleases\n\t</releases>'; //TODO check this
if (origAppStreamContent.contains('<releases')) {
return origAppStreamContent
.replaceAll('\n', '<~>')
.replaceFirst(RegExp('<releases.*</releases>'), releasesSection)
.replaceAll('<~>', '\n');
} else {
return origAppDataContent.replaceFirst('</component>', '\n\t$releasesSection\n</component>');
return origAppStreamContent.replaceFirst(
'</component>', '\n\t$releasesSection\n</component>');
}
}
}

View File

@@ -3,20 +3,21 @@ import 'dart:io';
import 'package:http/http.dart' as http;
/// Shared files for the two Flatpak-related scripts.
class Release {
final String version;
final String date; //todo add resources
final String date; //TODO add resources
Release({required this.version, required this.date});
}
enum CPUArchitecture {
x86_64('x86_64', 'x64'),
aarch64('aarch64', 'aarch64');
aarch64('aarch64', 'arm64');
final String flatpakArchCode;
final String flutterDirName;
const CPUArchitecture(this.flatpakArchCode, this.flutterDirName);
}
@@ -43,8 +44,9 @@ class Icon {
_fileExtension = path.split('.').last;
}
String getFilename(String appId) =>
(type == _symbolicType) ? '$appId-symbolic.$_fileExtension' : '$appId.$_fileExtension';
String getFilename(String appId) => (type == _symbolicType)
? '$appId-symbolic.$_fileExtension'
: '$appId.$_fileExtension';
}
class GithubReleases {
@@ -55,25 +57,26 @@ class GithubReleases {
GithubReleases(this.githubReleaseOrganization, this.githubReleaseProject);
Future<List<Release>> getReleases() async {
Future<List<Release>> getReleases(bool canBeEmpty) async {
if (_releases == null) {
await _fetchReleasesAndAssets();
await _fetchReleasesAndAssets(canBeEmpty);
}
return _releases!;
}
Future<List<ReleaseAsset>?> getLatestReleaseAssets() async {
if (_releases == null) {
await _fetchReleasesAndAssets();
await _fetchReleasesAndAssets(false);
}
return _latestReleaseAssets;
}
Future<void> _fetchReleasesAndAssets() async {
Future<void> _fetchReleasesAndAssets(bool canBeEmpty) async {
final releaseJsonContent = (await http.get(Uri(
scheme: 'https',
host: 'api.github.com',
path: '/repos/$githubReleaseOrganization/$githubReleaseProject/releases')))
path:
'/repos/$githubReleaseOrganization/$githubReleaseProject/releases')))
.body;
final decodedJson = jsonDecode(releaseJsonContent) as List;
@@ -84,27 +87,33 @@ class GithubReleases {
await Future.forEach<dynamic>(decodedJson, (dynamic releaseDynamic) async {
final releaseMap = releaseDynamic as Map;
final releaseDateAndTime = DateTime.parse(releaseMap['published_at'] as String);
final releaseDateString = releaseDateAndTime.toIso8601String().split('T').first;
final releaseDateAndTime =
DateTime.parse(releaseMap['published_at'] as String);
final releaseDateString =
releaseDateAndTime.toIso8601String().split('T').first;
if (latestReleaseAssetDate == null ||
(latestReleaseAssetDate?.compareTo(releaseDateAndTime) == -1)) {
final assets = await _parseReleaseAssets(releaseMap['assets'] as List);
final assets =
await _parseGithubReleaseAssets(releaseMap['assets'] as List);
if (assets != null) {
_latestReleaseAssets = assets;
latestReleaseAssetDate = releaseDateAndTime;
}
}
releases.add(Release(version: releaseMap['name'] as String, date: releaseDateString));
releases.add(Release(
version: releaseMap['name'] as String, date: releaseDateString));
});
if (releases.isNotEmpty) {
if (releases.isNotEmpty || canBeEmpty) {
_releases = releases;
} else {
throw Exception("Github must contain at least 1 release.");
}
}
Future<List<ReleaseAsset>?> _parseReleaseAssets(List assetMaps) async {
Future<List<ReleaseAsset>?> _parseGithubReleaseAssets(List assetMaps) async {
String? x64TarballUrl;
String? x64Sha;
String? aarch64TarballUrl;
@@ -115,7 +124,8 @@ class GithubReleases {
final downloadUrl = amMap['browser_download_url'] as String;
final filename = amMap['name'] as String;
final fileExtension = filename.substring(filename.indexOf('.') + 1);
final filenameWithoutExtension = filename.substring(0, filename.indexOf('.'));
final filenameWithoutExtension =
filename.substring(0, filename.indexOf('.'));
final arch = filenameWithoutExtension.endsWith('aarch64')
? CPUArchitecture.aarch64
@@ -166,15 +176,14 @@ class GithubReleases {
return res.isEmpty ? null : res;
}
Future<String> _readSha(String shaUrl) async {
return (await http.get(Uri.parse(shaUrl))).body.split(' ').first;
}
Future<String> _readSha(String shaUrl) async =>
(await http.get(Uri.parse(shaUrl))).body.split(' ').first;
}
class FlatpakMeta {
final String appId;
final String lowercaseAppName;
final String appDataPath;
final String appStreamPath;
final String desktopPath;
final List<Icon> icons;
@@ -202,7 +211,7 @@ class FlatpakMeta {
required List<Release>? localReleases,
required List<ReleaseAsset>? localReleaseAssets,
required this.localLinuxBuildDir,
required this.appDataPath,
required this.appStreamPath,
required this.desktopPath,
required this.icons,
required this.freedesktopRuntime,
@@ -212,88 +221,117 @@ class FlatpakMeta {
: _localReleases = localReleases,
_localReleaseAssets = localReleaseAssets {
if (githubReleaseOrganization != null && githubReleaseProject != null) {
_githubReleases = GithubReleases(githubReleaseOrganization!, githubReleaseProject!);
_githubReleases =
GithubReleases(githubReleaseOrganization!, githubReleaseProject!);
}
}
Future<List<Release>> getReleases(bool fetchReleasesFromGithub) async {
Future<List<Release>> getReleases(
bool fetchReleasesFromGithub, String? addedTodaysVersion) async {
final releases = List<Release>.empty(growable: true);
if (addedTodaysVersion != null) {
releases.add(Release(
version: addedTodaysVersion,
date: DateTime.now().toIso8601String().split("T").first));
}
if (fetchReleasesFromGithub) {
if (_githubReleases == null) {
throw Exception(
'Metadata must include Github repository info if fetching releases from Github.');
}
return await _githubReleases!.getReleases();
releases.addAll(
await _githubReleases!.getReleases(addedTodaysVersion != null));
} else {
if (_localReleases == null) {
throw Exception('Metadata must include releases if not fetching releases from Github.');
if (_localReleases == null && addedTodaysVersion == null) {
throw Exception(
'Metadata must include releases if not fetching releases from Github.');
}
if (_localReleases?.isNotEmpty ?? false) {
releases.addAll(_localReleases!);
}
return _localReleases!;
}
return releases;
}
Future<List<ReleaseAsset>?> getReleaseAssets(bool fetchReleasesFromGithub) async {
Future<List<ReleaseAsset>?> getLatestReleaseAssets(
bool fetchReleasesFromGithub) async {
if (fetchReleasesFromGithub) {
if (_githubReleases == null) {
throw Exception(
'Metadata must include Github repository info if fetching releases from Github.');
}
return _githubReleases!.getLatestReleaseAssets();
return await _githubReleases!.getLatestReleaseAssets();
} else {
if (_localReleases == null) {
throw Exception('Metadata must include releases if not fetching releases from Github.');
throw Exception(
'Metadata must include releases if not fetching releases from Github.');
}
return _localReleaseAssets;
}
}
static FlatpakMeta fromJson(File jsonFile) {
static FlatpakMeta fromJson(File jsonFile, {bool skipLocalReleases = false}) {
try {
final dynamic json = jsonDecode(jsonFile.readAsStringSync());
return FlatpakMeta(
appId: json['appId'] as String,
lowercaseAppName: json['lowercaseAppName'] as String,
githubReleaseOrganization: json['githubReleaseOrganization'] as String?,
githubReleaseOrganization:
json['githubReleaseOrganization'] as String?,
githubReleaseProject: json['githubReleaseProject'] as String?,
localReleases: (json['localReleases'] as List?)?.map((dynamic r) {
final rMap = r as Map;
return Release(version: rMap['version'] as String, date: rMap['date'] as String);
}).toList(),
localReleaseAssets: (json['localReleaseAssets'] as List?)?.map((dynamic ra) {
final raMap = ra as Map;
final archString = raMap['arch'] as String;
final arch = (archString == CPUArchitecture.x86_64.flatpakArchCode)
? CPUArchitecture.x86_64
: (archString == CPUArchitecture.aarch64.flatpakArchCode)
? CPUArchitecture.aarch64
: null;
if (arch == null) {
throw Exception(
'Architecture must be either "${CPUArchitecture.x86_64.flatpakArchCode}" or "${CPUArchitecture.aarch64.flatpakArchCode}"');
}
final tarballPath = '${jsonFile.parent.path}/${raMap['tarballPath'] as String}';
final preShasum = Process.runSync('shasum', ['-a', '256', tarballPath]);
final shasum = preShasum.stdout.toString().split(' ').first;
if (preShasum.exitCode != 0) {
throw Exception(preShasum.stderr);
}
return ReleaseAsset(
arch: arch,
tarballUrlOrPath: tarballPath,
isRelativeLocalPath: true,
tarballSha256: shasum);
}).toList(),
localReleases: skipLocalReleases
? null
: (json['localReleases'] as List?)?.map((dynamic r) {
final rMap = r as Map;
return Release(
version: rMap['version'] as String,
date: rMap['date'] as String);
}).toList(),
localReleaseAssets: skipLocalReleases
? null
: (json['localReleaseAssets'] as List?)?.map((dynamic ra) {
final raMap = ra as Map;
final archString = raMap['arch'] as String;
final arch = (archString ==
CPUArchitecture.x86_64.flatpakArchCode)
? CPUArchitecture.x86_64
: (archString == CPUArchitecture.aarch64.flatpakArchCode)
? CPUArchitecture.aarch64
: null;
if (arch == null) {
throw Exception(
'Architecture must be either "${CPUArchitecture.x86_64.flatpakArchCode}" or "${CPUArchitecture.aarch64.flatpakArchCode}"');
}
final tarballFile = File(
'${jsonFile.parent.path}/${raMap['tarballPath'] as String}');
final tarballPath = tarballFile.absolute.path;
final preShasum =
Process.runSync('shasum', ['-a', '256', tarballPath]);
final shasum = preShasum.stdout.toString().split(' ').first;
if (preShasum.exitCode != 0) {
throw Exception(preShasum.stderr);
}
return ReleaseAsset(
arch: arch,
tarballUrlOrPath: tarballPath,
isRelativeLocalPath: true,
tarballSha256: shasum);
}).toList(),
localLinuxBuildDir: json['localLinuxBuildDir'] as String,
appDataPath: json['appDataPath'] as String,
appStreamPath: json['appStreamPath'] as String,
desktopPath: json['desktopPath'] as String,
icons: (json['icons'] as Map).entries.map((mapEntry) {
return Icon(type: mapEntry.key as String, path: mapEntry.value as String);
return Icon(
type: mapEntry.key as String, path: mapEntry.value as String);
}).toList(),
freedesktopRuntime: json['freedesktopRuntime'] as String,
buildCommandsAfterUnpack: (json['buildCommandsAfterUnpack'] as List?)
?.map((dynamic bc) => bc as String)
.toList(),
extraModules: json['extraModules'] as List?,
finishArgs: (json['finishArgs'] as List).map((dynamic fa) => fa as String).toList());
finishArgs: (json['finishArgs'] as List)
.map((dynamic fa) => fa as String)
.toList());
} catch (e) {
throw Exception('Could not parse JSON file, due to this error:\n$e');
}

View File

@@ -1,8 +1,20 @@
// ignore_for_file: avoid_print
import 'dart:convert';
import 'dart:io';
import 'flatpak_shared.dart';
/// Generates the Flatpak manifest.
/// (Separate from the package generation, as those are generated per each
/// architecture.)
///
/// arguments:
/// --meta [file]
/// Required argument for providing the metadata file for this script.
/// --github
/// Use this option to pull release info from Github rather than the metadata file.
void main(List<String> arguments) async {
if (Platform.isWindows) {
throw Exception('Must be run under a UNIX-like operating system.');
@@ -14,7 +26,8 @@ void main(List<String> arguments) async {
'You must run this script with a metadata file argument, using the --meta flag.');
}
if (arguments.length == metaIndex + 1) {
throw Exception('The --meta flag must be followed by the path to the metadata file.');
throw Exception(
'The --meta flag must be followed by the path to the metadata file.');
}
final metaFile = File(arguments[metaIndex + 1]);
@@ -22,21 +35,25 @@ void main(List<String> arguments) async {
throw Exception('The provided metadata file does not exist.');
}
final meta = FlatpakMeta.fromJson(metaFile);
final fetchFromGithub = arguments.contains('--github');
final outputDir = Directory('${Directory.current.path}/flatpak_generator_exports');
final meta =
FlatpakMeta.fromJson(metaFile, skipLocalReleases: fetchFromGithub);
final outputDir =
Directory('${Directory.current.path}/flatpak_generator_exports');
outputDir.createSync();
final manifestGenerator = FlatpakManifestGenerator(meta);
final manifestContent = await manifestGenerator.generateFlatpakManifest(fetchFromGithub);
final manifestContent =
await manifestGenerator.generateFlatpakManifest(fetchFromGithub);
final manifestPath = '${outputDir.path}/${meta.appId}.json';
final manifestFile = File(manifestPath);
manifestFile.writeAsStringSync(manifestContent);
print('Generated $manifestPath');
final flathubJsonContent = await manifestGenerator.generateFlathubJson(fetchFromGithub);
final flathubJsonContent =
await manifestGenerator.generateFlathubJson(fetchFromGithub);
if (flathubJsonContent != null) {
final flathubJsonPath = '${outputDir.path}/flathub.json';
final flathubJsonFile = File(flathubJsonPath);
@@ -56,7 +73,7 @@ class FlatpakManifestGenerator {
Future<String> generateFlatpakManifest(bool fetchFromGithub) async {
final appName = meta.lowercaseAppName;
final appId = meta.appId;
final assets = await meta.getReleaseAssets(fetchFromGithub);
final assets = await meta.getLatestReleaseAssets(fetchFromGithub);
if (assets == null) {
throw Exception('There are no associated assets.');
@@ -88,7 +105,7 @@ class FlatpakManifestGenerator {
...meta.icons.map((icon) =>
'install -Dm644 $appName/icons/${icon.type}/${icon.getFilename(appId)} /app/share/icons/hicolor/${icon.type}/apps/${icon.getFilename(appId)}'),
'install -Dm644 $appName/$appId.desktop /app/share/applications/$appId.desktop',
'install -Dm644 $appName/$appId.appdata.xml /app/share/applications/$appId.appdata.xml'
'install -Dm644 $appName/$appId.metainfo.xml /app/share/metainfo/$appId.metainfo.xml'
],
'sources': assets
.map((a) => {
@@ -105,7 +122,7 @@ class FlatpakManifestGenerator {
}
Future<String?> generateFlathubJson(bool fetchFromGithub) async {
final assets = await meta.getReleaseAssets(fetchFromGithub);
final assets = await meta.getLatestReleaseAssets(fetchFromGithub);
if (assets == null) {
throw Exception('There are no associated assets.');
@@ -115,7 +132,8 @@ class FlatpakManifestGenerator {
const encoder = JsonEncoder.withIndent(' ');
final onlyArchListInput = fetchFromGithub ? _githubArchSupport! : _localArchSupport!;
final onlyArchListInput =
fetchFromGithub ? _githubArchSupport! : _localArchSupport!;
final onlyArchList = List<String>.empty(growable: true);
for (final e in onlyArchListInput.entries) {
@@ -131,7 +149,8 @@ class FlatpakManifestGenerator {
}
}
void _lazyGenerateArchSupportMap(bool fetchFromGithub, List<ReleaseAsset> assets) {
void _lazyGenerateArchSupportMap(
bool fetchFromGithub, List<ReleaseAsset> assets) {
if (fetchFromGithub) {
if (_githubArchSupport == null) {
_githubArchSupport = <CPUArchitecture, bool>{