Skip to content

Commit 988304f

Browse files
author
Miroslav Mazel
committed
Flatpak script updates
1 parent 0bc5e8e commit 988304f

File tree

7 files changed

+219
-146
lines changed

7 files changed

+219
-146
lines changed

.github/workflows/build-release.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ jobs:
1212
uses: actions/checkout@v4
1313

1414
- name: Setup Java
15-
uses: actions/setup-java@v4
15+
uses: actions/setup-java@v3
1616
with:
17-
java-version: '17'
18-
distribution: 'oracle'
17+
java-version: 17.x
1918

2019
- name: Setup Ruby
2120
uses: ruby/setup-ruby@v1
@@ -64,7 +63,7 @@ jobs:
6463
flutter build linux --release
6564
cd flatpak/scripts
6665
dart pub get
67-
dart flatpak_packager.dart --meta ../flatpak_meta.json --github
66+
dart flatpak_packager.dart --meta ../flatpak_meta.json --github --addTodaysVersion ${{ env.VERSION }}
6867
6968
- name: Build AAB
7069
run: flutter build appbundle --release
File renamed without changes.

flatpak/flatpak_meta.json

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,8 @@
33
"lowercaseAppName": "wger",
44
"githubReleaseOrganization": "wger-project",
55
"githubReleaseProject": "flutter",
6-
"localReleases": [
7-
8-
],
9-
"localReleaseAssets": [
10-
11-
],
126
"localLinuxBuildDir": "../build/linux",
13-
"appDataPath": "de.wger.flutter.appdata.xml",
7+
"appStreamPath": "de.wger.flutter.metainfo.xml",
148
"desktopPath": "de.wger.flutter.desktop",
159
"icons": {
1610
"64x64": "logo64.png",
Lines changed: 73 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
// ignore_for_file: avoid_print
22

33
import 'dart:io';
4-
54
import 'flatpak_shared.dart';
65

6+
/// Creates an archive containing all the sources for the Flatpak package for a
7+
/// specific architecture.
8+
///
79
/// arguments:
810
/// --meta [file]
11+
/// Required argument for providing the metadata file for this script.
12+
913
/// --github
14+
/// Use this option to pull release info from Github rather than the metadata file.
15+
16+
/// --addTodaysVersion [version]
17+
/// If pulling data from Github, this provides a way to specify the release to be released today.
18+
1019
void main(List<String> arguments) async {
11-
if (Platform.isWindows) {
12-
throw Exception('Must be run under a UNIX-like operating system.');
20+
if (!Platform.isLinux) {
21+
throw Exception('Must be run under Linux');
1322
}
1423

24+
// PARSE ARGUMENTS
1525
final metaIndex = arguments.indexOf('--meta');
1626
if (metaIndex == -1) {
1727
throw Exception(
@@ -22,123 +32,136 @@ void main(List<String> arguments) async {
2232
}
2333

2434
final metaFile = File(arguments[metaIndex + 1]);
25-
if (!metaFile.existsSync()) {
35+
if (!(await metaFile.exists())) {
2636
throw Exception('The provided metadata file does not exist.');
2737
}
2838

29-
final meta = FlatpakMeta.fromJson(metaFile);
30-
3139
final fetchFromGithub = arguments.contains('--github');
3240

41+
final addTodaysVersionIndex = arguments.indexOf('--addTodaysVersion');
42+
if (addTodaysVersionIndex != -1 && arguments.length == addTodaysVersionIndex + 1) {
43+
throw Exception('The --addTodaysVersion flag must be followed by the version name.');
44+
}
45+
46+
final addedTodaysVersion =
47+
addTodaysVersionIndex != -1 ? arguments[addTodaysVersionIndex + 1] : null;
48+
49+
// GENERATE PACKAGE
50+
51+
final meta = FlatpakMeta.fromJson(metaFile, skipLocalReleases: fetchFromGithub);
52+
3353
final outputDir = Directory('${Directory.current.path}/flatpak_generator_exports');
34-
outputDir.createSync();
54+
await outputDir.create();
3555

36-
final packageGenerator = PackageGenerator(inputDir: metaFile.parent, meta: meta);
56+
final packageGenerator = PackageGenerator(
57+
inputDir: metaFile.parent, meta: meta, addedTodaysVersion: addedTodaysVersion);
3758

38-
packageGenerator.generatePackage(
39-
outputDir,
40-
PackageGenerator.runningOnARM() ? CPUArchitecture.aarch64 : CPUArchitecture.x86_64,
41-
fetchFromGithub,
42-
);
59+
await packageGenerator.generatePackage(
60+
outputDir,
61+
await PackageGenerator.runningOnARM() ? CPUArchitecture.aarch64 : CPUArchitecture.x86_64,
62+
fetchFromGithub);
4363
}
4464

4565
class PackageGenerator {
4666
final Directory inputDir;
4767
final FlatpakMeta meta;
48-
final Map<CPUArchitecture, String> shaByArch = {};
68+
final String? addedTodaysVersion;
4969

50-
PackageGenerator({required this.inputDir, required this.meta});
70+
PackageGenerator({required this.inputDir, required this.meta, required this.addedTodaysVersion});
5171

5272
Future<void> generatePackage(
5373
Directory outputDir, CPUArchitecture arch, bool fetchReleasesFromGithub) async {
54-
final tempDir = outputDir.createTempSync('flutter_generator_temp');
74+
final tempDir = await outputDir.createTemp('flutter_generator_temp');
5575
final appId = meta.appId;
5676

5777
// desktop file
5878
final desktopFile = File('${inputDir.path}/${meta.desktopPath}');
5979

60-
if (!desktopFile.existsSync()) {
80+
if (!(await desktopFile.exists())) {
6181
throw Exception(
6282
'The desktop file does not exist under the specified path: ${desktopFile.path}');
6383
}
6484

65-
desktopFile.copySync('${tempDir.path}/$appId.desktop');
85+
await desktopFile.copy('${tempDir.path}/$appId.desktop');
6686

6787
// icons
6888
final iconTempDir = Directory('${tempDir.path}/icons');
6989

7090
for (final icon in meta.icons) {
7191
final iconFile = File('${inputDir.path}/${icon.path}');
72-
if (!iconFile.existsSync()) {
92+
if (!(await iconFile.exists())) {
7393
throw Exception('The icon file ${iconFile.path} does not exist.');
7494
}
7595
final iconSubdir = Directory('${iconTempDir.path}/${icon.type}');
76-
iconSubdir.createSync(recursive: true);
77-
iconFile.copySync('${iconSubdir.path}/${icon.getFilename(appId)}');
96+
await iconSubdir.create(recursive: true);
97+
await iconFile.copy('${iconSubdir.path}/${icon.getFilename(appId)}');
7898
}
7999

80-
// appdata file
81-
final origAppDataFile = File('${inputDir.path}/${meta.appDataPath}');
82-
if (!origAppDataFile.existsSync()) {
100+
// AppStream metainfo file
101+
final origAppStreamFile = File('${inputDir.path}/${meta.appStreamPath}');
102+
if (!(await origAppStreamFile.exists())) {
83103
throw Exception(
84-
'The app data file does not exist under the specified path: ${origAppDataFile.path}');
104+
'The app data file does not exist under the specified path: ${origAppStreamFile.path}');
85105
}
86106

87-
final editedAppDataContent = AppDataModifier.replaceVersions(
88-
origAppDataFile.readAsStringSync(), await meta.getReleases(fetchReleasesFromGithub));
107+
final editedAppStreamContent = AppStreamModifier.replaceVersions(
108+
await origAppStreamFile.readAsString(),
109+
await meta.getReleases(fetchReleasesFromGithub, addedTodaysVersion));
89110

90-
final editedAppDataFile = File('${tempDir.path}/$appId.appdata.xml');
91-
editedAppDataFile.writeAsStringSync(editedAppDataContent);
111+
final editedAppStreamFile = File('${tempDir.path}/$appId.metainfo.xml');
112+
await editedAppStreamFile.writeAsString(editedAppStreamContent);
92113

93114
// build files
94115
final bundlePath =
95116
'${inputDir.path}/${meta.localLinuxBuildDir}/${arch.flutterDirName}/release/bundle';
96117
final buildDir = Directory(bundlePath);
97-
if (!buildDir.existsSync()) {
118+
if (!(await buildDir.exists())) {
98119
throw Exception(
99120
'The linux build directory does not exist under the specified path: ${buildDir.path}');
100121
}
101122
final destDir = Directory('${tempDir.path}/bin');
102-
destDir.createSync();
123+
await destDir.create();
124+
125+
final baseFilename = '${meta.lowercaseAppName}-linux-${arch.flatpakArchCode}';
126+
final packagePath = '${outputDir.absolute.path}/$baseFilename.tar.gz';
127+
final shaPath = '${outputDir.absolute.path}/$baseFilename.sha256';
103128

104-
final baseFileName = '${meta.lowercaseAppName}-linux-${arch.flatpakArchCode}';
129+
await Process.run('cp', ['-r', '${buildDir.absolute.path}/.', destDir.absolute.path]);
130+
await Process.run('tar', ['-czvf', packagePath, '.'], workingDirectory: tempDir.absolute.path);
105131

106-
final packagePath = '${outputDir.absolute.path}/$baseFileName.tar.gz';
107-
Process.runSync('cp', ['-r', '${buildDir.absolute.path}/.', destDir.absolute.path]);
108-
Process.runSync('tar', ['-czvf', packagePath, '.'], workingDirectory: tempDir.absolute.path);
109132
print('Generated $packagePath');
110133

111-
final preShasum = Process.runSync('shasum', ['-a', '256', packagePath]);
112-
final sha256 = preShasum.stdout.toString().split(' ').first;
134+
final preShasum = await Process.run('shasum', ['-a', '256', packagePath]);
135+
final shasum = preShasum.stdout.toString().split(' ').first;
113136

114-
final shaFile = await File('${outputDir.path}/$baseFileName.sha256').writeAsString(sha256);
115-
print('Generated ${shaFile.path}');
137+
await File(shaPath).writeAsString(shasum);
116138

117-
shaByArch.putIfAbsent(arch, () => sha256);
139+
print('Generated $shaPath');
118140

119-
tempDir.deleteSync(recursive: true);
141+
await tempDir.delete(recursive: true);
120142
}
121143

122-
static bool runningOnARM() {
123-
final unameRes = Process.runSync('uname', ['-m']);
144+
static Future<bool> runningOnARM() async {
145+
final unameRes = await Process.run('uname', ['-m']);
124146
final unameString = unameRes.stdout.toString().trimLeft();
125147
return unameString.startsWith('arm') || unameString.startsWith('aarch');
126148
}
127149
}
128150

129-
// updates releases in ${appName}.appdata.xml
130-
class AppDataModifier {
131-
static String replaceVersions(String origAppDataContent, List<Release> versions) {
151+
// updates releases in ${appName}.metainfo.xml
152+
class AppStreamModifier {
153+
static String replaceVersions(String origAppStreamContent, List<Release> versions) {
132154
final joinedReleases =
133155
versions.map((v) => '\t\t<release version="${v.version}" date="${v.date}" />').join('\n');
134-
final releasesSection = '<releases>\n$joinedReleases\n\t</releases>'; //todo check this
135-
if (origAppDataContent.contains('<releases')) {
136-
return origAppDataContent
156+
final releasesSection = '<releases>\n$joinedReleases\n\t</releases>'; //TODO check this
157+
if (origAppStreamContent.contains('<releases')) {
158+
return origAppStreamContent
137159
.replaceAll('\n', '<~>')
138160
.replaceFirst(RegExp('<releases.*</releases>'), releasesSection)
139161
.replaceAll('<~>', '\n');
140162
} else {
141-
return origAppDataContent.replaceFirst('</component>', '\n\t$releasesSection\n</component>');
163+
return origAppStreamContent.replaceFirst(
164+
'</component>', '\n\t$releasesSection\n</component>');
142165
}
143166
}
144167
}

0 commit comments

Comments
 (0)