Skip to content

setup.shにプロファイル別(private/public)とOS別の処理を実装する #47

@yellow-seed

Description

@yellow-seed

概要

setup.shに以下の2つの拡張機能を追加し、より柔軟なセットアップを実現する:

  1. プロファイル別セットアップ: 個人PCと社用PCで異なるツール・アプリケーションをインストール
  2. OS別処理: macOSとUbuntu/Linuxで適切なパッケージマネージャーと設定を使用

使用例

# 個人PCでのセットアップ(デフォルト)
bash -c "$(curl -fsLS https://raw.githubusercontent.com/yellow-seed/dotfiles/main/setup.sh)"

# 明示的にプロファイルを指定
bash setup.sh private   # 個人利用PC
bash setup.sh public    # 社用PC

実装すべき機能

1. プロファイル別セットアップ

1.1 コマンドライン引数の処理

# 引数パース
PROFILE="${1:-private}"  # デフォルトはprivate

case "${PROFILE}" in
    private)
        echo "Setting up for private (personal) use..."
        ;;
    public)
        echo "Setting up for public (work) use..."
        ;;
    *)
        echo "Error: Unknown profile '${PROFILE}'"
        echo "Usage: $0 [private|public]"
        exit 1
        ;;
esac

1.2 Brewfileのプロファイル対応

現在の構造:

home/
  dot_Brewfile           # すべてのパッケージ

提案する構造:

home/
  dot_Brewfile.private.tmpl   # 個人PC用(フル機能)
  dot_Brewfile.public.tmpl    # 社用PC用(制限あり)
  dot_Brewfile.common         # 共通パッケージ

プロファイル別の内容例:

Private(個人PC)
  • 開発ツール: Docker Desktop, Postman, Insomnia
  • メディア: Spotify, VLC, IINA
  • ユーティリティ: Alfred, BetterTouchTool, Magnet
  • ゲーム: Steam
  • プライベートリポジトリ: 個人のGitHub設定
Public(社用PC)
  • 開発ツール: VS Code, JetBrains IDEs(会社ライセンス)
  • コミュニケーション: Slack, Microsoft Teams, Zoom
  • ユーティリティ: 基本的なツールのみ
  • 制限事項:
    • 個人的なメディアアプリを除外
    • 会社のセキュリティポリシーに準拠
    • プライベートなGit設定を除外
Common(共通)
  • CLI基本ツール: git, curl, wget, jq, ripgrep
  • シェル: zsh, starship
  • エディタ: vim, neovim
  • 開発言語: 会社・個人両方で使用するもの

1.3 miseのプロファイル対応

現在の構造:

home/dot_config/mise/config.toml

提案する構造:

home/dot_config/mise/
  config.private.toml.tmpl   # 個人PC用
  config.public.toml.tmpl    # 社用PC用
  config.common.toml         # 共通設定

1.4 Git設定のプロファイル対応

home/
  dot_gitconfig.private.tmpl   # 個人用メールアドレス
  dot_gitconfig.public.tmpl    # 会社用メールアドレス

chezmoiテンプレートでの実装例:

# .chezmoi.toml.tmpl
[data]
    profile = "{{ env "DOTFILES_PROFILE" | default "private" }}"
    
[data.git]
    {{ if eq .profile "private" }}
    email = "[email protected]"
    {{ else if eq .profile "public" }}
    email = "[email protected]"
    {{ end }}

2. OS別処理の実装

2.1 OS検出の強化

function get_os_type() {
    case "$(uname)" in
        Darwin)
            echo "macos"
            ;;
        Linux)
            if [ -f /etc/os-release ]; then
                . /etc/os-release
                echo "${ID}"  # ubuntu, debian, fedora, etc.
            else
                echo "linux"
            fi
            ;;
        *)
            echo "unknown"
            ;;
    esac
}

2.2 OS別パッケージマネージャーの使い分け

