Custom Metadata
EnhancedAdvanced
Overview
Posit Package Manager allows administrators to define custom key-value pairs as metadata for packages with flexible matching criteria.
Package metadata can be added globally, affecting multiple packages across a source or repository; or they can be as specific as a single package version in one source or repository.
Custom package metadata support is available at the Enhanced tier for local use and Advanced tier for remote use.
Custom Metadata System
Package metadata utilizes a criteria matching system to apply key-value pairs to packages with increasing specificity the more criteria are matched. As examples of how custom metadata can be applied, you can:
- Add a risk score to all packages in a repository
- Add a risk score to a single version of a specific package
- Add a documentation link to a specific package
The matching criteria for package metadata is displayed when creating metadata. Use the rspm create metadata
or rspm create bulk-metadata
commands to create new metadata, and rspm list metadata
command to list them.
Terminal
# Add a high risk score to all CRAN packages
$ rspm create metadata --source=cran --key=risk --value=10
# Add a high risk score to django 1.0.0
$ rspm create metadata --package-name=django --version='1.0.0' --key=risk --value=10
# Add a low risk score to django 1.0.0 in an exempt source
$ rspm create metadata --package-name=django --version='1.0.0' --source="exempt-source" --key=risk --value=0
# List all metadata
$ rspm list metadata
ID: 1 (global)
-- Data:
- Key: risk
- Value: 10
-- Constraints:
- Source: cran
ID: 2 (Package: django)
-- Data:
- Key: risk
- Value: 10
-- Constraints:
- Version: 1.0.0
ID: 3 (Package: django)
-- Data:
- Key: risk
- Value: 0
-- Constraints:
- Source: exempt-source
- Version: 1.0.0
Bulk Creation
Bulk creation of metadata can be done both via JSON and CSV input files. See rspm create bulk-metadata
for more information.
Terminal
# View the shape of the JSON
$ cat /tmp/metadata.json
[
{"package_name": "ggplot2",
"key": "risk",
"value": "10",
"repo": "cran",
"source": "cran"
},
{
"package_name": "ggplot2",
"key": "risk",
"value": "5",
"repo": "cran",
"source": "cran",
"version": "1.0.0"
}
]
# Bulk create the metadata
$ bin/rspm create bulk-metadata --path=/tmp/metadata.json
{
"affected": [
{
"id": 1,
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
}
]
},
{
"id": 2,
"package_name": "ggplot2",
"key": "risk",
"value": "5",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
},
{
"version": "1.0.0"
}
]
}
],
"rejected": null
}
Terminal
# View the shape of the CSV
$ cat /tmp/metadata.csv
"value","key","source","repo","version","package_name"
"10","risk","cran","cran","","ggplot2"
"5","risk","cran","cran","1.0.0","ggplot2"
# Bulk create the metadata
$ rspm create bulk-metadata --csv-in=/tmp/metadata.csv
{
"affected": [
{
"id": 1,
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
}
]
},
{
"id": 2,
"package_name": "ggplot2",
"key": "risk",
"value": "5",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
},
{
"version": "1.0.0"
}
]
}
],
"rejected": null
}
Matching Criteria
Custom metadata supports several matching criteria. These include:
- Package name: Name of the package. R packages are case-sensitive, while Python packages are case-insensitive.
- Version: A package version.
- Source: Name of the source, such as
cran
orpypi
. All source types are supported. - Repository: Name of the repository.
For more information on the matching criteria, reference the CLI appendix.
Specificity and Conflicting Key-Value Pairs
When multiple matching keys are matched to a package, the key-value pair with the highest specificity takes precedence.
Examples
Terminal
ID: 1 (global)
-- Data:
- Key: risk
- Value: 60
-- Constraints:
- Source: cran
ID: 2 (Package: plumber)
-- Data:
- Key: risk
- Value: 70
ID: 3 (Package: plumber)
-- Data:
- Key: risk
- Value: 80
-- Constraints:
- Version: 1.0.1
ID: 4 (Package: plumber)
-- Data:
- Key: risk
- Value: 90
-- Constraints:
- Source: cran
- Version: 1.0.1
ID: 5 (Package: plumber)
-- Data:
- Key: risk
- Value: 95
-- Constraints:
- Source: cran
- Repo: cran
- Version: 1.0.1
Given the above set of 5 metadata records, the plumber
package with version 1.0.1
in the cran
repository will have a risk score of 95.
Editing Metadata
Custom metadata can be edited using the same rspm create metadata
command, by passing the --update-existing
flag.
Following the example above for creating new metadata, we can update it like this:
Terminal
# Lower the risk score of all CRAN packages
$ rspm create metadata --source=cran --key=risk --value=5 --update-existing
# List all metadata
$ rspm list metadata
ID: 1 (global)
-- Data:
- Key: risk
- Value: 5
-- Constraints:
- Source: cran
Bulk Edit
Bulk edits of metadata is done via the rspm create bulk-metadata
command. There are no additional flags necessary, the command automatically updates existing records if the value
has changed.
Terminal
# View existing metadata
$ rspm list metadata --output-format=json
[
{"id": 1,
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
}
]
},
{
"id": 2,
"package_name": "ggplot2",
"key": "risk",
"value": "5",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
},
{
"version": "1.0.0"
}
]
}
]
# View the shape of the JSON
$ cat /tmp/metadata.json
[
{"package_name": "ggplot2",
"key": "risk",
"value": "20",
"repo": "cran",
"source": "cran"
},
{
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"repo": "cran",
"source": "cran",
"version": "1.0.0"
}
]
# Bulk edit the metadata
$ rspm create bulk-metadata --path=/tmp/metadata.json
{
"affected": [
{
"id": 1,
"package_name": "ggplot2",
"key": "risk",
"value": "20",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
}
]
},
{
"id": 2,
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
},
{
"version": "1.0.0"
}
]
}
],
"rejected": null
}
Terminal
# View existing metadata
$ rspm list metadata --output-format=json
[
{"id": 1,
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
}
]
},
{
"id": 2,
"package_name": "ggplot2",
"key": "risk",
"value": "5",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
},
{
"version": "1.0.0"
}
]
}
]
# View the shape of the CSV
$ cat /tmp/metadata.csv
"value","key","source","repo","version","package_name"
"20","risk","cran","cran","","ggplot2"
"10","risk","cran","cran","1.0.0","ggplot2"
# Bulk edit the metadata
$ rspm create bulk-metadata --csv-in=/tmp/metadata.csv
{
"affected": [
{
"id": 1,
"package_name": "ggplot2",
"key": "risk",
"value": "20",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
}
]
},
{
"id": 2,
"package_name": "ggplot2",
"key": "risk",
"value": "10",
"constraints": [
{
"repo_id": 2,
"repo": "cran",
},
{
"source_id": 1
"source_name": "cran"
},
{
"version": "1.0.0"
}
]
}
],
"rejected": null
}
Remote Usage
The metadata commands can also be used remotely, e.g. rspm create metadata
. This allows automating metadata management.
When generating a token to set metadata remotely, the rspm create token
command must include either --scope=metadata:admin
or --scope=global:admin
. The metadata:admin
scope gives full access to create, update, delete, and list metadata.
For more information on remotely adding or editing metadata, refer to the Admin CLI - Remote Use section.
Remote usage of custom metadata commands is available at the Advanced tier.