# Oras commands like attach, discover, and pull support an option to format output as JSON
**Status**: Work-in-progress
**Version**: draft
## Overview
The oras cli would benefit from having a JSON formatted output for commands such as `attach`, `discover`, and `pull`. Of course, this can be viewed as a starting point, as the rest of the oras commands could benefit from having such an option.
By enabling an option for a JSON formatted output to **stdout**, oras can improve the developer experience so that automation and scripting can become more dependable.
This option would not supersede the default of human readable, friendly text (similar to docker cli outputs), but would rather be an option such that developers can automate their workflows with oras without needing to rely on parsing text (which can change by version, by environment, by encoding, or other factors).
## What would you like to be added?
An option to format output as JSON for **stdout** for commands like `attach`, `discover`, and `pull` using a `--display json` option.
In the future, you would be able to support other formatting options such as:
1. text
2. json
3. csv
4. yaml
5. tty (this was included per the [github comment](https://github.com/oras-project/oras/issues/638#issuecomment-1295201574))
In order of preference (most preferred first):
1. `oras attach`
2. `oras pull`
3. `oras discover`
### Using a metadata file
You can use a metadata file to output a richer set of data for the container and other artifacts, see an example from [docker](https://docs.docker.com/engine/reference/commandline/buildx_build/#metadata-file).
You have the option to export the artifact metadata file using the flag `--metadata-file <path/to/metadata>`.
For convenience, the example is included here:
```json
{
"containerimage.buildinfo": {
"frontend": "dockerfile.v0",
"attrs": {
"context": "https://github.com/crazy-max/buildkit-buildsources-test.git#master",
"filename": "Dockerfile",
"source": "docker/dockerfile:master"
},
"sources": [
{
"type": "docker-image",
"ref": "docker.io/docker/buildx-bin:0.6.1@sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0",
"pin": "sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0"
},
{
"type": "docker-image",
"ref": "docker.io/library/alpine:3.13",
"pin": "sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c"
}
]
},
"containerimage.config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
"containerimage.descriptor": {
"annotations": {
"config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
"org.opencontainers.image.created": "2022-02-08T21:28:03Z"
},
"digest": "sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 506
},
"containerimage.digest": "sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3"
}
```
For automation purposes, a subset of the metadata file can be pushed to **stdout** as JSON with the ORAS cli using the `--display` flag.
### For oras attach
For `oras attach`, it would also be helpful to get the uploaded `artifactDigest`, `reference`, and `files` along with the other fields described in the below sample output.
Suppose you make the following call:
```shell
# You can make a call to oras attach and display the response in stdout
oras attach "<myacr>.azurecr.io/my/repo:tag" --artifact-type "someArtifactType" <path/to/some/artifact>:<type> --display json
```
And then you would get a JSON output like the following:
```json
{
"digest": "sha256:someHash",
"mediaType": "someType",
"artifactType": "someArtifactType",
"reference" : "<myacr>.azurecr.io/my/repo@sha256:someHash",
"files" : [
"path/to/my/uploaded/artifact.json",
"path/to/my/other/uploaded/artifact.json"
],
"size": sizeInBytes
}
```
### For oras discover
For example, suppose you make the call:
```shell
# You can call oras discover and display the response in stdout as JSON
oras discover <myacr>.azurecr.io/my/repo:tag --display json
```
And then you would get a JSON output like the following in **stdout**:
```json
{
"referrers": [
{
"digest": "sha256:someHash",
"mediaType": "someType",
"artifactType": "someArtifactType",
"reference" : "<myacr>.azurecr.io/my/repo@sha256:someHash",
"size": sizeInBytes
},
]
}
```
This would allow you to pull in the artifact (e.g. `oras pull <reference value>`).
### For oras pull
For `oras pull`, it would be helpful to get the downloaded `artifactType`, `reference`, and `files` along with the other fields described in the below sample output.
Suppose you make the following call:
```shell
# You can use oras pull and display the response in stdout as JSON
oras pull <reference value> --display json
```
And then you would get a JSON output like the following in **stdout**:
```json
{
"digest": "sha256:someHash",
"mediaType": "someType",
"artifactType": "someArtifactType",
"reference" : "<myacr>.azurecr.io/my/repo@sha256:someHash",
"files" : [
"path/to/my/downloaded/artifact.json",
"path/to/another/downloaded/artifact.json"
],
"size": sizeInBytes
}
```
#### Getting output files and displaying formatted JSON
Here's an example which will cover using both the `--output` option to cover the destination folder for the output files, and the `--display JSON` option to display the results as a JSON payload to **stdout**.
Suppose you make the call:
```shell
# You can have output files and display the response in stdout as JSON
oras pull example.contoso.com/myapp:v1 --output Downloads/myapp --display json
```
Then you would get the following JSON output response in **stdout**:
```json
{
"digest": "sha256:01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
"mediaType": "application/vnd.oci.artifact.manifest.v1+json",
"artifactType": "application/vnd.myapp",
"reference" : "example.contoso.com/myapp@sha256:01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
"files" : [
"Downloads/myapp/artifact.json",
"Downloads/myapp/app.tar"
],
"size": 532
}
```
You can then check for your downloaded output files.
```shell
# You can check for your output files
ls Downloads/myapp
artifact.json
app.tar
```
## Why is this needed for ORAS?
This would be helpful for programmatically checking artifact status vs. parsing text lines (which could change depending on environment).