# DarwinPorts APIs

## About This Chapter

DarwinPorts contains two application programming interfaces (APIs), written in Tcl.

The Ports API is an internal API used to run individual Portfiles. The DarwinPorts (dport*) API is a high-level API used by client applications such as DarwinPorts Manager.app or `port`.

## Ports API

The code for the Port API is located in `base/src/port1.0`. The Port API performs the following functions:

- Manages target registrations. All targets register themselves with the Port API. Accordingly, the Port API creates pre-/post-/main overrides for each of the targets.

- Option/Default handling. All `Portfile` options (`name`, `version`, `revision` ...) are registered by targets. The Port API creates procedures for these options, and sets up the complex variable traces necessary to support option defaults.

- Executes target procedures, including the pre/post/main routines.

- Manages a state file containing information about what variants were specified and what targets have run successfully.

- Provides essential portfile primitives (such as `reinplace`).

- Provides simple access to the ui_event mechanism by providing the various ui_ procedures (i.e., `ui_msg`, `ui_error`).

## DarwinPorts API

The code for the DarwinPorts API is located in base/src/darwinports1.0. The DarwinPorts API performs the following functions:

- Dependency implementation. This portion is implemented in a highly generic fashion, and is used throughout the system. The dependency functions are exported to the Port API, and the Port API uses them execute targets in the correct order.

- Software dependencies. Software dependencies are handled at this layer using the dependency implementation.

- UI abstractions. UI Abstractions are handled at this layer. Each port action is provided a context, and a mechanism for posting user interface events is exported to the Port API (`ui_event`).

- Registry management routines. Manages the rudimentary port registry in `${prefix}/var/db/dports/receipts/`.

  - `dportregistry::new`: create a new port registry entry

  - `dportregistry::exists`: check if a port registry entry exists (either versioned or not)

  - `dportregistry::delete`: delete an existing registry entry

  - `dportregistry::close`: closes a new registry entry

- Exports the "darwinports" API for use by client applications:

  - `dportinit`: Initializes the darwinports system. Should be called before trying to use any other procedure

  - `dportsearch`: Given a regexp, searches the PortIndex for ports with matching names

  - `dportopen`: Given a URI to a port, opens the port and returns an opaque handle to it

  - `dportclose`: Given a port handle, closes the port.

  - `dportexec`: Given a port handle, executes a target (i.e. install)

  - `dportinfo`: Given a port handle, this returns the PortInfo array (as a flat list of array elements). This is a little tricky and unstable and only used by the 'portindex' command

  - `dpoprtdepends`: Given a port handle, returns a list of ports the specified port depends upon

An example of how the DarwinPorts API is used:

`dportsearch` returns an arbitrary number of Tcl arrays containing data from the `PortIndex`. The returned data includes the port name, version, revision, epoch, variants, depends, etc. When one executes `port install cm3`, the `port` utility uses the `dportsearch` function to find the first port that matches the name "cm3", uses `dportopen` to open the port, and then uses `dportexec` to execute the install target in the port. Then, it uses `dportclose` to close the port. When one executes `port search cm3`, the port utility uses `dportsearch`, takes the list of arrays, and formats the data for human consumption.