From f56ffecbbc541e63235980b83f1b4bb85e79e56c Mon Sep 17 00:00:00 2001
From: ryoya ito <30540303+ry-itto@users.noreply.github.com>
Date: Wed, 20 Aug 2025 17:22:42 +0900
Subject: [PATCH 1/2] =?UTF-8?q?feat:=20CI=E5=AE=9F=E8=A1=8C=E6=99=82?=
=?UTF-8?q?=E3=81=ABREADME=E3=82=92=E8=87=AA=E5=8B=95=E6=9B=B4=E6=96=B0?=
=?UTF-8?q?=E3=81=99=E3=82=8B=E4=BB=95=E7=B5=84=E3=81=BF=E3=82=92=E8=BF=BD?=
=?UTF-8?q?=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- .Brewfileから意図したパッケージ情報を収集・表示
- main push時に自動的にREADME更新
- パッケージの説明とカテゴリ別表示を実装
- 明示的なバージョン指定がある場合のみバージョン表示
Changes:
- scripts/collect_environment.sh: 環境情報収集スクリプト
- scripts/parse_brewfile.py: Brewfileパーサー
- scripts/update_readme.py: README更新スクリプト
- README.template.md: READMEテンプレート
- .github/workflows/ci.yml: 統合CIワークフロー
- test.ymlとupdate-readme.ymlを統合
---
.github/workflows/{test.yml => ci.yml} | 58 +++++-
README.md | 272 ++++++++++++++++++++++++-
README.template.md | 213 +++++++++++++++++++
scripts/collect_environment.sh | 196 ++++++++++++++++++
scripts/parse_brewfile.py | 157 ++++++++++++++
scripts/update_readme.py | 186 +++++++++++++++++
6 files changed, 1075 insertions(+), 7 deletions(-)
rename .github/workflows/{test.yml => ci.yml} (75%)
create mode 100644 README.template.md
create mode 100755 scripts/collect_environment.sh
create mode 100755 scripts/parse_brewfile.py
create mode 100755 scripts/update_readme.py
diff --git a/.github/workflows/test.yml b/.github/workflows/ci.yml
similarity index 75%
rename from .github/workflows/test.yml
rename to .github/workflows/ci.yml
index 3670e66..d42a0fa 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/ci.yml
@@ -1,8 +1,11 @@
-name: CI Tests
+name: CI
on:
push:
branches: [ main ]
+ paths-ignore:
+ - 'README.md'
+ - '.github/workflows/update-readme.yml'
pull_request:
branches: [ main ]
@@ -181,4 +184,55 @@ jobs:
make install
# Should complete without errors
- echo "✓ Installation is idempotent"
\ No newline at end of file
+ echo "✓ Installation is idempotent"
+
+ update-readme:
+ name: Update README
+ runs-on: macos-latest
+ needs: [integration]
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+
+ permissions:
+ contents: write
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+
+ - name: Update README
+ run: |
+ echo "=== Updating README with environment information ==="
+ python3 scripts/update_readme.py
+
+ - name: Check for changes
+ id: check_changes
+ run: |
+ if [[ -n $(git status --porcelain README.md) ]]; then
+ echo "changes=true" >> $GITHUB_OUTPUT
+ echo "README.md has changes"
+ else
+ echo "changes=false" >> $GITHUB_OUTPUT
+ echo "No changes to README.md"
+ fi
+
+ - name: Commit and push changes
+ if: steps.check_changes.outputs.changes == 'true'
+ run: |
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
+ git config --local user.name "github-actions[bot]"
+
+ git add README.md
+ git commit -m "docs: update README with latest environment info [skip ci]
+
+ Auto-generated by GitHub Actions
+ Workflow: ${{ github.workflow }}
+ Run: ${{ github.run_number }}"
+
+ git push
\ No newline at end of file
diff --git a/README.md b/README.md
index 31557c0..424dd95 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,277 @@
# dotfiles
-## Vim
+My personal dotfiles for macOS development environment setup. This repository contains configurations for various development tools and automated installation scripts.
-### Coc
+## 🚀 Quick Start
-#### Extensions
+```bash
+# Clone the repository
+git clone https://github.com/ry-itto/dotfiles.git ~/ghq/github.com/ry-itto/dotfiles
+cd ~/ghq/github.com/ry-itto/dotfiles
-Install extensions by
+# Install everything (dotfiles + dependencies)
+make all
+```
+
+## 📋 Requirements
+
+- macOS (tested on macOS 14+)
+- Command Line Tools for Xcode
+- Internet connection for downloading packages
+
+
+## 📦 Package Configuration
+
+> **Tested on**: macOS 15.5 (arm64) - Last updated: 2025-08-20 08:18 UTC
+
+The following packages are defined in `.Brewfile` for installation:
+
+
+🛠️ Homebrew Formulae (30 packages)
+
+
+**zsh関係**
+
+- `zsh` - Z shell - Modern shell with advanced features
+- `zplug` - Zsh plugin manager
+
+**iOS**
+
+- `xcodegen` - Generate Xcode projects from spec files
+- `xcbeautify` - Xcode build output formatter
+
+**Flutter**
+
+- `usbmuxd` - USB multiplexing daemon for iOS devices
+- `libimobiledevice` (latest development version) - iOS device communication library
+- `ideviceinstaller` - Manage iOS apps from command line
+- `ios-deploy` - Install and debug iOS apps from command line
+
+**MCP**
+
+- `uv` - Fast Python package installer and resolver
+
+**ツール**
+
+- `ag` - The Silver Searcher - Fast code searching
+- `gh` - GitHub CLI
+- `ghq` - Git repository organizer
+- `fzf` - Fuzzy finder for command line
+- `jq` - JSON processor
+- `tig` - Text-mode interface for git
+- `tree` - Display directory tree structure
+- `nkf` - Network Kanji Filter - Character encoding converter
+- `git` - Distributed version control system
+- `emojify` - Emoji on the command line
+- `nvim` - Neovim - Hyperextensible Vim-based text editor
+- `tmux` - Terminal multiplexer
+- `starship` - Cross-shell prompt
+- `mise` - Development environment manager (formerly rtx)
+- `act` - Run GitHub Actions locally
+
+**gPRC**
+
+- `protobuf` - Protocol Buffers - Google's data interchange format
+
+**ruby-build**
+
+- `openssl@3` - Cryptography and SSL/TLS toolkit
+- `readline` - GNU readline library
+- `libyaml` - YAML parser and emitter library
+- `autoconf` - Automatic configure script builder
+- `gmp` - GNU multiple precision arithmetic library
+
+
+
+
+🖥️ Homebrew Casks - GUI Applications (12 apps)
+
+
+**Cask**
+
+- `clipy` - Clipboard manager
+- `raycast` - Productivity launcher
+- `font-hack-nerd-font` - Hack font with Nerd Font patches
+- `font-hackgen` - Japanese programming font
+- `font-hackgen-nerd` - HackGen with Nerd Font patches
+- `notion` - All-in-one workspace
+- `notion-calendar` - Calendar app by Notion
+- `figma` - Collaborative design tool
+- `discord` - Voice, video, and text chat
+- `rectangle` - Window management app
+- `hammerspoon` - Desktop automation tool
+- `wezterm` - GPU-accelerated terminal emulator
+
+
+
+
+## 🛠 Installation
+
+### Full Installation (Recommended)
+
+Installs all dotfiles and dependencies:
+
+```bash
+make all
+```
+
+### Partial Installation
+
+Install only dotfiles (symlinks and configs):
+
+```bash
+make install
+```
+
+Install only dependencies (Homebrew, tools, etc.):
+
+```bash
+make deps
+```
+
+### Manual Installation
+
+You can also run individual installer scripts as needed:
+
+```bash
+# Install Homebrew and packages
+/bin/zsh installers/brew.sh
+
+# Install development tools
+/bin/zsh installers/mise.sh # Version management
+/bin/zsh installers/flutter.sh # Flutter SDK
+/bin/zsh installers/rust.sh # Rust toolchain
+/bin/zsh installers/vim.sh # Vim plugins
+/bin/zsh installers/xcode.sh # Xcode tools
+/bin/zsh installers/zplug.sh # Zsh plugin manager
+```
+
+## 📂 Directory Structure
```
+.
+├── .config/ # Application configs (copied to ~/.config/)
+│ ├── hammerspoon/ # Hammerspoon automation
+│ ├── karabiner/ # Karabiner-Elements key mappings
+│ ├── raycast/ # Raycast shortcuts
+│ ├── starship.toml # Starship prompt config
+│ └── wezterm/ # WezTerm terminal config
+├── .zsh/ # Modular Zsh configuration
+│ ├── alias.zsh # Command aliases
+│ ├── env.zsh # Environment variables
+│ ├── plugin.zsh # Zsh plugins
+│ └── style.zsh # Shell appearance
+├── installers/ # Installation scripts
+├── scripts/ # Utility scripts
+│ ├── collect_environment.sh # Collect system info
+│ └── update_readme.py # Update README with env info
+├── settings/ # Platform-specific settings
+│ ├── macos/ # macOS system preferences
+│ ├── vscode/ # VSCode settings & extensions
+│ └── xcode/ # Xcode themes & templates
+├── .Brewfile # Homebrew bundle definition
+├── .commit_template # Git commit template
+├── .gitconfig # Git configuration
+├── .tmux.conf # Tmux configuration
+├── .zshrc # Main shell configuration
+├── CLAUDE.md # AI assistant instructions
+├── README.md # This file (auto-generated from template)
+├── README.template.md # Template for README generation
+└── Makefile # Installation orchestrator
+```
+
+## 🎯 What's Included
+
+### Development Tools
+
+- **Package Managers**: Homebrew, mise (for version management)
+- **Shell**: Zsh with zplug, Starship prompt
+- **Terminal**: WezTerm, tmux
+- **Editors**: Neovim, VSCode
+- **Version Control**: Git, GitHub CLI, Lazygit
+
+### Development Stacks
+
+- **iOS Development**: Xcode, XcodeGen, Mint, SwiftLint, SwiftFormat
+- **Flutter Development**: Flutter SDK, Dart, FVM
+- **Web Development**: Node.js (via n), npm packages
+- **General**: Go, Rust, Ruby
+
+### macOS Applications
+
+- **Productivity**: Raycast, Hammerspoon, Karabiner-Elements
+- **Development**: Docker, Orbstack, TablePlus, Fork
+- **Communication**: Slack, Discord, Zoom
+- **Utilities**: 1Password, AppCleaner, The Unarchiver
+
+## ⚙️ Configuration
+
+### Zsh
+
+The shell configuration is modular and organized in `.zsh/`:
+
+- `alias.zsh`: Custom command aliases
+- `env.zsh`: Environment variables and PATH setup
+- `plugin.zsh`: Zsh plugin configuration
+- `style.zsh`: Prompt and appearance settings
+
+### Git
+
+Custom Git configuration includes:
+- Commit template for consistent commit messages
+- Useful aliases and shortcuts
+- GitHub CLI integration
+
+### Tmux
+
+Pre-configured with:
+- Custom key bindings
+- Status bar configuration
+- Plugin management via TPM
+
+### Vim/Neovim
+
+Vim configuration includes:
+
+#### Coc Extensions
+
+Install extensions using:
+
+```vim
:CocInstall {extension-name}
```
-- coc-flutter
+Included extensions:
+- coc-flutter - Flutter/Dart language support
+
+## 🔧 Customization
+
+1. **Fork this repository** to create your own version
+2. **Edit configuration files** to match your preferences:
+ - Modify `.Brewfile` to add/remove packages
+ - Update `.zsh/alias.zsh` for custom aliases
+ - Adjust `.gitconfig` with your user information
+3. **Add your own dotfiles** - they'll be automatically symlinked
+4. **Customize installers** in the `installers/` directory
+
+## 📝 Make Commands
+
+```bash
+make all # Install everything
+make install # Install dotfiles only
+make deps # Install dependencies only
+make list # List all dotfiles to be installed
+make help # Show available commands
+```
+
+## 🤝 Contributing
+
+Feel free to open issues or submit pull requests if you have suggestions for improvements.
+
+## 📄 License
+
+This repository is available under the MIT License. Feel free to fork and modify for your own use.
+
+## 🙏 Acknowledgments
+
+Inspired by the dotfiles community and various developers who share their configurations publicly.
\ No newline at end of file
diff --git a/README.template.md b/README.template.md
new file mode 100644
index 0000000..c86d32c
--- /dev/null
+++ b/README.template.md
@@ -0,0 +1,213 @@
+# dotfiles
+
+My personal dotfiles for macOS development environment setup. This repository contains configurations for various development tools and automated installation scripts.
+
+## 🚀 Quick Start
+
+```bash
+# Clone the repository
+git clone https://github.com/ry-itto/dotfiles.git ~/ghq/github.com/ry-itto/dotfiles
+cd ~/ghq/github.com/ry-itto/dotfiles
+
+# Install everything (dotfiles + dependencies)
+make all
+```
+
+## 📋 Requirements
+
+- macOS (tested on macOS 14+)
+- Command Line Tools for Xcode
+- Internet connection for downloading packages
+
+
+## 📦 Package Configuration
+
+> **Tested on**: {{OS_NAME}} {{OS_VERSION}} ({{ARCH}}) - Last updated: {{UPDATED_AT}}
+
+The following packages are defined in `.Brewfile` for installation:
+
+
+🛠️ Homebrew Formulae ({{FORMULAE_COUNT}} packages)
+
+{{FORMULAE_LIST}}
+
+
+
+
+🖥️ Homebrew Casks - GUI Applications ({{CASKS_COUNT}} apps)
+
+{{CASKS_LIST}}
+
+
+
+
+## 🛠 Installation
+
+### Full Installation (Recommended)
+
+Installs all dotfiles and dependencies:
+
+```bash
+make all
+```
+
+### Partial Installation
+
+Install only dotfiles (symlinks and configs):
+
+```bash
+make install
+```
+
+Install only dependencies (Homebrew, tools, etc.):
+
+```bash
+make deps
+```
+
+### Manual Installation
+
+You can also run individual installer scripts as needed:
+
+```bash
+# Install Homebrew and packages
+/bin/zsh installers/brew.sh
+
+# Install development tools
+/bin/zsh installers/mise.sh # Version management
+/bin/zsh installers/flutter.sh # Flutter SDK
+/bin/zsh installers/rust.sh # Rust toolchain
+/bin/zsh installers/vim.sh # Vim plugins
+/bin/zsh installers/xcode.sh # Xcode tools
+/bin/zsh installers/zplug.sh # Zsh plugin manager
+```
+
+## 📂 Directory Structure
+
+```
+.
+├── .config/ # Application configs (copied to ~/.config/)
+│ ├── hammerspoon/ # Hammerspoon automation
+│ ├── karabiner/ # Karabiner-Elements key mappings
+│ ├── raycast/ # Raycast shortcuts
+│ ├── starship.toml # Starship prompt config
+│ └── wezterm/ # WezTerm terminal config
+├── .zsh/ # Modular Zsh configuration
+│ ├── alias.zsh # Command aliases
+│ ├── env.zsh # Environment variables
+│ ├── plugin.zsh # Zsh plugins
+│ └── style.zsh # Shell appearance
+├── installers/ # Installation scripts
+├── scripts/ # Utility scripts
+│ ├── collect_environment.sh # Collect system info
+│ └── update_readme.py # Update README with env info
+├── settings/ # Platform-specific settings
+│ ├── macos/ # macOS system preferences
+│ ├── vscode/ # VSCode settings & extensions
+│ └── xcode/ # Xcode themes & templates
+├── .Brewfile # Homebrew bundle definition
+├── .commit_template # Git commit template
+├── .gitconfig # Git configuration
+├── .tmux.conf # Tmux configuration
+├── .zshrc # Main shell configuration
+├── CLAUDE.md # AI assistant instructions
+├── README.md # This file (auto-generated from template)
+├── README.template.md # Template for README generation
+└── Makefile # Installation orchestrator
+```
+
+## 🎯 What's Included
+
+### Development Tools
+
+- **Package Managers**: Homebrew, mise (for version management)
+- **Shell**: Zsh with zplug, Starship prompt
+- **Terminal**: WezTerm, tmux
+- **Editors**: Neovim, VSCode
+- **Version Control**: Git, GitHub CLI, Lazygit
+
+### Development Stacks
+
+- **iOS Development**: Xcode, XcodeGen, Mint, SwiftLint, SwiftFormat
+- **Flutter Development**: Flutter SDK, Dart, FVM
+- **Web Development**: Node.js (via n), npm packages
+- **General**: Go, Rust, Ruby
+
+### macOS Applications
+
+- **Productivity**: Raycast, Hammerspoon, Karabiner-Elements
+- **Development**: Docker, Orbstack, TablePlus, Fork
+- **Communication**: Slack, Discord, Zoom
+- **Utilities**: 1Password, AppCleaner, The Unarchiver
+
+## ⚙️ Configuration
+
+### Zsh
+
+The shell configuration is modular and organized in `.zsh/`:
+
+- `alias.zsh`: Custom command aliases
+- `env.zsh`: Environment variables and PATH setup
+- `plugin.zsh`: Zsh plugin configuration
+- `style.zsh`: Prompt and appearance settings
+
+### Git
+
+Custom Git configuration includes:
+- Commit template for consistent commit messages
+- Useful aliases and shortcuts
+- GitHub CLI integration
+
+### Tmux
+
+Pre-configured with:
+- Custom key bindings
+- Status bar configuration
+- Plugin management via TPM
+
+### Vim/Neovim
+
+Vim configuration includes:
+
+#### Coc Extensions
+
+Install extensions using:
+
+```vim
+:CocInstall {extension-name}
+```
+
+Included extensions:
+- coc-flutter - Flutter/Dart language support
+
+## 🔧 Customization
+
+1. **Fork this repository** to create your own version
+2. **Edit configuration files** to match your preferences:
+ - Modify `.Brewfile` to add/remove packages
+ - Update `.zsh/alias.zsh` for custom aliases
+ - Adjust `.gitconfig` with your user information
+3. **Add your own dotfiles** - they'll be automatically symlinked
+4. **Customize installers** in the `installers/` directory
+
+## 📝 Make Commands
+
+```bash
+make all # Install everything
+make install # Install dotfiles only
+make deps # Install dependencies only
+make list # List all dotfiles to be installed
+make help # Show available commands
+```
+
+## 🤝 Contributing
+
+Feel free to open issues or submit pull requests if you have suggestions for improvements.
+
+## 📄 License
+
+This repository is available under the MIT License. Feel free to fork and modify for your own use.
+
+## 🙏 Acknowledgments
+
+Inspired by the dotfiles community and various developers who share their configurations publicly.
\ No newline at end of file
diff --git a/scripts/collect_environment.sh b/scripts/collect_environment.sh
new file mode 100755
index 0000000..c4c16fa
--- /dev/null
+++ b/scripts/collect_environment.sh
@@ -0,0 +1,196 @@
+#!/bin/zsh
+
+# Collect environment information for README
+# This script outputs JSON format for easy parsing
+
+set -e
+
+# Initialize JSON output
+echo "{"
+
+# System Information
+echo ' "system": {'
+echo ' "os": "'$(sw_vers -productName)'",'
+echo ' "version": "'$(sw_vers -productVersion)'",'
+echo ' "arch": "'$(uname -m)'",'
+echo ' "kernel": "'$(uname -r)'"'
+echo ' },'
+
+# Homebrew packages
+echo ' "homebrew": {'
+if command -v brew &> /dev/null; then
+ echo ' "version": "'$(brew --version | head -n1 | cut -d' ' -f2)'",'
+ echo ' "formulae": ['
+
+ # Get installed formulae with versions
+ first=true
+ brew list --formula --versions | while IFS= read -r line; do
+ if [ "$first" = true ]; then
+ first=false
+ else
+ echo ","
+ fi
+ name=$(echo "$line" | cut -d' ' -f1)
+ version=$(echo "$line" | cut -d' ' -f2-)
+ printf ' {"name": "%s", "version": "%s"}' "$name" "$version"
+ done
+
+ echo ''
+ echo ' ],'
+ echo ' "casks": ['
+
+ # Get installed casks
+ first=true
+ brew list --cask --versions 2>/dev/null | while IFS= read -r line; do
+ if [ "$first" = true ]; then
+ first=false
+ else
+ echo ","
+ fi
+ name=$(echo "$line" | cut -d' ' -f1)
+ version=$(echo "$line" | cut -d' ' -f2-)
+ printf ' {"name": "%s", "version": "%s"}' "$name" "$version"
+ done
+
+ echo ''
+ echo ' ]'
+else
+ echo ' "version": "not installed",'
+ echo ' "formulae": [],'
+ echo ' "casks": []'
+fi
+echo ' },'
+
+# Programming Languages and Tools
+echo ' "languages": {'
+
+# Node.js
+if command -v node &> /dev/null; then
+ echo ' "node": "'$(node --version)'",'
+else
+ echo ' "node": "not installed",'
+fi
+
+# npm
+if command -v npm &> /dev/null; then
+ echo ' "npm": "'$(npm --version)'",'
+else
+ echo ' "npm": "not installed",'
+fi
+
+# Python
+if command -v python3 &> /dev/null; then
+ echo ' "python": "'$(python3 --version 2>&1 | cut -d' ' -f2)'",'
+else
+ echo ' "python": "not installed",'
+fi
+
+# Ruby
+if command -v ruby &> /dev/null; then
+ echo ' "ruby": "'$(ruby --version | cut -d' ' -f2)'",'
+else
+ echo ' "ruby": "not installed",'
+fi
+
+# Go
+if command -v go &> /dev/null; then
+ echo ' "go": "'$(go version | cut -d' ' -f3 | sed 's/go//')'",'
+else
+ echo ' "go": "not installed",'
+fi
+
+# Rust
+if command -v rustc &> /dev/null; then
+ echo ' "rust": "'$(rustc --version | cut -d' ' -f2)'",'
+else
+ echo ' "rust": "not installed",'
+fi
+
+# Dart
+if command -v dart &> /dev/null; then
+ echo ' "dart": "'$(dart --version 2>&1 | cut -d' ' -f4)'",'
+else
+ echo ' "dart": "not installed",'
+fi
+
+# Flutter
+if command -v flutter &> /dev/null; then
+ flutter_version=$(flutter --version 2>/dev/null | head -n1 | cut -d' ' -f2)
+ echo ' "flutter": "'$flutter_version'"'
+else
+ echo ' "flutter": "not installed"'
+fi
+
+echo ' },'
+
+# Development Tools
+echo ' "tools": {'
+
+# Git
+if command -v git &> /dev/null; then
+ echo ' "git": "'$(git --version | cut -d' ' -f3)'",'
+else
+ echo ' "git": "not installed",'
+fi
+
+# Docker
+if command -v docker &> /dev/null; then
+ echo ' "docker": "'$(docker --version | cut -d' ' -f3 | sed 's/,//')'",'
+else
+ echo ' "docker": "not installed",'
+fi
+
+# tmux
+if command -v tmux &> /dev/null; then
+ echo ' "tmux": "'$(tmux -V | cut -d' ' -f2)'",'
+else
+ echo ' "tmux": "not installed",'
+fi
+
+# Neovim
+if command -v nvim &> /dev/null; then
+ echo ' "neovim": "'$(nvim --version | head -n1 | cut -d' ' -f2)'",'
+else
+ echo ' "neovim": "not installed",'
+fi
+
+# Starship
+if command -v starship &> /dev/null; then
+ echo ' "starship": "'$(starship --version | head -n1 | cut -d' ' -f2)'",'
+else
+ echo ' "starship": "not installed",'
+fi
+
+# GitHub CLI
+if command -v gh &> /dev/null; then
+ echo ' "gh": "'$(gh --version | head -n1 | cut -d' ' -f3)'",'
+else
+ echo ' "gh": "not installed",'
+fi
+
+# mise
+if command -v mise &> /dev/null; then
+ echo ' "mise": "'$(mise --version 2>&1 | cut -d' ' -f2)'",'
+else
+ echo ' "mise": "not installed",'
+fi
+
+# fzf
+if command -v fzf &> /dev/null; then
+ echo ' "fzf": "'$(fzf --version | cut -d' ' -f1)'"'
+else
+ echo ' "fzf": "not installed"'
+fi
+
+echo ' },'
+
+# Shell Information
+echo ' "shell": {'
+echo ' "default": "'$SHELL'",'
+echo ' "zsh_version": "'$ZSH_VERSION'"'
+echo ' },'
+
+# Timestamp
+echo ' "updated_at": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"'
+
+echo "}"
\ No newline at end of file
diff --git a/scripts/parse_brewfile.py b/scripts/parse_brewfile.py
new file mode 100755
index 0000000..897ef04
--- /dev/null
+++ b/scripts/parse_brewfile.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python3
+
+import re
+import json
+from pathlib import Path
+
+def parse_brewfile():
+ """Parse .Brewfile and extract package information with categories"""
+ brewfile_path = Path(__file__).parent.parent / ".Brewfile"
+
+ if not brewfile_path.exists():
+ return {"formulae": {}, "casks": {}}
+
+ with open(brewfile_path, 'r') as f:
+ lines = f.readlines()
+
+ result = {
+ "formulae": {},
+ "casks": {}
+ }
+
+ current_category = "Uncategorized"
+
+ for line in lines:
+ line = line.strip()
+
+ # Skip empty lines
+ if not line:
+ continue
+
+ # Detect category comments
+ if line.startswith('#'):
+ current_category = line[1:].strip()
+ continue
+
+ # Parse brew formula
+ brew_match = re.match(r'brew\s+[\'"]([^\'",]+)[\'"](?:,\s*args:\s*\[(.*?)\])?', line)
+ if brew_match:
+ package = brew_match.group(1)
+ args = brew_match.group(2)
+
+ if current_category not in result["formulae"]:
+ result["formulae"][current_category] = []
+
+ package_info = {"name": package}
+
+ # Check for specific version or special args
+ if args:
+ if "HEAD" in args:
+ package_info["version"] = "HEAD"
+ # Add other args parsing if needed
+ package_info["args"] = args
+
+ result["formulae"][current_category].append(package_info)
+ continue
+
+ # Parse cask
+ cask_match = re.match(r'cask\s+[\'"]([^\'",]+)[\'"]', line)
+ if cask_match:
+ package = cask_match.group(1)
+
+ if current_category not in result["casks"]:
+ result["casks"][current_category] = []
+
+ result["casks"][current_category].append({"name": package})
+
+ return result
+
+def get_package_descriptions():
+ """Define descriptions for common packages"""
+ return {
+ # Shell & Terminal
+ "zsh": "Z shell - Modern shell with advanced features",
+ "zplug": "Zsh plugin manager",
+ "tmux": "Terminal multiplexer",
+ "starship": "Cross-shell prompt",
+ "wezterm": "GPU-accelerated terminal emulator",
+
+ # iOS Development
+ "xcodegen": "Generate Xcode projects from spec files",
+ "xcbeautify": "Xcode build output formatter",
+ "mint": "Swift package manager for command line tools",
+
+ # Flutter/Mobile
+ "usbmuxd": "USB multiplexing daemon for iOS devices",
+ "libimobiledevice": "iOS device communication library",
+ "ideviceinstaller": "Manage iOS apps from command line",
+ "ios-deploy": "Install and debug iOS apps from command line",
+
+ # Version Management
+ "mise": "Development environment manager (formerly rtx)",
+ "n": "Node.js version manager",
+
+ # Git & Source Control
+ "git": "Distributed version control system",
+ "gh": "GitHub CLI",
+ "ghq": "Git repository organizer",
+ "tig": "Text-mode interface for git",
+ "lazygit": "Terminal UI for git commands",
+
+ # Search & Navigation
+ "ag": "The Silver Searcher - Fast code searching",
+ "fzf": "Fuzzy finder for command line",
+ "tree": "Display directory tree structure",
+
+ # Development Tools
+ "nvim": "Neovim - Hyperextensible Vim-based text editor",
+ "jq": "JSON processor",
+ "nkf": "Network Kanji Filter - Character encoding converter",
+ "emojify": "Emoji on the command line",
+ "act": "Run GitHub Actions locally",
+ "uv": "Fast Python package installer and resolver",
+
+ # Language Support
+ "protobuf": "Protocol Buffers - Google's data interchange format",
+ "openssl@3": "Cryptography and SSL/TLS toolkit",
+ "readline": "GNU readline library",
+ "libyaml": "YAML parser and emitter library",
+ "autoconf": "Automatic configure script builder",
+ "gmp": "GNU multiple precision arithmetic library",
+
+ # GUI Applications
+ "clipy": "Clipboard manager",
+ "raycast": "Productivity launcher",
+ "rectangle": "Window management app",
+ "hammerspoon": "Desktop automation tool",
+ "notion": "All-in-one workspace",
+ "notion-calendar": "Calendar app by Notion",
+ "figma": "Collaborative design tool",
+ "discord": "Voice, video, and text chat",
+
+ # Fonts
+ "font-hack-nerd-font": "Hack font with Nerd Font patches",
+ "font-hackgen": "Japanese programming font",
+ "font-hackgen-nerd": "HackGen with Nerd Font patches",
+ }
+
+def main():
+ """Main function to output parsed Brewfile data"""
+ data = parse_brewfile()
+ descriptions = get_package_descriptions()
+
+ # Enhance with descriptions
+ for category, packages in data["formulae"].items():
+ for package in packages:
+ if package["name"] in descriptions:
+ package["description"] = descriptions[package["name"]]
+
+ for category, packages in data["casks"].items():
+ for package in packages:
+ if package["name"] in descriptions:
+ package["description"] = descriptions[package["name"]]
+
+ print(json.dumps(data, indent=2, ensure_ascii=False))
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/scripts/update_readme.py b/scripts/update_readme.py
new file mode 100755
index 0000000..27a5cd5
--- /dev/null
+++ b/scripts/update_readme.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python3
+
+import json
+import sys
+import subprocess
+from datetime import datetime
+from pathlib import Path
+
+def run_command(cmd):
+ """Run a shell command and return output"""
+ try:
+ result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
+ return result.stdout.strip()
+ except Exception as e:
+ print(f"Error running command '{cmd}': {e}", file=sys.stderr)
+ return None
+
+def collect_environment():
+ """Collect environment information"""
+ script_path = Path(__file__).parent / "collect_environment.sh"
+ output = run_command(f"zsh {script_path}")
+ if output:
+ try:
+ return json.loads(output)
+ except json.JSONDecodeError as e:
+ print(f"Error parsing JSON: {e}", file=sys.stderr)
+ print(f"Output was: {output}", file=sys.stderr)
+ return None
+
+def parse_brewfile():
+ """Parse .Brewfile to get intended packages"""
+ script_path = Path(__file__).parent / "parse_brewfile.py"
+ output = run_command(f"python3 {script_path}")
+ if output:
+ try:
+ return json.loads(output)
+ except json.JSONDecodeError as e:
+ print(f"Error parsing Brewfile JSON: {e}", file=sys.stderr)
+ return {"formulae": {}, "casks": {}}
+
+def format_languages_table(languages):
+ """Format programming languages as a markdown table"""
+ lines = ["| Language | Version |", "|----------|---------|"]
+
+ lang_display = {
+ "node": "Node.js",
+ "npm": "npm",
+ "python": "Python",
+ "ruby": "Ruby",
+ "go": "Go",
+ "rust": "Rust",
+ "dart": "Dart",
+ "flutter": "Flutter"
+ }
+
+ for key, version in languages.items():
+ if version != "not installed":
+ display_name = lang_display.get(key, key.title())
+ lines.append(f"| {display_name} | `{version}` |")
+
+ return "\n".join(lines)
+
+def format_tools_table(tools):
+ """Format development tools as a markdown table"""
+ lines = ["| Tool | Version |", "|------|---------|"]
+
+ tool_display = {
+ "git": "Git",
+ "docker": "Docker",
+ "tmux": "tmux",
+ "neovim": "Neovim",
+ "starship": "Starship",
+ "gh": "GitHub CLI",
+ "mise": "mise",
+ "fzf": "fzf"
+ }
+
+ for key, version in tools.items():
+ if version != "not installed":
+ display_name = tool_display.get(key, key.title())
+ lines.append(f"| {display_name} | `{version}` |")
+
+ return "\n".join(lines)
+
+def format_brewfile_packages(brewfile_data, package_type="formulae"):
+ """Format packages from Brewfile with categories and descriptions"""
+ packages = brewfile_data.get(package_type, {})
+
+ if not packages:
+ return f"*No {package_type} defined*"
+
+ lines = []
+
+ for category, items in packages.items():
+ if not items:
+ continue
+
+ # Add category header
+ lines.append(f"\n**{category}**\n")
+
+ for item in items:
+ name = item['name']
+ description = item.get('description', '')
+ version = item.get('version', '')
+
+ # Format the line
+ if version and version != 'unknown':
+ if version == 'HEAD':
+ line = f"- `{name}` (latest development version)"
+ else:
+ line = f"- `{name}` (v{version})"
+ else:
+ line = f"- `{name}`"
+
+ # Add description if available
+ if description:
+ line += f" - {description}"
+
+ lines.append(line)
+
+ return "\n".join(lines)
+
+def update_readme(env_data, brewfile_data):
+ """Update README.md with environment information"""
+ template_path = Path(__file__).parent.parent / "README.template.md"
+ readme_path = Path(__file__).parent.parent / "README.md"
+
+ if not template_path.exists():
+ print(f"Template file not found: {template_path}", file=sys.stderr)
+ return False
+
+ # Read template
+ with open(template_path, 'r') as f:
+ content = f.read()
+
+ # Count total packages from Brewfile
+ formulae_count = sum(len(items) for items in brewfile_data.get('formulae', {}).values())
+ casks_count = sum(len(items) for items in brewfile_data.get('casks', {}).values())
+
+ # Prepare replacement values
+ replacements = {
+ "{{OS_NAME}}": env_data['system']['os'],
+ "{{OS_VERSION}}": env_data['system']['version'],
+ "{{ARCH}}": env_data['system']['arch'],
+ "{{UPDATED_AT}}": datetime.fromisoformat(env_data['updated_at'].replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M UTC'),
+ "{{FORMULAE_COUNT}}": str(formulae_count),
+ "{{FORMULAE_LIST}}": format_brewfile_packages(brewfile_data, "formulae"),
+ "{{CASKS_COUNT}}": str(casks_count),
+ "{{CASKS_LIST}}": format_brewfile_packages(brewfile_data, "casks")
+ }
+
+ # Replace placeholders
+ for placeholder, value in replacements.items():
+ content = content.replace(placeholder, value)
+
+ # Write updated README
+ with open(readme_path, 'w') as f:
+ f.write(content)
+
+ print(f"✅ README.md updated successfully")
+ print(f" - Environment: {env_data['system']['os']} {env_data['system']['version']} ({env_data['system']['arch']})")
+ print(f" - {formulae_count} Homebrew formulae defined in .Brewfile")
+ print(f" - {casks_count} Homebrew casks defined in .Brewfile")
+
+ return True
+
+def main():
+ """Main function"""
+ print("📊 Collecting environment information...")
+ env_data = collect_environment()
+
+ if not env_data:
+ print("❌ Failed to collect environment information", file=sys.stderr)
+ sys.exit(1)
+
+ print("📦 Parsing .Brewfile...")
+ brewfile_data = parse_brewfile()
+
+ print("📝 Updating README.md...")
+ if update_readme(env_data, brewfile_data):
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
From a05fb779ccedf02bea25c86ea620b4f70af8f546 Mon Sep 17 00:00:00 2001
From: ryoya ito <30540303+ry-itto@users.noreply.github.com>
Date: Wed, 20 Aug 2025 17:43:43 +0900
Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AA?=
=?UTF-8?q?=E3=82=B9=E3=82=AF=E3=83=AA=E3=83=97=E3=83=88=E3=82=92=E5=89=8A?=
=?UTF-8?q?=E9=99=A4=E3=81=97=E3=81=A6=E3=82=B7=E3=83=B3=E3=83=97=E3=83=AB?=
=?UTF-8?q?=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- collect_environment.shを削除(システム情報はPythonで直接取得)
- update_readme.pyから未使用の関数を削除
- システム情報取得をget_system_info()に統合
動作は変わらず、コードがシンプルになりました。
---
README.md | 2 +-
scripts/collect_environment.sh | 196 ---------------------------------
scripts/update_readme.py | 95 +++++-----------
3 files changed, 28 insertions(+), 265 deletions(-)
delete mode 100755 scripts/collect_environment.sh
diff --git a/README.md b/README.md
index 424dd95..e28e7ee 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ make all
## 📦 Package Configuration
-> **Tested on**: macOS 15.5 (arm64) - Last updated: 2025-08-20 08:18 UTC
+> **Tested on**: macOS 15.5 (arm64) - Last updated: 2025-08-20 08:41 UTC
The following packages are defined in `.Brewfile` for installation:
diff --git a/scripts/collect_environment.sh b/scripts/collect_environment.sh
deleted file mode 100755
index c4c16fa..0000000
--- a/scripts/collect_environment.sh
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/bin/zsh
-
-# Collect environment information for README
-# This script outputs JSON format for easy parsing
-
-set -e
-
-# Initialize JSON output
-echo "{"
-
-# System Information
-echo ' "system": {'
-echo ' "os": "'$(sw_vers -productName)'",'
-echo ' "version": "'$(sw_vers -productVersion)'",'
-echo ' "arch": "'$(uname -m)'",'
-echo ' "kernel": "'$(uname -r)'"'
-echo ' },'
-
-# Homebrew packages
-echo ' "homebrew": {'
-if command -v brew &> /dev/null; then
- echo ' "version": "'$(brew --version | head -n1 | cut -d' ' -f2)'",'
- echo ' "formulae": ['
-
- # Get installed formulae with versions
- first=true
- brew list --formula --versions | while IFS= read -r line; do
- if [ "$first" = true ]; then
- first=false
- else
- echo ","
- fi
- name=$(echo "$line" | cut -d' ' -f1)
- version=$(echo "$line" | cut -d' ' -f2-)
- printf ' {"name": "%s", "version": "%s"}' "$name" "$version"
- done
-
- echo ''
- echo ' ],'
- echo ' "casks": ['
-
- # Get installed casks
- first=true
- brew list --cask --versions 2>/dev/null | while IFS= read -r line; do
- if [ "$first" = true ]; then
- first=false
- else
- echo ","
- fi
- name=$(echo "$line" | cut -d' ' -f1)
- version=$(echo "$line" | cut -d' ' -f2-)
- printf ' {"name": "%s", "version": "%s"}' "$name" "$version"
- done
-
- echo ''
- echo ' ]'
-else
- echo ' "version": "not installed",'
- echo ' "formulae": [],'
- echo ' "casks": []'
-fi
-echo ' },'
-
-# Programming Languages and Tools
-echo ' "languages": {'
-
-# Node.js
-if command -v node &> /dev/null; then
- echo ' "node": "'$(node --version)'",'
-else
- echo ' "node": "not installed",'
-fi
-
-# npm
-if command -v npm &> /dev/null; then
- echo ' "npm": "'$(npm --version)'",'
-else
- echo ' "npm": "not installed",'
-fi
-
-# Python
-if command -v python3 &> /dev/null; then
- echo ' "python": "'$(python3 --version 2>&1 | cut -d' ' -f2)'",'
-else
- echo ' "python": "not installed",'
-fi
-
-# Ruby
-if command -v ruby &> /dev/null; then
- echo ' "ruby": "'$(ruby --version | cut -d' ' -f2)'",'
-else
- echo ' "ruby": "not installed",'
-fi
-
-# Go
-if command -v go &> /dev/null; then
- echo ' "go": "'$(go version | cut -d' ' -f3 | sed 's/go//')'",'
-else
- echo ' "go": "not installed",'
-fi
-
-# Rust
-if command -v rustc &> /dev/null; then
- echo ' "rust": "'$(rustc --version | cut -d' ' -f2)'",'
-else
- echo ' "rust": "not installed",'
-fi
-
-# Dart
-if command -v dart &> /dev/null; then
- echo ' "dart": "'$(dart --version 2>&1 | cut -d' ' -f4)'",'
-else
- echo ' "dart": "not installed",'
-fi
-
-# Flutter
-if command -v flutter &> /dev/null; then
- flutter_version=$(flutter --version 2>/dev/null | head -n1 | cut -d' ' -f2)
- echo ' "flutter": "'$flutter_version'"'
-else
- echo ' "flutter": "not installed"'
-fi
-
-echo ' },'
-
-# Development Tools
-echo ' "tools": {'
-
-# Git
-if command -v git &> /dev/null; then
- echo ' "git": "'$(git --version | cut -d' ' -f3)'",'
-else
- echo ' "git": "not installed",'
-fi
-
-# Docker
-if command -v docker &> /dev/null; then
- echo ' "docker": "'$(docker --version | cut -d' ' -f3 | sed 's/,//')'",'
-else
- echo ' "docker": "not installed",'
-fi
-
-# tmux
-if command -v tmux &> /dev/null; then
- echo ' "tmux": "'$(tmux -V | cut -d' ' -f2)'",'
-else
- echo ' "tmux": "not installed",'
-fi
-
-# Neovim
-if command -v nvim &> /dev/null; then
- echo ' "neovim": "'$(nvim --version | head -n1 | cut -d' ' -f2)'",'
-else
- echo ' "neovim": "not installed",'
-fi
-
-# Starship
-if command -v starship &> /dev/null; then
- echo ' "starship": "'$(starship --version | head -n1 | cut -d' ' -f2)'",'
-else
- echo ' "starship": "not installed",'
-fi
-
-# GitHub CLI
-if command -v gh &> /dev/null; then
- echo ' "gh": "'$(gh --version | head -n1 | cut -d' ' -f3)'",'
-else
- echo ' "gh": "not installed",'
-fi
-
-# mise
-if command -v mise &> /dev/null; then
- echo ' "mise": "'$(mise --version 2>&1 | cut -d' ' -f2)'",'
-else
- echo ' "mise": "not installed",'
-fi
-
-# fzf
-if command -v fzf &> /dev/null; then
- echo ' "fzf": "'$(fzf --version | cut -d' ' -f1)'"'
-else
- echo ' "fzf": "not installed"'
-fi
-
-echo ' },'
-
-# Shell Information
-echo ' "shell": {'
-echo ' "default": "'$SHELL'",'
-echo ' "zsh_version": "'$ZSH_VERSION'"'
-echo ' },'
-
-# Timestamp
-echo ' "updated_at": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"'
-
-echo "}"
\ No newline at end of file
diff --git a/scripts/update_readme.py b/scripts/update_readme.py
index 27a5cd5..ca26580 100755
--- a/scripts/update_readme.py
+++ b/scripts/update_readme.py
@@ -3,6 +3,7 @@
import json
import sys
import subprocess
+import platform
from datetime import datetime
from pathlib import Path
@@ -15,17 +16,23 @@ def run_command(cmd):
print(f"Error running command '{cmd}': {e}", file=sys.stderr)
return None
-def collect_environment():
- """Collect environment information"""
- script_path = Path(__file__).parent / "collect_environment.sh"
- output = run_command(f"zsh {script_path}")
- if output:
- try:
- return json.loads(output)
- except json.JSONDecodeError as e:
- print(f"Error parsing JSON: {e}", file=sys.stderr)
- print(f"Output was: {output}", file=sys.stderr)
- return None
+def get_system_info():
+ """Get basic system information"""
+ try:
+ # Get macOS version using sw_vers command
+ os_name = run_command('sw_vers -productName') or platform.system()
+ os_version = run_command('sw_vers -productVersion') or platform.release()
+ except:
+ # Fallback to platform module
+ os_name = platform.system()
+ os_version = platform.release()
+
+ return {
+ 'os': os_name,
+ 'version': os_version,
+ 'arch': platform.machine(),
+ 'updated_at': datetime.utcnow().isoformat() + 'Z'
+ }
def parse_brewfile():
"""Parse .Brewfile to get intended packages"""
@@ -38,50 +45,6 @@ def parse_brewfile():
print(f"Error parsing Brewfile JSON: {e}", file=sys.stderr)
return {"formulae": {}, "casks": {}}
-def format_languages_table(languages):
- """Format programming languages as a markdown table"""
- lines = ["| Language | Version |", "|----------|---------|"]
-
- lang_display = {
- "node": "Node.js",
- "npm": "npm",
- "python": "Python",
- "ruby": "Ruby",
- "go": "Go",
- "rust": "Rust",
- "dart": "Dart",
- "flutter": "Flutter"
- }
-
- for key, version in languages.items():
- if version != "not installed":
- display_name = lang_display.get(key, key.title())
- lines.append(f"| {display_name} | `{version}` |")
-
- return "\n".join(lines)
-
-def format_tools_table(tools):
- """Format development tools as a markdown table"""
- lines = ["| Tool | Version |", "|------|---------|"]
-
- tool_display = {
- "git": "Git",
- "docker": "Docker",
- "tmux": "tmux",
- "neovim": "Neovim",
- "starship": "Starship",
- "gh": "GitHub CLI",
- "mise": "mise",
- "fzf": "fzf"
- }
-
- for key, version in tools.items():
- if version != "not installed":
- display_name = tool_display.get(key, key.title())
- lines.append(f"| {display_name} | `{version}` |")
-
- return "\n".join(lines)
-
def format_brewfile_packages(brewfile_data, package_type="formulae"):
"""Format packages from Brewfile with categories and descriptions"""
packages = brewfile_data.get(package_type, {})
@@ -120,7 +83,7 @@ def format_brewfile_packages(brewfile_data, package_type="formulae"):
return "\n".join(lines)
-def update_readme(env_data, brewfile_data):
+def update_readme(system_info, brewfile_data):
"""Update README.md with environment information"""
template_path = Path(__file__).parent.parent / "README.template.md"
readme_path = Path(__file__).parent.parent / "README.md"
@@ -139,10 +102,10 @@ def update_readme(env_data, brewfile_data):
# Prepare replacement values
replacements = {
- "{{OS_NAME}}": env_data['system']['os'],
- "{{OS_VERSION}}": env_data['system']['version'],
- "{{ARCH}}": env_data['system']['arch'],
- "{{UPDATED_AT}}": datetime.fromisoformat(env_data['updated_at'].replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M UTC'),
+ "{{OS_NAME}}": system_info['os'],
+ "{{OS_VERSION}}": system_info['version'],
+ "{{ARCH}}": system_info['arch'],
+ "{{UPDATED_AT}}": datetime.fromisoformat(system_info['updated_at'].replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M UTC'),
"{{FORMULAE_COUNT}}": str(formulae_count),
"{{FORMULAE_LIST}}": format_brewfile_packages(brewfile_data, "formulae"),
"{{CASKS_COUNT}}": str(casks_count),
@@ -158,7 +121,7 @@ def update_readme(env_data, brewfile_data):
f.write(content)
print(f"✅ README.md updated successfully")
- print(f" - Environment: {env_data['system']['os']} {env_data['system']['version']} ({env_data['system']['arch']})")
+ print(f" - Environment: {system_info['os']} {system_info['version']} ({system_info['arch']})")
print(f" - {formulae_count} Homebrew formulae defined in .Brewfile")
print(f" - {casks_count} Homebrew casks defined in .Brewfile")
@@ -166,18 +129,14 @@ def update_readme(env_data, brewfile_data):
def main():
"""Main function"""
- print("📊 Collecting environment information...")
- env_data = collect_environment()
-
- if not env_data:
- print("❌ Failed to collect environment information", file=sys.stderr)
- sys.exit(1)
+ print("📊 Getting system information...")
+ system_info = get_system_info()
print("📦 Parsing .Brewfile...")
brewfile_data = parse_brewfile()
print("📝 Updating README.md...")
- if update_readme(env_data, brewfile_data):
+ if update_readme(system_info, brewfile_data):
sys.exit(0)
else:
sys.exit(1)