1
1
// ignore_for_file: avoid_print
2
2
3
3
import 'dart:io' ;
4
-
5
4
import 'flatpak_shared.dart' ;
6
5
6
+ /// Creates an archive containing all the sources for the Flatpak package for a
7
+ /// specific architecture.
8
+ ///
7
9
/// arguments:
8
10
/// --meta [file]
11
+ /// Required argument for providing the metadata file for this script.
12
+
9
13
/// --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
+
10
19
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 ' );
13
22
}
14
23
24
+ // PARSE ARGUMENTS
15
25
final metaIndex = arguments.indexOf ('--meta' );
16
26
if (metaIndex == - 1 ) {
17
27
throw Exception (
@@ -22,123 +32,136 @@ void main(List<String> arguments) async {
22
32
}
23
33
24
34
final metaFile = File (arguments[metaIndex + 1 ]);
25
- if (! metaFile.existsSync ( )) {
35
+ if (! ( await metaFile.exists () )) {
26
36
throw Exception ('The provided metadata file does not exist.' );
27
37
}
28
38
29
- final meta = FlatpakMeta .fromJson (metaFile);
30
-
31
39
final fetchFromGithub = arguments.contains ('--github' );
32
40
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
+
33
53
final outputDir = Directory ('${Directory .current .path }/flatpak_generator_exports' );
34
- outputDir.createSync ();
54
+ await outputDir.create ();
35
55
36
- final packageGenerator = PackageGenerator (inputDir: metaFile.parent, meta: meta);
56
+ final packageGenerator = PackageGenerator (
57
+ inputDir: metaFile.parent, meta: meta, addedTodaysVersion: addedTodaysVersion);
37
58
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);
43
63
}
44
64
45
65
class PackageGenerator {
46
66
final Directory inputDir;
47
67
final FlatpakMeta meta;
48
- final Map < CPUArchitecture , String > shaByArch = {} ;
68
+ final String ? addedTodaysVersion ;
49
69
50
- PackageGenerator ({required this .inputDir, required this .meta});
70
+ PackageGenerator ({required this .inputDir, required this .meta, required this .addedTodaysVersion });
51
71
52
72
Future <void > generatePackage (
53
73
Directory outputDir, CPUArchitecture arch, bool fetchReleasesFromGithub) async {
54
- final tempDir = outputDir.createTempSync ('flutter_generator_temp' );
74
+ final tempDir = await outputDir.createTemp ('flutter_generator_temp' );
55
75
final appId = meta.appId;
56
76
57
77
// desktop file
58
78
final desktopFile = File ('${inputDir .path }/${meta .desktopPath }' );
59
79
60
- if (! desktopFile.existsSync ( )) {
80
+ if (! ( await desktopFile.exists () )) {
61
81
throw Exception (
62
82
'The desktop file does not exist under the specified path: ${desktopFile .path }' );
63
83
}
64
84
65
- desktopFile.copySync ('${tempDir .path }/$appId .desktop' );
85
+ await desktopFile.copy ('${tempDir .path }/$appId .desktop' );
66
86
67
87
// icons
68
88
final iconTempDir = Directory ('${tempDir .path }/icons' );
69
89
70
90
for (final icon in meta.icons) {
71
91
final iconFile = File ('${inputDir .path }/${icon .path }' );
72
- if (! iconFile.existsSync ( )) {
92
+ if (! ( await iconFile.exists () )) {
73
93
throw Exception ('The icon file ${iconFile .path } does not exist.' );
74
94
}
75
95
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 )}' );
78
98
}
79
99
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 () )) {
83
103
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 }' );
85
105
}
86
106
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));
89
110
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 );
92
113
93
114
// build files
94
115
final bundlePath =
95
116
'${inputDir .path }/${meta .localLinuxBuildDir }/${arch .flutterDirName }/release/bundle' ;
96
117
final buildDir = Directory (bundlePath);
97
- if (! buildDir.existsSync ( )) {
118
+ if (! ( await buildDir.exists () )) {
98
119
throw Exception (
99
120
'The linux build directory does not exist under the specified path: ${buildDir .path }' );
100
121
}
101
122
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' ;
103
128
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);
105
131
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);
109
132
print ('Generated $packagePath ' );
110
133
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;
113
136
114
- final shaFile = await File ('${outputDir .path }/$baseFileName .sha256' ).writeAsString (sha256);
115
- print ('Generated ${shaFile .path }' );
137
+ await File (shaPath).writeAsString (shasum);
116
138
117
- shaByArch. putIfAbsent (arch, () => sha256 );
139
+ print ( 'Generated $ shaPath ' );
118
140
119
- tempDir.deleteSync (recursive: true );
141
+ await tempDir.delete (recursive: true );
120
142
}
121
143
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' ]);
124
146
final unameString = unameRes.stdout.toString ().trimLeft ();
125
147
return unameString.startsWith ('arm' ) || unameString.startsWith ('aarch' );
126
148
}
127
149
}
128
150
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) {
132
154
final joinedReleases =
133
155
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
137
159
.replaceAll ('\n ' , '<~>' )
138
160
.replaceFirst (RegExp ('<releases.*</releases>' ), releasesSection)
139
161
.replaceAll ('<~>' , '\n ' );
140
162
} else {
141
- return origAppDataContent.replaceFirst ('</component>' , '\n\t $releasesSection \n </component>' );
163
+ return origAppStreamContent.replaceFirst (
164
+ '</component>' , '\n\t $releasesSection \n </component>' );
142
165
}
143
166
}
144
167
}
0 commit comments