function install_packages() {
    local os_type="$1"
    local profile="$2"
    
    case "${os_type}" in
        macos)
            install_homebrew
            brew bundle install --file="${HOME}/.Brewfile.${profile}"
            ;;
        ubuntu|debian)
            sudo apt-get update
            sudo apt-get install -y $(cat "${HOME}/.config/apt/packages.${profile}.txt")
            ;;
        fedora|rhel|centos)
            sudo dnf install -y $(cat "${HOME}/.config/dnf/packages.${profile}.txt")
            ;;
        *)
            echo "Unsupported OS: ${os_type}"
            exit 1
            ;;
    esac
}

2.3 OS別設定ファイルの配置

ディレクトリ構造:

home/
  # macOS専用
  dot_Brewfile.private.tmpl
  dot_Brewfile.public.tmpl
  
  # Ubuntu/Debian専用
  dot_config/apt/
    packages.private.txt.tmpl
    packages.public.txt.tmpl
  
  # 共通
  dot_config/mise/config.toml
  dot_gitconfig.tmpl

chezmoiの条件付き適用:

# .chezmoiignore
{{ if ne .chezmoi.os "darwin" }}
.Brewfile*
{{ end }}

{{ if ne .chezmoi.os "linux" }}
.config/apt/
{{ end }}

3. 環境変数による設定

3.1 プロファイル指定

# 環境変数で指定
export DOTFILES_PROFILE=public
bash setup.sh

# または引数で指定
bash setup.sh public

3.2 chezmoi設定への反映

# setup.sh内
export DOTFILES_PROFILE="${1:-${DOTFILES_PROFILE:-private}}"
chezmoi init --apply "${GITHUB_USERNAME}" \
    --promptString "profile=${DOTFILES_PROFILE}"

ディレクトリ構造の全体像

.
├── home/
│   ├── .chezmoi.toml.tmpl           # プロファイル設定を含む
│   ├── .chezmoiignore               # OS別の除外設定
│   │
│   # macOS専用ファイル
│   ├── dot_Brewfile.private.tmpl    # 個人PC用Brewfile
│   ├── dot_Brewfile.public.tmpl     # 社用PC用Brewfile
│   │
│   # Git設定(プロファイル別)
│   ├── dot_gitconfig.tmpl           # テンプレート化
│   │
│   # 共通設定
│   ├── dot_zshrc
│   ├── dot_gitignore_global
│   │
│   └── dot_config/
│       ├── mise/
│       │   ├── config.private.toml.tmpl   # 個人PC用mise設定
│       │   ├── config.public.toml.tmpl    # 社用PC用mise設定
│       │   └── config.common.toml         # 共通mise設定
│       │
│       # Ubuntu/Linux専用
│       └── apt/
│           ├── packages.private.txt.tmpl
│           └── packages.public.txt.tmpl
│
├── install/
│   ├── macos/
│   │   └── common/
│   │       ├── brew.sh              # Homebrew自動インストール
│   │       └── brewfile.sh          # Brewfile適用
│   └── ubuntu/
│       └── common/
│           └── apt.sh               # apt自動セットアップ(新規)
│
└── setup.sh                         # 統合セットアップスクリプト

実装の流れ

graph TD
    A[setup.sh実行] --> B{引数チェック}
    B -->|引数あり| C[プロファイル設定]
    B -->|引数なし| D[デフォルト: private]
    C --> E{OS検出}
    D --> E
    E -->|macOS| F[chezmoi適用<br/>private/public選択]
    E -->|Ubuntu| G[chezmoi適用<br/>private/public選択]
    E -->|その他| H[エラー: 未対応OS]
    F --> I[Homebrew<br/>インストール]
    G --> J[apt<br/>アップデート]
    I --> K[Brewfile<br/>プロファイル適用]
    J --> L[apt packages<br/>プロファイル適用]
    K --> M[mise install]
    L --> M
    M --> N[シェルリロード]
    N --> O[セットアップ完了]
Loading

技術的な考慮事項

chezmoiテンプレートの活用

# .chezmoi.toml.tmpl
[data]
    profile = "{{ env "DOTFILES_PROFILE" | default "private" }}"
    
[data.git]
    {{ if eq .profile "private" }}
    name = "Your Name"
    email = "[email protected]"
    {{ else if eq .profile "public" }}
    name = "Your Name"
    email = "[email protected]"
    {{ end }}
