快適な開発環境のつくりかた (Mac, 2022)

# A Guide to Comfortable Developments (for Mac)

プログラマを目指す友人のために。
（オンデマンドに加筆・更新を行う可能性があります。）

:::note warn
M1 チップ（Apple Silicon）搭載の Mac の場合は、旧来の Intel チップ搭載の場合と異なる点が出てくる可能性があります。CPU の種類及びアーキテクチャとして Intel (x86-64) と Apple Silicon (ARM) の 2 択が出てきた場合は **Apple Silicon (ARM)** の方を選択するようにしてください。とはいえ中々に M1 チップも普及し、このことを意識する頻度は低くなってきています。
:::

:::note warn
取り扱うプログラミング言語として汎用性が高いであろう Python と JavaScript を選びました。特に Python はインターネットに出てくる記事に落とし穴が多く、その観点からも環境構築のガイドラインは価値があるものだと考えています。
:::

## Summary of this article

1. MacOS settings
1. Applications
1. CLI tools
1. Languages
    1. Python
    1. JavaScript
    1. Any languages

Details are shown in the Table of Contents.

## MacOS settings

### Swap Control and CapsLock [Highly Recommended]
https://seriblog.net/change-control/

If you do not need CapsLock, set both of the keys to Control.

### Lower beep volume [Optional]
https://pc-karuma.net/mac-sound-alert/

It is noisy.

## Applications

### 英かな [Recommended]

For US Layout keyboard users. https://ei-kana.appspot.com/

### Google 日本語入力 [Optional]

https://www.google.co.jp/ime/

