Bug fixes to installx
This commit is contained in:
parent
3113d5aa5a
commit
2340501574
2 changed files with 71 additions and 27 deletions
|
@ -41,7 +41,7 @@ async function runScript(key, script) {
|
||||||
fs.writeFileSync(`${cacheDir}/${key}-glow`, (file.stdout ? `# ${file.stdout}\n\n` : '') + (brief.stdout ? `> ${brief.stdout}\n\n` : '') + '```sh\n' + templatedScript.stdout + "\n```")
|
fs.writeFileSync(`${cacheDir}/${key}-glow`, (file.stdout ? `# ${file.stdout}\n\n` : '') + (brief.stdout ? `> ${brief.stdout}\n\n` : '') + '```sh\n' + templatedScript.stdout + "\n```")
|
||||||
fs.writeFileSync(`${cacheDir}/${key}`, templatedScript.stdout)
|
fs.writeFileSync(`${cacheDir}/${key}`, templatedScript.stdout)
|
||||||
try {
|
try {
|
||||||
runSilentCommand(`glow --width 140 "${cacheDir}/${key}-glow"`)
|
runSilentCommand(`glow --width 80 "${cacheDir}/${key}-glow"`)
|
||||||
// TODO: Set process.env.DEBUG || true here because the asynchronous method is not logging properly / running slow
|
// TODO: Set process.env.DEBUG || true here because the asynchronous method is not logging properly / running slow
|
||||||
if (process.env.DEBUG || true) {
|
if (process.env.DEBUG || true) {
|
||||||
return runSilentCommand(`bash "${cacheDir}/${key}" || logg error 'Error occurred while processing script for ${key}'`)
|
return runSilentCommand(`bash "${cacheDir}/${key}" || logg error 'Error occurred while processing script for ${key}'`)
|
||||||
|
@ -143,8 +143,8 @@ function expandDeps(keys) {
|
||||||
return [...keys]
|
return [...keys]
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createCaskLinks() {
|
async function createCaskLinks(caskMap) {
|
||||||
const caskApps = pkgMap(pkgs)
|
const caskApps = caskMap
|
||||||
.filter(x => {
|
.filter(x => {
|
||||||
// Filter out macOS apps that already have a _app installed
|
// Filter out macOS apps that already have a _app installed
|
||||||
if (x.installType === 'cask' || (osId === 'darwin' && x._app)) {
|
if (x.installType === 'cask' || (osId === 'darwin' && x._app)) {
|
||||||
|
@ -153,14 +153,27 @@ async function createCaskLinks() {
|
||||||
const sysDir = fs.existsSync(`/Applications/${x[appField]}`)
|
const sysDir = fs.existsSync(`/Applications/${x[appField]}`)
|
||||||
const homeDir = fs.existsSync(`${os.homedir()}/Applications/${x[appField]}`)
|
const homeDir = fs.existsSync(`${os.homedir()}/Applications/${x[appField]}`)
|
||||||
const binFile = fs.existsSync(`${os.homedir()}/.local/bin/cask/${x[binField]}`)
|
const binFile = fs.existsSync(`${os.homedir()}/.local/bin/cask/${x[binField]}`)
|
||||||
return (sysDir || homeDir) && !binFile
|
if (sysDir || homeDir) {
|
||||||
}
|
return !binFile
|
||||||
|
} else {
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
caskApps.length && await $`mkdir -p "$HOME/.local/bin/cask"`
|
caskApps.length && await $`mkdir -p "$HOME/.local/bin/cask"`
|
||||||
for (const app of caskApps) {
|
for (const app of caskApps) {
|
||||||
const appField = getPkgData('_app', app, app.installType)
|
const appField = getPkgData('_app', app, app.installType)
|
||||||
|
if (!appField) {
|
||||||
|
log(`${app.listKey} is missing an _app definition`)
|
||||||
|
return
|
||||||
|
}
|
||||||
const binField = getPkgData('_bin', app, app.installType)
|
const binField = getPkgData('_bin', app, app.installType)
|
||||||
|
if (!binField) {
|
||||||
|
log(`${app.listKey} is missing a _bin definition`)
|
||||||
|
return
|
||||||
|
}
|
||||||
if (fs.existsSync(`${os.homedir()}/Applications/${app[appField]}`)) {
|
if (fs.existsSync(`${os.homedir()}/Applications/${app[appField]}`)) {
|
||||||
fs.writeFileSync(`${os.homedir()}/.local/bin/cask/${app[binField]}`, `#!/usr/bin/env bash\nopen "$HOME/Applications/${app[appField]}" $*`)
|
fs.writeFileSync(`${os.homedir()}/.local/bin/cask/${app[binField]}`, `#!/usr/bin/env bash\nopen "$HOME/Applications/${app[appField]}" $*`)
|
||||||
await $`chmod +x '${os.homedir()}/.local/bin/cask/${app[binField]}'`
|
await $`chmod +x '${os.homedir()}/.local/bin/cask/${app[binField]}'`
|
||||||
|
@ -174,10 +187,10 @@ async function createCaskLinks() {
|
||||||
caskApps.length && log(`Finished creating Homebrew cask links in ~/.local/bin/cask`)
|
caskApps.length && log(`Finished creating Homebrew cask links in ~/.local/bin/cask`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createFlatpakLinks() {
|
async function createFlatpakLinks(flatpakMap) {
|
||||||
const flatpakInstallations = await $`flatpak --installations`
|
const flatpakInstallations = await $`flatpak --installations`
|
||||||
const flatpakDir = flatpakInstallations.stdout.replace('\n', '')
|
const flatpakDir = flatpakInstallations.stdout.replace('\n', '')
|
||||||
const flatpakApps = pkgMap(pkgs)
|
const flatpakApps = flatpakMap
|
||||||
.filter(x => {
|
.filter(x => {
|
||||||
if (x.installType === 'flatpak') {
|
if (x.installType === 'flatpak') {
|
||||||
const binField = getPkgData('_bin', x, x.installType)
|
const binField = getPkgData('_bin', x, x.installType)
|
||||||
|
@ -189,6 +202,10 @@ async function createFlatpakLinks() {
|
||||||
flatpakApps.length && await $`mkdir -p "$HOME/.local/bin/flatpak"`
|
flatpakApps.length && await $`mkdir -p "$HOME/.local/bin/flatpak"`
|
||||||
for (const app of flatpakApps) {
|
for (const app of flatpakApps) {
|
||||||
const binField = getPkgData('_bin', app, app.installType)
|
const binField = getPkgData('_bin', app, app.installType)
|
||||||
|
if (!binField) {
|
||||||
|
log(`${app.listKey} is missing a _bin definition`)
|
||||||
|
return
|
||||||
|
}
|
||||||
if (fs.existsSync(`${flatpakDir}/app/${app.installList[0]}`)) {
|
if (fs.existsSync(`${flatpakDir}/app/${app.installList[0]}`)) {
|
||||||
fs.writeFileSync(`${os.homedir()}/.local/bin/flatpak/${app[binField]}`, `#!/usr/bin/env bash\nflatpak run ${app.installList[0]} $*`)
|
fs.writeFileSync(`${os.homedir()}/.local/bin/flatpak/${app[binField]}`, `#!/usr/bin/env bash\nflatpak run ${app.installList[0]} $*`)
|
||||||
await $`chmod +x '${os.homedir()}/.local/bin/flatpak/${app[binField]}'`
|
await $`chmod +x '${os.homedir()}/.local/bin/flatpak/${app[binField]}'`
|
||||||
|
@ -199,15 +216,21 @@ async function createFlatpakLinks() {
|
||||||
flatpakApps.length && log(`Finished creating Flatpak links in ~/.local/bin/flatpak`)
|
flatpakApps.length && log(`Finished creating Flatpak links in ~/.local/bin/flatpak`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bundleInstall(brews, casks) {
|
async function bundleInstall(brews, casks, caskMap) {
|
||||||
try {
|
try {
|
||||||
const lines = []
|
const lines = []
|
||||||
log(`Adding following casks to Brewfile for installation: ${casks.join(' ')}`)
|
casks.length && log(`Adding following casks to Brewfile for installation: ${casks.join(' ')}`)
|
||||||
for (const cask of casks) {
|
for (const cask of casks) {
|
||||||
|
if (cask.indexOf('/') !== -1) {
|
||||||
|
lines.push(`tap "${cask.substring(0, cask.lastIndexOf('/'))}"`)
|
||||||
|
}
|
||||||
lines.push(`cask "${cask}"`)
|
lines.push(`cask "${cask}"`)
|
||||||
}
|
}
|
||||||
log(`Adding following brews to Brewfile for installation: ${casks.join(' ')}`)
|
brews.length && log(`Adding following brews to Brewfile for installation: ${brews.join(' ')}`)
|
||||||
for (const brew of brews) {
|
for (const brew of brews) {
|
||||||
|
if (brew.indexOf('/') !== -1) {
|
||||||
|
lines.push(`tap "${brew.substring(0, brew.lastIndexOf('/'))}"`)
|
||||||
|
}
|
||||||
lines.push(`brew "${brew}"`)
|
lines.push(`brew "${brew}"`)
|
||||||
}
|
}
|
||||||
log(`Creating Brewfile to install from`)
|
log(`Creating Brewfile to install from`)
|
||||||
|
@ -215,8 +238,9 @@ async function bundleInstall(brews, casks) {
|
||||||
log(`Installing packages via brew bundle`)
|
log(`Installing packages via brew bundle`)
|
||||||
await $`brew bundle --file Brewfile`
|
await $`brew bundle --file Brewfile`
|
||||||
log(`Finished installing via Brewfile`)
|
log(`Finished installing via Brewfile`)
|
||||||
await createCaskLinks()
|
await createCaskLinks(caskMap)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.log('Error:', e)
|
||||||
log(`Error occurred while installing via Brewfile`)
|
log(`Error occurred while installing via Brewfile`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +263,7 @@ async function installPackages(pkgInstructions) {
|
||||||
}
|
}
|
||||||
log(`Running Homebrew installation via Brewfile`)
|
log(`Running Homebrew installation via Brewfile`)
|
||||||
if ((combined.brew && combined.brew.length) || (combined.cask && combined.cask.length)) {
|
if ((combined.brew && combined.brew.length) || (combined.cask && combined.cask.length)) {
|
||||||
promises.push(bundleInstall(combined.brew ? combined.brew.flatMap(x => x.installList.flatMap(i => i)) : [], combined.cask ? combined.cask.flatMap(x => x.installList.flatMap(i => i)) : []))
|
promises.push(bundleInstall(combined.brew ? combined.brew.flatMap(x => x.installList.flatMap(i => i)) : [], combined.cask ? combined.cask.flatMap(x => x.installList.flatMap(i => i)) : [], combined.cask))
|
||||||
}
|
}
|
||||||
for (const key of Object.keys(combined)) {
|
for (const key of Object.keys(combined)) {
|
||||||
if (key !== 'script') {
|
if (key !== 'script') {
|
||||||
|
@ -272,13 +296,15 @@ async function installPackages(pkgInstructions) {
|
||||||
case 'crew':
|
case 'crew':
|
||||||
case 'gem':
|
case 'gem':
|
||||||
case 'go':
|
case 'go':
|
||||||
case 'npm':
|
|
||||||
case 'pip':
|
case 'pip':
|
||||||
case 'pipx':
|
case 'pipx':
|
||||||
case 'scoop': // Maybe needs forEachSeries
|
case 'scoop': // Maybe needs forEachSeries
|
||||||
case 'winget': // Maybe needs forEachSeries
|
case 'winget': // Maybe needs forEachSeries
|
||||||
promises.push(...combined[key].flatMap(x => x.installList.flatMap(i => $`${key} install ${i}`)))
|
promises.push(...combined[key].flatMap(x => x.installList.flatMap(i => $`${key} install ${i}`)))
|
||||||
break
|
break
|
||||||
|
case 'npm':
|
||||||
|
promises.push(...combined[key].flatMap(x => x.installList.flatMap(i => $`${key} install -g ${i}`)))
|
||||||
|
break
|
||||||
case 'binary':
|
case 'binary':
|
||||||
// TODO
|
// 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}`)))
|
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}`)))
|
||||||
|
@ -337,16 +363,18 @@ async function installPackages(pkgInstructions) {
|
||||||
log(`Unable to find install key instructions for ${key}`)
|
log(`Unable to find install key instructions for ${key}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log(`Performing ${promises.length} installations`)
|
||||||
|
process.env.DEBUG && console.log('Queued installs:', promises)
|
||||||
const installs = await Promise.allSettled(promises)
|
const installs = await Promise.allSettled(promises)
|
||||||
log(`All of the installations have finished`)
|
log(`All of the installations have finished`)
|
||||||
process.env.DEBUG && console.log('Installs:', installs)
|
process.env.DEBUG && console.log('Completed installs:', installs)
|
||||||
await postInstall(combined)
|
await postInstall(combined)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function postInstall(combined) {
|
async function postInstall(combined) {
|
||||||
log(`Running post-install routine`)
|
log(`Running post-install routine`)
|
||||||
const promises = []
|
const promises = []
|
||||||
Object.keys(combined).includes('flatpak') && promises.push(createFlatpakLinks())
|
Object.keys(combined).includes('flatpak') && promises.push(createFlatpakLinks(combined.flatpak))
|
||||||
const postInstalls = await Promise.allSettled(promises)
|
const postInstalls = await Promise.allSettled(promises)
|
||||||
process.env.DEBUG && console.log('Post installs:', postInstalls)
|
process.env.DEBUG && console.log('Post installs:', postInstalls)
|
||||||
}
|
}
|
||||||
|
@ -408,7 +436,7 @@ async function main() {
|
||||||
sysType = initData[2]
|
sysType = initData[2]
|
||||||
installOrder = initData[1].installerPreference
|
installOrder = initData[1].installerPreference
|
||||||
log(`Populating lists of pre-installed packages`)
|
log(`Populating lists of pre-installed packages`)
|
||||||
const lists = [
|
const listPromises = [
|
||||||
acquireManagerList('apt', `if command -v dpkg; then dpkg -l; fi`),
|
acquireManagerList('apt', `if command -v dpkg; then dpkg -l; fi`),
|
||||||
acquireManagerList('brew', `brew list -1`),
|
acquireManagerList('brew', `brew list -1`),
|
||||||
acquireManagerList('cargo', `cargo install --list | awk '/^[[:alnum:]]/ {print $1}'`),
|
acquireManagerList('cargo', `cargo install --list | awk '/^[[:alnum:]]/ {print $1}'`),
|
||||||
|
@ -422,6 +450,7 @@ async function main() {
|
||||||
acquireManagerList('snap', `if command -v snapd; then snap list; fi`),
|
acquireManagerList('snap', `if command -v snapd; then snap list; fi`),
|
||||||
acquireManagerList('zap', `zap list`)
|
acquireManagerList('zap', `zap list`)
|
||||||
]
|
]
|
||||||
|
const lists = await Promise.all(listPromises)
|
||||||
const managerLists = {
|
const managerLists = {
|
||||||
appimage: lists[6],
|
appimage: lists[6],
|
||||||
apt: lists[0],
|
apt: lists[0],
|
||||||
|
@ -445,30 +474,46 @@ async function main() {
|
||||||
const installData = pkgMap(installKeys)
|
const installData = pkgMap(installKeys)
|
||||||
log(`Filtering install instructions`)
|
log(`Filtering install instructions`)
|
||||||
const installInstructions = installData
|
const installInstructions = installData
|
||||||
|
.map(x => {
|
||||||
|
return {
|
||||||
|
...x,
|
||||||
|
installList: x.installList.filter(y => {
|
||||||
|
if ((x.installType === 'brew' || x.installType === 'cask') && y.includes('/')) {
|
||||||
|
return managerLists[x.installType] ? !managerLists[x.installType].includes(y.substring(y.lastIndexOf('/') + 1, y.length)) : true
|
||||||
|
} else {
|
||||||
|
return managerLists[x.installType] ? !managerLists[x.installType].includes(y) : true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
.filter(x => {
|
.filter(x => {
|
||||||
// Filter out packages already installed by by package managers
|
// Filter out packages already installed by by package managers
|
||||||
return !Object.keys(managerLists).includes(x.installType)
|
return x.installList.length
|
||||||
})
|
})
|
||||||
.filter(x => {
|
.filter(x => {
|
||||||
// Filter out macOS apps that already have a _app installed
|
// Filter out macOS apps that already have a _app installed
|
||||||
if (x.installType === 'cask' || (osId === 'darwin' && x._app)) {
|
if (x.installType === 'cask' || (osId === 'darwin' && x._app)) {
|
||||||
const appField = getPkgData('_app', x, x.installType)
|
const appField = getPkgData('_app', x, x.installType)
|
||||||
return !(fs.existsSync(`/Applications/${x[appField]}`) || fs.existsSync(`${os.homedir()}/Applications/${x[appField]}`))
|
const appCheck = fs.existsSync(`/Applications/${x[appField]}`) || fs.existsSync(`${os.homedir()}/Applications/${x[appField]}`)
|
||||||
}
|
appCheck && log(`Skipping installation of ${x.listKey} because the application is in an Applications folder`)
|
||||||
|
return !appCheck
|
||||||
|
} else {
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.filter(x => {
|
.filter(x => {
|
||||||
// Filter out packages that already have a bin in the PATH
|
// Filter out packages that already have a bin in the PATH
|
||||||
const binField = getPkgData('_bin', x, x.installType)
|
const binField = getPkgData('_bin', x, x.installType)
|
||||||
const isArray = Array.isArray(x[binField])
|
const isArray = Array.isArray(x[binField])
|
||||||
if (typeof x[binField] === 'string' || isArray) {
|
if (typeof x[binField] === 'string' || isArray) {
|
||||||
if (isArray) {
|
isArray && log(`_bin field for ${x.listKey} is an array so the first entry will be used to check`)
|
||||||
log(`_bin field for ${x.listKey} is an array so the first entry will be used to check`)
|
const whichCheck = which.sync(typeof x[binField] === 'string' ? x[binField] : x[binField][0], { nothrow: true })
|
||||||
}
|
whichCheck && log(`Skipping installation of ${x.listKey} because its binary is available in the PATH`)
|
||||||
return !(which.sync(typeof x[binField] === 'string' ? x[binField] : x[binField][0], { nothrow: true }))
|
return !whichCheck
|
||||||
}
|
} else {
|
||||||
log(`Ignoring _bin check because the _bin field for ${x.listKey} is not a string or array`)
|
log(`Ignoring _bin check because the _bin field for ${x.listKey} is not a string or array`)
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.filter(x => {
|
.filter(x => {
|
||||||
// Filter out packages that do not pass _when check
|
// Filter out packages that do not pass _when check
|
||||||
|
|
|
@ -1748,7 +1748,7 @@ softwarePackages:
|
||||||
scoop: cloc
|
scoop: cloc
|
||||||
clocker:
|
clocker:
|
||||||
_app: Clocker.app
|
_app: Clocker.app
|
||||||
_bin: null
|
_bin: clocker
|
||||||
_desc: Clocker is designed to help you keep track of your friends and colleagues in different time zones.
|
_desc: Clocker is designed to help you keep track of your friends and colleagues in different time zones.
|
||||||
_github: https://github.com/n0shake/clocker
|
_github: https://github.com/n0shake/clocker
|
||||||
_name: "Clocker "
|
_name: "Clocker "
|
||||||
|
@ -11998,7 +11998,6 @@ softwarePackages:
|
||||||
_name: upt
|
_name: upt
|
||||||
_short: "upt is a lightweight uptime monitor written in Go. "
|
_short: "upt is a lightweight uptime monitor written in Go. "
|
||||||
cargo: upt
|
cargo: upt
|
||||||
"cargo:": upt
|
|
||||||
upx:
|
upx:
|
||||||
_bin: upx
|
_bin: upx
|
||||||
_desc: "[UPX](https://upx.github.io/) is an advanced executable file compressor. UPX will typically reduce the file size of programs and DLLs by around 50%-70%, thus reducing disk space, network load times, download times and other distribution and storage costs. It supports compressing a wide variety of binary-like files. Surprisingly, it even compresses executables better than WinZip. Best of all, it is free and open source."
|
_desc: "[UPX](https://upx.github.io/) is an advanced executable file compressor. UPX will typically reduce the file size of programs and DLLs by around 50%-70%, thus reducing disk space, network load times, download times and other distribution and storage costs. It supports compressing a wide variety of binary-like files. Surprisingly, it even compresses executables better than WinZip. Best of all, it is free and open source."
|
||||||
|
|
Loading…
Reference in a new issue