# pravo providers

List the providers a root resolves, print a provider's schema, pin archive hashes for more platforms and copy a provider to a container registry.

## Quick reference

| | |
|---|---|
| Synopsis | `pravo providers [--json]` |
| | `pravo providers schema LOCAL_NAME` |
| | `pravo providers lock [--platforms os_arch,...]` |
| | `pravo providers copy SOURCE VERSION oci://HOST/PATH/TYPE [--platforms os_arch,...]` |
| Changes infrastructure | No. |
| Taught in | [Upgrade pravo and providers](../how-to/upgrading.md) and [Install providers from your own registry](../how-to/providers-from-a-registry.md). [B1, Providers and resources](../learn/b01-providers-and-resources.md) teaches the declaration. |

| Subcommand | Does | Network |
|---|---|---|
| none | Lists the providers of the root with their versions and paths. | no |
| `schema` | Prints the schema of one provider as CUE. | no |
| `lock` | Records archive hashes of the locked providers for more platforms in `pravo.lock.cue`. | yes |
| `copy` | Publishes one version of a provider to a container registry. | yes |

### Flags

| Flag | Subcommand | Default | Meaning |
|---|---|---|---|
| `--platforms os_arch,...` | `lock`, `copy` | `linux_amd64,linux_arm64,darwin_arm64,darwin_amd64` | The platforms to pin or to publish. |
| `-t`, `--tag key=value`, `-T` | none | none | Tags, as for [`pravo plan`](plan.md). |

The [global flags](global-flags.md) apply. `schema`, `lock` and `copy` take no tags. With `--json`, the list is an array of objects.

### Exit codes

| Code | Meaning |
|---|---|
| 0 | Done. |
| 1 | The provider is not required by the root, a hash that is already pinned differs from the one the source states, or the registry could not be reached. |
| 6 | The specification does not load or evaluate. |

## Examples

Work in an empty directory named `demo`.

```cue file=main.cue
package demo

import (
	rnd "pravo.dev/providers/hashicorp/random"
	loc "pravo.dev/providers/hashicorp/local"
)

$random: rnd.#Provider
$local:  loc.#Provider
```

### List the providers

```sh run
pravo init > /dev/null
pravo providers
```

```text out
local = hashicorp/local v2.9.1
    ~/.pravo/providers/registry.opentofu.org/hashicorp/local/<version>/<os>_<arch>/terraform-provider-local
random = hashicorp/random v3.9.1
    ~/.pravo/providers/registry.opentofu.org/hashicorp/random/<version>/<os>_<arch>/terraform-provider-random
```

Each provider has a line with its local name, its source and its version, and a line with the path of the binary. The list has one entry per source, so two provider structs of one source appear once. A provider that only the state requires is marked `(implied by resource types)`. A provider that runs already, through `$protocol: "tfplugin+reattach"`, shows `reattached at ADDRESS (not started or stopped by pravo)` in place of the path.

```sh run
pravo providers --json | grep -E '"(name|source|version|protocol)"'
```

```text out
    "name": "local",
    "protocol": "tfplugin",
    "source": "registry.opentofu.org/hashicorp/local",
    "version": "2.9.1"
    "name": "random",
    "protocol": "tfplugin",
    "source": "registry.opentofu.org/hashicorp/random",
    "version": "3.9.1"
```

### pravo providers schema

The schema is the generated package that `pravo init` writes for the provider. Pass the local name of the provider as the root declares it.

```sh run
pravo providers schema random | head -n 4
```

```text out
// Provider registry.opentofu.org/hashicorp/random v3.9.1
// Code generated by pravo. DO NOT EDIT.

package random
```

To read one type, use [`pravo schema`](schema.md).

### pravo providers lock

`init` pins the archive hash of the platform it runs on. A CI runner of another platform then installs a provider whose hash is not in the lock file. `lock` adds the hashes for the other platforms from the checksums that the provider source states. It downloads nothing. A hash that is already pinned and differs is an error.

```sh run
pravo providers lock
grep -o '"[a-z]*_[a-z0-9]*"' pravo.lock.cue | sort -u
```

```text out
Pinned 4 platforms in pravo.lock.cue
"darwin_amd64"
"darwin_arm64"
"linux_amd64"
"linux_arm64"
```

### pravo providers copy

`copy` reads one version of a provider from a provider registry or a container registry. It writes the version to a container registry repository that pravo can then use as `$source`. It checks the archives against the checksums the source gives. It does not verify the signature of the release. A published version is never replaced.

```sh
pravo providers copy hashicorp/random 3.6.3 oci://ghcr.io/acme/providers/random
```

On success the command prints `Published`, the target and the version, and the import line to use. It needs credentials for the target registry, so this page does not run it. See [Providers from a registry](../how-to/providers-from-a-registry.md).

## See also

- [`pravo init`](init.md) resolves and installs the providers.
- [Provider declarations](spec-providers.md) describes `$version`, `$path`, `$protocol` and `$address`.
- [Providers](../concepts/providers.md) explains how pravo starts a provider.
