diff --git a/README.md b/README.md index cc3aaf1..208679f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,6 @@ ### Install ``` -sudo curl -L https://github.com/cirolosapio/envman/releases/download/v0.0.15/envman -o /usr/local/bin/envman +sudo curl -L https://github.com/cirolosapio/envman/releases/download/v0.0.16/envman -o /usr/local/bin/envman sudo chmod +x /usr/local/bin/envman ``` diff --git a/functions.ts b/functions.ts index 070e353..6d5c665 100644 --- a/functions.ts +++ b/functions.ts @@ -33,6 +33,21 @@ export async function isDocker() { return await hasDockerEnv() || await hasDockerCGroup() } +export async function isCurrentUserInDockerGroup() { + const groups = (await run(['groups'])).split(' ') + return groups.includes('docker') +} + +export async function hasDockerDesktop() { + return await exists('/mnt/c/Program Files/Docker/Docker/Docker Desktop.exe') +} + +export async function dockerServiceStartsAutomatically() { + if (await hasDockerDesktop()) return true + const status = await run(['systemctl', 'is-enabled', 'docker']) + return status.trim() === 'enabled' +} + export async function run(cmds: string[], encoding: Encoding = 'utf-8') { const [cmd, ...args] = cmds const { code, stdout, stderr } = await (new Deno.Command(cmd, { args })).output() @@ -85,7 +100,6 @@ export async function isOhMyZshInstalled() { } export async function isInstalled(tool: string) { - // return (await run(`which ${tool}`.split(' '))).trim() !== '' const { code, stdout } = await (new Deno.Command('which', { args: [tool] })).output() return code === 1 ? false : new TextDecoder().decode(stdout).trim() !== '' } @@ -108,3 +122,8 @@ export async function getJetBrainsGatewayVersion() { if (name.startsWith('JetBrainsGateway')) return name.split('-')[1] } } + +export async function getLastEnvmanVersion() { + const tags = await fetch('https://api.github.com/repos/cirolosapio/envman/tags').then((res) => res.json()) + return tags[0].name +} diff --git a/main.ts b/main.ts index 06c40f3..27365a6 100644 --- a/main.ts +++ b/main.ts @@ -1,55 +1,122 @@ -import { Checkbox, Confirm } from 'https://deno.land/x/cliffy@v1.0.0-rc.4/prompt/mod.ts' +import { Checkbox, CheckboxOption, Confirm } from 'https://deno.land/x/cliffy@v1.0.0-rc.4/prompt/mod.ts' import { colors } from 'https://deno.land/x/cliffy@v1.0.0-rc.4/ansi/colors.ts' -import { checkOption, isDocker, isOhMyZshInstalled, isWsl, run, selectWsl } from './functions.ts' -import { installBottom, installCarootOnWsl, installCtop, installDeno, installDockerEngine, installEnvman, installJetBrainsGateway, installMage2Postman, installMagentoCloudCli, installMkcert, installMkcertWin, installOhMyZsh, installSig, installSshs, installStarship } from './softwares.ts' +import { checkOption, dockerServiceStartsAutomatically, getLastEnvmanVersion, isCurrentUserInDockerGroup, isDocker, isOhMyZshInstalled, isWsl, run, selectWsl } from './functions.ts' +import { dockerEnginePostInstall, installBottom, installCarootOnWsl, installCtop, installDeno, installDockerEngine, installEnvman, installJetBrainsGateway, installMage2Postman, installMagentoCloudCli, installMkcert, installMkcertWin, installOhMyZsh, installSig, installSshs, installStarship } from './softwares.ts' -export const VERSION = 'v0.0.15' +export const VERSION = 'v0.0.16' async function main() { if (await isDocker()) { console.log(colors.yellow('running in docker')) console.log(colors.yellow('run this tool on windows/wsl')) } else if (await isWsl()) { - const softwares = await Checkbox.prompt({ - info: true, - minOptions: 1, - message: 'Select the softwares to install', - maxRows: 13, - options: [ - { name: 'Docker Engine - open source containerization technology', value: 'docker-engine', ...await checkOption('docker') }, - { name: 'OhMyZsh - open source, community-driven framework for managing your zsh configuration', value: 'ohmyzsh', ...await checkOption(await isOhMyZshInstalled()) }, - { name: "mkcert - A simple zero-config tool to make locally trusted development certificates with any names you'd like", value: 'mkcert', ...await checkOption('mkcert') }, - { name: 'Starship - The minimal, blazing-fast, and infinitely customizable prompt for any shell!', value: 'starship', ...await checkOption('starship') }, - { name: 'Deno - Next-generation JavaScript runtime', value: 'deno', ...await checkOption('deno', false) }, - { name: 'ctop - Top-like interface for container metrics', value: 'ctop', ...await checkOption('ctop', false) }, - { name: 'sshs - Terminal user interface for SSH', value: 'sshs', ...await checkOption('sshs', false) }, - { name: 'bottom - Yet another cross-platform graphical process/system monitor', value: 'bottom', ...await checkOption('btm', false) }, - { name: 'sig - Interactive grep', value: 'sig', ...await checkOption('sig', false) }, - { name: 'Magento Cloud Cli - Command-line tool for managing Magento Commerce Cloud projects', value: 'mgc', ...await checkOption('mgc', false) }, - { name: 'Mage2Postman - Generate postman collection from Magento', value: 'mage2postman', ...await checkOption('mage2postman', false) }, - { name: 'JetBrains Gateway - Your single entry point to all remote development environments', value: 'jetbrains-gateway', ...await checkOption('gateway', false, false) }, - { name: 'envman - Update this tool', value: 'envman' }, - ], - }) - - const toInstall = [] - await run(`sudo apt-get -y update`.split(' ')) - if (softwares.includes('ohmyzsh')) await installOhMyZsh() - if (softwares.includes('deno')) await installDeno() - if (softwares.includes('jetbrains-gateway')) await installJetBrainsGateway() - if (softwares.includes('bottom')) await installBottom() - if (softwares.includes('sig')) await installSig() - if (softwares.includes('mkcert')) toInstall.push(installMkcert()) - if (softwares.includes('docker-engine')) toInstall.push(installDockerEngine()) - if (softwares.includes('ctop')) toInstall.push(installCtop()) - if (softwares.includes('sshs')) toInstall.push(installSshs()) - if (softwares.includes('mgc')) toInstall.push(installMagentoCloudCli()) - if (softwares.includes('mage2postman')) toInstall.push(installMage2Postman()) - if (softwares.includes('starship')) toInstall.push(installStarship()) - if (softwares.includes('envman')) toInstall.push(installEnvman()) - await Promise.all(toInstall) - - if (await Confirm.prompt('Do you want to install another software?')) await main() + const [ + showDocker, + showOhmyzsh, + showMkcert, + showStarship, + showDeno, + showCtop, + showSshs, + showBtm, + showSig, + showMgc, + showMage2postman, + showGateway, + lastEnvmanVersion, + ] = await Promise.all([ + checkOption('docker'), + checkOption(await isOhMyZshInstalled()), + checkOption('mkcert'), + checkOption('starship'), + checkOption('deno', false), + checkOption('ctop', false), + checkOption('sshs', false), + checkOption('btm', false), + checkOption('sig', false), + checkOption('mgc', false), + checkOption('mage2postman', false), + checkOption('gateway', false, false), + getLastEnvmanVersion(), + ]) + + const installed = [] + const options: CheckboxOption[] = [] + + if (lastEnvmanVersion !== VERSION) options.push({ name: colors.yellow('envman - Update needed!'), value: 'envman', checked: true }) + + if (showDocker.disabled) { + installed.push('Docker Engine') + + const postInstallInstalled = await isCurrentUserInDockerGroup() && await dockerServiceStartsAutomatically() + !postInstallInstalled && options.push({ name: 'Docker Engine Post Install', value: 'docker-engine-post-install', ...await checkOption(false) }) + } else options.push({ name: 'Docker Engine - open source containerization technology', value: 'docker-engine', ...showDocker }) + + if (showGateway.disabled) installed.push('JetBrains Gateway') + else options.push({ name: 'JetBrains Gateway - Your single entry point to all remote development environments', value: 'jetbrains-gateway', ...showGateway }) + + if (showMage2postman.disabled) installed.push('Mage2Postman') + else options.push({ name: 'Mage2Postman - Generate postman collection from Magento', value: 'mage2postman', ...showMage2postman }) + + if (showMgc.disabled) installed.push('Magento Cloud Cli') + else options.push({ name: 'Magento Cloud Cli - Command-line tool for managing Magento Commerce Cloud projects', value: 'mgc', ...showMgc }) + + if (showSig.disabled) installed.push('sig') + else options.push({ name: 'sig - Interactive grep', value: 'sig', ...showSig }) + + if (showBtm.disabled) installed.push('bottom') + else options.push({ name: 'bottom - Yet another cross-platform graphical process/system monitor', value: 'bottom', ...showBtm }) + + if (showSshs.disabled) installed.push('sshs') + else options.push({ name: 'sshs - Terminal user interface for SSH', value: 'sshs', ...showSshs }) + + if (showCtop.disabled) installed.push('ctop') + else options.push({ name: 'ctop - Top-like interface for container metrics', value: 'ctop', ...showCtop }) + + if (showDeno.disabled) installed.push('Deno') + else options.push({ name: 'Deno - Next-generation JavaScript runtime', value: 'deno', ...showDeno }) + + if (showStarship.disabled) installed.push('Starship') + else options.push({ name: 'Starship - The minimal, blazing-fast, and infinitely customizable prompt for any shell!', value: 'starship', ...showStarship }) + + if (showMkcert.disabled) installed.push('mkcert') + else options.push({ name: "mkcert - A simple zero-config tool to make locally trusted development certificates with any names you'd like", value: 'mkcert', ...showMkcert }) + + if (showOhmyzsh.disabled) installed.push('OhMyZsh') + else options.push({ name: 'OhMyZsh - open source, community-driven framework for managing your zsh configuration', value: 'ohmyzsh', ...showOhmyzsh }) + + installed.forEach((software) => console.log(colors.green(` ✔ ${software} already installed`))) + console.log() + + if (options.length > 0) { + const softwares = await Checkbox.prompt({ + info: true, + minOptions: 1, + message: 'Select the softwares to install', + maxRows: options.length, + options, + }) + + const toInstall = [] + await run(`sudo apt-get -y update`.split(' ')) + if (softwares.includes('ohmyzsh')) await installOhMyZsh() + if (softwares.includes('deno')) await installDeno() + if (softwares.includes('jetbrains-gateway')) await installJetBrainsGateway() + if (softwares.includes('bottom')) await installBottom() + if (softwares.includes('sig')) await installSig() + if (softwares.includes('docker-engine-post-install')) toInstall.push(dockerEnginePostInstall()) + if (softwares.includes('mkcert')) toInstall.push(installMkcert()) + if (softwares.includes('docker-engine')) toInstall.push(installDockerEngine()) + if (softwares.includes('ctop')) toInstall.push(installCtop()) + if (softwares.includes('sshs')) toInstall.push(installSshs()) + if (softwares.includes('mgc')) toInstall.push(installMagentoCloudCli()) + if (softwares.includes('mage2postman')) toInstall.push(installMage2Postman()) + if (softwares.includes('starship')) toInstall.push(installStarship()) + if (softwares.includes('envman')) toInstall.push(installEnvman()) + await Promise.all(toInstall) + + if (await Confirm.prompt('Do you want to install another software?')) await main() + } else console.log(colors.green('All software are installed ✔')) } else { const softwares = await Checkbox.prompt({ info: true, diff --git a/softwares.ts b/softwares.ts index 31c5332..f4951a8 100644 --- a/softwares.ts +++ b/softwares.ts @@ -1,4 +1,4 @@ -import { bash, exists, getJetBrainsGatewayVersion, getUser, isInstalled, ps, run, runn } from './functions.ts' +import { bash, exists, getJetBrainsGatewayVersion, getUser, hasDockerDesktop, isCurrentUserInDockerGroup, isInstalled, ps, run, runn } from './functions.ts' import { colors } from 'https://deno.land/x/cliffy@v1.0.0-rc.4/ansi/colors.ts' import { VERSION } from './main.ts' @@ -8,14 +8,23 @@ export async function installDockerEngine() { await run('curl -fsSL https://get.docker.com -o get-docker.sh'.split(' ')) await run('sudo sh ./get-docker.sh'.split(' ')) - await Promise.all([ - bash('sudo usermod -aG docker $USER'), + await dockerEnginePostInstall() + + console.log(colors.green('docker installed ✔\n')) +} + +export async function dockerEnginePostInstall() { + console.log(colors.blue('processing docker engine post-install...')) + + await bash('sudo usermod -aG docker $USER') + !(await hasDockerDesktop()) && await Promise.all([ run(`sudo systemctl enable docker.service`.split(' ')), run(`sudo systemctl enable containerd.service`.split(' ')), ]) + await run('newgrp docker'.split(' ')) - console.log(colors.green('docker installed!\n')) - console.log(colors.bgYellow('reopen your terminal to use docker without sudo!')) + console.log(colors.green('docker post-install processed ✔\n')) + !(await isCurrentUserInDockerGroup()) && console.log(colors.bgYellow.bold('reopen your terminal to use docker without sudo!')) } export async function installOhMyZsh() { @@ -29,8 +38,8 @@ export async function installOhMyZsh() { plugins.unshift('docker', 'copypath', 'copyfile', 'sudo', 'dirhistory') await runn(`sed -i 's/plugins=(git)/plugins=(git ${plugins.join(' ')})/' /home/$USER/.zshrc`) - console.log(colors.bgYellow('run "chsh -s $(which zsh)" to set as a default shell!')) - console.log(colors.green('ohmyzsh installed!\n')) + console.log(colors.bgYellow.bold('run "chsh -s $(which zsh)" to set as a default shell!')) + console.log(colors.green('ohmyzsh installed ✔\n')) } async function installZshPlugin(plugin: string) { @@ -38,7 +47,7 @@ async function installZshPlugin(plugin: string) { if (!await exists(path)) { console.log(colors.blue(`installing ohmyzsh plugin ${plugin}...`)) await bash(`git clone https://github.com/zsh-users/${plugin} ${path}`) - console.log(colors.green(`ohmyzsh plugin ${plugin} installed!\n`)) + console.log(colors.green(`ohmyzsh plugin ${plugin} installed ✔\n`)) } else console.log(colors.yellow(`${plugin} already installed`)) } @@ -52,7 +61,7 @@ export async function installDeno() { runn(`echo 'export DENO_INSTALL="/home/${user}/.deno"' >> ${rc_profile}`), runn(`echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> ${rc_profile}`), ]) - console.log(colors.green(`deno installed!\n`)) + console.log(colors.green(`deno installed ✔\n`)) } export async function installStarship() { @@ -60,7 +69,7 @@ export async function installStarship() { await run(['sh', '-c', 'curl -sS https://starship.rs/install.sh | FORCE=true sh']) if (await isInstalled('zsh')) await runn(`echo 'eval "$(starship init zsh)"' >> ~/.zshrc`) else await runn(`echo 'eval "$(starship init bash)"' >> ~/.bashrc`) - console.log(colors.green(`starship installed!\n`)) + console.log(colors.green(`starship installed ✔\n`)) } export async function installMkcert() { @@ -71,7 +80,7 @@ export async function installMkcert() { await runn('sudo cp mkcert-v*-linux-amd64 /usr/local/bin/mkcert') await runn('rm mkcert-v*-linux-amd64') await runn('mkdir -p /home/$USER/.local/share/mkcert') - console.log(colors.green(`mkcert installed!\n`)) + console.log(colors.green(`mkcert installed ✔\n`)) } export async function installMkcertWin() { @@ -81,7 +90,7 @@ export async function installMkcertWin() { await ps('scoop bucket add extras') await ps('scoop install mkcert') await ps('mkcert -install') - console.log(colors.green(`mkcert installed!\n`)) + console.log(colors.green(`mkcert installed ✔\n`)) return (await ps('mkcert -CAROOT')).trim() } @@ -93,7 +102,7 @@ export async function installCarootOnWsl(path: string, target: string) { ps(`cp ${path}\\rootCA.pem ${destination}`), ps(`cp ${path}\\rootCA-key.pem ${destination}`), ]) - console.log(colors.green(`mkcert root certs successfully installed in ${target}!`)) + console.log(colors.green(`mkcert root certs successfully installed in ${target} ✔`)) } export async function installCtop() { @@ -101,7 +110,7 @@ export async function installCtop() { console.log(colors.blue('installing ctop...')) await run(`sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-amd64 -O /usr/local/bin/ctop`.split(' ')) await run(`sudo chmod +x /usr/local/bin/ctop`.split(' ')) - console.log(colors.green(`ctop installed!\n`)) + console.log(colors.green(`ctop installed ✔\n`)) } export async function installSshs() { @@ -109,7 +118,7 @@ export async function installSshs() { console.log(colors.blue('installing sshs...')) await run(`sudo wget https://github.com/quantumsheep/sshs/releases/download/4.4.1/sshs-linux-amd64 -O /usr/local/bin/sshs`.split(' ')) await run(`sudo chmod +x /usr/local/bin/sshs`.split(' ')) - console.log(colors.green(`sshs installed!\n`)) + console.log(colors.green(`sshs installed ✔\n`)) } export async function installBottom() { @@ -118,7 +127,7 @@ export async function installBottom() { await run(`curl -LO https://github.com/ClementTsang/bottom/releases/download/0.9.6/bottom_0.9.6_amd64.deb`.split(' ')) await run(`sudo dpkg -i bottom_0.9.6_amd64.deb`.split(' ')) await run(`rm bottom_0.9.6_amd64.deb`.split(' ')) - console.log(colors.green(`bottom installed!\n`)) + console.log(colors.green(`bottom installed ✔\n`)) } export async function installMagentoCloudCli() { @@ -127,14 +136,14 @@ export async function installMagentoCloudCli() { let cmd = `curl -sS https://accounts.magento.cloud/cli/installer | php` if (await isInstalled('zsh')) cmd += ' -- --shell-type zsh' await run(['sh', '-c', cmd]) - console.log(colors.green(`magento-cloud-cli installed!\n`)) + console.log(colors.green(`magento-cloud-cli installed ✔\n`)) } export async function installMage2Postman() { console.log(colors.blue('installing mage2postman...')) await run(`sudo curl -L https://github.com/cirolosapio/mage2postman/releases/download/v0.0.2/mage2postman -o /usr/local/bin/mage2postman`.split(' ')) await run('sudo chmod +x /usr/local/bin/mage2postman'.split(' ')) - console.log(colors.green(`mage2postman installed!\n`)) + console.log(colors.green(`mage2postman installed ✔\n`)) } export async function installEnvman() { @@ -142,7 +151,7 @@ export async function installEnvman() { await run('sudo rm /usr/local/bin/envman'.split(' ')) await run(`sudo curl -L https://github.com/cirolosapio/envman/releases/download/${VERSION}/envman -o /usr/local/bin/envman`.split(' ')) await run('sudo chmod +x /usr/local/bin/envman'.split(' ')) - console.log(colors.green(`evnman installed!\n`)) + console.log(colors.green(`evnman installed ✔\n`)) } export async function installJetBrainsGateway() { @@ -164,7 +173,7 @@ export async function installJetBrainsGateway() { run('sudo apt-get install -y libxrender-dev libxtst6 libxi6 libfreetype-dev xdg-utils'.split(' ')), ]) await run(`sudo ln -s /opt/JetBrainsGateway-${await getJetBrainsGatewayVersion()}/bin/gateway.sh /usr/local/bin/gateway`.split(' ')) - console.log(colors.green(`JetBrains Gateway installed!\n`)) + console.log(colors.green(`JetBrains Gateway installed ✔\n`)) } } @@ -175,5 +184,5 @@ export async function installSig() { await run('tar -xf sigrs-x86_64-unknown-linux-gnu.tar.xz'.split(' ')) await run('sudo mv sigrs-x86_64-unknown-linux-gnu/sig /usr/local/bin/sig'.split(' ')) await run('rm -rf sigrs-x86_64-unknown-linux-gnu sigrs-x86_64-unknown-linux-gnu.tar.xz'.split(' ')) - console.log(colors.green(`sig installed!\n`)) + console.log(colors.green(`sig installed ✔\n`)) }