I do not like default IME. cf. [My settings of Google 日本語入力](https://github.com/lambda-chat/dotfiles/tree/main/google-ja-input).

### BetterSnapTool [Recommended]

https://apps.apple.com/us/app/bettersnaptool/id417375580

:::note warn
BetterSnapTools is not free software, but it is worth it.
:::

For example, I assigned `⌥←` to "Snap to Left".

### iTerm2 [Recommended]

https://iterm2.com/

Getting Started: [iTerm2のおすすめ設定〜ターミナル作業を効率化する〜](https://qiita.com/ruwatana/items/8d9c174250061721ad11)

For example, I assigned `⌘-[space]` to toggle iTerm2.

:::note warn
When you create some customized profile(s), make sure that the hotkeys are not duplicated.
:::


### Xcode / Command Line Tools for Xcode [Highly Recommended]

> **Command Line Tools for Xcode**
> This package enables UNIX-style development via Terminal by installing command line developer tools, as well as macOS SDK frameworks and headers. Many useful tools are included, such as the Apple LLVM compiler, linker, and Make. If you use Xcode, these tools are also embedded within the Xcode IDE.

Required an apple account.

#### Option A. Install Xcode [Recommended if your storage is enough]

Pros: All in one package.
Cons: Huge.

https://apps.apple.com/us/app/xcode/id497799835

#### Option B. Install Command Line Tools for Xcode [Alternative]

Pros: Relatively small.
Cons: Some build requires tools that are not included in Command Line Tools for Xcode.

https://developer.apple.com/download/all/?q=Command%20Line%20Tools

### Docker Desktop [Recommended]

Nowadays, **Docker** is an essential tool.

https://www.docker.com/products/docker-desktop

A considerable alternative is **Lima**.
cf. [Docker on Limaで脱Docker Desktop for Mac](https://zenn.dev/matsukaz/articles/31bc31ff1c54b4).

### Visual Studio Code (VS Code) [Highly Recommended]

https://code.visualstudio.com/

This is one of the best editors. There is no reason you do not take advantage of this.

To Activate: `code [<directory or file>]` (Usually I type `code .`)

#### Recommended VS Code extensions

- Git Extension Pack
- Remote - SSH
- Remote - Containers
- Live Share
- Python
- Prettier
- YAML
- Vim [NOT recommended if you are not a **vim** user]

#### Advanced usage of VS Code - Developing inside a container

:::note
All you need to prepare is `.devcontainer/*` (with Docker and Remote-Containers extension). You will be free from OS-specific matters and runtime management.
:::

A sample repository:

https://github.com/lambda-chat/python-template

## CLI tools

### Homebrew [Must]
> Homebrew installs the stuff you need that Apple (or your Linux system) didn’t.

Install:
```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

(from https://brew.sh/#install)

Usage: `brew install <package(s) which you want>`

Comparison of common package managers (FYI):
| *OS* | MacOS | Debian, Ubuntu, etc. | CentOS, RHEL, Amazon Linux, etc. | Windows |
|:-:|:-:|:-:|:-:|:-:|
| *Package Manager* | Homebrew `brew`| APT `apt` | YUM `yum` | Scoop `scoop` / Chocolatey `choco` / Windows Package Manager CLI `winget` |


### tmux [Recommended]
> **tmux** is a terminal multiplexer. It lets you switch easily between several programs in one terminal, detach them (they keep running in the background) and reattach them to a different terminal.

Install:
```sh
brew install tmux
```
Getting started: [tmuxを使い始めたので基本的な機能の使い方とかを整理してみた](http://kanjuku-tomato.blogspot.com/2014/02/tmux.html)
Cheatsheet: [tmuxチートシート](https://qiita.com/nmrmsys/items/03f97f5eabec18a3a18b)

### fish shell [Optional]

> **fish** is a smart and user-friendly command line shell for Linux, macOS, and the rest of the family.

:::note warn
fish shell is not compatible with the POSIX standard. You may have to switch shells, depending on circumstances.
:::

https://fishshell.com/

See also:
- https://github.com/jorgebucaran/fisher
- https://github.com/edc/bass
- https://github.com/FabioAntunes/fish-nvm

### Starship [Optional]

> The minimal, blazing-fast, and infinitely customizable prompt for any shell!

https://starship.rs/

### Akamai MFA (was Krypton) [Optional]

> The `akr` command line utility is Akamai's "Krypton" SSH Agent, the successor to `kr` which works exclusively with the Akamai MFA Authenticator for iOS and Android. Akr enables your smart phone to become a "push-based" FIDO2 authenticator for SSH authentication.

:::note warn
This is **beta** software. Use at your own risk. I have confirmed that it works on M1 Mac (OS X 12.2.1).
:::

:::note
**1Password** supports push-based SSH authenticator since Mar 2022. 
See https://blog.1password.com/1password-ssh-agent/. Its M1 Mac version is also beta, but worth to try it, I think. Please check it.
:::

Install smartphone application for 2FA (App Store / Google Play):

https://mfa.akamai.com/help

Install CLI software:
```sh
brew install akamai/mfa/akr
```
Setup:
```sh
akr setup
akr pair  # scan the printed QR code by the smartphone app
akr generate --name <your_key_name_here>  # a public key will be printed
akr load  # print the public key when you forget it
```
(from https://github.com/akamai/akr)

For example, I named the key by my iPhone's name.

cf. [秘密鍵をスマホに保管できるKryptonの代替のAkamai MFA](https://zenn.dev/garebare/articles/89a60b20fbd7d4)

## Languages

### Python

:::note warn
By default, `python` means Python2 that locates in `/usr/bin/python` -- to see this, execute `python -V`. Python3 is also installed by default and located in `/usr/bin/python3`.
:::

If you want to use another version of Python3, use some runtime manager as below or install some specific runtime directly. 

You had better create 'virtualenvs' per your project unless using some virtual machine system or container system like Docker.

What is virtualenvs?:
[【種類別】Pythonの仮想環境を使うメリット4つと使い方を紹介！](https://www.acrovision.jp/career/?p=2254)

:::note alert
Do not use `venv` or `virtualenv`. These are legacy now.
:::

:::note warn
Avoid using `conda` unless there is some particular reason.
:::

#### Python runtime manager

##### pyenv [Recommended]

Install runtime manager:
```sh
brew install pyenv
```

Install available runtime(s):
```sh
pyenv install --list  # to see available runtimes
pyenv install 3.10.2  # for example, 3.10.2
pyenv global 3.10.2   # switch default python to 3.10.2, if needed
```

#### Python package manager

Comparison of Python package managers:
| *Python package manager* | Poetry | Pipenv | Anaconda/Miniconda (cf. [Mamba](https://github.com/mamba-org/mamba)) | Pip/Pip-tools |
|:-:|:-:|:-:|:-:|:-:|
| *subjective assessment* | ○ - ◎ | ○ | △ - ○ | △ |
| *supports virtualenvs* | Yes (by default) | Yes (by default) | Yes (optional) | No |
| *Git friendly* | Yes | Yes | No | No |
| *use case* | Any | Any | Numerical calculation | Pip: Installation of core packages like `poetry`, `pipenv` and so on |
| *package management file(s)* | pyproject.toml, poetry.lock | Pipfile, Pipfile.lock | environment.yml | requirements.txt / setup.py, requirements.in |

##### Poetry [Recommended]

:::note
Poetry runs faster than Pipenv, and its dependency resolver is stronger than Pipenv's one.
:::

Install:
```sh
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
```
(from https://python-poetry.org/docs/#osx--linux--bashonwindows-install-instructions)

After installation, add `$HOME/.poetry/bin` to `$PATH`. For example:
```sh
echo 'export PATH="$HOME/.poetry/bin:$PATH"' >> ~/.zprofile
```
A recommended setting:
```sh
poetry config virtualenvs.in-project true
```
Usage:

https://qiita.com/ksato9700/items/b893cf1db83605898d8a

##### Pipenv [Alternative]

:::note
Pipenv is a little more secure than Poetry.
:::

Install:
```sh
pip3 install --user pipenv
```

##### Anaconda/Miniconda [Alternative]

:::note warn
Conda is NOT recommended for usual cases.
:::

For more information, you can use your favorite search engine.

##### Pip, Pip-tools [Alternative]

:::note warn
`pip` or `pip3` will **globally** install python packages. In developments, Poetry (Pipenv) is more suitable than Pip.
:::

:::note alert
You do not have to use Pip like `pip install numpy pandas scikit-learn torch` or `pip install -r requirements.txt`.
:::

### JavaScript (JS)

If you do not know **Node.js** yet, at first, learn Node.js as a runtime:

https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb

#### Node runtime manager

Comparison of Node runtime (version) managers:
| *Node runtime manager* | nvm | n | others |
|:-:|:-:|:-:|:-:|
| *subjective assessment* | ○ - ◎ | ○ | ？ |

##### nvm [Recommended]

De facto node version manager.

https://github.com/nvm-sh/nvm

##### n [Alternative]

Alternative node version manager: https://github.com/tj/n.

##### asdf [Alternative]

Alternative *-runtime manager: https://github.com/asdf-vm/asdf. 

> `asdf` is a CLI tool that can manage multiple language runtime versions on a per-project basis. It is like `gvm`, `nvm`, `rbenv` & `pyenv` (and more) all in one! Simply install your language's plugin!

##### Volta [Alternative]

A newcomer built in Rust.

:::note
Volta manages both Node runtime and JavaScript packages, and it runs fast.
:::

:::note warn
Introducing Volta to your CI environments may be complicated for now.
:::

https://volta.sh/

#### JavaScript package manager

The following JavaScript package managers create a directory named `node_modules`, which is a counterpart of virtualenvs (`.venv`) in Python.

Comparison of JavaScript package managers:
| *JS package manager* | npm | Yarn | Volta |
|:-:|:-:|:-:|:-:|
| *subjective assessment* | ○ | ○ - ◎ | ？ |
| *package management file(s)* | package.json, package-lock.json | package.json, yarn.lock | ？ |

##### npm [Default]

npm is included in Node.js, so you do not need to install it.

Usage: `npm install <package>`
https://docs.npmjs.com/downloading-and-installing-packages-locally

:::note warn
When you want to recover `node_modules/`, use `npm ci` instead of `npm install` -- cf. [npm ciを使おう あるいはより速く
](https://qiita.com/mstssk/items/8759c71f328cab802670)
:::

##### Yarn [Alternative] [Recommended]

:::note
Yarn runs faster than npm.
:::

Install:
```sh
npm install -g yarn
```

Another Installation:
https://yarnpkg.com/getting-started/install

Usage: `yarn add <package>`
https://yarnpkg.com/getting-started/usage

### Any Languages

Check linters and formatters of each language.

For example:
|  | Python | JS |
|:-:|:-:|:-:|
| *linter* | Flake8 | ESLint |
| *formatter* | Black, isort | Prettier |