1コマンドでMacBook Proに最低限の開発環境構築

使っていた端末の調子が悪くなって端末交換したので、開発環境構築のお時間です。

できるだけ簡単に旧端末の設定を引き継ぎつつセットアップしたかったので、いろいろと調べてまとめてみたら、1コマンドでできるようになりました。(準備は含めず)

旧端末を環境構築したときとだいぶ変わりました。

5分でできるMacBook Proに最低限の開発環境構築 - Qiita
https://qiita.com/kai_kou/items/3107e0a056c7a1b569cd

## 手順

ターミナルを立ち上げて、

```console
> sh -c "$(curl -fsSL https://gist.githubusercontent.com/<GitHub UserID>/<Gist ID>/raw)"
```

おーかんたん。これで必要なアプリがだいたいインストールされます。
※コマンド実行中、パスワードを求められることがあります。


## 何をしているのか？

セットアップに必要なコマンドをファイルにまとめてGistへアップロードして`sh -c` コマンドで実行しています。

```sh:setup.sh
#!/bin/sh

# Command Line Tools for Xcode
xcode-select --install

# HomeBrew
# see https://brew.sh/index_ja.html
if [ ! -x "`which brew`" ]; then
  echo "start install and update brew"
  /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  brew update
  brew upgrade
  brew -v
fi

# BrewfileをGistから取得する
if [ ! -e "~/Brewfile" ]; then
  curl -fsSL https://gist.githubusercontent.com/<GitHub UserID>/<Gist ID>/raw > ~/Brewfile

  brew bundle

  # VSCodeの拡張機能インストール
  if [ -x "`which code`" ]; then
    echo 'Setup VSCode'
    code --install-extension Shan.code-settings-sync -force
    echo "done"
  fi
fi

# BrewはAppStoreでインストールできないアプリ
if [  -x "`which wget`" ]; then
  echo 'Setup Other App'
  if [ ! -e "/Applications/forghetti.app" ]; then
    # Forghetti
    wget https://downloads.forghetti.com/Forghetti.dmg -O ~/Downloads/Forghetti.dmg
    hdiutil mount ~/Downloads/Forghetti.dmg
    cd /Volumes/forghetti\ 1.0.6/
    cp -r forghetti.app /Applications/
    cd ~/
    hdiutil detach /Volumes/forghetti\ 1.0.6/
  fi
  echo 'done'
fi

# システム環境設定
echo 'Setup defaults'

# http://neos21.hatenablog.com/entry/2019/01/10/080000
# ~/Library ディレクトリを見えるようにする
chflags nohidden ~/Library
# /Volumes ディレクトリを見えるようにする
sudo chflags nohidden /Volumes
# ブート時のサウンドを無効化する
sudo nvram SystemAudioVolume=" "
# 時計アイコンクリック時に OS やホスト名 IP を表示する
sudo defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName
# ファイルを開くときのアニメーションを無効にする
defaults write -g NSAutomaticWindowAnimationsEnabled -bool false
# ツールチップ表示までのタイムラグをなくす
defaults write -g NSInitialToolTipDelay -integer 0
# ダイアログ表示やウィンドウリサイズ速度を高速化する
defaults write -g NSWindowResizeTime 0.1
# 全ての拡張子のファイルを表示する
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# スクロールバーを常時表示する
#defaults write NSGlobalDomain AppleShowScrollBars -string "Always"
# スプリングロード遅延を除去する
#defaults write NSGlobalDomain com.apple.springing.delay -float 0
# ディレクトリのスプリングロードを有効にする
# キーリピートの速度
#defaults write NSGlobalDomain com.apple.springing.enabled -bool true#defaults write NSGlobalDomain KeyRepeat -int 2
# キーリピート開始までのタイミング
#defaults write NSGlobalDomain InitialKeyRepeat -int 15
# コンソールアプリケーションの画面サイズ変更を高速にする
#defaults write NSGlobalDomain NSWindowResizeTime -float 0.001
# Safari のコンテキストメニューに Web インスペクタを追加する
defaults write NSGlobalDomain WebKitDeveloperExtras -bool true
# Bluetooth ヘッドフォン・ヘッドセットの音質を向上させる
defaults write com.apple.BluetoothAudioAgent "Apple Bitpool Min (editable)" -int 40
# クラッシュレポートを無効化する
defaults write com.apple.CrashReporter DialogType -string "none"
# Dashboard を無効化する
# defaults write com.apple.dashboard mcx-disabled -bool true
# USB やネットワークストレージに .DS_Store ファイルを作成しない
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
# Dock が表示されるまでの待ち時間を無効にする
defaults write com.apple.dock autohide-delay -float 0
# Mission Control を使用不可にする
# defaults write com.apple.dock mcx-expose-disabled -bool true
# Finder のタイトルバーにフルパスを表示する
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true
# 名前で並べ替えを選択時にディレクトリを前に置くようにする
defaults write com.apple.finder _FXSortFoldersFirst -bool true
# フォルダを開くときのアニメーションを無効にする
defaults write com.apple.finder AnimateWindowZoom -bool false
# 不可視ファイルを表示する
defaults write com.apple.finder AppleShowAllFiles YES
# 検索時にデフォルトでカレントディレクトリを検索する
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# 拡張子変更時の警告を無効化する
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
# クイックルックでテキストを選択可能にする
defaults write com.apple.finder QLEnableTextSelection -bool true
# Finder を終了させる項目を追加する
defaults write com.apple.Finder QuitMenuItem -bool true
# パスバーを表示する
defaults write com.apple.finder ShowPathbar -bool true
# ステータスバーを表示する
defaults write com.apple.finder ShowStatusBar -bool true
# タブバーを表示する
defaults write com.apple.finder ShowTabView -bool true
# ゴミ箱を空にする前の警告を無効化する
#defaults write com.apple.finder WarnOnEmptyTrash -bool false
# 未確認のアプリケーションを実行する際のダイアログを無効にする
defaults write com.apple.LaunchServices LSQuarantine -bool false
# ファイル共有を有効にした時、共有先に自分の Mac を表示させる
#defaults write com.apple.NetworkBrowser ShowThisComputer -bool true
# ファイルのダウンロード後に自動でファイルを開くのを無効化する
defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari IncludeDevelopMenu -bool true
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari IncludeInternalDebugMenu -bool true
# アドレスバーに完全な URL を表示する
defaults write com.apple.Safari ShowFullURLInSmartSearchField -bool true
# ステータスバーを表示する
defaults write com.apple.Safari ShowStatusBar -bool true
# 検索クエリを Apple へ送信しない
defaults write com.apple.Safari SuppressSearchSuggestions -bool true
# 検索クエリを Apple へ送信しない
defaults write com.apple.Safari UniversalSearchEnabled -bool false
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true
# スクリーンキャプチャの影をなくす
defaults write com.apple.screencapture disable-shadow -bool true
# スクリーンショットの保存形式を PNG にする
defaults write com.apple.screencapture type -string "png"
# UTF-8 のみを使用する
defaults write com.apple.terminal StringEncodings -array 4

# https://qiita.com/djmonta/items/17531dde1e82d9786816
# Date options: Show the day of the week: on （日付表示設定、曜日を表示）
defaults write com.apple.menuextra.clock 'DateFormat' -string 'EEE H:mm:ss'

# https://qiita.com/ryuichi1208/items/5905240f3bfce793b33d
# Spotlight トレイアイコンを非表示
$ sudo chmod 600 /System/Library/CoreServices/Search.bundle/Contents/MacOS/Search

echo "done"


# Dotfileのリストア
if [ ! -e "~/.mackup.cfg" ]; then
  echo 'Setup Mackup'
  cat <<EOF > ~/.mackup.cfg
[storage]
engine = file_system
path = /Users/xxx/OneDrive - hoge/
directory = config
EOF
  echo "Run > mackup restore"
fi
```

