2022-11-29 22:26:34 -08:00
|
|
|
|
#!/usr/bin/env zx
|
|
|
|
|
|
|
|
|
|
const execSync = require('child_process').execSync
|
|
|
|
|
|
2022-12-02 15:07:52 -08:00
|
|
|
|
// 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) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
let icon, message
|
2022-12-02 15:07:52 -08:00
|
|
|
|
if (type === 'info') {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
icon = chalk.cyanBright(figures.pointer)
|
|
|
|
|
message = chalk.gray.bold(msg)
|
2022-12-02 15:07:52 -08:00
|
|
|
|
} else if (type === 'star') {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
icon = chalk.yellowBright(figures.star)
|
2022-12-02 15:07:52 -08:00
|
|
|
|
message = chalk.bold(msg)
|
|
|
|
|
} else if (type === 'success') {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
icon = chalk.greenBright(figures.play)
|
|
|
|
|
message = chalk.bold(msg)
|
2022-12-02 15:07:52 -08:00
|
|
|
|
} else if (type === 'warn') {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
icon = `${chalk.yellowBright(figures.lozenge)} ${chalk.bold.black.bgYellowBright(' WARNING ')}`
|
|
|
|
|
message = chalk.yellowBright(msg)
|
2022-12-02 15:07:52 -08:00
|
|
|
|
} else if (type === 'error') {
|
2022-12-02 16:28:07 -08:00
|
|
|
|
icon = `${chalk.redBright(figures.cross)} ${chalk.black.bold.bgRedBright(' ERROR ')}`
|
2022-12-02 15:07:52 -08:00
|
|
|
|
message = chalk.redBright(msg)
|
|
|
|
|
}
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const outputMessage = `${icon} ${chalk.bold(label)} ${message}`
|
2022-12-02 15:07:52 -08:00
|
|
|
|
console.log(outputMessage)
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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(
|
2022-11-30 01:43:30 -08:00
|
|
|
|
"https://gitlab.com/megabyte-labs/misc/dotfiles/-/raw/master/.local/share/chezmoi/software.yml"
|
2022-11-29 22:26:34 -08:00
|
|
|
|
);
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
const text = await response.text()
|
|
|
|
|
return YAML.parse(text)
|
|
|
|
|
} else {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('error', 'Catalog Download', `Failed to download the installation map`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Creates the installOrders object which maps package managers to arrays of packages to install
|
|
|
|
|
async function generateInstallOrders() {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const logStage = 'Install Orders'
|
2022-11-29 22:26:34 -08:00
|
|
|
|
const packagesToInstall = process.argv.slice(3);
|
|
|
|
|
const installerPreference = await OSTypeInstallerKey()
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `Installer preference category detected as ${installerPreference}`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
const preferenceOrder = installData.installerPreference[installerPreference];
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `Preference order acquired:`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
console.log(preferenceOrder)
|
|
|
|
|
const softwarePackages = installData.softwarePackages;
|
2022-12-02 16:13:21 -08:00
|
|
|
|
pkgFor:
|
2022-11-29 22:26:34 -08:00
|
|
|
|
for (let pkg of packagesToInstall) {
|
|
|
|
|
let packageKey;
|
2022-12-02 16:13:21 -08:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
if (softwarePackages[pkg + ":" + osID]) {
|
|
|
|
|
packageKey = pkg + ":" + osID;
|
|
|
|
|
} else if (softwarePackages[pkg + ":" + osType]) {
|
|
|
|
|
packageKey = pkg + ":" + osType;
|
|
|
|
|
} else if (softwarePackages[pkg]) {
|
|
|
|
|
packageKey = pkg
|
|
|
|
|
} else {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('warn', logStage, `The package \`${pkg}\` was not found in the installation map`)
|
|
|
|
|
continue
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
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] = [];
|
|
|
|
|
}
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', 'Install Orders', `Found a match for the package \`${pkg}\` (${packageKey} via ${scopedPreference})`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
const newPackages = packages[scopedPreference];
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const newPkgs = typeof newPackages === "string" ? [newPackages] : newPackages
|
|
|
|
|
installOrders[preference] = installOrders[preference].concat(newPkgs);
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 {
|
2022-12-02 08:55:33 -08:00
|
|
|
|
try {
|
|
|
|
|
await $`test -d /Applications && test -d /Library`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
return 'darwin'
|
2022-12-02 08:55:33 -08:00
|
|
|
|
} catch (e) {
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const logStage = 'Post-Install Package Manager'
|
2022-11-29 22:26:34 -08:00
|
|
|
|
if (packageManager === 'appimage') {
|
|
|
|
|
} else if (packageManager === 'ansible') {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `Ensuring temporary passwordless sudo privileges used by Ansible are removed`)
|
2022-12-02 15:28:30 -08:00
|
|
|
|
const gsed = which.sync('gsed', { nothrow: true })
|
|
|
|
|
if (gsed) {
|
2022-12-02 16:28:07 -08:00
|
|
|
|
await $`sudo gsed -i '/# TEMPORARY FOR ANSIBLE INSTALL/d' /etc/sudoers`
|
2022-12-02 15:28:30 -08:00
|
|
|
|
} else {
|
2022-12-02 16:28:07 -08:00
|
|
|
|
await $`sudo sed -i '/# TEMPORARY FOR ANSIBLE INSTALL/d' /etc/sudoers`
|
2022-12-02 15:28:30 -08:00
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} 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) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const logStage = 'Pre-Install Package Manager'
|
2022-11-29 22:26:34 -08:00
|
|
|
|
if (packageManager === 'appimage') {
|
|
|
|
|
} else if (packageManager === 'ansible') {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `Temporarily enabling passwordless sudo for Ansible role installations`)
|
2022-12-02 15:28:30 -08:00
|
|
|
|
await $`echo "$(whoami) ALL=(ALL:ALL) NOPASSWD: ALL # TEMPORARY FOR ANSIBLE INSTALL" | sudo tee -a`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} 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') {
|
2022-12-02 09:25:27 -08:00
|
|
|
|
if (osType === 'darwin') {
|
|
|
|
|
const docker = which.sync('docker', { nothrow: true })
|
2022-12-02 09:09:59 -08:00
|
|
|
|
if (!docker) {
|
|
|
|
|
await $`brew install --cask docker`
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
await $`docker run --rm hello-world`
|
|
|
|
|
} catch (e) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('warn', logStage, `The command \`docker run --rm hello-world\` failed`)
|
2022-12-02 09:09:59 -08:00
|
|
|
|
try {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, 'Attempting to open \`/Applications/Docker.app\` (Docker Desktop for macOS). This should take about 30 seconds.')
|
2022-12-02 15:07:52 -08:00
|
|
|
|
const promises = [$`test -d /Applications/Docker.app`, $`open /Applications/Docker.app`]
|
2022-12-02 09:25:27 -08:00
|
|
|
|
await Promise.all(promises)
|
|
|
|
|
const gum = which.sync('gum', { nothrow: true })
|
2022-12-02 09:09:59 -08:00
|
|
|
|
if (gum) {
|
2022-12-02 09:25:27 -08:00
|
|
|
|
execSync('gum spin --spinner dot --title "Waiting for Docker Desktop to start up.." -- sleep 30', {stdio: 'inherit', shell: true})
|
2022-12-02 09:09:59 -08:00
|
|
|
|
} else {
|
|
|
|
|
await $`sleep 30`
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('warn', logStage, `Docker Desktop appears to not be installed!`)
|
2022-12-02 09:09:59 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-12-02 09:01:47 -08:00
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'winget') {
|
|
|
|
|
} else if (packageManager === 'yay') {
|
|
|
|
|
} else if (packageManager === 'zypper') {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function ensureInstalled(bin, callback) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const logStage = 'Package Manager Install'
|
2022-11-29 22:26:34 -08:00
|
|
|
|
const installed = which.sync(bin, { nothrow: true })
|
|
|
|
|
if (installed) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`${bin}\` is available`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('warn', logStage, `\`${bin}\` is not installed!`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
if (callback) {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await callback
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('error', logStage, `There does not appear to be an installation method available for \`${bin}\``)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-02 09:50:31 -08:00
|
|
|
|
async function ensurePackageManagerAnsible() {
|
|
|
|
|
await $`pipx install ansible`
|
|
|
|
|
await $`pipx inject ansible PyObjC PyObjC-core docker lxml netaddr pexpect python-vagrant pywinrm requests-credssp watchdog`
|
2022-12-02 10:38:35 -08:00
|
|
|
|
await $`mkdir -p "$HOME/.cache/megabyte-labs"`
|
|
|
|
|
await $`touch "$HOME/.cache/megabyte-labs/ansible-installed"`
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', 'Package Manager Install', `Ansible and its supporting packages are now installed via pipx`)
|
2022-12-02 09:50:31 -08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 22:26:34 -08:00
|
|
|
|
// Ensure the package manager is available
|
|
|
|
|
let packageManagerInstalled = {};
|
|
|
|
|
async function ensurePackageManager(packageManager) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const logStage = 'Package Manager Install'
|
|
|
|
|
log('info', logStage, `Ensuring \`${packageManager}\` is set up`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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') {
|
2022-12-02 09:50:31 -08:00
|
|
|
|
try {
|
2022-12-02 10:39:43 -08:00
|
|
|
|
await $`test -f "$HOME/.cache/megabyte-labs/ansible-installed"`
|
2022-12-02 09:50:31 -08:00
|
|
|
|
const ansible = which.sync('ansible', { nothrow: true })
|
|
|
|
|
if (ansible) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`ansible\` and its supporting packages appear to be installed`)
|
2022-12-02 09:50:31 -08:00
|
|
|
|
} else {
|
|
|
|
|
await ensurePackageManagerAnsible()
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
await ensurePackageManagerAnsible()
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'apk') {
|
|
|
|
|
await ensureInstalled('apk', false)
|
|
|
|
|
} else if (packageManager === 'apt') {
|
|
|
|
|
await ensureInstalled('apt', false)
|
|
|
|
|
} else if (packageManager === 'basher') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('basher', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
# TODO
|
|
|
|
|
echo "Bash script that installs basher here"
|
|
|
|
|
`)
|
|
|
|
|
} else if (packageManager === 'binary') {
|
|
|
|
|
} else if (packageManager === 'bpkg') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('bpkg', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
# TODO
|
|
|
|
|
echo "Bash script that installs bpkg here"
|
|
|
|
|
`)
|
|
|
|
|
} else if (packageManager === 'brew' || packageManager === 'cask') {
|
2022-12-02 06:30:38 -08:00
|
|
|
|
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
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, 'Homebrew is not installed. Password may be required.')
|
2022-12-02 06:30:38 -08:00
|
|
|
|
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
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('warn', logStage, 'Homebrew was installed but part of the installation failed. Attempting to fix..')
|
2022-12-02 06:30:38 -08:00
|
|
|
|
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
|
2022-11-29 22:26:34 -08:00
|
|
|
|
fi
|
|
|
|
|
fi
|
2022-12-02 06:30:38 -08:00
|
|
|
|
`)
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'cargo') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('cargo', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
# TODO Bash script that installs cargo
|
|
|
|
|
`)
|
|
|
|
|
} else if (packageManager === 'choco') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('choco', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('crew', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
# 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) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`dnf\` is available`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (yum) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`yum\` is available`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('error', logStage, `Both \`dnf\` and \`yum\` are not available`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'flatpak') {
|
|
|
|
|
const flatpak = which.sync('flatpak', { nothrow: true })
|
|
|
|
|
if (flatpak) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`flatpak\` is available`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} 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 {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('error', logStage, `\`flatpak\` failed to install!`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`flatpak\` was installed. It may require a reboot to function correctly.`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'gem') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('gem', $`brew install ruby`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'go') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('gem', $`brew install go`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'nix') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('nix', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', logStage, `\`npm\`, \`node\`, and \`volta\` are available`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} 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') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('pipx', $`brew install pipx && pipx ensurepath`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'pkg') {
|
|
|
|
|
await ensureInstalled('pkg', false)
|
|
|
|
|
} else if (packageManager === 'port') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('port', $`
|
2022-12-02 06:11:26 -08:00
|
|
|
|
echo -n "TODO - script that installs port on macOS here"
|
2022-11-29 22:26:34 -08:00
|
|
|
|
`)
|
|
|
|
|
} else if (packageManager === 'scoop') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('scoop', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('whalebrew', $`brew install whalebrew`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'winget') {
|
2022-12-02 06:21:47 -08:00
|
|
|
|
await ensureInstalled('winget', $`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
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) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
const logStage = 'Package Install'
|
2022-12-02 09:50:31 -08:00
|
|
|
|
let pkg = packages
|
2022-11-29 22:26:34 -08:00
|
|
|
|
try {
|
|
|
|
|
if (packageManager === 'appimage') {
|
|
|
|
|
} else if (packageManager === 'ansible') {
|
2022-12-02 16:36:16 -08:00
|
|
|
|
console.log(packageManager)
|
|
|
|
|
console.log(packages)
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
2022-12-02 16:36:16 -08:00
|
|
|
|
console.log(pkg)
|
2022-12-02 16:44:43 -08:00
|
|
|
|
try {
|
2022-12-02 16:47:05 -08:00
|
|
|
|
execSync(`gum spin --spinner dot --title "Installing ${pkg} via Ansible" -- ansible localhost -m setup -m include_role -a name=${pkg} -e ansible_user=${process.env.USER} -e include_homebrew_install=false`, {stdio: 'inherit', shell: true})
|
2022-12-02 16:44:43 -08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
await $`ansible localhost -m setup -m include_role -a name=${pkg} -e ansible_user=${process.env.USER} -e include_homebrew_install=false`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'apk') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo apk add ${packages}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'apt') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo apt-get install -y ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'basher') {
|
|
|
|
|
} else if (packageManager === 'binary') {
|
|
|
|
|
} else if (packageManager === 'brew') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`brew install ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'cask') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`brew install --cask ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'cargo') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (const pkg of packages) {
|
|
|
|
|
await $`cargo install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'choco') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`choco install -y ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'crew') {
|
|
|
|
|
} else if (packageManager === 'dnf') {
|
|
|
|
|
const dnf = which.sync('dnf', { nothrow: true })
|
|
|
|
|
const yum = which.sync('yum', { nothrow: true })
|
|
|
|
|
if (dnf) {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo dnf install -y ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (yum) {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo yum install -y ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'flatpak') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo flatpak install flathub ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'gem') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`gem install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'go') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`go install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'nix') {
|
|
|
|
|
} else if (packageManager === 'npm') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`volta install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'pacman') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo pacman -Sy --noconfirm --needed ${pkg}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
} else if (packageManager === 'pipx') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`pipx install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'pkg') {
|
|
|
|
|
} else if (packageManager === 'port') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo port install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'scoop') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`scoop install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'snap') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo snap install -y ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'whalebrew') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`whalebrew install ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'winget') {
|
|
|
|
|
} else if (packageManager === 'yay') {
|
2022-12-02 06:40:47 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`yay -Sy --noconfirm --needed ${pkg}`
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} else if (packageManager === 'zypper') {
|
2022-12-02 15:15:45 -08:00
|
|
|
|
for (let pkg of packages) {
|
|
|
|
|
await $`sudo zypper install -y ${packages}`
|
|
|
|
|
}
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
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..`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// main process
|
|
|
|
|
async function main() {
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', 'Catalog Download', `Fetching the latest version of the installation map`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
installData = await downloadInstallData();
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', 'Install Orders', `Calculating the install orders`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
await generateInstallOrders();
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', `Ensuring any package managers that will be used are installed / configured`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
const packageManagers = Object.keys(installOrders);
|
|
|
|
|
for (const packageManager of packageManagers) {
|
|
|
|
|
await ensurePackageManager(packageManager);
|
|
|
|
|
}
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', 'Install Orders', `The install orders were generated:`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
console.log(installOrders)
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', 'Package Manager Pre-Install', `Running package manager pre-installation steps`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
for (const packageManager of packageManagers) {
|
|
|
|
|
await beforeInstall(packageManager);
|
|
|
|
|
}
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', 'Package Pre-Install', `Running package-specific pre-installation steps`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
for (const script of installOrdersPre) {
|
|
|
|
|
await $`${script}`;
|
|
|
|
|
}
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', 'Package Install', `Installing the packages`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
for (const packageManager of packageManagers) {
|
|
|
|
|
const asyncOrders = [];
|
|
|
|
|
asyncOrders.push(
|
|
|
|
|
Promise.resolve(
|
|
|
|
|
installPackageList(packageManager, installOrders[packageManager])
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
await Promise.all(asyncOrders);
|
|
|
|
|
}
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('info', 'Package Post-Install', `Running package-specific post-installation steps`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
for (const script of installOrdersPost) {
|
|
|
|
|
await $`${script}`;
|
|
|
|
|
}
|
2022-12-02 16:13:21 -08:00
|
|
|
|
log('info', 'Package Manager Post-Install', `Running package manager post-installation steps`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
for (const packageManager of packageManagers) {
|
|
|
|
|
await afterInstall(packageManager);
|
|
|
|
|
}
|
2022-12-02 15:07:52 -08:00
|
|
|
|
log('success', 'Installation Complete', `Done!`)
|
2022-11-29 22:26:34 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start the main process
|
|
|
|
|
await main();
|