Class: Aircon::CLI
- Inherits:
-
Thor
- Object
- Thor
- Aircon::CLI
- Defined in:
- lib/aircon/cli.rb
Constant Summary collapse
- SAMPLE_CONFIG =
<<~'YAML' # Aircon configuration — ERB is supported (e.g. <%= ENV['GITHUB_TOKEN'] %>) # See: https://github.com/creativesorcery/aircon # Docker Compose file to use (default: .aircon/docker-compose.yml) # compose_file: .aircon/docker-compose.yml # Application name used for database credentials etc. (default: directory basename) # app_name: myapp # GitHub personal access token (supports ERB) # gh_token: <%= ENV['GITHUB_TOKEN'] %> # How to obtain Claude Code credentials: "keychain" (macOS), "file", "oauth_token", or "api_key" # credentials_source: keychain # Claude Code OAuth token — used when credentials_source is "oauth_token" (supports ERB) # Falls back to CLAUDE_CODE_OAUTH_TOKEN env var if not set here. # claude_code_oauth_token: <%= ENV['CLAUDE_CODE_OAUTH_TOKEN'] %> # Anthropic API key — used when credentials_source is "api_key" (supports ERB) # Falls back to ANTHROPIC_API_KEY env var if not set here. # anthropic_api_key: <%= ENV['ANTHROPIC_API_KEY'] %> # Workspace folder path inside the container # workspace_path: /myproject # Path to host's Claude config file # claude_config_path: ~/.claude.json # Path to host's Claude directory # claude_dir_path: ~/.claude # Docker Compose service name for the main container # service: app # Git author identity inside the container # git_email: claude_docker@localhost.com # git_name: Claude Docker # Non-root user inside the container # container_user: appuser # Script to run inside the container after setup (path relative to project root) # Defaults to .aircon/aircon_init.sh — edit that file to add your setup steps. # init_script: .aircon/aircon_init.sh YAML
- INIT_SCRIPT_TEMPLATE =
<<~'BASH' #!/bin/bash # .aircon/aircon_init.sh # # This script runs inside the container after aircon completes its setup. # It is invoked as a login shell (bash -l), so environment variables # configured by aircon are available: # # GH_TOKEN / GITHUB_PERSONAL_ACCESS_TOKEN — GitHub personal access token # CLAUDE_CODE_OAUTH_TOKEN — Claude Code OAuth token # PATH — includes ~/.local/bin (claude, gh, etc.) # # The working directory is the repository root inside the container. # # Examples: # npm install # bundle install # cp .env.example .env BASH
- DOCKERFILE_TEMPLATE =
<<~'DOCKERFILE' FROM ruby:4.0.1 RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - # Add GitHub CLI repository RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null # Install dependencies RUN apt-get update -qq && \ apt-get install -y --no-install-recommends \ bash \ build-essential \ git \ libpq-dev \ postgresql-client \ curl \ libvips \ bubblewrap \ socat \ nodejs \ gh \ && rm -rf /var/lib/apt/lists/* # Make /bin/sh point to bash instead of dash (required for devcontainer features) RUN ln -sf /bin/bash /bin/sh # Ensure bash is the default shell for RUN commands SHELL ["/bin/bash", "-c"] # Create a non-root user ARG USERNAME=appuser ARG USER_UID=1000 ARG USER_GID=$USER_UID ARG WORKSPACE_PATH=/workspace RUN groupadd --gid $USER_GID $USERNAME \ && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ && apt-get update \ && apt-get install -y sudo \ && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ && chmod 0440 /etc/sudoers.d/$USERNAME \ && rm -rf /var/lib/apt/lists/* # Give the container user write access to the gem directory RUN chown -R $USER_UID:$USER_GID /usr/local/bundle RUN npm install -g @anthropic-ai/sandbox-runtime RUN npm install -g yarn RUN npm install -g playwright@1.58.1 RUN playwright install --with-deps chromium COPY --chown=$USERNAME:$USERNAME . $WORKSPACE_PATH USER $USERNAME RUN playwright install chromium WORKDIR $WORKSPACE_PATH RUN bundle install DOCKERFILE
- COMPOSE_TEMPLATE =
<<~'YAML' services: app: image: ${AIRCON_APP_NAME:-aircon}-app:latest build: context: .. dockerfile: .aircon/Dockerfile args: USERNAME: ${AIRCON_CONTAINER_USER:-appuser} WORKSPACE_PATH: ${AIRCON_WORKSPACE_PATH:-/workspace} ports: - "${HOST_PORT:-3001}:3000" command: sleep infinity environment: DATABASE_HOST: db DATABASE_USER: ${AIRCON_APP_NAME:-app} RAILS_ENV: development RAILS_BIND: 0.0.0.0 depends_on: db: condition: service_started db: image: postgres:18 restart: unless-stopped environment: POSTGRES_USER: ${AIRCON_APP_NAME:-app} POSTGRES_HOST_AUTH_METHOD: trust POSTGRES_DB: ${AIRCON_APP_NAME:-app}_development YAML
Class Method Summary collapse
Instance Method Summary collapse
- #down(name) ⇒ Object
- #init ⇒ Object
- #up(name, port = "3001") ⇒ Object
- #version ⇒ Object
- #vscode(name) ⇒ Object
Class Method Details
.exit_on_failure? ⇒ Boolean
8 9 10 |
# File 'lib/aircon/cli.rb', line 8 def self.exit_on_failure? true end |
Instance Method Details
#down(name) ⇒ Object
24 25 26 27 |
# File 'lib/aircon/cli.rb', line 24 def down(name) config = Configuration.new Commands::Down.new(config: config).call(name) end |
#init ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/aircon/cli.rb', line 36 def init FileUtils.mkdir_p(File.join(Dir.pwd, ".aircon")) { "aircon.yml" => SAMPLE_CONFIG, "aircon_init.sh" => INIT_SCRIPT_TEMPLATE, "Dockerfile" => DOCKERFILE_TEMPLATE, "docker-compose.yml" => COMPOSE_TEMPLATE }.each do |filename, content| path = File.join(Dir.pwd, ".aircon", filename) if File.exist?(path) puts "Skipped .aircon/#{filename} (already exists)" else File.write(path, content) puts "Created .aircon/#{filename}" end end end |
#up(name, port = "3001") ⇒ Object
17 18 19 20 21 |
# File 'lib/aircon/cli.rb', line 17 def up(name, port = "3001") config = Configuration.new branch = [:branch] || name Commands::Up.new(config: config).call(name, branch: branch, port: port, detach: [:detach]) end |
#version ⇒ Object
56 57 58 |
# File 'lib/aircon/cli.rb', line 56 def version puts "aircon #{VERSION}" end |