This commit is contained in:
Brian Zalewski 2024-01-15 07:20:22 +00:00
parent 96baf091a1
commit 6e97ef4274
5 changed files with 193 additions and 92 deletions

View file

@ -47,12 +47,14 @@ if command -v install-program > /dev/null; then
if command -v unbuffer > /dev/null; then
logg info 'Running unbuffer install-program'
unbuffer install-program {{ $softwareList }}
logg info 'Running unbuffer installx'
unbuffer installx {{ $softwareList }}
else
logg info 'Running install-program without unbuffer'
install-program {{ $softwareList }}
logg info 'Running installx'
installx {{ $softwareList }}
fi
# TODO - Figure out how to configure no logs to print to ~/.ansible.log -- should be printing to the value specified in the ansible.cfg
rm -rf "$HOME/.ansible.log"
else
logg error 'zx is not available'
fi

View file

@ -654,12 +654,25 @@ installBrewPackages() {
logg success 'Finished installing auxilary Homebrew packages'
}
ensureMacportsInstalled() {
if [ -d /Applications ] && [ -d /System ]; then
if ! command -v port > /dev/null; then
logg info 'Ensuring /opt/mports/macports-base is removed' && sudo rm -rf /opt/mports/macports-base
logg info 'Cloning source for macports to /opt/mports/macports-base' && sudo git clone --branch v2.8.0 --depth 1 https://github.com/macports/macports-base.git /opt/mports/macports-base
cd /opt/mports/macports-base
logg info 'Building macports' && sudo bash --noprofile --norc -c './configure --enable-readline && make && make install && make distclean'
logg info 'Running sudo port selfupdate' && sudo port selfupdate
fi
fi
}
if [ -n "$DEBUG" ] || [ -n "$DEBUG_MODE" ]; then
logg info 'The DEBUG or DEBUG_MODE environment variable is set so preliminary system tweaks will be run synchronously'
allocateSwap
configureGPG
disableDStoreFileCreation
enableDarkTransparentMode
ensureMacportsInstalled
ensureUserGroup
increaseMapCount
installBrewPackages
@ -676,6 +689,7 @@ else
configureGPG &
disableDStoreFileCreation &
enableDarkTransparentMode &
ensureMacportsInstalled &
ensureUserGroup &
increaseMapCount &
installBrewPackages &

View file

@ -185,6 +185,9 @@ export CURLOPT_ACCEPT_ENCODING=true
### Dagu
export DAGU_HOME="${XDG_CONFIG_HOME:-$HOME/.config}/dagu"
### Debian
export DEBIAN_FRONTEND=noninteractive
### Desk
export DESK_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/desk"
export DESK_DESKS_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/desk/desks"
@ -225,6 +228,10 @@ if command -v flatpak > /dev/null; then
export XDG_DATA_DIRS="${XDG_CONFIG_HOME:-$HOME/.local/share}/flatpak/exports/share:$FLATPAK_INSTALLATIONS/exports/share:$XDG_DATA_DIRS"
fi
### FreeBSD
export ASSUME_ALWAYS_YES="yes"
export DEFAULT_ALWAYS_YES="yes"
### fzf
if command -v fd > /dev/null; then
export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow --exclude .git'

View file

