Chapter 1: Introduction to Live Reloading

What is Live Reloading?

Live reloading is a feature that enables your development environment to watch for changes in your code and automatically reload your application. When you save a file, the live reload tool detects the change, rebuilds the application, and restarts it. This saves you from the manual process of stopping the server, rebuilding the application, and starting it again after every change.

Benefits of Live Reloading for Go Development

Live reloading can significantly speed up the development process. For Go developers, who are used to compiling their code before running it, live reloading means an improved workflow with immediate feedback. The benefits include:

  1. Increased Productivity: Developers can stay in the zone without interruption, as they do not need to perform manual rebuilds.
  2. Time Savings: Live reloading reduces the turnaround time for seeing code changes reflected in the running application.
  3. Error Detection: Instant rebuilds and restarts allow developers to detect and correct errors faster.
  4. Streamlined Workflow: Integrates seamlessly into the development process, making it smoother and more efficient.

Chapter 2: What is Air?

Air is a command-line utility designed to provide live reloading capabilities for Go applications. It monitors changes in your source code and automatically rebuilds and restarts your Go application. This means you can focus more on developing features and less on repetitive tasks.

Features

Air provides a range of features suitable for a modern Go development environment:

  • Automatic Rebuilds: Detects file changes and triggers rebuilds.
  • Customizable Build Commands: Allows you to customize the build commands for your project needs.
  • Directory Exclusions: Lets you specify directories to exclude from watching.
  • Support for New Directories: Can watch new directories added after Air has been started.
  • Colorful and Readable Logs: Enhances the readability of output logs with color coding.
  • CLI Arguments: Configuration fields can be set directly through command-line arguments for quick adjustments.

Refer to the developer's provided context for a full list of features and functionalities available with Air.

Chapter 3: Installing air

3.1 Installation via go install

To install Air using the Go toolchain version 1.18 or higher:

go install github.com/cosmtrek/air@latest

This will make air available in your GOPATH/bin.

3.2 Using the install.sh script

Another method is through a provided installation script:

curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

After installation, verify it by running:

air -v

3.3 Special Installations (Docker/Podman and Custom PATH)

For those using Docker or Podman, there's a streamlined way to include Air:

docker run -it --rm \
    -w "/path/to/project" \
    -v $(pwd):/path/to/project \
    -p port:port \
    cosmtrek/air

Replace /path/to/project with your project's path and port:port with the desired port mapping.

Alternatively, for a specific PATH installation:

curl -sSfL https://goblin.run/github.com/cosmtrek/air | PREFIX=/custom/path sh

Chapter 4: Configuring air for Your Go Project

4.1 Understanding .air.toml Configuration

.air.toml is the configuration file for Air. It allows you to specify settings related to the build process, directory monitoring, and log output. Here is a brief overview of key sections:

  • root: Sets the working directory for Air.
  • build: Contains build-related settings such as commands to run before/after building, and the main build command.
  • tmp_dir: The directory where temporary build files are stored.
  • log: Configures the log file settings.
  • color: Customizes the color of each part of the log output.

4.2 Generating and Modifying the Configuration File

To generate a default .air.toml configuration file, run:

air init

This will create a .air.toml with default settings in your current directory. You can then modify it to fit your project's requirements. For reference, you may look at the air_example.toml provided in the context.

4.3 Overwriting Configuration with CLI Arguments

For quick tests or minor changes, you can override the configuration in .air.toml by passing CLI arguments. For example:

air --build.cmd "go build -o myapp" --build.bin "./myapp"

This flexibility allows you to easily customize Air's behavior without changing the configuration file.

Chapter 5: Running air in Your Development Environment

6.1 Starting air in Your Project

To get started with air in your project, navigate to the root directory of your project in your terminal and execute the air command. If a .air.toml configuration file is present, air will automatically use it. Otherwise, it will use the default settings.

cd /path/to/your_project
air

Tip: If you encounter permission issues with the air executable, ensure that it has the necessary execution permissions (chmod +x $(go env GOPATH)/bin/air).

6.2 Customizing Build and Run Commands with air

You can customize the build and run commands used by air by modifying the .air.toml configuration file, specifically under the [build] section. For example, to change the build command and specify a different binary file:

[build]
cmd = "go build -o ./tmp/my-custom-binary ."
bin = "tmp/my-custom-binary"

For more complex build requirements, the pre_cmd and post_cmd arrays in the configuration file allow you to execute commands before and after the build process, respectively.

Tips: A complete example of air configuration

6.3 Excluding Directories and Watching for Changes

air also allows you to exclude directories from being watched for changes, which can be helpful for directories containing assets or dependencies that don't need to trigger a rebuild.

To configure this, update the exclude_dir field in .air.toml:

[build]
exclude_dir = ["assets", "tmp", "vendor", "node_modules"]

You can also instruct air to include additional directories using include_dir, or watch for specific file extensions with include_ext.

Chapter 6: Advanced Usage

6.1 Setting Up air with Docker Containers

Using air within a Docker container can streamline your development setup, especially when working with teams. To include air in your Docker environment, update your Dockerfile to install air and copy your .air.toml into the container:

# Choose a Go image version
FROM golang:1.18-alpine AS builder

# Install air
RUN go install github.com/cosmtrek/air@latest

# Set the working directory
WORKDIR /app

# Copy the go.mod file and download the dependencies
COPY go.mod .
COPY go.sum .
RUN go mod download

# Copy the rest of your source code and the .air.toml configuration
COPY . .

# Run air on container start
CMD ["air", "-c", ".air.toml"]

6.3 Using air in a Docker-compose Environment

To integrate air into a service managed by docker-compose, define a service in your docker-compose.yaml file:

version: '3.8'
services:
  app:
    build: .
    ports:
      - "808:808"
    volumes:
      - .:/app
    command: ["air", "-c", ".air.toml"]

Ensure that the volumes directive is correctly mapping your project directory to the working directory in the container so that air can detect file changes.

Chapter 7: Common Troubleshooting and FAQs

7.1 Fixing command not found: air

If you encounter a command not found: air error, it typically means that the air binary is not in your system's PATH. To resolve this, add the Go binaries path to your PATH environment variable:

export PATH=$PATH:$(go env GOPATH)/bin

7.2 Issues in WSL Environments

In a Windows Subsystem for Linux (WSL) environment, ensure that you're escaping special characters in your .air.toml. For example, use \\ to escape backslashes in file paths.

7.3 Tips on Hot Compilation Without Running the Binary

If you want air to compile your Go application without running it, set the cmd in the [build] section of your .air.toml to a no-operation command (like /bin/true on Unix-based systems):

[build]
cmd = "/bin/true"

By doing this, air will still observe file changes and trigger the build process, but it won't attempt to execute the resulting binary file.