Skip to content

Commit

Permalink
feat: add for macOS and linux (Ubuntu)
Browse files Browse the repository at this point in the history
  • Loading branch information
leoli0605 committed Mar 13, 2024
1 parent 3804e08 commit 490d23a
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 59 deletions.
24 changes: 21 additions & 3 deletions packageData.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,14 @@
"install": {
"linux": "asdf plugin add nodejs && asdf install nodejs 16.20.2 && asdf global nodejs 16.20.2",
"mac": "asdf plugin add nodejs && asdf install nodejs 18.18.0 && asdf global nodejs 18.18.0",
"windows": "choco install nvm -y; nvm install 18.18.0; nvm use 18.18.0"
"windows": "choco install nvm -y ; nvm install 18.18.0 ; nvm use 18.18.0"
},
"type": "force"
},
"OpenSSH": {
"description": "",
"install": {
"linux": "sudo apt install openssh-server -y",
"linux": "sudo apt install openssh-server -y && mkdir -p ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys",
"mac": "",
"windows": ""
},
Expand Down Expand Up @@ -234,6 +234,24 @@
},
"type": "disable"
},
"TypeScript": {
"description": "",
"install": {
"linux": "npm install -g typescript ts-node",
"mac": "npm install -g typescript ts-node",
"windows": "npm install -g typescript ts-node"
},
"type": "enable"
},
"VSCode Extension Development": {
"description": "VSCode 擴充套件開發工具",
"install": {
"linux": "npm install -g yo generator-code vsce esbuild",
"mac": "npm install -g yo generator-code vsce esbuild",
"windows": "npm install -g yo generator-code vsce esbuild"
},
"type": "disable"
},
"Virtual Box": {
"description": "自由及開放原始碼的虛擬機器軟體",
"install": {
Expand Down Expand Up @@ -510,7 +528,7 @@
"description": "",
"install": {
"linux": "",
"mac": "brew install --cask microsoft-edge",
"mac": "brew install --cask microsoft-edge && echo 'export CHROME_EXECUTABLE=\"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\"' >>~/.zshrc",
"windows": ""
},
"type": "enable"
Expand Down
Empty file removed scripts/linux/.gitkeep
Empty file.
17 changes: 17 additions & 0 deletions scripts/linux/basesetup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

sudo apt install -y curl software-properties-common apt-transport-https lsb-release
sudo apt update && sudo apt upgrade -y && sudo apt install -y git

# Load git-prompt.sh to use __git_ps1 for Git branch name
echo "# Load git prompt script for version control information" >> ~/.bashrc
echo "if type __git_ps1 &>/dev/null; then" >> ~/.bashrc
echo " GIT_PS1_SHOWDIRTYSTATE=1" >> ~/.bashrc
echo " GIT_PS1_SHOWSTASHSTATE=1" >> ~/.bashrc
echo " GIT_PS1_SHOWUNTRACKEDFILES=1" >> ~/.bashrc
echo " GIT_PS1_SHOWUPSTREAM='auto'" >> ~/.bashrc
echo " PROMPT_COMMAND='__git_ps1 \"\\[\\e[32m\\]\\w\\[\\e[0m\\]\" \" \\\$ \" \""'"'%F{87}(%s)%f'"'"'\"'" >> ~/.bashrc
echo "else" >> ~/.bashrc
echo " PS1='\\[\\e[32m\\]\\w\\[\\e[0m\\] \$ '" >> ~/.bashrc
echo "fi" >> ~/.bashrc
echo "" >> ~/.bashrc
Empty file removed scripts/macos/.gitkeep
Empty file.
9 changes: 9 additions & 0 deletions scripts/macos/homebrew.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
(
echo
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"'
) >>~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
source ~/.zprofile
14 changes: 14 additions & 0 deletions scripts/macos/macsetup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

# Reset Launchpad
# //////////////////////////////////////////////////
defaults write com.apple.dock ResetLaunchPad -bool true
killall Dock

# Display full path in Finder title bar
# //////////////////////////////////////////////////
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true

# Show path bar in Finder
# //////////////////////////////////////////////////
defaults write com.apple.finder ShowPathbar -bool true
14 changes: 14 additions & 0 deletions scripts/macos/zshsetup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

echo "# Load version control information" >>~/.zshrc
echo "autoload -Uz vcs_info" >>~/.zshrc
echo "precmd() { vcs_info }" >>~/.zshrc
echo "" >>~/.zshrc
echo "# Format the vcs_info_msg_0_ variable" >>~/.zshrc
echo "zstyle ':vcs_info:git:*' formats ' %F{87}(%b)%f'" >>~/.zshrc
echo "" >>~/.zshrc
echo "# Set up the prompt (with git branch name)" >>~/.zshrc
echo "setopt PROMPT_SUBST" >>~/.zshrc
echo "PROMPT='[%F{82}%~%f]\${vcs_info_msg_0_} $ '" >>~/.zshrc
echo "" >>~/.zshrc
source ~/.zshrc
2 changes: 1 addition & 1 deletion scripts/npm.setup
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
npm install -g npm
npm install -g npm@latest
npm install -g pnpm
npm install -g npm-check-updates
npm install -g @leoli0605/git-setup
Empty file removed scripts/windows/.gitkeep
Empty file.
23 changes: 23 additions & 0 deletions src/base_shell.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class BaseShell {
constructor() {
this.commands = [];
this.environment = [];
this.scripts = [];
}

addCommand(command) {
this.commands.push(command);
console.log(`Command added: ${command}`);
}

addEnvironment(path) {
this.environment.push(path);
console.log(`Environment added: ${path}`);
}

script() {
throw new Error('You have to implement the method script!');
}
}

export default BaseShell;
24 changes: 24 additions & 0 deletions src/bash.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import BaseShell from './base_shell.mjs';

class Bash extends BaseShell {
constructor(type = 'bash') {
super();
this.type = type;
}

script() {
for (const e of this.environment) {
if (type === 'bash') {
this.scripts.push(`echo ${e} >> ~/.bashrc\n`);
} else if (type === 'zsh') {
this.scripts.push(`echo ${e} >> ~/.zshrc\n`);
}
}
this.scripts.push('source ~/.bashrc\n');
this.scripts.push('source ~/.zshrc\n');
this.scripts.push(this.commands.join('\n'));
return '#!/bin/bash\n' + this.scripts.toString().replace(/#!\/bin\/bash/g, '') + '\n';
}
}

export default Bash;
107 changes: 81 additions & 26 deletions src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs';
import os from 'os';
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import path from 'path';
import Bash from './bash.mjs';
import { cmd } from './cmd_process.mjs';
import { getAppDir } from './dirname.mjs';
import { selectPackages } from './package_selector.mjs';
Expand All @@ -11,63 +11,118 @@ const __dirname = getAppDir();

selectPackages()
.then((selectedPackages) => {
let shell;
let command = '';
let args = [];
if (os.platform() === 'win32') {
const ps = new PowerShell();
console.log('Windows detected');
shell = new PowerShell();

for (const p of selectedPackages) {
if (p) {
ps.addCommand(p.installCommand);
shell.addCommand(p.installCommand);
}
}
ps.addCommand('refreshenv\n'); // for powershell to refresh environment variables
shell.addCommand('refreshenv\n');

if (selectedPackages.some((p) => p && p.packageName.startsWith('Python'))) {
ps.addEnvironment('$HOME\\AppData\\Roaming\\Python\\Scripts');
ps.addCommand('python.exe -m pip install --upgrade pip'); // for pip
ps.addCommand('(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -'); // for poetry
ps.addCommand('poetry config virtualenvs.in-project true'); // for poetry
const pipSetup = fs.readFileSync(path.join(__dirname, 'scripts/pip.setup'), 'utf8').trim();
ps.addCommand(pipSetup);
shell.addEnvironment('$HOME\\AppData\\Roaming\\Python\\Scripts');
shell.addCommand('(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -');
shell.addCommand('poetry config virtualenvs.in-project true');
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/pip.setup'), 'utf8').trim());
}
if (selectedPackages.some((p) => p && p.packageName.startsWith('Rust'))) {
ps.addEnvironment('$HOME\\leoli\\.cargo\\bin');
shell.addEnvironment('$HOME\\.cargo\\bin');
}
ps.addCommand('refreshenv\n'); // for powershell to refresh environment variables
shell.addCommand('refreshenv\n');

if (selectedPackages.some((p) => p && p.packageName.startsWith('Node.js'))) {
const npmSetup = fs.readFileSync(path.join(__dirname, 'scripts/npm.setup'), 'utf8').trim();
ps.addCommand(npmSetup);
ps.addCommand('npx @leoli0605/git-setup'); // for git
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/npm.setup'), 'utf8').trim());
}
ps.addCommand('refreshenv\n'); // for powershell to refresh environment variables
shell.addCommand('refreshenv\n');

if (selectedPackages.some((p) => p && p.packageName.startsWith('Sublime Text'))) {
let sublimeSetup = fs.readFileSync(path.join(__dirname, 'scripts/windows/SublimeSetup.ps1'), 'utf8').trim();
sublimeSetup = sublimeSetup.replace('${PATH}', path.join(__dirname, 'scripts/windows/Preferences.sublime-settings'));
ps.addCommand(sublimeSetup);
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/windows/SublimeSetup.ps1'), 'utf8').trim().replace('${PATH}', path.join(__dirname, 'scripts/windows/Preferences.sublime-settings')));
}
ps.addCommand('refreshenv\n'); // for powershell to refresh environment variables

const psScript = ps.getScripts();
// fs.writeFileSync(path.join(__dirname, 'scripts.ps1.log'), psScript);
shell.addCommand('refreshenv\n');
shell.addCommand('npx @leoli0605/git-setup');
const script = shell.script();

const encodedPsScript = Buffer.from(psScript, 'utf16le').toString('base64');
const encodedScript = Buffer.from(script, 'utf16le').toString('base64');
command = 'powershell.exe';
args = ['-NoProfile', '-EncodedCommand', encodedPsScript];
args = ['-NoProfile', '-EncodedCommand', encodedScript];
} else if (os.platform() === 'darwin') {
console.log('MacOS detected');
shell = new Bash('zsh');

shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/macos/homebrew.sh'), 'utf8').trim());
shell.addCommand('brew install asdf');
shell.addEnvironment('". /opt/homebrew/opt/asdf/libexec/asdf.sh"');

for (const p of selectedPackages) {
if (p) {
shell.addCommand(p.installCommand);
}
}

if (selectedPackages.some((p) => p && p.packageName.startsWith('Python'))) {
shell.addCommand('curl -sSL https://install.python-poetry.org | python3');
shell.addEnvironment('\'export PATH="$HOME/.local/bin:$PATH"\'');
shell.addCommand('poetry config virtualenvs.in-project true');
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/pip.setup'), 'utf8').trim());
}
if (selectedPackages.some((p) => p && p.packageName.startsWith('Node.js'))) {
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/npm.setup'), 'utf8').trim());
}
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/macos/zshsetup.sh'), 'utf8').trim());
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/macos/macsetup.sh'), 'utf8').trim());
shell.addCommand('npx @leoli0605/git-setup');
const script = shell.script();

command = '/bin/bash';
args = ['-c', script];
} else if (os.platform() === 'linux') {
shell = new Bash('bash');

shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/linux/basesetup.sh'), 'utf8').trim());
shell.addCommand('git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0');
shell.addEnvironment('\'. "$HOME/.asdf/asdf.sh"\'');
shell.addEnvironment('\'. "$HOME/.asdf/completions/asdf.bash"\'');

for (const p of selectedPackages) {
if (p) {
shell.addCommand(p.installCommand);
}
}

if (selectedPackages.some((p) => p && p.packageName.startsWith('Python'))) {
shell.addCommand('curl -sSL https://install.python-poetry.org | python3');
shell.addEnvironment('\'export PATH="$HOME/.local/bin:$PATH"\'');
shell.addCommand('poetry config virtualenvs.in-project true');
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/pip.setup'), 'utf8').trim());
}

const distro = os
.release()
.split('.')
.map((v) => parseInt(v));
console.log('Linux distribution version:', distro);
if (distro[0] >= 20 /* && distro[1] === 4 */) {
console.log('Ubuntu 20.04 detected');
shell.addCommand('asdf install nodejs 18.18.0');
shell.addCommand('asdf global nodejs 18.18.0');
} else {
console.log('Ubuntu 20.04 not detected');
}

if (selectedPackages.some((p) => p && p.packageName.startsWith('Node.js'))) {
shell.addCommand(fs.readFileSync(path.join(__dirname, 'scripts/npm.setup'), 'utf8').trim());
}
shell.addCommand('npx @leoli0605/git-setup');
const script = shell.script();

command = '/bin/bash';
args = ['-c', script];
}

console.log(`command: ${command}`);
Expand Down
2 changes: 1 addition & 1 deletion src/package_selector.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import chalk from 'chalk';
import fs from 'fs';
import inquirer from 'inquirer';
import os from 'os';
import path, { dirname } from 'path';
import path from 'path';
import { getAppDir } from './dirname.mjs';

export async function selectPackages() {
Expand Down
9 changes: 4 additions & 5 deletions src/powershell.mjs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import fs from 'fs';
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import path from 'path';
import BaseShell from './base_shell.mjs';
import { getAppDir } from './dirname.mjs';
import ShellScript from './shell_script.mjs';

const __dirname = getAppDir();

class PowerShell extends ShellScript {
class PowerShell extends BaseShell {
constructor() {
super();
this.scripts.push(fs.readFileSync(path.join(__dirname, 'scripts/windows/RunAsAdministrator.ps1'), 'utf8') + '\n');
this.scripts.push(fs.readFileSync(path.join(__dirname, 'scripts/windows/Chocolatey.ps1'), 'utf8') + '\n');
}

getScripts() {
script() {
const paths = this.environment.map((e) => `"${e}"`).join(',\n ');
let envSetup = fs.readFileSync(path.join(__dirname, 'scripts/windows/EnvSetup.ps1'), 'utf8');
envSetup = envSetup.replace('${PATHS}', paths);
Expand Down
23 changes: 0 additions & 23 deletions src/shell_script.mjs

This file was deleted.

0 comments on commit 490d23a

Please sign in to comment.