Update Build Script
This commit is contained in:
parent
c5f9a519c5
commit
b767b9d4ec
@ -9,7 +9,7 @@ elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
|
|||||||
endif()
|
endif()
|
||||||
set(RUNTIME "${CPACK_TOPLEVEL_DIRECTORY}/runtime")
|
set(RUNTIME "${CPACK_TOPLEVEL_DIRECTORY}/runtime")
|
||||||
file(DOWNLOAD
|
file(DOWNLOAD
|
||||||
"https://github.com/AppImage/AppImageKit/releases/download/continuous/runtime-${RUNTIME_ARCH}"
|
"https://github.com/AppImage/type2-runtime/releases/download/continuous/runtime-${RUNTIME_ARCH}"
|
||||||
"${RUNTIME}"
|
"${RUNTIME}"
|
||||||
STATUS DOWNLOAD_STATUS
|
STATUS DOWNLOAD_STATUS
|
||||||
)
|
)
|
||||||
@ -34,10 +34,11 @@ execute_process(
|
|||||||
COMMAND
|
COMMAND
|
||||||
"${CMAKE_COMMAND}" "-E" "env"
|
"${CMAKE_COMMAND}" "-E" "env"
|
||||||
"ARCH=${APPIMAGE_ARCH}"
|
"ARCH=${APPIMAGE_ARCH}"
|
||||||
|
"VERSION=${CPACK_MCPI_VERSION}"
|
||||||
"appimagetool"
|
"appimagetool"
|
||||||
"--updateinformation" "zsync|${CPACK_MCPI_REPO}/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}"
|
"--updateinformation" "zsync|${CPACK_MCPI_REPO}/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}"
|
||||||
"--runtime-file" "${RUNTIME}"
|
"--runtime-file" "${RUNTIME}"
|
||||||
"--comp" "xz"
|
"--comp" "zstd"
|
||||||
"${CPACK_TEMPORARY_DIRECTORY}"
|
"${CPACK_TEMPORARY_DIRECTORY}"
|
||||||
"${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}"
|
"${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}"
|
||||||
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
|
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
|
||||||
|
@ -21,6 +21,7 @@ if(MCPI_IS_APPIMAGE_BUILD)
|
|||||||
macro(pass_to_cpack var)
|
macro(pass_to_cpack var)
|
||||||
set("CPACK_MCPI_${var}" "${MCPI_${var}}")
|
set("CPACK_MCPI_${var}" "${MCPI_${var}}")
|
||||||
endmacro()
|
endmacro()
|
||||||
|
pass_to_cpack(VERSION)
|
||||||
pass_to_cpack(ARCH)
|
pass_to_cpack(ARCH)
|
||||||
pass_to_cpack(REPO)
|
pass_to_cpack(REPO)
|
||||||
pass_to_cpack(APPIMAGE_EXT)
|
pass_to_cpack(APPIMAGE_EXT)
|
||||||
|
@ -27,7 +27,7 @@ The AppImage requires Debian Bullseye or higher. This is equivalent to Ubuntu 20
|
|||||||
|
|
||||||
It also requires some additional packages. To install them, run:
|
It also requires some additional packages. To install them, run:
|
||||||
```sh
|
```sh
|
||||||
sudo apt install -y libfuse2 libopenal1 libglib2.0-0
|
sudo apt install -y libopenal1 libglib2.0-0
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -2,113 +2,28 @@
|
|||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import * as url from 'node:url';
|
import * as url from 'node:url';
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as child_process from 'node:child_process';
|
import { info, err, run } from './lib/util.mjs';
|
||||||
|
import { parseOptions, Enum, Architectures } from './lib/options.mjs';
|
||||||
// Logging
|
|
||||||
const EXIT_FAILURE = 1;
|
|
||||||
function fail(message) {
|
|
||||||
console.error(message);
|
|
||||||
process.exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
function err(message) {
|
|
||||||
fail('ERROR: ' + message);
|
|
||||||
}
|
|
||||||
function info(message) {
|
|
||||||
console.log('INFO: ' + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enums
|
// Enums
|
||||||
function Enum(values) {
|
const PackageTypes = new Enum([
|
||||||
for (const value of values) {
|
|
||||||
this[value] = {
|
|
||||||
prettyName: value,
|
|
||||||
name: value.toLowerCase()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Enum.prototype.get = function (name) {
|
|
||||||
for (const value in this) {
|
|
||||||
if (value.toLowerCase() === name.toLowerCase()) {
|
|
||||||
return this[value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
function wrap(obj) {
|
|
||||||
return new Proxy(obj, {
|
|
||||||
get(target, property) {
|
|
||||||
if (property in target) {
|
|
||||||
return target[property];
|
|
||||||
} else {
|
|
||||||
err('Undefined Value: ' + property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const PackageTypes = wrap(new Enum([
|
|
||||||
'None',
|
'None',
|
||||||
'AppImage',
|
'AppImage',
|
||||||
'Flatpak'
|
'Flatpak'
|
||||||
]));
|
]);
|
||||||
const Architectures = wrap(new Enum([
|
|
||||||
'AMD64',
|
|
||||||
'ARM64',
|
|
||||||
'ARMHF',
|
|
||||||
'Host'
|
|
||||||
]));
|
|
||||||
const Configurations = wrap(new Enum([
|
|
||||||
'Release',
|
|
||||||
'Debug'
|
|
||||||
]));
|
|
||||||
|
|
||||||
// Folders
|
// CMake Options
|
||||||
const __filename = url.fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = path.dirname(__filename);
|
|
||||||
const root = path.join(__dirname, '..');
|
|
||||||
let build = path.join(root, 'build');
|
|
||||||
let out = path.join(root, 'out');
|
|
||||||
|
|
||||||
// Positional Arguments
|
|
||||||
let argIndex = 2; // Skip First Two Arguments
|
|
||||||
function parseArg(arg, from, type) {
|
|
||||||
// Check Argument
|
|
||||||
if (arg === undefined) {
|
|
||||||
err('Expecting ' + type);
|
|
||||||
}
|
|
||||||
// Read Argument
|
|
||||||
const value = from.get(arg);
|
|
||||||
if (value === null) {
|
|
||||||
err(`Invalid ${type}: ${arg}`);
|
|
||||||
}
|
|
||||||
// Return
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
function readArg(...args) {
|
|
||||||
return parseArg(process.argv[argIndex++], ...args);
|
|
||||||
}
|
|
||||||
// Type Of Packaging
|
|
||||||
const packageType = readArg(PackageTypes, 'Package Type');
|
|
||||||
// Build Architecture
|
|
||||||
const architecture = readArg(Architectures, 'Architecture');
|
|
||||||
// Flatpak Builds Work Best Without Custom Toolchains
|
|
||||||
if (packageType === PackageTypes.Flatpak && architecture !== Architectures.Host) {
|
|
||||||
err('Flatpak Builds Do Not Support Custom Toolchains');
|
|
||||||
}
|
|
||||||
|
|
||||||
// CMake Build Options
|
|
||||||
const options = new Map();
|
|
||||||
|
|
||||||
// Other Arguments
|
|
||||||
let clean = false;
|
|
||||||
let install = false;
|
|
||||||
let config = Configurations.Release;
|
|
||||||
for (; argIndex < process.argv.length; argIndex++) {
|
|
||||||
const arg = process.argv[argIndex];
|
|
||||||
const cmakeArgPrefix = '-D';
|
const cmakeArgPrefix = '-D';
|
||||||
if (arg.startsWith(cmakeArgPrefix)) {
|
const cmakeArgSeparator = '=';
|
||||||
|
const cmakeOptions = new Map();
|
||||||
|
function parseCMakeOption(arg) {
|
||||||
|
if (arg === null) {
|
||||||
|
// Usage Text
|
||||||
|
return `${cmakeArgPrefix}var${cmakeArgSeparator}value...`;
|
||||||
|
} else if (arg.startsWith(cmakeArgPrefix)) {
|
||||||
// Pass Build Option To CMake
|
// Pass Build Option To CMake
|
||||||
let parsedArg = arg.substring(cmakeArgPrefix.length);
|
let parsedArg = arg.substring(cmakeArgPrefix.length);
|
||||||
const parts = parsedArg.split('=');
|
const parts = parsedArg.split(cmakeArgSeparator);
|
||||||
if (parts.length !== 2) {
|
if (parts.length !== 2) {
|
||||||
err('Unable To Parse Build Option: ' + arg);
|
err('Unable To Parse Build Option: ' + arg);
|
||||||
}
|
}
|
||||||
@ -117,50 +32,68 @@ for (; argIndex < process.argv.length; argIndex++) {
|
|||||||
if (!/^[a-zA-Z_]+$/.test(name) || name.length === 0) {
|
if (!/^[a-zA-Z_]+$/.test(name) || name.length === 0) {
|
||||||
err('Invalid Build Option Name: ' + name);
|
err('Invalid Build Option Name: ' + name);
|
||||||
}
|
}
|
||||||
options.set(name, value);
|
cmakeOptions.set(name, value);
|
||||||
} else if (arg === '--clean') {
|
return true;
|
||||||
// Remove Existing Build Directory
|
} else {
|
||||||
clean = true;
|
// Unknown Option
|
||||||
} else if (arg === '--install') {
|
return false;
|
||||||
// Install To System Instead Of Output Directory
|
}
|
||||||
if (packageType === PackageTypes.AppImage) {
|
}
|
||||||
|
|
||||||
|
// Options
|
||||||
|
const options = parseOptions([
|
||||||
|
['packageType', PackageTypes],
|
||||||
|
['architecture', Architectures]
|
||||||
|
], [
|
||||||
|
'clean',
|
||||||
|
'install',
|
||||||
|
'debug'
|
||||||
|
], parseCMakeOption);
|
||||||
|
|
||||||
|
// Check Options
|
||||||
|
if (options.packageType === PackageTypes.Flatpak && options.architecture !== Architectures.Host) {
|
||||||
|
err('Flatpak Builds Do Not Support Custom Toolchains');
|
||||||
|
}
|
||||||
|
if (options.packageType === PackageTypes.AppImage && options.install) {
|
||||||
err('AppImages Cannot Be Installed');
|
err('AppImages Cannot Be Installed');
|
||||||
}
|
}
|
||||||
install = true;
|
|
||||||
} else if (arg === '--config') {
|
|
||||||
// Set Configuration
|
|
||||||
config = parseArg(process.argv[++argIndex], Configurations, 'Configuration');
|
|
||||||
} else {
|
|
||||||
// Invalid
|
|
||||||
err('Invalid Argument: ' + arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update Folders
|
// Folders
|
||||||
function updateDir(dir) {
|
const __filename = url.fileURLToPath(import.meta.url);
|
||||||
if (packageType !== PackageTypes.None) {
|
const __dirname = path.dirname(__filename);
|
||||||
dir = path.join(dir, packageType.name);
|
const root = path.join(__dirname, '..');
|
||||||
}
|
let build = path.join(root, 'build');
|
||||||
return path.join(dir, architecture.name);
|
let out = path.join(root, 'out');
|
||||||
}
|
|
||||||
build = updateDir(build);
|
|
||||||
let cleanOut = false;
|
|
||||||
// AppImages Are Placed Directly In ./out
|
|
||||||
if (packageType !== PackageTypes.AppImage) {
|
|
||||||
cleanOut = true;
|
|
||||||
out = updateDir(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure Build Options
|
// Update Build Directory
|
||||||
function toCmakeBool(val) {
|
function specializeDir(dir) {
|
||||||
return val ? 'ON' : 'OFF';
|
// Use Unique Folder For Build Type
|
||||||
|
return path.join(dir, options.packageType.name, options.architecture.name);
|
||||||
}
|
}
|
||||||
options.set('MCPI_IS_APPIMAGE_BUILD', toCmakeBool(packageType === PackageTypes.AppImage));
|
build = specializeDir(build);
|
||||||
options.set('MCPI_IS_FLATPAK_BUILD', toCmakeBool(packageType === PackageTypes.Flatpak));
|
// Update Output Directory
|
||||||
if (architecture !== Architectures.Host) {
|
const useOutRoot = options.packageType === PackageTypes.AppImage;
|
||||||
options.set('CMAKE_TOOLCHAIN_FILE', path.join(root, 'cmake', 'toolchain', architecture.name + '-toolchain.cmake'));
|
if (!useOutRoot) {
|
||||||
|
out = specializeDir(out);
|
||||||
|
}
|
||||||
|
// Print Directories
|
||||||
|
function printDir(name, dir) {
|
||||||
|
info(name + ' Directory: ' + dir);
|
||||||
|
}
|
||||||
|
printDir('Build', build);
|
||||||
|
printDir('Output', out);
|
||||||
|
|
||||||
|
// Configure CMake Options
|
||||||
|
function setupPackageTypeOption(type) {
|
||||||
|
cmakeOptions.set(`MCPI_IS_${type.name.toUpperCase()}_BUILD`, options.packageType === type ? 'ON' : 'OFF');
|
||||||
|
}
|
||||||
|
setupPackageTypeOption(PackageTypes.AppImage);
|
||||||
|
setupPackageTypeOption(PackageTypes.Flatpak);
|
||||||
|
const toolchainOption = 'CMAKE_TOOLCHAIN_FILE';
|
||||||
|
if (options.architecture !== Architectures.Host) {
|
||||||
|
cmakeOptions.set(toolchainOption, path.join(root, 'cmake', 'toolchain', options.architecture.name + '-toolchain.cmake'));
|
||||||
} else {
|
} else {
|
||||||
options.delete('CMAKE_TOOLCHAIN_FILE');
|
cmakeOptions.delete(toolchainOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make Build Directory
|
// Make Build Directory
|
||||||
@ -170,39 +103,31 @@ function createDir(dir, clean) {
|
|||||||
}
|
}
|
||||||
fs.mkdirSync(dir, {recursive: true});
|
fs.mkdirSync(dir, {recursive: true});
|
||||||
}
|
}
|
||||||
createDir(build, clean);
|
createDir(build, options.clean);
|
||||||
if (!install) {
|
if (!options.install) {
|
||||||
createDir(out, cleanOut);
|
createDir(out, !useOutRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run CMake
|
// Run CMake
|
||||||
function run(command) {
|
|
||||||
try {
|
|
||||||
info('Running: ' + command.join(' '));
|
|
||||||
child_process.execFileSync(command[0], command.slice(1), {cwd: build, stdio: 'inherit'});
|
|
||||||
} catch (e) {
|
|
||||||
err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const configure = ['cmake', '-GNinja Multi-Config'];
|
const configure = ['cmake', '-GNinja Multi-Config'];
|
||||||
options.forEach((value, key, map) => {
|
cmakeOptions.forEach((value, key) => {
|
||||||
configure.push(`-D${key}=${value}`);
|
configure.push(cmakeArgPrefix + key + cmakeArgSeparator + value);
|
||||||
});
|
});
|
||||||
configure.push(root);
|
configure.push('-S', root, '-B', build);
|
||||||
run(configure);
|
run(configure);
|
||||||
|
|
||||||
// Build
|
// Build
|
||||||
const configArg = ['--config', config.prettyName];
|
const configArg = ['--config', options.debug ? 'Debug' : 'Release'];
|
||||||
run(['cmake', '--build', '.', ...configArg/*, '-v'/*, '--', '-n', '-j1', '-j1'*/]);
|
run(['cmake', '--build', build, ...configArg]);
|
||||||
|
|
||||||
// Package
|
// Package
|
||||||
if (packageType !== PackageTypes.AppImage) {
|
if (options.packageType !== PackageTypes.AppImage) {
|
||||||
if (!install) {
|
if (!options.install) {
|
||||||
process.env.DESTDIR = out;
|
process.env.DESTDIR = out;
|
||||||
}
|
}
|
||||||
run(['cmake', '--install', '.', ...configArg]);
|
run(['cmake', '--install', build, ...configArg]);
|
||||||
} else {
|
} else {
|
||||||
run(['cmake', '--build', '.', '--target', 'package', ...configArg]);
|
run(['cmake', '--build', build, '--target', 'package', ...configArg]);
|
||||||
// Copy Generated Files
|
// Copy Generated Files
|
||||||
const files = fs.readdirSync(build);
|
const files = fs.readdirSync(build);
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
|
@ -61,19 +61,19 @@ run_build() {
|
|||||||
"libxext-dev:$1" \
|
"libxext-dev:$1" \
|
||||||
`# QEMU Dependencies` \
|
`# QEMU Dependencies` \
|
||||||
"libglib2.0-dev:$1" \
|
"libglib2.0-dev:$1" \
|
||||||
`# AppStream Verification` \
|
`# AppImage` \
|
||||||
appstream
|
appstream \
|
||||||
|
zsync
|
||||||
|
|
||||||
# Install appimagetool
|
# Install appimagetool
|
||||||
sudo rm -rf /opt/squashfs-root /opt/appimagetool /usr/local/bin/appimagetool
|
sudo rm -rf /opt/squashfs-root /opt/appimagetool /usr/local/bin/appimagetool
|
||||||
case "$(dpkg --print-architecture)" in
|
case "$(dpkg --print-architecture)" in
|
||||||
'armhf') APPIMAGE_ARCH='armhf';;
|
'armhf') APPIMAGE_ARCH='armhf';;
|
||||||
'arm64') APPIMAGE_ARCH='aarch64';;
|
'arm64') APPIMAGE_ARCH='aarch64';;
|
||||||
'i386') APPIMAGE_ARCH='i686';;
|
|
||||||
'amd64') APPIMAGE_ARCH='x86_64';;
|
'amd64') APPIMAGE_ARCH='x86_64';;
|
||||||
esac
|
esac
|
||||||
sudo mkdir -p /opt
|
sudo mkdir -p /opt
|
||||||
sudo wget -O /opt/appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-${APPIMAGE_ARCH}.AppImage"
|
sudo wget -O /opt/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${APPIMAGE_ARCH}.AppImage"
|
||||||
sudo chmod +x /opt/appimagetool
|
sudo chmod +x /opt/appimagetool
|
||||||
# Workaround AppImage Issues With Docker
|
# Workaround AppImage Issues With Docker
|
||||||
sudo ./scripts/fix-appimage-for-docker.sh /opt/appimagetool
|
sudo ./scripts/fix-appimage-for-docker.sh /opt/appimagetool
|
||||||
@ -83,7 +83,8 @@ run_build() {
|
|||||||
sudo rm -f ./appimagetool
|
sudo rm -f ./appimagetool
|
||||||
# Link
|
# Link
|
||||||
sudo mv ./squashfs-root ./appimagetool
|
sudo mv ./squashfs-root ./appimagetool
|
||||||
sudo ln -s /opt/appimagetool/AppRun /usr/local/bin/appimagetool
|
printf '#!/bin/sh\nexec /opt/appimagetool/AppRun "$@"\n' | sudo tee /usr/local/bin/appimagetool > /dev/null
|
||||||
|
sudo chmod +x /usr/local/bin/appimagetool
|
||||||
}
|
}
|
||||||
|
|
||||||
# Test Dependencies
|
# Test Dependencies
|
||||||
|
91
scripts/lib/options.mjs
Normal file
91
scripts/lib/options.mjs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { fail } from './util.mjs';
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
export function Enum(values) {
|
||||||
|
this.values = [];
|
||||||
|
for (const value of values) {
|
||||||
|
const obj = {
|
||||||
|
prettyName: value,
|
||||||
|
name: value.toLowerCase()
|
||||||
|
};
|
||||||
|
this[value] = obj;
|
||||||
|
this.values.push(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Enum.prototype.get = function (name) {
|
||||||
|
if (name) {
|
||||||
|
for (const value of this.values) {
|
||||||
|
if (value.name === name.toLowerCase()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported Architectures
|
||||||
|
export const Architectures = new Enum([
|
||||||
|
'AMD64',
|
||||||
|
'ARM64',
|
||||||
|
'ARMHF',
|
||||||
|
'Host'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
function formatFlag(name) {
|
||||||
|
return '--' + name;
|
||||||
|
}
|
||||||
|
function formatOptionalArg(arg) {
|
||||||
|
return '[' + arg + '] ';;
|
||||||
|
}
|
||||||
|
export function parseOptions(positionalArgs, flags, customHandler) {
|
||||||
|
// Usage Text
|
||||||
|
let usage = 'USAGE: ';
|
||||||
|
for (const arg of positionalArgs) {
|
||||||
|
const option = arg[1];
|
||||||
|
const arr = [];
|
||||||
|
for (const value of option.values) {
|
||||||
|
arr.push(value.name);
|
||||||
|
}
|
||||||
|
usage += '<' + arr.join('|') + '> ';
|
||||||
|
}
|
||||||
|
for (const flag of flags) {
|
||||||
|
usage += formatOptionalArg(formatFlag(flag));
|
||||||
|
}
|
||||||
|
usage += formatOptionalArg(customHandler(null));
|
||||||
|
usage = usage.trim();
|
||||||
|
|
||||||
|
// Copy Arguments
|
||||||
|
const args = process.argv.slice(2); // Skip First Two Arguments
|
||||||
|
|
||||||
|
// Read Positional Arguments
|
||||||
|
const out = {};
|
||||||
|
for (const arg of positionalArgs) {
|
||||||
|
let value = args.shift();
|
||||||
|
value = arg[1].get(value);
|
||||||
|
if (value === null) {
|
||||||
|
fail(usage);
|
||||||
|
}
|
||||||
|
out[arg[0]] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Flags
|
||||||
|
for (const flag of flags) {
|
||||||
|
const name = formatFlag(flag);
|
||||||
|
const isSet = args.includes(name);
|
||||||
|
if (isSet) {
|
||||||
|
args.splice(args.indexOf(name), 1);
|
||||||
|
}
|
||||||
|
out[flag] = isSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown Arguments
|
||||||
|
for (const arg of args) {
|
||||||
|
if (!customHandler(arg)) {
|
||||||
|
fail(usage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return out;
|
||||||
|
}
|
24
scripts/lib/util.mjs
Normal file
24
scripts/lib/util.mjs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import * as child_process from 'node:child_process';
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
const EXIT_FAILURE = 1;
|
||||||
|
export function fail(message) {
|
||||||
|
console.error(message);
|
||||||
|
process.exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
export function err(message) {
|
||||||
|
fail('ERROR: ' + message);
|
||||||
|
}
|
||||||
|
export function info(message) {
|
||||||
|
console.log('INFO: ' + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub-Process
|
||||||
|
export function run(command) {
|
||||||
|
try {
|
||||||
|
info('Running: ' + command.join(' '));
|
||||||
|
child_process.execFileSync(command[0], command.slice(1), {stdio: 'inherit'});
|
||||||
|
} catch (e) {
|
||||||
|
err(e);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user