それぞれ何をしているのかみてみます。

### `brew bundle` でアプリをインストール

macOS用のパッケージマネージャとしてHomebrewが有名ですが、`brew bundle` という素敵コマンドがあったのでそれを利用して、`brew`、`brew cask`、`mas` コマンドでインストールしていたものを一括でインストールします。
詳しくは下記が参考になります。

Homebrew/homebrew-bundle: 📦 Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask and the Mac App Store.
https://github.com/Homebrew/homebrew-bundle

俺のBrewfileが完成したので晒す ⋆ binfish {{ blog
https://blog.binfish.jp/diary/oreno-brewfile/

Macの開発環境構築を自動化する(2019年6月編) – karakaram-blog
https://www.karakaram.com/how-to-automate-your-mac-set-up#brewfile

brew tap で入れる Homebrew 外部コマンド - Qiita
https://qiita.com/tearoom6/items/1abf24ca6d872e6579b0#brew-bundle


`Brewfile` が必要となりますが、これもGistにアップロードしておきます。
これはshファイルにまとめても良いかもですね。

```sh:setup.sh抜粋
# Command Line Tools for Xcode
xcode-select --install

# HomeBrew
# see https://brew.sh/index_ja.html
if [ ! -x "`which brew`" ]; then
  echo "start install and update brew"
  /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  brew update
  brew upgrade
  brew -v
fi

# BrewfileをGistから取得する
if [ ! -e "~/Brewfile" ]; then
curl -fsSL https://gist.githubusercontent.com/<GitHub UserID>/<Gist ID>/raw > ~/Brewfile

  brew bundle

  # VSCodeの拡張機能インストール
  if [ -x "`which code`" ]; then
    echo 'Setup VSCode'
    code --install-extension Shan.code-settings-sync -force
    echo "done"
  fi
fi
```

参考までにわたしのBrewfileを晒しておきます。
`mas` でインストールするアプリがある場合、AppStoreアプリでサインインしておく必要があります。

```txt:Brewfile
tap "delphinus/sfmono-square"
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/cask-versions"
tap "homebrew/core"

brew "bat"
brew "cask"
brew "mas", link: false
brew "fish"
brew "git"
brew "git-flow"
brew "htop"
brew "jq"
brew "tree"
brew "wget"
brew "awscli"
brew "mackup"

# Tmux
brew "tmux"
brew "reattach-to-user-namespace"

# Font
brew "delphinus/sfmono-square/sfmono-square"

# Browser
cask "google-chrome"
cask "firefox"

# Tool
cask "alfred"
cask "google-japanese-ime"
cask "slack-beta"
cask "skitch"
cask "onedrive"
cask "zoomus"

# ScreenSaver
cask "fliqlo"

# Dev
cask "hyper"
cask "docker"
cask "visual-studio-code"
cask "unity-hub"
cask "visual-studio"
cask "dotnet"
cask "google-cloud-sdk"


# App Store
mas "Keynote", id: 409183694
mas "TweetDeck", id: 485812721
mas "Xcode", id: 497799835
```

`brew bundle` 後にVSCodeの拡張機能をインストールしますが、これはVSCodeの拡張機能Setting Syncが便利なのでそちらを利用します。
詳細はこちらが参考になります。

VSCode(Visual Studio Code)の設定を同期させる拡張機能「Setting Sync」が便利 | カレリエ
https://www.karelie.net/vscode-setting-sync/

```sh:setup.sh抜粋
  # VSCodeの拡張機能インストール
  if [ -x "`which code`" ]; then
    echo 'Setup VSCode'
    code --install-extension Shan.code-settings-sync -force
    code
    echo "done"
  fi
```

コマンド実行後にVSCodeを立ち上げて、Setting Syncの設定をしてリストアです。

Setting Syncを利用せず、毎回拡張機能を指定してインストールしたい場合には、下記が参考になります。

Visual Studio Code で必要な拡張パッケージを一括でインストールするスクリプト - Qiita
https://qiita.com/takeru08ma/items/43705af9fa864cf3bc18


### BrewやAppStoreでインストールできないアプリのインストール

これはご参考レベルで。Forghetti便利っすよ。


MacOS(OSX)でコマンドラインからdmgインストール - Qiita
https://qiita.com/skycat_me/items/be78d27c5f6c5422e3b6

forghetti - Password Manager - Forget your passwords. Forever.
https://www.forghetti.com/


```sh:setup.sh抜粋
# BrewやAppStoreでインストールできないアプリ
if [  -x "`which wget`" ]; then
  echo 'Setup Other App'
  if [ ! -e "/Applications/forghetti.app" ]; then
    # Forghetti
    wget https://downloads.forghetti.com/Forghetti.dmg -O ~/Downloads/Forghetti.dmg
    hdiutil mount ~/Downloads/Forghetti.dmg
    cd /Volumes/forghetti\ 1.0.6/
    cp -r forghetti.app /Applications/
    cd ~/
    hdiutil detach /Volumes/forghetti\ 1.0.6/
  fi
  echo 'done'
fi
```

### システム環境設定

`defaults` コマンドを利用してMacのシステム環境を設定します。設定内容はお好みで。

MacOS で設定する defaults コマンドをまとめてみた - Corredor
http://neos21.hatenablog.com/entry/2019/01/10/080000

ターミナルから Mac を設定する（defaults write コマンド等） - Qiita
https://qiita.com/djmonta/items/17531dde1e82d9786816

iMac/MacBook購入後に必ず設定したい設定項目 - Qiita
https://qiita.com/ryuichi1208/items/5905240f3bfce793b33d


```sh:setup.sh抜粋
# システム環境設定
echo 'Setup defaults'

# http://neos21.hatenablog.com/entry/2019/01/10/080000
# ~/Library ディレクトリを見えるようにする
chflags nohidden ~/Library
# /Volumes ディレクトリを見えるようにする
sudo chflags nohidden /Volumes
# ブート時のサウンドを無効化する
sudo nvram SystemAudioVolume=" "
# 時計アイコンクリック時に OS やホスト名 IP を表示する
sudo defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName
# ファイルを開くときのアニメーションを無効にする
defaults write -g NSAutomaticWindowAnimationsEnabled -bool false
# ツールチップ表示までのタイムラグをなくす
defaults write -g NSInitialToolTipDelay -integer 0
# ダイアログ表示やウィンドウリサイズ速度を高速化する
defaults write -g NSWindowResizeTime 0.1
# 全ての拡張子のファイルを表示する
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# スクロールバーを常時表示する
#defaults write NSGlobalDomain AppleShowScrollBars -string "Always"
# スプリングロード遅延を除去する
#defaults write NSGlobalDomain com.apple.springing.delay -float 0
# ディレクトリのスプリングロードを有効にする
# キーリピートの速度
#defaults write NSGlobalDomain com.apple.springing.enabled -bool true#defaults write NSGlobalDomain KeyRepeat -int 2
# キーリピート開始までのタイミング
#defaults write NSGlobalDomain InitialKeyRepeat -int 15
# コンソールアプリケーションの画面サイズ変更を高速にする
#defaults write NSGlobalDomain NSWindowResizeTime -float 0.001
# Safari のコンテキストメニューに Web インスペクタを追加する
defaults write NSGlobalDomain WebKitDeveloperExtras -bool true
# Bluetooth ヘッドフォン・ヘッドセットの音質を向上させる
defaults write com.apple.BluetoothAudioAgent "Apple Bitpool Min (editable)" -int 40
# クラッシュレポートを無効化する
defaults write com.apple.CrashReporter DialogType -string "none"
# Dashboard を無効化する
# defaults write com.apple.dashboard mcx-disabled -bool true
# USB やネットワークストレージに .DS_Store ファイルを作成しない
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
# Dock が表示されるまでの待ち時間を無効にする
defaults write com.apple.dock autohide-delay -float 0
# Mission Control を使用不可にする
# defaults write com.apple.dock mcx-expose-disabled -bool true
# Finder のタイトルバーにフルパスを表示する
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true
# 名前で並べ替えを選択時にディレクトリを前に置くようにする
defaults write com.apple.finder _FXSortFoldersFirst -bool true
# フォルダを開くときのアニメーションを無効にする
defaults write com.apple.finder AnimateWindowZoom -bool false
# 不可視ファイルを表示する
defaults write com.apple.finder AppleShowAllFiles YES
# 検索時にデフォルトでカレントディレクトリを検索する
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# 拡張子変更時の警告を無効化する
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
# クイックルックでテキストを選択可能にする
defaults write com.apple.finder QLEnableTextSelection -bool true
# Finder を終了させる項目を追加する
defaults write com.apple.Finder QuitMenuItem -bool true
# パスバーを表示する
defaults write com.apple.finder ShowPathbar -bool true
# ステータスバーを表示する
defaults write com.apple.finder ShowStatusBar -bool true
# タブバーを表示する
defaults write com.apple.finder ShowTabView -bool true
# ゴミ箱を空にする前の警告を無効化する
#defaults write com.apple.finder WarnOnEmptyTrash -bool false
# 未確認のアプリケーションを実行する際のダイアログを無効にする
defaults write com.apple.LaunchServices LSQuarantine -bool false
# ファイル共有を有効にした時、共有先に自分の Mac を表示させる
#defaults write com.apple.NetworkBrowser ShowThisComputer -bool true
# ファイルのダウンロード後に自動でファイルを開くのを無効化する
defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari IncludeDevelopMenu -bool true
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari IncludeInternalDebugMenu -bool true
# アドレスバーに完全な URL を表示する
defaults write com.apple.Safari ShowFullURLInSmartSearchField -bool true
# ステータスバーを表示する
defaults write com.apple.Safari ShowStatusBar -bool true
# 検索クエリを Apple へ送信しない
defaults write com.apple.Safari SuppressSearchSuggestions -bool true
# 検索クエリを Apple へ送信しない
defaults write com.apple.Safari UniversalSearchEnabled -bool false
# Safari の開発・デバッグメニューを有効にする
defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true
# スクリーンキャプチャの影をなくす
defaults write com.apple.screencapture disable-shadow -bool true
# スクリーンショットの保存形式を PNG にする
defaults write com.apple.screencapture type -string "png"
# UTF-8 のみを使用する
defaults write com.apple.terminal StringEncodings -array 4

# https://qiita.com/djmonta/items/17531dde1e82d9786816
# Date options: Show the day of the week: on （日付表示設定、曜日を表示）
defaults write com.apple.menuextra.clock 'DateFormat' -string 'EEE H:mm:ss'

# https://qiita.com/ryuichi1208/items/5905240f3bfce793b33d
# Spotlight トレイアイコンを非表示
$ sudo chmod 600 /System/Library/CoreServices/Search.bundle/Contents/MacOS/Search

echo "done"
```

### dotfilesを復元する

Mackupというツールを利用して、旧端末のdotfilesをDropBoxなどのファイル共有サービス経由で復元できるようにしました。

lra/mackup: Keep your application settings in sync (OS X/Linux)
https://github.com/lra/mackup

dotfiles, アプリケーションの設定をMackupで管理する - Qiita
https://qiita.com/saboyutaka/items/b4aaa1f5fcd0ea148b2a


OneDriveを利用しているので、`engine = file_system` としてパス指定するようにしています。
`mackup restore` はファイルで実行せずにあとから実行できるようにしました。(なんとなく)

```sh:setup.sh抜粋
# Dotfileのリストア
if [ ! -e "~/.mackup.cfg" ]; then
  echo 'Setup Mackup'
  cat <<EOF > ~/.mackup.cfg
[storage]
engine = file_system
path = /Users/xxx/OneDrive - hoge/
directory = config
EOF
  echo "Run > mackup restore"
fi
```

※ `.ssh` は鍵ファイルは対象外っぽいので、自前でシンボリックリンクを貼ったりするのが良さげです。

Does Mackup still sync SSH keys by default? · Issue #1227 · lra/mackup
https://github.com/lra/mackup/issues/1227

```console:ご参考
> mv ~/.ssh ~/.ssh_old
> ln -s ~/OneDrive\ -\ hoge/config/.ssh/ ~/
> chmod 400 ~/.ssh/id_*
> chmod 400 ~/.ssh/*.pub
> chmod 400 ~/.ssh/*.pem
```


## まとめ

こんな感じで、環境構築って結局毎回やり方を変えてるので手間がかかります。(楽しいですね


## 参考

5分でできるMacBook Proに最低限の開発環境構築 - Qiita
https://qiita.com/kai_kou/items/3107e0a056c7a1b569cd

Homebrew/homebrew-bundle: 📦 Bundler for non-Ruby dependencies from Homebrew, Homebrew Cask and the Mac App Store.
https://github.com/Homebrew/homebrew-bundle

俺のBrewfileが完成したので晒す ⋆ binfish {{ blog
https://blog.binfish.jp/diary/oreno-brewfile/

Macの開発環境構築を自動化する(2019年6月編) – karakaram-blog
https://www.karakaram.com/how-to-automate-your-mac-set-up#brewfile

brew tap で入れる Homebrew 外部コマンド - Qiita
https://qiita.com/tearoom6/items/1abf24ca6d872e6579b0#brew-bundle

VSCode(Visual Studio Code)の設定を同期させる拡張機能「Setting Sync」が便利 | カレリエ
https://www.karelie.net/vscode-setting-sync/

Visual Studio Code で必要な拡張パッケージを一括でインストールするスクリプト - Qiita
https://qiita.com/takeru08ma/items/43705af9fa864cf3bc18

MacOS(OSX)でコマンドラインからdmgインストール - Qiita
https://qiita.com/skycat_me/items/be78d27c5f6c5422e3b6

forghetti - Password Manager - Forget your passwords. Forever.
https://www.forghetti.com/

MacOS で設定する defaults コマンドをまとめてみた - Corredor
http://neos21.hatenablog.com/entry/2019/01/10/080000

ターミナルから Mac を設定する（defaults write コマンド等） - Qiita
https://qiita.com/djmonta/items/17531dde1e82d9786816

iMac/MacBook購入後に必ず設定したい設定項目 - Qiita
https://qiita.com/ryuichi1208/items/5905240f3bfce793b33d

lra/mackup: Keep your application settings in sync (OS X/Linux)
https://github.com/lra/mackup

dotfiles, アプリケーションの設定をMackupで管理する - Qiita
https://qiita.com/saboyutaka/items/b4aaa1f5fcd0ea148b2a

Does Mackup still sync SSH keys by default? · Issue #1227 · lra/mackup
https://github.com/lra/mackup/issues/1227