# dot_gitconfig.tmpl
[user]
    name = {{ .git.name }}
    email = {{ .git.email }}

Brewfileのマージ処理

共通パッケージ + プロファイル固有パッケージを統合:

# brewfile.sh内
function merge_brewfiles() {
    local profile="$1"
    local temp_brewfile="/tmp/Brewfile.merged"
    
    # 共通パッケージ
    cat "${HOME}/.Brewfile.common" > "${temp_brewfile}"
    
    # プロファイル固有パッケージ
    cat "${HOME}/.Brewfile.${profile}" >> "${temp_brewfile}"
    
    echo "${temp_brewfile}"
}

環境変数の優先順位

  1. コマンドライン引数(最優先)
  2. 環境変数 DOTFILES_PROFILE
  3. デフォルト値(private
PROFILE="${1:-${DOTFILES_PROFILE:-private}}"

テスト戦略

単体テスト(BATS)

# tests/files/setup.bats

@test "setup.sh accepts private profile" {
    PROFILE=private run bash setup.sh private
    [[ "$output" =~ "Setting up for private" ]]
}

@test "setup.sh accepts public profile" {
    PROFILE=public run bash setup.sh public
    [[ "$output" =~ "Setting up for public" ]]
}

@test "setup.sh rejects invalid profile" {
    run bash setup.sh invalid
    [ "$status" -ne 0 ]
    [[ "$output" =~ "Unknown profile" ]]
}

@test "setup.sh detects macOS correctly" {
    skip_if_not_macos
    run get_os_type
    [[ "$output" =~ "macos" ]]
}

@test "setup.sh detects Ubuntu correctly" {
    skip_if_not_ubuntu
    run get_os_type
    [[ "$output" =~ "ubuntu" ]]
}

統合テスト(GitHub Actions)

# .github/workflows/test_setup_profiles.yml
name: Test Setup Profiles

on: [push, pull_request]

jobs:
  test-macos-private:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test private profile
        run: bash setup.sh private

  test-macos-public:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test public profile
        run: bash setup.sh public

  test-ubuntu-private:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test private profile
        run: bash setup.sh private

実装の優先度

Phase 1: プロファイル別セットアップ(macOS)

  • コマンドライン引数のパース
  • Brewfileのプロファイル分割(private/public/common)
  • chezmoiテンプレートでのプロファイル設定
  • Git設定のプロファイル対応
  • BATSテストの追加

Phase 2: OS別処理の実装

  • OS検出ロジックの強化
  • macOS: Homebrewベースの処理
  • Ubuntu: aptベースの処理
  • 条件付きファイル適用(.chezmoiignore)

Phase 3: miseのプロファイル対応

  • mise設定のプロファイル分割
  • プロファイル別ツールリスト

Phase 4: ドキュメント整備

  • README.mdの更新
  • AGENTS.mdの更新
  • 使用例とベストプラクティスの追加

セキュリティとプライバシー

機密情報の管理

  • privateプロファイル:

    • 個人のGitHub Token
    • プライベートAPI Keys
    • 個人用SSH Keys
  • publicプロファイル:

    • 会社のGitHub Token(必要に応じて)
    • 会社承認済みのAPI Keys
    • 会社用SSH Keys

.chezmoiignore での制御

# public プロファイルでは個人設定を無視
{{ if eq .profile "public" }}
.ssh/config.personal
.config/gh/config.personal.yml
{{ end }}

# private プロファイルでは会社設定を無視
{{ if eq .profile "private" }}
.ssh/config.work
.config/gh/config.work.yml
{{ end }}

受け入れ基準

  • setup.sh private で個人PC用のセットアップが完了する
  • setup.sh public で社用PC用のセットアップが完了する
  • macOSとUbuntuの両方で動作する
  • プロファイル別のBrewfile/パッケージリストが適用される
  • Git設定がプロファイルに応じて切り替わる
  • 無効なプロファイル指定時にエラーメッセージが表示される
  • 未対応OSでのエラーハンドリングが適切
  • すべてのBATSテストがパス
  • CI/CDで両プロファイルがテストされる
  • ドキュメントが更新される

関連Issue

  • なし(新規提案)

参考資料

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions