buildLinuxPackage function
Future<String>
buildLinuxPackage({
- required String repoRoot,
- required ArtifactPayload payload,
- required LinuxPackageConfig config,
- required LinuxPackageFormat format,
- required String outputPath,
- required String nfpmToolPath,
Builds a deb or rpm from a prebuilt payload using a caller-supplied nfpm.
File modes and the /usr/bin link are declared in the manifest rather than
created on disk, so staging behaves the same on every host.
Implementation
Future<String> buildLinuxPackage({
required String repoRoot,
required ArtifactPayload payload,
required LinuxPackageConfig config,
required LinuxPackageFormat format,
required String outputPath,
required String nfpmToolPath,
}) async {
if (format == LinuxPackageFormat.rpm && config.license == null) {
throw const ShipworldException(
'rpm packages require a license',
code: 'invalid_config',
);
}
final workDir = p.join(
repoRoot,
'.shipworld',
format.packagerName,
config.name,
);
final artifactPath = p.join(repoRoot, outputPath);
final workDirectory = Directory(workDir);
if (workDirectory.existsSync()) {
await workDirectory.delete(recursive: true);
}
final stagedRoot = p.join(workDir, 'root');
await Directory(stagedRoot).create(recursive: true);
await Directory(p.dirname(artifactPath)).create(recursive: true);
await payload.stage(stagedRoot);
final desktopPath = p.join(workDir, '${config.appId}.desktop');
await File(desktopPath).writeAsString(_installedDesktopEntry(config));
final launcherInstallPath = p.url.join(
config.installDirectory,
p.url.joinAll(p.split(payload.launcherRelativePath)),
);
String? wrapperPath;
if (config.launcherStyle == LinuxLauncherStyle.wrapper) {
wrapperPath = p.join(workDir, config.executableName);
await File(
wrapperPath,
).writeAsString(_launcherWrapper(launcherInstallPath));
}
final stagedIcons = <({LinuxIconAsset icon, String stagedPath})>[];
for (final icon in config.icons) {
final stagedPath = p.join(
workDir,
'icons',
'${icon.themeDirectory}${p.extension(icon.sourcePath)}',
);
await Directory(p.dirname(stagedPath)).create(recursive: true);
await File(icon.sourcePath).copy(stagedPath);
stagedIcons.add((icon: icon, stagedPath: stagedPath));
}
final payloadFiles =
Directory(stagedRoot)
.listSync(recursive: true, followLinks: false)
.whereType<File>()
.map((file) => p.relative(file.path, from: stagedRoot))
.toList()
..sort();
final manifestPath = p.join(workDir, 'nfpm.json');
await File(manifestPath).writeAsString(
const JsonEncoder.withIndent(' ').convert(
_nfpmManifest(
config: config,
format: format,
stagedRoot: stagedRoot,
launcherInstallPath: launcherInstallPath,
desktopPath: desktopPath,
icons: stagedIcons,
payloadFiles: payloadFiles,
launcherRelativePath: payload.launcherRelativePath,
wrapperPath: wrapperPath,
),
),
);
stdout.writeln('Building ${format.packagerName} package...');
await runChecked(nfpmToolPath, <String>[
'package',
'--config',
manifestPath,
'--packager',
format.packagerName,
'--target',
artifactPath,
], workingDirectory: repoRoot);
return artifactPath;
}