# MacPorts APIs

## About This Chapter

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

The Ports API is an internal API used to run individual Portfiles. The MacPorts (mport*) API is a high-level API used by client applications such as MacPorts 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`).

## MacPorts API

The code for the MacPorts API is located in base/src/macports1.0. The MacPorts 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/mports/receipts/`.

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

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

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

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

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

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

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

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

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

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

  - `mportinfo`: 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

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

An example of how the MacPorts API is used:

`mportsearch` 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 `mportsearch` function to find the first port that matches the name "cm3", uses `mportopen` to open the port, and then uses `mportexec` to execute the install target in the port. Then, it uses `mportclose` to close the port. When one executes `port search cm3`, the port utility uses `mportsearch`, takes the list of arrays, and formats the data for human consumption.