@ -1,12 +1,27 @@
#!/usr/bin/env zx
import osInfo from 'linux-os-info'
// $.verbose = false
let installOrder, osArch, osId, osType, pkgs, sysType
const cacheDir = os.homedir() + '/.cache/installx'
async function getOsInfo() {
return osInfo({ mode: 'sync' })
}
async function runSilentCommand(command) {
require('child_process').execSync(`${command}`, { stdio: 'inherit', shell: true })
}
async function runScript(key, script) {
fs.writeFileSync(`${cacheDir}/${key}`, script)
const file = await $`cat ${cacheDir}/${key} | grep "^# @file" | sed 's/^# @file //'`
const brief = await $`cat ${cacheDir}/${key} | grep "^# @brief" | sed 's/^# @brief //'`
fs.writeFileSync(`${cacheDir}/${key}-glow`, "# " + file.stdout + "\n> " + brief.stdout + "\n```sh\n" + script + "\n```")
runSilentCommand(`glow "${cacheDir}/${key}-glow" && bash "${cacheDir}/${key}"`)
}
function getPkgData(pref, pkg, installer) {
if (installer) {
if (pkg[`${pref}:${installer}:${osId}:${osArch}`]) {
@ -79,36 +94,6 @@ async function getSystemType() {
}
}
async function getBrewFormulas() {
await $`brew list -1 > brew-list`
return fs.readFileSync('./brew-list').toString().split('\n')
}
async function getGems() {
await $`gem query --local > gem-list`
return fs.readFileSync('./gem-list').toString().split('\n').map(x => x.split(' ')[0])
}
async function getVoltaInstalls() {
await $`volta list --format plain > volta-list`
return fs.readFileSync('./volta-list').toString().split('\n').filter(x => x).map(x => x.split(' ')[1].split('@')[0])
}
async function getCrates() {
await $`cargo install --list | awk '/^[[:alnum:]]/ {print $1}' > cargo-list`
return fs.readFileSync('./cargo-list').toString().split('\n')
}
async function getPipxPackages() {
await $`pipx list --short > pipx-list`
return fs.readFileSync('./pipx-list').toString().split('\n').map(x => x.split(' ')[0])
}
async function getPips() {
await $`pip3 list > pip-list`
return fs.readFileSync('./pip-list').toString().split('\n').map(x => x.split(' ')[0])
}
function expandDeps(keys) {
for (const i of keys) {
for (const pref of installOrder[sysType]) {
@ -130,64 +115,144 @@ function expandDeps(keys) {
async function bundleInstall(brews, casks) {
const lines = []
for (const cask of casks) {
lines.push(`cask "${cask}"`)
lines.push(`cask "${cask.cask}"`)
}
for (const brew of brews) {
lines.push(`brew "${brew}"`)
lines.push(`brew "${brew.brew}"`)
}
fs.writeFileSync('Brewfile', lines.join('\n'))
await $`brew bundle --file Brewfile`
}
async function forEachSeries(iterable) {
for (const x of iterable) {
await x
}
}
async function installPackages(pkgInstructions) {
const combined = {}
const promises = []
for (const option of installOrder[sysType]) {
combined[option] = pkgInstructions.filter(x => x.installType === option)
const instructions = pkgInstructions.filter(x => x.installType === option)
if (instructions.length) {
combined[option] = instructions
}
}
if (combined.brew || combined.cask) {
if ((combined.brew && combined.brew.length) || (combined.cask && combined.cask.length)) {
promises.push(bundleInstall(combined.brew ? combined.brew : [], combined.cask ? combined.cask : []))
}
if (combined.cargo) {
for (const pkg of combined.cargo) {
promises.push($`cargo install ${pkg}`)
for (const key of Object.keys(combined)) {
switch(key) {
case 'ansible':
promises.push(forEachSeries(combined[key].flatMap(x => x.installList.flatMap(i => $`${key} 127.0.0.1 -v${process.env.DEBUG && 'vv'} -e '{ ansible_connection: "local", ansible_become_user: "root", ansible_user: "${process.env.USER}", ansible_family: "${osId.charAt(0).toUpperCase() + osId.slice(1)}", install_homebrew: False }' -m include_role -a name=${i}`))))
case 'apk':
promises.push($`sudo ${key} add ${combined[key].flatMap(x => x.installList).split(' ')}`)
case 'appimage':
promises.push(...combined[key].flatMap(x => x.installList.flatMap(i => {
if (x.substring(0, 4) === 'http') {
return $`zap install --select-first -q --from ${i}`
} else if ((x.match(/\//g) || []).length === 1) {
return $`zap install --select-first -q --github --from ${i}`
} else {
return $`zap install --select-first -q ${i}`
}
})))
case 'apt':
promises.push($`DEBIAN_FRONTEND=noninteractive sudo apt-get -o DPkg::Options::=--force-confdef install -y ${combined[key].flatMap(x => x.installList).split(' ')}`)
case 'basher':
case 'baulk':
case 'cargo':
case 'crew':
case 'gem':
case 'go':
case 'npm':
case 'pip':
case 'pipx':
case 'scoop': // Maybe needs forEachSeries
case 'winget': // Maybe needs forEachSeries
promises.push(...combined[key].flatMap(x => x.installList.flatMap(i => $`${key} install ${i}`)))
break;
case 'binary':
// TODO
promises.push(...combined[key].flatMap(x => x.installList.flatMap(i => $`TMP="$(mktemp)" && curl -sSL ${i} > "$TMP" && sudo mv "$TMP" /usr/local/src/${x._bin} && chmod +x /usr/local/src/${x._bin}`)))
case 'brew':
case 'cask': // Handled above
break;
case 'choco':
promises.push($`${key} install -y ${combined[key].flatMap(x => x.installList).split(' ')}`)
case 'dnf':
case 'yum':
case 'zypper':
promises.push($`sudo ${key} install -y ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
case 'emerge':
case 'pkg_add':
promises.push($`sudo ${key} ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
case 'eopkg':
case 'pkg-freebsd':
case 'pkg-termux':
case 'pkgin':
case 'port':
case 'snap': // TODO - snap testing.. combine with snap-classic and add appropriate logic
promises.push($`sudo ${key === 'pkg-freebsd' || key === 'pkg-termux' ? 'pkg' : key} install ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
case 'flatpak':
promises.push(forEachSeries(combined[key].flatMap(x => x.installList.flatMap(i => $`sudo ${key} install -y flathub ${i}`))))
break;
case 'github': // TODO
break;
case 'nix-env': // TODO
case 'nix-pkg': // TODO
case 'nix-shell': // TODO
break;
case 'pacman':
promises.push($`sudo ${key} -Sy --noconfirm --needed ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
case 'pkg-darwin':
break;
case 'sbopkg': // TODO
break;
case 'script':
promises.push(...combined[key].flatMap(x => x.installList.map(i => $`${i}`)))
break;
case 'snap-classic':
promises.push($`sudo snap install --classic ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
case 'whalebrew': // TODO
break;
case 'xbps':
promises.push($`sudo xbps-install -S ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
case 'yay':
promises.push($`yay -Sy --noconfirm --needed ${combined[key].flatMap(x => x.installList).split(' ')}`)
break;
default:
console.log(`Unable to find install key instructions for ${key}`)
}
}
if (combined.go) {
for (const pkg of combined.go) {
promises.push($`go install ${pkg}`)
}
await Promise.all(promises)
}
async function acquireManagerList(type, command) {
if (fs.existsSync(`${cacheDir}/${type}`)) {
setTimeout(() => {
require('child_process').execSync(`${command} > ${cacheDir}/${type}`)
}, 0)
} else {
require('child_process').execSync(`${command} > ${cacheDir}/${type}`)
}
if (combined.npm) {
for (const pkg of combined.npm) {
promises.push($`volta install ${pkg}`)
}
}
if (combined.pacman) {
const pacmanPkgs = combined.pacman.map(x => )
promises.push($`sudo pacman -Sy --noconfirm --needed ${combined.pacman.map}`)
}
if (combined.pipx) {
for (const pkg of combined.pipx) {
promises.push($`pipx install ${pkg}`)
}
}
console.log(combinedInstructions)
return fs.readFileSync(`${cacheDir}/${type}`).toString().split('\n')
}
async function main() {
cd(await $`mktemp -d`)
await $`mkdir -p ${cacheDir}`
const initData = await Promise.all([
getOsInfo(),
getSoftwareDefinitions(),
getSystemType(),
getBrewFormulas(),
getGems(),
getVoltaInstalls(),
getCrates(),
getPipxPackages(),
getPips()
getSystemType()
])
osArch = initData[0].arch
osId = process.platform === 'win32' ? 'win32' : (process.platform === 'linux' ? initData[0].id : process.platform)
@ -195,17 +260,25 @@ async function main() {
pkgs = initData[1].softwarePackages
sysType = initData[2]
installOrder = initData[1].installerPreference
const lists = [
acquireManagerList('brew', `brew list -1`),
acquireManagerList('cargo', `cargo install --list | awk '/^[[:alnum:]]/ {print $1}'`),
acquireManagerList('gem', `gem list | awk '{print $1}'`),
acquireManagerList('npm', `volta list --format plain | awk '{print $2}' | sed 's/@.*//'`),
acquireManagerList('pip3', `pip3 list | awk '{print $1}'`),
acquireManagerList('pipx', `pipx list --short | awk '{print $1}'`)
]
const managerLists = {
brew: initData[3],
cargo: initData[6],
gem: initData[4],
npm: initData[5],
pip: initData[8],
pipx: initData[7]
brew: lists[0],
cargo: lists[1],
gem: lists[2],
npm: lists[3],
pip3: lists[4],
pipx: lists[5]
}
const installKeys = argv._
const installInstructions = Object.keys(pkgs)
.filter(i => expandDeps(installKeys).includes(i))
const installKeys = Object.keys(pkgs)
.filter(i => expandDeps(argv._).includes(i))
const installData = installKeys
.map(i => {
for (const pref of installOrder[sysType]) {
const installKey = getPkgData(pref, pkgs[i], false)
@ -228,6 +301,7 @@ async function main() {
}
})
.filter(x => x.installKey)
const installInstructions = installData
.filter(x => {
// Filter out packages already installed by by package managers
return Object.keys(managerLists).includes(x.installType)
@ -255,8 +329,12 @@ async function main() {
return whenField ? whenCheck : true
})
await installPackages(installInstructions)
//.filter(x => x.installKey)
console.log('install instructions', installInstructions)
const postScripts = installData
.flatMap(x => {
const postField = getPkgData('_post', x, x.installType)
return (postField && runScript(x.listKey, x[postField])) || Promise.resolve()
})
await Promise.all(postScripts)
}
main()

View file

@ -3224,7 +3224,7 @@ softwarePackages:
if command -v termux-setup-storage > /dev/null; then
apt install termux-api
fi
pip: ntfy[emoji,matrix,pid,slack]
pip3: ntfy[emoji,matrix,pid,slack]
makeself:
_bin: makeself
_github: https://github.com/megastep/makeself
@ -3539,7 +3539,7 @@ softwarePackages:
nix-env: nixpkgs.clipboard-jh
scoop: clipboard
snap: clipboard
xbps-install: clipboard
xbps: clipboard
yay: clipboard
editly:
_bin: editly
@ -3653,7 +3653,7 @@ softwarePackages:
_name: Polybar
apt: polybar
pacman: polybar
xbps-install: polybar
xbps: polybar
zypper: polybar
pkg-freebsd: polybar
dnf: polybar
@ -3666,7 +3666,7 @@ softwarePackages:
emerge: app-shells/hstr
apk: hstr
pkg-freebsd: hstr
xbps-install: hstr
xbps: hstr
brew: hstr
port: histr
nix-env: hstr
@ -4862,7 +4862,7 @@ softwarePackages:
pacman: fzf
pkgin: fzf
pkg-freebsd: fzf
pkg-openbsd: fzf
pkg_add: fzf
port: fzf
xbps: fzf
zypper: fzf
@ -5178,7 +5178,7 @@ softwarePackages:
pacman: zola
pkgin: zola
pkg-freebsd: zola
pkg-openbsd: zola
pkg_add: zola
port: zola
scoop: zola
snap: zola
@ -6953,7 +6953,7 @@ softwarePackages:
pkg-termux: lsd
port: lsd
scoop: lsd
xbps-install: lsd
xbps: lsd
zypper: lsd
lxc:
_bin: lxc
@ -8706,7 +8706,7 @@ softwarePackages:
brew: neofetch
nix-env: neofetch
eopkg: neofetch
xbps-install: neofetch
xbps: neofetch
zypper: neofetch
scoop: neofetch
neovide:
@ -9981,7 +9981,7 @@ softwarePackages:
nix: restic
pacman: restic
pkg-freebsd: restic
pkg-openbsd: restic
pkg_add: restic
port: restic
scoop: restic
zypper: restic
@ -10649,7 +10649,7 @@ softwarePackages:
nix: nixpkgs.shellcheck
pacman: shellcheck
pkg-freebsd: shellcheck
pkg-openbsd: shellcheck
pkg_add: shellcheck
port: shellcheck
scoop: shellcheck
snap: shellcheck
@ -11414,7 +11414,7 @@ softwarePackages:
pacman: just
nix-env: nixpkgs.just
eopkg: just
xbps-install: just
xbps: just
pkg-freebsd: just
apk: just
dnf: just
@ -11658,7 +11658,7 @@ softwarePackages:
pacman: vhs
port: vhs
scoop: vhs
xbps-install: vhs
xbps: vhs
soft-serve:
_bin: soft
_desc: A tasty, self-hostable Git server for the command line
@ -13724,7 +13724,7 @@ softwarePackages:
pkg_add: pick
port: pick
yay: pick
xbps-install: pick
xbps: pick
nve:
_bin: nve
_github: https://github.com/ehmicky/nve
@ -13905,7 +13905,7 @@ softwarePackages:
port: task
emerge: task
pacman: task
xbps-install: task
xbps: task
zypper: taskwarrior
boringtun:
_bin: boringtun-cli
@ -14254,7 +14254,7 @@ softwarePackages:
nix: yank
pacman: yank
pkg-freebsd: yank
pkg-openbsd: yank
pkg_add: yank
port: yank
scoop: win32yank
zypper: yank