install.fairie/.local/share/chezmoi/home/dot_local/bin/executable_install-program

792 lines
28 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env zx
const execSync = require('child_process').execSync
// Log symbols
const figuresDefault = {
bullet: '●',
circle: '◯',
cross: '✖',
lozenge: '◆',
play: '▶',
pointer: '',
square: '◼',
star: '★',
tick: '✔'
}
const figuresFallback = {
bullet: '■',
circle: '□',
cross: '×',
lozenge: '♦',
play: '►',
pointer: '>',
square: '■',
star: '✶',
tick: '√'
}
function isUnicodeSupported() {
if (process.platform !== 'win32') {
// Linux console (kernel)
return process.env.TERM !== 'linux'
}
return (
Boolean(process.env.CI) ||
// Windows Terminal
Boolean(process.env.WT_SESSION) ||
// ConEmu and cmder
process.env.ConEmuTask === '{cmd::Cmder}' ||
process.env.TERM_PROGRAM === 'vscode' ||
process.env.TERM === 'xterm-256color' ||
process.env.TERM === 'alacritty'
)
}
const figures = isUnicodeSupported() ? figuresDefault : figuresFallback
function log(type, label, msg) {
let icon, message
if (type === 'info') {
icon = chalk.cyanBright(figures.pointer)
message = chalk.gray.bold(msg)
} else if (type === 'star') {
icon = chalk.yellowBright(figures.star)
message = chalk.bold(msg)
} else if (type === 'success') {
icon = chalk.greenBright(figures.play)
message = chalk.bold(msg)
} else if (type === 'warn') {
icon = `${chalk.yellowBright(figures.lozenge)} ${chalk.bold.black.bgYellowBright(' WARNING ')}`
message = chalk.yellowBright(msg)
} else if (type === 'error') {
icon = `${chalk.redBright(figures.cross)} ${chalk.black.bold.bgRedBright(' ERROR ')}`
message = chalk.redBright(msg)
}
const outputMessage = `${icon} ${chalk.bold(label)} ${message}`
console.log(outputMessage)
}
let installData
const installOrders = {};
const installOrdersPre = [];
const installOrdersPost = [];
const osType = await OSType();
let osID = osType
if(osType === 'linux') {
osID = await realeaseID()
}
// Download the installation map
async function downloadInstallData() {
const response = await fetch(
"https://gitlab.com/megabyte-labs/misc/dotfiles/-/raw/master/.local/share/chezmoi/software.yml"
);
if (response.ok) {
const text = await response.text()
return YAML.parse(text)
} else {
log('error', 'Catalog Download', `Failed to download the installation map`)
}
}
// Creates the installOrders object which maps package managers to arrays of packages to install
async function generateInstallOrders() {
const logStage = 'Install Orders'
const packagesToInstall = process.argv.slice(3);
const installerPreference = await OSTypeInstallerKey()
log('info', logStage, `Installer preference category detected as ${installerPreference}`)
const preferenceOrder = installData.installerPreference[installerPreference];
log('info', logStage, `Preference order acquired:`)
console.log(preferenceOrder)
const softwarePackages = installData.softwarePackages;
pkgFor:
for (let pkg of packagesToInstall) {
let packageKey;
const bins = [
softwarePackages[pkg + ":" + osID] && softwarePackages[pkg + ":" + osID]['_bin'],
softwarePackages[pkg + ":" + osType] && softwarePackages[pkg + ":" + osType]['_bin'],
softwarePackages[pkg] && softwarePackages[pkg]['_bin']
]
for (const bin of bins) {
if (bin) {
const alreadyInstalled = which.sync(bin, { nothrow: true })
if (alreadyInstalled) {
continue pkgFor
}
}
}
if (softwarePackages[pkg + ":" + osID]) {
packageKey = pkg + ":" + osID;
} else if (softwarePackages[pkg + ":" + osType]) {
packageKey = pkg + ":" + osType;
} else if (softwarePackages[pkg]) {
packageKey = pkg
} else {
log('warn', logStage, `The package \`${pkg}\` was not found in the installation map`)
continue
}
for (let preference of preferenceOrder) {
if (softwarePackages[packageKey][preference + ":" + osID]) {
await updateInstallMaps(
preference,
softwarePackages[packageKey],
preference + ":" + osID,
pkg,
packageKey
);
break
} else if (softwarePackages[packageKey][preference + ":" + osType]) {
await updateInstallMaps(
preference,
softwarePackages[packageKey],
preference + ":" + osType,
pkg,
packageKey
);
break
} else if (softwarePackages[packageKey][preference]) {
await updateInstallMaps(preference, softwarePackages[packageKey], preference, pkg, packageKey);
break
}
}
}
return installOrders;
}
// Update install, pre-hook, and post-hook objects
async function updateInstallMaps(preference, packages, scopedPreference, pkg, packageKey) {
const preHook = getHook(packages, "pre", scopedPreference, preference);
if (preHook) {
installOrdersPre.concat(typeof preHook === "string" ? [preHook] : preHook);
}
const postHook = getHook(packages, "post", scopedPreference, preference);
if (postHook) {
installOrdersPost.concat(
typeof postHook === "string" ? [postHook] : postHook
);
}
if (!installOrders[preference]) {
installOrders[preference] = [];
}
log('info', 'Install Orders', `Found a match for the package \`${pkg}\` (${packageKey} via ${scopedPreference})`)
const newPackages = packages[scopedPreference];
const newPkgs = typeof newPackages === "string" ? [newPackages] : newPackages
installOrders[preference] = installOrders[preference].concat(newPkgs);
}
// Get pre / post install hooks
function getHook(packages, hook, scopedPreference, preference) {
const hookLabel = "_" + hook + ":";
if (packages[hookLabel + scopedPreference]) {
return packages[hookLabel + scopedPreference];
} else if (packages[hookLabel + preference]) {
return packages[hookLabel + preference];
} else if (packages[hookLabel + osID]) {
return packages;
} else if (packages[hookLabel + osType]) {
return packages[hookLabel + osType];
} else if (packages["_" + hook]) {
return packages["_" + hook];
}
}
// Acquire OS type installer key (for the installerPreference data key)
async function OSTypeInstallerKey() {
const apt = which.sync('apt-get', { nothrow: true })
const dnf = which.sync('dnf', { nothrow: true })
const freebsd = which.sync('pkg', { nothrow: true })
const pacman = which.sync('pacman', { nothrow: true })
const yum = which.sync('yum', { nothrow: true })
const zypper = which.sync('zypper', { nothrow: true })
if (apt) {
return 'apt'
} else if (dnf || yum) {
return 'dnf'
} else if(pacman) {
return 'pacman'
} else if(zypper) {
return 'zypper'
} else if (freebsd) {
return 'freebsd'
} else {
try {
await $`test -d /Applications && test -d /Library`
return 'darwin'
} catch (e) {
return 'windows'
}
}
}
// Acquire OS type
async function OSType() {
try {
await $`test -d /Applications && test -d /Library`
return 'darwin'
} catch(e) {
try {
await $`test -f /etc/os-release`
return 'linux'
} catch (e) {
return 'windows'
}
}
}
// Acquire release ID (for Linux)
async function releaseID() {
const ID = await $`
if [ -f /etc/os-release ]; then
. /etc/os-release
echo -n $ID
fi
`;
return ID.stdout;
}
// Post-install hook
async function afterInstall(packageManager) {
const logStage = 'Post-Install Package Manager'
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
log('info', logStage, `Ensuring temporary passwordless sudo privileges used by Ansible are removed`)
const gsed = which.sync('gsed', { nothrow: true })
if (gsed) {
await $`sudo gsed -i '/# TEMPORARY FOR ANSIBLE INSTALL/d' /etc/sudoers`
} else {
await $`sudo sed -i '/# TEMPORARY FOR ANSIBLE INSTALL/d' /etc/sudoers`
}
} else if (packageManager === 'apk') {
} else if (packageManager === 'apt') {
} else if (packageManager === 'basher') {
} else if (packageManager === 'binary') {
} else if (packageManager === 'brew' || packageManager === 'cask') {
} else if (packageManager === 'cargo') {
} else if (packageManager === 'choco') {
} else if (packageManager === 'crew') {
} else if (packageManager === 'dnf') {
} else if (packageManager === 'flatpak') {
} else if (packageManager === 'gem') {
} else if (packageManager === 'go') {
} else if (packageManager === 'nix') {
} else if (packageManager === 'npm') {
} else if (packageManager === 'pacman') {
} else if (packageManager === 'pipx') {
} else if (packageManager === 'pkg') {
} else if (packageManager === 'port') {
} else if (packageManager === 'scoop') {
} else if (packageManager === 'crew') {
} else if (packageManager === 'dnf') {
} else if (packageManager === 'flatpak') {
} else if (packageManager === 'snap') {
} else if (packageManager === 'whalebrew') {
} else if (packageManager === 'winget') {
} else if (packageManager === 'yay') {
} else if (packageManager === 'zypper') {
}
}
// Pre-install hook
async function beforeInstall(packageManager) {
const logStage = 'Pre-Install Package Manager'
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
log('info', logStage, `Temporarily enabling passwordless sudo for Ansible role installations`)
await $`echo "$(whoami) ALL=(ALL:ALL) NOPASSWD: ALL # TEMPORARY FOR ANSIBLE INSTALL" | sudo tee -a`
} else if (packageManager === 'apk') {
} else if (packageManager === 'apt') {
await $`sudo apt-get update`
} else if (packageManager === 'basher') {
} else if (packageManager === 'binary') {
} else if (packageManager === 'brew' || packageManager === 'cask') {
} else if (packageManager === 'cargo') {
} else if (packageManager === 'choco') {
} else if (packageManager === 'crew') {
} else if (packageManager === 'dnf') {
} else if (packageManager === 'flatpak') {
} else if (packageManager === 'gem') {
} else if (packageManager === 'go') {
} else if (packageManager === 'nix') {
} else if (packageManager === 'npm') {
} else if (packageManager === 'pacman') {
await $`sudo pacman -Syu`
} else if (packageManager === 'pipx') {
} else if (packageManager === 'pkg') {
} else if (packageManager === 'port') {
} else if (packageManager === 'scoop') {
} else if (packageManager === 'crew') {
} else if (packageManager === 'dnf') {
} else if (packageManager === 'flatpak') {
} else if (packageManager === 'snap') {
} else if (packageManager === 'whalebrew') {
if (osType === 'darwin') {
const docker = which.sync('docker', { nothrow: true })
if (!docker) {
await $`brew install --cask docker`
}
try {
await $`docker run --rm hello-world`
} catch (e) {
log('warn', logStage, `The command \`docker run --rm hello-world\` failed`)
try {
log('info', logStage, 'Attempting to open \`/Applications/Docker.app\` (Docker Desktop for macOS). This should take about 30 seconds.')
const promises = [$`test -d /Applications/Docker.app`, $`open /Applications/Docker.app`]
await Promise.all(promises)
const gum = which.sync('gum', { nothrow: true })
if (gum) {
execSync('gum spin --spinner dot --title "Waiting for Docker Desktop to start up.." -- sleep 30', {stdio: 'inherit', shell: true})
} else {
await $`sleep 30`
}
} catch (e) {
log('warn', logStage, `Docker Desktop appears to not be installed!`)
}
}
}
} else if (packageManager === 'winget') {
} else if (packageManager === 'yay') {
} else if (packageManager === 'zypper') {
}
}
async function ensureInstalled(bin, callback) {
const logStage = 'Package Manager Install'
const installed = which.sync(bin, { nothrow: true })
if (installed) {
log('info', logStage, `\`${bin}\` is available`)
} else {
log('warn', logStage, `\`${bin}\` is not installed!`)
if (callback) {
await callback
} else {
log('error', logStage, `There does not appear to be an installation method available for \`${bin}\``)
}
}
}
async function ensurePackageManagerAnsible() {
await $`pipx install ansible`
await $`pipx inject ansible PyObjC PyObjC-core docker lxml netaddr pexpect python-vagrant pywinrm requests-credssp watchdog`
await $`mkdir -p "$HOME/.cache/megabyte-labs"`
await $`touch "$HOME/.cache/megabyte-labs/ansible-installed"`
log('info', 'Package Manager Install', `Ansible and its supporting packages are now installed via pipx`)
}
// Ensure the package manager is available
let packageManagerInstalled = {};
async function ensurePackageManager(packageManager) {
const logStage = 'Package Manager Install'
log('info', logStage, `Ensuring \`${packageManager}\` is set up`)
if (packageManagerInstalled[packageManager]) {
return;
} else {
packageManagerInstalled[packageManager] = true;
}
if (packageManager === "ansible") {
await ensurePackageManager("pipx");
}
if (
packageManager === "gem" ||
packageManager === "go" ||
packageManager === "npm" ||
packageManager === "pipx" ||
packageManager === "whalebrew"
) {
await ensurePackageManager("brew");
}
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
try {
await $`test -f "$HOME/.cache/megabyte-labs/ansible-installed"`
const ansible = which.sync('ansible', { nothrow: true })
if (ansible) {
log('info', logStage, `\`ansible\` and its supporting packages appear to be installed`)
} else {
await ensurePackageManagerAnsible()
}
} catch (e) {
await ensurePackageManagerAnsible()
}
} else if (packageManager === 'apk') {
await ensureInstalled('apk', false)
} else if (packageManager === 'apt') {
await ensureInstalled('apt', false)
} else if (packageManager === 'basher') {
await ensureInstalled('basher', $`
# TODO
echo "Bash script that installs basher here"
`)
} else if (packageManager === 'binary') {
} else if (packageManager === 'bpkg') {
await ensureInstalled('bpkg', $`
# TODO
echo "Bash script that installs bpkg here"
`)
} else if (packageManager === 'brew' || packageManager === 'cask') {
const brew = which.sync('brew', { nothrow: true })
if (!brew) {
await ensureInstalled('brew', $`
if command -v sudo > /dev/null && sudo -n true; then
echo | bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
else
log('info', logStage, 'Homebrew is not installed. Password may be required.')
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || BREW_EXIT_CODE="$?"
if [ -n "$BREW_EXIT_CODE" ]; then
if command -v brew > /dev/null; then
log('warn', logStage, 'Homebrew was installed but part of the installation failed. Attempting to fix..')
BREW_DIRS="share/man share/doc share/zsh/site-functions etc/bash_completion.d"
for BREW_DIR in $BREW_DIRS; do
if [ -d "$(brew --prefix)/$BREW_DIR" ]; then
sudo chown -R "$(whoami)" "$(brew --prefix)/$BREW_DIR"
fi
done
brew update --force --quiet
fi
fi
fi
`)
}
} else if (packageManager === 'cargo') {
await ensureInstalled('cargo', $`
# TODO Bash script that installs cargo
`)
} else if (packageManager === 'choco') {
await ensureInstalled('choco', $`
powershell "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"
`)
} else if (packageManager === 'crew') {
await ensureInstalled('crew', $`
# TODO Bash script that installs crew here
# Source: https://github.com/chromebrew/chromebrew
curl -Ls git.io/vddgY | bash
`)
} else if (packageManager === 'dnf') {
const dnf = which.sync('dnf', { nothrow: true })
const yum = which.sync('yum', { nothrow: true })
if (dnf) {
log('info', logStage, `\`dnf\` is available`)
} else if (yum) {
log('info', logStage, `\`yum\` is available`)
} else {
log('error', logStage, `Both \`dnf\` and \`yum\` are not available`)
}
} else if (packageManager === 'flatpak') {
const flatpak = which.sync('flatpak', { nothrow: true })
if (flatpak) {
log('info', logStage, `\`flatpak\` is available`)
} else {
const apk = which.sync('apk', { nothrow: true })
const apt = which.sync('apt', { nothrow: true })
const dnf = which.sync('dnf', { nothrow: true })
const yum = which.sync('yum', { nothrow: true })
const pacman = which.sync('pacman', { nothrow: true })
const zypper = which.sync('zypper', { nothrow: true })
if (apk) {
$`sudo apk add flatpak`
} else if(apt) {
$`
sudo apt install -y flatpak
if [ -f /usr/bin/gnome-shell ]; then
sudo apt install -y gnome-software-plugin-flatpak
fi
if [ -f /usr/bin/plasmashell ]; then
sudo apt install -y plasmashell
fi
`
} else if(dnf) {
await $`sudo dnf install -y flatpak`
} else if(yum) {
await $`sudo yum install -y flatpak`
} else if (pacman) {
await $`sudo pacman -Sy flatpak`
} else if (zypper) {
await $`sudo zypper install -y flatpak`
}
const flatpakPost = which.sync('flatpak', { nothrow: true })
if (flatpakPost) {
await $`flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`
} else {
log('error', logStage, `\`flatpak\` failed to install!`)
}
log('info', logStage, `\`flatpak\` was installed. It may require a reboot to function correctly.`)
}
} else if (packageManager === 'gem') {
await ensureInstalled('gem', $`brew install ruby`)
} else if (packageManager === 'go') {
await ensureInstalled('gem', $`brew install go`)
} else if (packageManager === 'nix') {
await ensureInstalled('nix', $`
if [ -d /Applications ] && [ -d /Library ]; then
sh <(curl -L https://nixos.org/nix/install)
else
sh <(curl -L https://nixos.org/nix/install) --daemon
fi
`)
} else if (packageManager === 'npm') {
const npm = which('npm', { nothrow: true })
const node = which('node', { nothrow: true })
const volta = which('volta', { nothrow: true })
if (npm && node && volta) {
log('info', logStage, `\`npm\`, \`node\`, and \`volta\` are available`)
} else {
if (!volta) {
await $`brew install volta`
}
await $`
if [ -z "$VOLTA_HOME" ]; then
volta setup
fi
export PATH="$VOLTA_HOME/bin:$PATH"
volta install node
`
}
} else if (packageManager === 'pacman') {
await ensureInstalled('pacman', false)
} else if (packageManager === 'pipx') {
await ensureInstalled('pipx', $`brew install pipx && pipx ensurepath`)
} else if (packageManager === 'pkg') {
await ensureInstalled('pkg', false)
} else if (packageManager === 'port') {
await ensureInstalled('port', $`
echo -n "TODO - script that installs port on macOS here"
`)
} else if (packageManager === 'scoop') {
await ensureInstalled('scoop', $`
powershell 'Set-ExecutionPolicy RemoteSigned -Scope CurrentUser'
powershell 'irm get.scoop.sh | iex
`)
} else if (packageManager === 'snap') {
const apk = which.sync('apk', { nothrow: true })
const apt = which.sync('apt-get', { nothrow: true })
const dnf = which.sync('dnf', { nothrow: true })
const yum = which.sync('yum', { nothrow: true })
const pacman = which.sync('pacman', { nothrow: true })
const zypper = which.sync('zypper', { nothrow: true })
if (apt) {
await $`
if [ -f /etc/apt/preferences.d/nosnap.pref ]; then
sudo mv /etc/apt/preferences.d/nosnap.pref /etc/apt/nosnap.pref.bak
fi
sudo apt install -y snapd
`
// TODO Following may be required on Kali -> https://snapcraft.io/docs/installing-snap-on-kali
// systemctl enable --now snapd apparmor
} else if (dnf) {
await $`
sudo dnf install -y snapd
if [ ! -d /snap ]; then
sudo ln -s /var/lib/snapd/snap /snap
fi
`
} else if (yum) {
await $`
sudo yum install -y snapd
sudo systemctl enable --now snapd.socket
if [ ! -d /snap ]; then
sudo ln -s /var/lib/snapd/snap /snap
fi
`
} else if (pacman) {
await $`
if [ -f /etc/arch-release ]; then
sudo git clone https://aur.archlinux.org/snapd.git /usr/local/src/snapd
cd /usr/local/src/snapd
sudo makepkg -si
else
sudo pacman -S snapd
sudo systemctl enable --now snapd.socket
if [ ! -d /snap ]; then
sudo ln -s /var/lib/snapd/snap /snap
fi
fi
`
} else if (zypper) {
// TODO See https://snapcraft.io/docs/installing-snap-on-opensuse
await $`
echo "TODO - Bash script that installs snap w/ zypper"
`
}
const snap = which.sync('snap', { nothrow: true })
if (snap) {
$`sudo snap install core`
}
} else if (packageManager === 'whalebrew') {
await ensureInstalled('whalebrew', $`brew install whalebrew`)
} else if (packageManager === 'winget') {
await ensureInstalled('winget', $`
echo "TODO - Script that installs winget here"
`)
} else if (packageManager === 'yay') {
const yay = which.sync('yay', { nothrow: true })
await $`sudo pacman -S --needed base-devel git`
await $`
if [ -d /usr/local/src ]; then
git clone https://aur.archlinux.org/yay.git /usr/local/src/yay
cd /usr/local/src/yay
makepkg -si
fi
`
} else if (packageManager === 'zypper') {
await ensureInstalled('zypper', false)
}
}
// Installs a list of packages via the specified package manager
async function installPackageList(packageManager, packages) {
const logStage = 'Package Install'
let pkg = packages
try {
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
console.log(packageManager)
console.log(packages)
for (let pkg of packages) {
console.log(pkg)
//execSync('gum spin --spinner dot --title "Installing ' + pkg + ' via Ansible" -- ansible localhost --skip-tags brew -m setup -m include_role -a name=' + pkg + ' -e ansible_user=' + process.env.USER, {stdio: 'inherit', shell: true})
await $`ansible localhost --skip-tags brew -m setup -m include_role -a name=${pkg} -e ansible_user=${process.env.USER}`
}
} else if (packageManager === 'apk') {
for (let pkg of packages) {
await $`sudo apk add ${packages}`
}
} else if (packageManager === 'apt') {
for (let pkg of packages) {
await $`sudo apt-get install -y ${pkg}`
}
} else if (packageManager === 'basher') {
} else if (packageManager === 'binary') {
} else if (packageManager === 'brew') {
for (let pkg of packages) {
await $`brew install ${pkg}`
}
} else if (packageManager === 'cask') {
for (let pkg of packages) {
await $`brew install --cask ${pkg}`
}
} else if (packageManager === 'cargo') {
for (const pkg of packages) {
await $`cargo install ${pkg}`
}
} else if (packageManager === 'choco') {
for (let pkg of packages) {
await $`choco install -y ${pkg}`
}
} else if (packageManager === 'crew') {
} else if (packageManager === 'dnf') {
const dnf = which.sync('dnf', { nothrow: true })
const yum = which.sync('yum', { nothrow: true })
if (dnf) {
for (let pkg of packages) {
await $`sudo dnf install -y ${pkg}`
}
} else if (yum) {
for (let pkg of packages) {
await $`sudo yum install -y ${pkg}`
}
}
} else if (packageManager === 'flatpak') {
for (let pkg of packages) {
await $`sudo flatpak install flathub ${pkg}`
}
} else if (packageManager === 'gem') {
for (let pkg of packages) {
await $`gem install ${pkg}`
}
} else if (packageManager === 'go') {
for (let pkg of packages) {
await $`go install ${pkg}`
}
} else if (packageManager === 'nix') {
} else if (packageManager === 'npm') {
for (let pkg of packages) {
await $`volta install ${pkg}`
}
} else if (packageManager === 'pacman') {
for (let pkg of packages) {
await $`sudo pacman -Sy --noconfirm --needed ${pkg}`
}
} else if (packageManager === 'pipx') {
for (let pkg of packages) {
await $`pipx install ${pkg}`
}
} else if (packageManager === 'pkg') {
} else if (packageManager === 'port') {
for (let pkg of packages) {
await $`sudo port install ${pkg}`
}
} else if (packageManager === 'scoop') {
for (let pkg of packages) {
await $`scoop install ${pkg}`
}
} else if (packageManager === 'snap') {
for (let pkg of packages) {
await $`sudo snap install -y ${pkg}`
}
} else if (packageManager === 'whalebrew') {
for (let pkg of packages) {
await $`whalebrew install ${pkg}`
}
} else if (packageManager === 'winget') {
} else if (packageManager === 'yay') {
for (let pkg of packages) {
await $`yay -Sy --noconfirm --needed ${pkg}`
}
} else if (packageManager === 'zypper') {
for (let pkg of packages) {
await $`sudo zypper install -y ${packages}`
}
}
} catch (e) {
log('error', logStage, `Possibly encountered an error while installing via \`${packageManager}\``)
log('info', logStage, `Error was encountered while installing: ${pkg}`)
log('info', logStage, `Proceeding with the installation..`)
}
}
// main process
async function main() {
log('info', 'Catalog Download', `Fetching the latest version of the installation map`)
installData = await downloadInstallData();
log('info', 'Install Orders', `Calculating the install orders`)
await generateInstallOrders();
log('info', `Ensuring any package managers that will be used are installed / configured`)
const packageManagers = Object.keys(installOrders);
for (const packageManager of packageManagers) {
await ensurePackageManager(packageManager);
}
log('info', 'Install Orders', `The install orders were generated:`)
console.log(installOrders)
log('info', 'Package Manager Pre-Install', `Running package manager pre-installation steps`)
for (const packageManager of packageManagers) {
await beforeInstall(packageManager);
}
log('info', 'Package Pre-Install', `Running package-specific pre-installation steps`)
for (const script of installOrdersPre) {
await $`${script}`;
}
log('info', 'Package Install', `Installing the packages`)
for (const packageManager of packageManagers) {
const asyncOrders = [];
asyncOrders.push(
Promise.resolve(
installPackageList(packageManager, installOrders[packageManager])
)
);
await Promise.all(asyncOrders);
}
log('info', 'Package Post-Install', `Running package-specific post-installation steps`)
for (const script of installOrdersPost) {
await $`${script}`;
}
log('info', 'Package Manager Post-Install', `Running package manager post-installation steps`)
for (const packageManager of packageManagers) {
await afterInstall(packageManager);
}
log('success', 'Installation Complete', `Done!`)
}
// Start the main process
await main();