Skip to content

Commit 728e875

Browse files
authored
Merge pull request #142 from thaim/add-claude
add CLAUDE.md
2 parents 0ab2613 + 6b0a3fe commit 728e875

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

CLAUDE.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
Ansible roles collection for automating development environment setup across Ubuntu, macOS, and Debian. Contains ~78 roles for installing/configuring dev tools, languages, and applications.
7+
8+
## Common Commands
9+
10+
### Setup
11+
- `poetry install --sync` — install Python dependencies
12+
- `ansible-galaxy install -r requirements.yml` — install Ansible collections
13+
- `poetry shell` — enter virtual environment
14+
15+
### Running Playbooks
16+
- `poetry run ansible-playbook -i inventories/localhost playbook-desktop.yml`
17+
- Run specific roles: `--tags git,shell`
18+
- Dry run: `--check`
19+
20+
### Linting
21+
- **IMPORTANT**: Always run `poetry run ansible-lint` on modified roles before committing
22+
- Lint specific role: `poetry run ansible-lint roles/ROLE_NAME/tasks/main.yml`
23+
- Syntax check: `ansible-playbook --syntax-check playbook-desktop.yml`
24+
- CI runs ansible-lint on `roles/` via GitHub Actions on every PR
25+
26+
## Architecture
27+
28+
### Playbooks
29+
- `playbook-desktop.yml` — Desktop environment (GUI apps, personal tools)
30+
- `playbook-devel.yml` — Development environment (multi-play, uses host groups: `all`, `webapp`, `devos`, `terraform`)
31+
- `playbook-docker-service.yml` — Docker-based services
32+
- `playbook-gitlab.yml` — GitLab server configuration
33+
34+
Roles are assigned in playbooks with: `{ role: NAME, tags: TAG, VAR: VALUE }`
35+
36+
### Custom Filter Plugin
37+
`filter_plugins/shell_config.py` provides the `shell_config` filter. Usage:
38+
```yaml
39+
- ansible.builtin.set_fact:
40+
shell_info: "{{ ansible_user_shell | shell_config }}"
41+
# Returns: { name: 'bash', rc_file: '.bashrc', profile_path: '.bash_profile' }
42+
# Or for zsh: { name: 'zsh', rc_file: '.zshrc', profile_path: '.zprofile' }
43+
```
44+
45+
## Coding Conventions
46+
47+
### Module Names
48+
Always use fully qualified collection names (FQCN): `ansible.builtin.command`, `ansible.builtin.apt`, etc.
49+
50+
### Variable Naming
51+
- `UPPER_SNAKE_CASE` with role name as prefix: `GOLANG_VERSION`, `DOCKER_USER`, `GIT_INSTALLER`
52+
- Lint enforces: `^[a-z_][a-z0-9_]*$|[A-Z][A-Z0-9_]*$`
53+
54+
### OS-Specific Task Dispatch
55+
Roles split OS-specific logic into separate files dispatched from `tasks/main.yml`:
56+
```yaml
57+
- ansible.builtin.include_tasks: install_{{ ansible_distribution }}.yml
58+
```
59+
File naming: `install_Ubuntu.yml`, `install_MacOSX.yml` (or `install_MacOS.yml`), `install_Debian.yml`
60+
61+
### Install-Check Pattern
62+
Check if a tool is installed before running install tasks:
63+
```yaml
64+
- name: Check if TOOL installed
65+
ansible.builtin.command: which TOOL
66+
register: status_tool
67+
changed_when: false
68+
failed_when: false
69+
70+
- name: Install TOOL
71+
ansible.builtin.include_tasks: install_{{ ansible_distribution }}.yml
72+
when: status_tool.rc != 0
73+
```
74+
75+
### Version Comparison Pattern
76+
For roles that manage tool versions (golang, nodejs, terraform, etc.):
77+
```yaml
78+
- name: Check installed version
79+
ansible.builtin.shell: /bin/bash -lc 'TOOL --version'
80+
changed_when: false
81+
failed_when: false
82+
register: version_check
83+
when: status_tool.rc == 0
84+
85+
- name: Install TOOL
86+
ansible.builtin.include_tasks: install_{{ ansible_distribution }}.yml
87+
when: status_tool.rc != 0 or
88+
version_check.stdout is version(TOOL_VERSION, '<')
89+
```
90+
91+
### Privileged Tasks
92+
Use `become: yes` on tasks requiring root (package installs, system config). Do not set `become` at play level.
93+
94+
### Lint Exceptions
95+
When `shell` is required instead of `command` (e.g., for PATH-aware login shell execution), use inline noqa:
96+
```yaml
97+
# noqa: command-instead-of-shell
98+
```
99+
100+
## Lint Configuration
101+
- `.ansible-lint`: skips `git-latest` rule, excludes `roles/*/files/*`
102+
- `.yamllint`: line length max 160, truthy values `["true", "false", "yes", "no"]`
103+
104+
## Python Environment
105+
- Poetry for dependency management
106+
- Python 3.9+ (< 3.12), ansible-core ^2.15.13
107+
- Required collections: `community.general` 7.4.0, `ansible.posix` 1.5.2

0 commit comments

Comments
 (0)