# Features

<details>

<summary>Explicit Dependency Management</summary>

#### What is Explicit Dependency Management?

In Bazel, **Explicit Dependency Management** means that you must clearly and explicitly list all the dependencies that your build targets need. Unlike some other build systems where dependencies might be inferred automatically, Bazel requires you to specify each dependency directly. The dependency graph in Bazel must always be a **directed acyclic graph** which means <mark style="color:red;">no cycles are allowed</mark>.

#### Basic Idea

* **Clear Declaration:** You must list every file, library, or target your build depends on in your build configuration files. This ensures that Bazel knows exactly what each target needs to build correctly.
* **No Implicit Dependencies:** There is no automatic assumption about what dependencies a target might need based on file locations or other heuristics. Everything must be explicitly stated.

#### Example Scenario

Let’s say you’re working on a project with a library and an application that depends on that library. Here’s how you’d manage dependencies in Bazel:

1. **Project Structure:**

   ```less
   lessCopy codemy_project/
   ├── //app
   │   ├── BUILD.bazel
   │   └── main.py
   └── //lib
       ├── BUILD.bazel
       └── utils.py
   ```
2. **Targets and Dependencies:**
   * **`//lib:utils`** - A target that builds a library with utility functions.
   * **`//app:main`** - A target that builds an application and depends on the utility functions.
3. **Setting Up Explicit Dependencies:**

   **`//lib/BUILD.bazel`**

   ```python
   py_library(
       name = "utils",
       srcs = ["utils.py"],
   )
   ```

   **`//app/BUILD.bazel`**

   ```python
   py_binary(
       name = "main",
       srcs = ["main.py"],
       deps = ["//lib:utils"],  # Explicitly declare the dependency on //lib:utils
   )
   ```

#### Explanation

* **Explicit Declaration:**
  * In the `//lib/BUILD.bazel` file, the `py_library` target `//lib:utils` is defined with its source files. This target represents the library with utility functions.
  * In the `//app/BUILD.bazel` file, the `py_binary` target `//app:main` is defined as a Python binary. The `deps`attribute explicitly lists `//lib:utils` as a dependency. This means that `//app:main` requires `//lib:utils` to build.
* **No Implicit Dependencies:**
  * Bazel doesn’t guess or infer that `//app:main` might need `//lib:utils` based on file paths or other heuristics. You must explicitly state this dependency in the `deps` attribute.

#### Benefits

* **Predictability:** By explicitly declaring all dependencies, you ensure that your build is predictable and reproducible. You know exactly what each target depends on.
* **Clarity:** It makes the build configuration clear and understandable. Anyone looking at the build files can see all the dependencies listed without guessing.
* **Error Prevention:** It reduces the risk of build errors due to missing dependencies. Since everything is declared explicitly, Bazel will catch any missing dependencies and prompt you to fix them.

#### Comparison to Implicit Dependencies

* **Implicit Dependencies:** In some build systems, dependencies might be inferred based on file locations or naming conventions. This can lead to unexpected issues if the system makes incorrect assumptions.
* **Explicit Dependencies (Bazel):** Bazel’s requirement for explicit declarations avoids such issues. You specify exactly what each target needs, which makes the build process more reliable.

#### Summary

**Explicit Dependency Management** in Bazel means you must clearly list every dependency your build targets require. This approach ensures that your build process is predictable, clear, and free from implicit assumptions about what dependencies are needed. By specifying dependencies directly in your build configuration files, you avoid potential issues and make your project easier to manage.

</details>

<details>

<summary>Advanced Visibility Features</summary>

#### What is Visibility in Bazel?

In Bazel, visibility is a feature that allows you to control which parts of your code can access or depend on specific build targets. This helps you manage and restrict how different parts of your project interact with each other, improving modularity and reducing the risk of unintended dependencies.

#### Basic Idea

* **Visibility Control:** You can limit which packages or targets are allowed to depend on a particular target. This way, you can keep certain parts of your codebase hidden from others and only expose what's necessary.

#### Example Scenario

Imagine you have a project with multiple modules:

1. **Project Structure:**

```less
my_project/
├── //frontend
│   ├── BUILD.bazel
│   └── main.py
├── //backend
│   ├── BUILD.bazel
│   └── service.py
└── //shared
    ├── BUILD.bazel
    └── utils.py
```

2. **Targets and Visibility:**
   * **`//frontend:main`** - A target that builds the frontend module.
   * **`//backend:service`** - A target that builds the backend module.
   * **`//shared:utils`** - A target that builds some shared utility functions.
3. **Setting Up Visibility:**
   * You want to allow only the `frontend` module to use the utilities from `shared`, but you don’t want the `backend` module to have access to these utilities.

Here’s how you can set it up in Bazel:

**`//shared/BUILD.bazel`**

```python
pythonCopy codepy_library(
    name = "utils",
    srcs = ["utils.py"],
    visibility = ["//frontend:__pkg__"],  # Only the frontend module can use this target
)
```

**`//frontend/BUILD.bazel`**

```python
pythonCopy codepy_binary(
    name = "main",
    srcs = ["main.py"],
    deps = ["//shared:utils"],  # Can depend on utils
)
```

**`//backend/BUILD.bazel`**

```python
pythonCopy codepy_binary(
    name = "service",
    srcs = ["service.py"],
    # No dependency on //shared:utils, as it's not listed here
)
```

#### Explanation

* **Visibility Declaration:**
  * In the `//shared/BUILD.bazel` file, the `visibility` attribute for `//shared:utils` is set to `["//frontend:__pkg__"]`. This means that only targets in the `frontend` package can see and depend on the `//shared:utils` target.
* **Controlled Access:**
  * The `frontend` module can use the `utils` library because it is explicitly allowed by the visibility setting.
  * The `backend` module cannot access the `utils` library because it’s not listed in the visibility setting. This prevents unintended dependencies and keeps the `backend` module isolated from the `shared` utilities.

#### Benefits

* **Modularity:** By controlling visibility, you can better organize your project and enforce modular design. Each part of the project only has access to the dependencies it needs.
* **Maintainability:** It reduces the risk of changes in one part of the project affecting others unintentionally, making the project easier to maintain and refactor.

#### Summary

Bazel’s visibility feature lets you control which parts of your project can access specific build targets. By using visibility, you can limit dependencies and keep different parts of your codebase modular and isolated, similar to how you might use package visibility in Java or namespaces in C++.

</details>

**TODO:**&#x20;

* Remote Build Execution and Caching
* Build Dependency Analysis
* Fast, Correct Builds (and Tests)
