Update .local/share/chezmoi/home/dot_local/bin/executable_install-program

This commit is contained in:
Brian Zalewski 2022-12-02 23:07:52 +00:00
parent 41eb0d434d
commit c9362d6b60

View file

@ -2,6 +2,78 @@
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, labelStyle, message
if (type === 'info') {
icon = chalk.cyanBright(this.figures.pointer)
labelStyle = chalk.bold.underline
message = chalk.bold(msg)
} else if (type === 'star') {
icon = chalk.yellowBright(this.figures.star)
labelStyle = chalk.bold.underline
message = chalk.bold(msg)
} else if (type === 'success') {
icon = chalk.greenBright(this.figures.play)
labelStyle = chalk.bold.underline
chalk.bold(msg)
} else if (type === 'warn') {
icon = `${chalk.yellowBright(this.figures.lozenge)} ${chalk.bold.black.bgYellowBright(' WARNING ')}`
labelStyle = chalk.bold.underline
chalk.yellowBright(msg)
} else if (type === 'error') {
icon = `${chalk.redBright(this.figures.cross)} ${chalk.black.bold.bgRedBright(' ERROR ')} + ' '}`
labelStyle = chalk.bold.underline
message = chalk.redBright(msg)
}
const outputMessage = `${icon} ${labelStyle(label)} ${message}`
console.log(outputMessage)
}
$.log = (entry) => {
if (entry.kind === 'cmd' && entry.cmd.substring(0, 4) === 'logg') {
//execSync(entry.cmd, {stdio: 'inherit', shell: true})
@ -29,7 +101,7 @@ async function downloadInstallData() {
const text = await response.text()
return YAML.parse(text)
} else {
await $`logg error 'Failed to download the installation map'`
log('error', 'Install Data', `Failed to download the installation map`)
}
}
@ -37,9 +109,9 @@ async function downloadInstallData() {
async function generateInstallOrders() {
const packagesToInstall = process.argv.slice(3);
const installerPreference = await OSTypeInstallerKey()
await $`logg info 'Installer preference category detected as ${installerPreference}'`
log('info', 'Install Orders', `Installer preference category detected as ${installerPreference}`)
const preferenceOrder = installData.installerPreference[installerPreference];
await $`logg info 'Preference order acquired:'`
log('info', 'Install Orders', `Preference order acquired:`)
console.log(preferenceOrder)
const softwarePackages = installData.softwarePackages;
for (let pkg of packagesToInstall) {
@ -51,7 +123,7 @@ async function generateInstallOrders() {
} else if (softwarePackages[pkg]) {
packageKey = pkg
} else {
await $`logg warn 'The package \`${pkg}\` was not found in the installation map'`
log('warn', 'Install Orders', `The package \`${pkg}\` was not found in the installation map`)
continue;
}
for (let preference of preferenceOrder) {
@ -97,7 +169,7 @@ async function updateInstallMaps(preference, packages, scopedPreference, pkg, pa
if (!installOrders[preference]) {
installOrders[preference] = [];
}
await $`logg info 'Found a match for the package \`${pkg}\` (${packageKey} via ${scopedPreference})'`
log('info', 'Install Orders', `Found a match for the package \`${pkg}\` (${packageKey} via ${scopedPreference})`)
const newPackages = packages[scopedPreference];
installOrders[preference] = installOrders[preference].concat(
typeof newPackages === "string" ? [newPackages] : newPackages
@ -178,8 +250,8 @@ async function releaseID() {
async function afterInstall(packageManager) {
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
await $`logg info 'Ensuring temporary passwordless sudo privileges used by Ansible are removed'`
await $`echo "$(whoami) ALL=(ALL:ALL) NOPASSWD: ALL # TEMPORARY FOR ANSIBLE INSTALL" | sudo tee -a /etc/sudoers`
log('info', 'Post-Install', `Ensuring temporary passwordless sudo privileges used by Ansible are removed`)
await $`sudo sed -i '/# TEMPORARY FOR ANSIBLE INSTALL/d' /etc/sudoers`
} else if (packageManager === 'apk') {
} else if (packageManager === 'apt') {
} else if (packageManager === 'basher') {
@ -214,7 +286,7 @@ async function afterInstall(packageManager) {
async function beforeInstall(packageManager) {
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
await $`logg info 'Temporarily enabling passwordless sudo for Ansible role installations'`
log('info', 'Pre-Install', `Temporarily enabling passwordless sudo for Ansible role installations`)
await $`sudo echo "$(whoami) ALL=(ALL:ALL) NOPASSWD: ALL # TEMPORARY FOR ANSIBLE INSTALL" > /etc/sudoers`
} else if (packageManager === 'apk') {
} else if (packageManager === 'apt') {
@ -250,9 +322,10 @@ async function beforeInstall(packageManager) {
try {
await $`docker run --rm hello-world`
} catch (e) {
await $`logg warn 'The command \`docker run --rm hello-world\` failed'`
log('warn', `The command \`docker run --rm hello-world\` failed`)
try {
const promises = [$`test -d /Applications/Docker.app`, $`logg info 'Attempting to open \`/Applications/Docker.app\` (Docker Desktop for macOS). This should take about 30 seconds.'`, $`open /Applications/Docker.app`]
log('info', 'Package Manager', '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) {
@ -261,7 +334,7 @@ async function beforeInstall(packageManager) {
await $`sleep 30`
}
} catch (e) {
await $`logg warn 'Docker Desktop appears to not be installed!'`
log('warn', 'Package Manager', `Docker Desktop appears to not be installed!`)
}
}
}
@ -274,13 +347,13 @@ async function beforeInstall(packageManager) {
async function ensureInstalled(bin, callback) {
const installed = which.sync(bin, { nothrow: true })
if (installed) {
await $`logg info '\`${bin}\` is available'`
log('info', `\`${bin}\` is available`)
} else {
await $`logg warn '\`${bin}\` is not installed!'`
log('warn', `\`${bin}\` is not installed!`)
if (callback) {
await callback
} else {
await $`logg error 'There does not appear to be an installation method available for \`${bin}\`'`
log('error', `There does not appear to be an installation method available for \`${bin}\``)
}
}
}
@ -290,13 +363,13 @@ async function ensurePackageManagerAnsible() {
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"`
await $`logg info 'Ansible and its supporting packages are now installed via pipx'`
log('info', `Ansible and its supporting packages are now installed via pipx`)
}
// Ensure the package manager is available
let packageManagerInstalled = {};
async function ensurePackageManager(packageManager) {
await $`logg info 'Ensuring \`${packageManager}\` is set up'`
log('info', `Ensuring \`${packageManager}\` is set up`)
if (packageManagerInstalled[packageManager]) {
return;
} else {
@ -320,7 +393,7 @@ async function ensurePackageManager(packageManager) {
await $`test -f "$HOME/.cache/megabyte-labs/ansible-installed"`
const ansible = which.sync('ansible', { nothrow: true })
if (ansible) {
await $`logg info '\`ansible\` and its supporting packages appear to be installed'`
log('info', `\`ansible\` and its supporting packages appear to be installed`)
} else {
await ensurePackageManagerAnsible()
}
@ -349,11 +422,11 @@ async function ensurePackageManager(packageManager) {
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
logg info 'Homebrew is not installed. Password may be required.'
log('info', 'Package Manager', '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
logg warn 'Homebrew was installed but part of the installation failed. Attempting to fix..'
log('warn', 'Package Manager', '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
@ -384,16 +457,16 @@ async function ensurePackageManager(packageManager) {
const dnf = which.sync('dnf', { nothrow: true })
const yum = which.sync('yum', { nothrow: true })
if (dnf) {
await $`logg info '\`dnf\` is available'`
log('info', 'Package Manager', `\`dnf\` is available`)
} else if (yum) {
await $`logg info '\`yum\` is available'`
log('info', 'Package Manager', `\`yum\` is available`)
} else {
await $`logg error 'Both \`dnf\` and \`yum\` are not available'`
log('error', 'Package Manager', `Both \`dnf\` and \`yum\` are not available`)
}
} else if (packageManager === 'flatpak') {
const flatpak = which.sync('flatpak', { nothrow: true })
if (flatpak) {
await $`logg info '\`flatpak\` is available'`
log('info', 'Package Manager', `\`flatpak\` is available`)
} else {
const apk = which.sync('apk', { nothrow: true })
const apt = which.sync('apt', { nothrow: true })
@ -426,9 +499,9 @@ async function ensurePackageManager(packageManager) {
if (flatpakPost) {
await $`flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`
} else {
await $`logg error '\`flatpak\` failed to install!'`
log('error', 'Package Manager', `\`flatpak\` failed to install!`)
}
await $`logg info '\`flatpak\` was installed. It may require a reboot to function correctly.'`
log('info', 'Package Manager', `\`flatpak\` was installed. It may require a reboot to function correctly.`)
}
} else if (packageManager === 'gem') {
await ensureInstalled('gem', $`brew install ruby`)
@ -447,7 +520,7 @@ async function ensurePackageManager(packageManager) {
const node = which('node', { nothrow: true })
const volta = which('volta', { nothrow: true })
if (npm && node && volta) {
await $`logg info '\`npm\`, \`node\`, and \`volta\` are available'`
log('info', 'Package Manager', `\`npm\`, \`node\`, and \`volta\` are available`)
} else {
if (!volta) {
await $`brew install volta`
@ -558,7 +631,7 @@ async function installPackageList(packageManager, packages) {
if (packageManager === 'appimage') {
} else if (packageManager === 'ansible') {
for (const role of packages) {
execSync('gum spin --spinner dot --title "Installing ' + role + ' via Ansible" -- ansible localhost -m setup -m include_role -a name=' + role + ' -e ansible_user="$USER"', , {stdio: 'inherit', shell: true})
execSync('gum spin --spinner dot --title "Installing ' + role + ' via Ansible" -- ansible localhost --skip-tags brew -m setup -m include_role -a name=' + role + ' -e ansible_user="$USER"', {stdio: 'inherit', shell: true})
}
} else if (packageManager === 'apk') {
await $`sudo apk add ${packages}`
@ -634,34 +707,34 @@ async function installPackageList(packageManager, packages) {
await $`sudo zypper install -y ${packages}`
}
} catch (e) {
await $`logg error 'Possibly encountered an error while installing via \`${packageManager}\`'`
await $`logg info 'Error was encountered while installing: ${pkg}'`
await $`logg info 'Proceeding with the installation..'`
log('error', 'Package Install', `Possibly encountered an error while installing via \`${packageManager}\``)
log('info', 'Package Install', `Error was encountered while installing: ${pkg}`)
log('info', 'Package Install', `Proceeding with the installation..`)
}
}
// main process
async function main() {
await $`logg info 'Fetching the latest version of the installation map'`
log('info', `Fetching the latest version of the installation map`)
installData = await downloadInstallData();
await $`logg info 'Calculating the install orders'`
log('info', 'Install Orders', `Calculating the install orders`)
await generateInstallOrders();
await $`logg info 'Ensuring any package managers that will be used are installed / configured'`
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);
}
await $`logg info 'The install orders were generated:'`
log('info', 'Install Orders', `The install orders were generated:`)
console.log(installOrders)
await $`logg info 'Running package manager pre-installation steps'`
log('info', 'Package Manager', `Running package manager pre-installation steps`)
for (const packageManager of packageManagers) {
await beforeInstall(packageManager);
}
await $`logg info 'Running package-specific pre-installation steps'`
log('info', 'Package Pre-Install', `Running package-specific pre-installation steps`)
for (const script of installOrdersPre) {
await $`${script}`;
}
await $`logg info 'Installing the packages'`
log('info', 'Package Install', `Installing the packages`)
for (const packageManager of packageManagers) {
const asyncOrders = [];
asyncOrders.push(
@ -671,15 +744,15 @@ async function main() {
);
await Promise.all(asyncOrders);
}
await $`logg info 'Running package-specific post-installation steps'`
log('info', 'Package Post-Install', `Running package-specific post-installation steps`)
for (const script of installOrdersPost) {
await $`${script}`;
}
await $`logg info 'Running package manager post-installation steps'`
log('info', 'Post-Install Package Manager', `Running package manager post-installation steps`)
for (const packageManager of packageManagers) {
await afterInstall(packageManager);
}
await $`logg success 'Done!'`
log('success', 'Installation Complete', `Done!`)
}
// Start the main process