From 9c2383446d035e0c1a84eff0b162bbb411d1a587 Mon Sep 17 00:00:00 2001 From: Joseph Ferguson Date: Thu, 9 May 2024 15:48:27 -0700 Subject: [PATCH 1/7] Add repo metadata, start with categories! scripts for checking repo categories, updating the canonical set added categories to push.pl --- .ci/check-metadata.sh | 9 +++ .github/workflows/ci.yml | 5 ++ README.md | 13 ++++ get-categories.sh | 21 ++++++ metadata.json | 22 ++++++ metadata.sh | 140 +++++++++++++++++++++++++++++++++++++++ push.pl | 27 ++++++++ 7 files changed, 237 insertions(+) create mode 100755 .ci/check-metadata.sh create mode 100755 get-categories.sh create mode 100644 metadata.json create mode 100755 metadata.sh diff --git a/.ci/check-metadata.sh b/.ci/check-metadata.sh new file mode 100755 index 000000000000..06a9408412be --- /dev/null +++ b/.ci/check-metadata.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.." + +# metadata.sh takes directories with a 'metadata.json' in them +# metadata.json is expected in every repo +# "." so that the canonical source metadata.json is checked too +./metadata.sh -d -c */ . diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 130d1c4e7cdc..ebe9572e6e2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,3 +46,8 @@ jobs: fetch-depth: 0 - run: .ci/check-pr-no-readme.sh if: ${{ github.event_name == 'pull_request' }} + metadata: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: .ci/check-metadata.sh diff --git a/README.md b/README.md index 5ce616d5f612..d02275a7110f 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ After opening your Pull Request the changes will be checked by an automated `mar - Create a `license.md` (required) - Create a `maintainer.md` (required) - Create a `github-repo` (required) +- Create a `metadata.json` (required) - Add a `logo.png` (recommended) Optionally: @@ -128,6 +129,18 @@ The image is automatically scaled to a 120 pixel square for the top of the Docke This file should contain a link to the maintainers of the Dockerfile. +## `metadata.json` + +This file contains data about the repo for Docker Hub. The minimum file is defined below. `./metadata.sh [repo-name]` must be used to correctly format it (use `-f` to apply its suggested changes). There is a limit to the number of Docker Hub categories allowed; run with `-c` to check the limit and categories. `metadata.json` in the root contains the list of categories to choose from. + +```json +{ + "hub": { + "categories": [] + } +} +``` + ## `README-short.txt` This is the short description for the Docker Hub, limited to 100 characters in a single line. diff --git a/get-categories.sh b/get-categories.sh new file mode 100755 index 000000000000..540a1f19e5ce --- /dev/null +++ b/get-categories.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +workdir="$(readlink -f "$BASH_SOURCE")" +workdir="$(dirname "$workdir")" + +jsonFile='metadata.json' +canonicalMetadataFile="$workdir/$jsonFile" + +allCategories="$(curl -fsSL https://hub.docker.com/v2/categories)" +export allCategories + +# add categories slugs to canonicalMetadataFile without losing other keys there +json="$( + jq --sort-keys ' + (env.allCategories | fromjson) as $allCategories + | .hub.categories = ( [ $allCategories[].slug ] | sort ) + ' "$canonicalMetadataFile" +)" + +echo "$json" | tee "$canonicalMetadataFile" diff --git a/metadata.json b/metadata.json new file mode 100644 index 000000000000..e12e4b04f598 --- /dev/null +++ b/metadata.json @@ -0,0 +1,22 @@ +{ + "hub": { + "categories": [ + "api-management", + "content-management-system", + "data-science", + "databases-and-storage", + "developer-tools", + "integration-and-delivery", + "internet-of-things", + "languages-and-frameworks", + "machine-learning-and-ai", + "message-queues", + "monitoring-and-observability", + "networking", + "operating-systems", + "security", + "web-analytics", + "web-servers" + ] + } +} diff --git a/metadata.sh b/metadata.sh new file mode 100755 index 000000000000..64ac61c9178c --- /dev/null +++ b/metadata.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +workdir="$(readlink -f "$BASH_SOURCE")" +workdir="$(dirname "$workdir")" +#cd "$workdir" + +jsonFile='metadata.json' +canonicalMetadataFile="$workdir/$jsonFile" +maxCategories=3 + +self="$(basename "$0")" + +usage() { + cat <&2 && false; })" +eval set -- "$opts" + +categories= +diff= +fmt= + +while true; do + flag="$1" + shift + case "$flag" in + --categories|-c) categories=1 ;; + --diff|-d) diff=1 ;; + --fmt|--format|-f) fmt=1 ;; + --help|-h) usage && exit 0 ;; + --) break ;; + *) + { + echo "error: unknown flag: $flag" + usage + } >&2 + exit 1 + ;; + esac +done + +# default to print diff +if [ -z "$diff" ] && [ -z "$categories" ] && [ -z "$fmt" ]; then + diff=1 +fi + +repos=( "$@" ) +if [ "${#repos[@]}" -eq 0 ]; then + repos=( */ ) +fi +repos=( "${repos[@]%/}" ) + +canonicalMetadataFileJson="$(cat "$canonicalMetadataFile")" +export canonicalMetadataFileJson + +failure= +for repo in "${repos[@]}"; do + repoFile="$workdir/$repo/$jsonFile" + if [ ! -f "$repoFile" ]; then + failure=1 + echo "error file does not exist: $repo/$jsonFile" + continue + fi + repoFile="$(readlink -f "$repoFile")" + + if [ -n "$diff" ] || [ -n "$fmt" ]; then + # sort object keys and pretty print with jq as our "cannonical json" + # sort categories array + if ! repoFilejson="$(jq --sort-keys '.hub.categories |= sort' "$repoFile")"; then + echo "error $repo/$jsonFile improper json" + failure=1 + continue + fi + if ! filediff="$(diff -u "$repoFile" <(echo "$repoFilejson"))"; then + if [ -n "$diff" ]; then + echo >&2 "$repoFile" + # skip diff headers + echo "$filediff" | tail -n +3 + failure=1 + fi + if [ -n "$fmt" ]; then + # TODO should fmt + categories remove invalid or categories over max? + echo "$repoFilejson" > "$repoFile" + fi + fi + fi + + # TODO also check for required keys and/or types? + if [ -n "$categories" ]; then + # the canonicalMetadataFile doesn't have too many categories since it is the source of categories + # all other metadata.json files must not be more than maxCategories + if [ "$canonicalMetadataFile" != "$repoFile" ]; then + tooManyCategories="$(jq --raw-output ' + .hub.categories + | if length > '"$maxCategories"' then + length + else empty end + ' "$repoFile")" + if [ -n "$tooManyCategories" ]; then + echo >&2 "$repo, error too many Docker Hub categories: $tooManyCategories, max $maxCategories" + failure=1 + fi + fi + # check for categories that aren't in the canonical set + extraCategories="$(jq -c ' + (env.canonicalMetadataFileJson | fromjson | .hub.categories) as $canonicalCategories + | .hub.categories + | map(. as $cat | select($canonicalCategories | index($cat) < 0)) + | if length > 0 then . else empty end + ' "$repoFile")" + if [ -n "$extraCategories" ]; then + echo >&2 "$repo, error unkown categories: $extraCategories" + failure=1 + fi + fi +done + +if [ "$failure" ]; then + exit 1 +fi diff --git a/push.pl b/push.pl index d9ef38e2544f..eb6c1d37a3db 100755 --- a/push.pl +++ b/push.pl @@ -8,6 +8,7 @@ use File::Temp; use Getopt::Long; use Mojo::File; +use Mojo::JSON qw(decode_json); use Mojo::UserAgent; use Mojo::Util qw(decode encode trim url_escape); @@ -211,6 +212,32 @@ sub prompt_for_edit { my $repoDetails = $repoTx->res->json; $repoDetails->{description} //= ''; $repoDetails->{full_description} //= ''; + $repoDetails->{categories} //= []; + my @repoCategories = sort map { $_->{slug} } @{$repoDetails->{categories}}; + + # read local categories from metadata.json + my $repoMetadataBytes = Mojo::File->new($repoName . '/metadata.json')->slurp; + my $repoMetadataJson = decode_json $repoMetadataBytes; + my @localRepoCategories = sort @{$repoMetadataJson->{hub}{categories}}; + + # check if the local categories differ in length or items from the remote + my $needCat = @localRepoCategories != @repoCategories; + if (! $needCat) { + foreach my $i (0..@localRepoCategories) { + last if ! defined $repoCategories[$i]; # length difference already covered, so we can bail + if ($localRepoCategories[$i] ne $repoCategories[$i]) { + $needCat = 1; + last; + } + } + } + if ($needCat) { + say 'updating ' . $repoName . ' categories'; + my $catsPatch = $ua->patch($repoUrl . 'categories/' => { %$authorizationHeader, Accept => 'application/json' } => json => [ + map { { slug => $_ => name => 'All those moments will be lost in time, like tears in rain... Time to die.' } } @{$repoMetadataJson->{hub}{categories}} + ]); + die 'patch to categories failed: ' . $catsPatch->res->text unless $catsPatch->res->is_success; + } my $hubShort = prompt_for_edit($repoDetails->{description}, $repoName . '/README-short.txt'); my $hubLong = prompt_for_edit($repoDetails->{full_description}, $repoName . '/README.md', $hubLengthLimit); From e4274deddc24f25eb85f484cdfe225832f2886f0 Mon Sep 17 00:00:00 2001 From: Joseph Ferguson Date: Thu, 9 May 2024 15:51:32 -0700 Subject: [PATCH 2/7] Add initial set of semi-acurate categories --- adminer/metadata.json | 7 +++++++ aerospike/metadata.json | 7 +++++++ almalinux/metadata.json | 7 +++++++ alpine/metadata.json | 7 +++++++ alt/metadata.json | 7 +++++++ amazoncorretto/metadata.json | 7 +++++++ amazonlinux/metadata.json | 7 +++++++ api-firewall/metadata.json | 7 +++++++ arangodb/metadata.json | 7 +++++++ archlinux/metadata.json | 7 +++++++ backdrop/metadata.json | 7 +++++++ bash/metadata.json | 7 +++++++ bonita/metadata.json | 7 +++++++ buildpack-deps/metadata.json | 7 +++++++ busybox/metadata.json | 7 +++++++ caddy/metadata.json | 7 +++++++ cassandra/metadata.json | 7 +++++++ centos/metadata.json | 5 +++++ chronograf/metadata.json | 7 +++++++ cirros/metadata.json | 7 +++++++ clearlinux/metadata.json | 7 +++++++ clefos/metadata.json | 7 +++++++ clojure/metadata.json | 7 +++++++ composer/metadata.json | 7 +++++++ consul/metadata.json | 5 +++++ convertigo/metadata.json | 7 +++++++ couchbase/metadata.json | 7 +++++++ couchdb/metadata.json | 7 +++++++ crate/metadata.json | 7 +++++++ dart/metadata.json | 7 +++++++ debian/metadata.json | 7 +++++++ docker/metadata.json | 7 +++++++ drupal/metadata.json | 7 +++++++ eclipse-mosquitto/metadata.json | 7 +++++++ eclipse-temurin/metadata.json | 7 +++++++ eggdrop/metadata.json | 5 +++++ elasticsearch/metadata.json | 7 +++++++ elixir/metadata.json | 7 +++++++ emqx/metadata.json | 7 +++++++ erlang/metadata.json | 7 +++++++ express-gateway/metadata.json | 5 +++++ fedora/metadata.json | 7 +++++++ flink/metadata.json | 7 +++++++ fluentd/metadata.json | 7 +++++++ friendica/metadata.json | 5 +++++ gazebo/metadata.json | 7 +++++++ gcc/metadata.json | 7 +++++++ geonetwork/metadata.json | 7 +++++++ ghost/metadata.json | 7 +++++++ golang/metadata.json | 7 +++++++ gradle/metadata.json | 7 +++++++ groovy/metadata.json | 7 +++++++ haproxy/metadata.json | 7 +++++++ haskell/metadata.json | 7 +++++++ haxe/metadata.json | 7 +++++++ hello-world/metadata.json | 5 +++++ hitch/metadata.json | 7 +++++++ httpd/metadata.json | 7 +++++++ hylang/metadata.json | 7 +++++++ ibm-semeru-runtimes/metadata.json | 7 +++++++ ibmjava/metadata.json | 7 +++++++ influxdb/metadata.json | 7 +++++++ irssi/metadata.json | 5 +++++ jetty/metadata.json | 7 +++++++ jobber/metadata.json | 5 +++++ joomla/metadata.json | 7 +++++++ jruby/metadata.json | 7 +++++++ julia/metadata.json | 7 +++++++ kapacitor/metadata.json | 7 +++++++ kibana/metadata.json | 7 +++++++ kong/metadata.json | 7 +++++++ lightstreamer/metadata.json | 7 +++++++ liquibase/metadata.json | 7 +++++++ logstash/metadata.json | 7 +++++++ mageia/metadata.json | 7 +++++++ mariadb/metadata.json | 7 +++++++ matomo/metadata.json | 7 +++++++ maven/metadata.json | 7 +++++++ mediawiki/metadata.json | 7 +++++++ memcached/metadata.json | 7 +++++++ mongo-express/metadata.json | 7 +++++++ mongo/metadata.json | 7 +++++++ monica/metadata.json | 7 +++++++ mono/metadata.json | 7 +++++++ mysql/metadata.json | 7 +++++++ nats-streaming/metadata.json | 5 +++++ nats/metadata.json | 7 +++++++ neo4j/metadata.json | 7 +++++++ neurodebian/metadata.json | 7 +++++++ nextcloud/metadata.json | 7 +++++++ nginx/metadata.json | 7 +++++++ node/metadata.json | 7 +++++++ notary/metadata.json | 7 +++++++ odoo/metadata.json | 7 +++++++ open-liberty/metadata.json | 7 +++++++ openjdk/metadata.json | 5 +++++ oraclelinux/metadata.json | 7 +++++++ orientdb/metadata.json | 7 +++++++ percona/metadata.json | 7 +++++++ perl/metadata.json | 7 +++++++ photon/metadata.json | 7 +++++++ php-zendserver/metadata.json | 7 +++++++ php/metadata.json | 7 +++++++ phpmyadmin/metadata.json | 7 +++++++ plone/metadata.json | 7 +++++++ postfixadmin/metadata.json | 7 +++++++ postgres/metadata.json | 7 +++++++ pypy/metadata.json | 7 +++++++ python/metadata.json | 7 +++++++ r-base/metadata.json | 7 +++++++ rabbitmq/metadata.json | 7 +++++++ rakudo-star/metadata.json | 7 +++++++ redis/metadata.json | 7 +++++++ redmine/metadata.json | 7 +++++++ registry/metadata.json | 7 +++++++ rethinkdb/metadata.json | 7 +++++++ rocket.chat/metadata.json | 5 +++++ rockylinux/metadata.json | 7 +++++++ ros/metadata.json | 7 +++++++ ruby/metadata.json | 7 +++++++ rust/metadata.json | 7 +++++++ sapmachine/metadata.json | 7 +++++++ satosa/metadata.json | 7 +++++++ scratch/metadata.json | 5 +++++ silverpeas/metadata.json | 7 +++++++ sl/metadata.json | 7 +++++++ solr/metadata.json | 7 +++++++ sonarqube/metadata.json | 7 +++++++ spark/metadata.json | 7 +++++++ spiped/metadata.json | 7 +++++++ storm/metadata.json | 7 +++++++ swift/metadata.json | 7 +++++++ swipl/metadata.json | 7 +++++++ teamspeak/metadata.json | 5 +++++ telegraf/metadata.json | 7 +++++++ tomcat/metadata.json | 7 +++++++ tomee/metadata.json | 7 +++++++ traefik/metadata.json | 7 +++++++ ubuntu/metadata.json | 7 +++++++ unit/metadata.json | 7 +++++++ varnish/metadata.json | 7 +++++++ vault/metadata.json | 5 +++++ websphere-liberty/metadata.json | 7 +++++++ wordpress/metadata.json | 7 +++++++ xwiki/metadata.json | 7 +++++++ yourls/metadata.json | 7 +++++++ znc/metadata.json | 5 +++++ zookeeper/metadata.json | 7 +++++++ 148 files changed, 1006 insertions(+) create mode 100644 adminer/metadata.json create mode 100644 aerospike/metadata.json create mode 100644 almalinux/metadata.json create mode 100644 alpine/metadata.json create mode 100644 alt/metadata.json create mode 100644 amazoncorretto/metadata.json create mode 100644 amazonlinux/metadata.json create mode 100644 api-firewall/metadata.json create mode 100644 arangodb/metadata.json create mode 100644 archlinux/metadata.json create mode 100644 backdrop/metadata.json create mode 100644 bash/metadata.json create mode 100644 bonita/metadata.json create mode 100644 buildpack-deps/metadata.json create mode 100644 busybox/metadata.json create mode 100644 caddy/metadata.json create mode 100644 cassandra/metadata.json create mode 100644 centos/metadata.json create mode 100644 chronograf/metadata.json create mode 100644 cirros/metadata.json create mode 100644 clearlinux/metadata.json create mode 100644 clefos/metadata.json create mode 100644 clojure/metadata.json create mode 100644 composer/metadata.json create mode 100644 consul/metadata.json create mode 100644 convertigo/metadata.json create mode 100644 couchbase/metadata.json create mode 100644 couchdb/metadata.json create mode 100644 crate/metadata.json create mode 100644 dart/metadata.json create mode 100644 debian/metadata.json create mode 100644 docker/metadata.json create mode 100644 drupal/metadata.json create mode 100644 eclipse-mosquitto/metadata.json create mode 100644 eclipse-temurin/metadata.json create mode 100644 eggdrop/metadata.json create mode 100644 elasticsearch/metadata.json create mode 100644 elixir/metadata.json create mode 100644 emqx/metadata.json create mode 100644 erlang/metadata.json create mode 100644 express-gateway/metadata.json create mode 100644 fedora/metadata.json create mode 100644 flink/metadata.json create mode 100644 fluentd/metadata.json create mode 100644 friendica/metadata.json create mode 100644 gazebo/metadata.json create mode 100644 gcc/metadata.json create mode 100644 geonetwork/metadata.json create mode 100644 ghost/metadata.json create mode 100644 golang/metadata.json create mode 100644 gradle/metadata.json create mode 100644 groovy/metadata.json create mode 100644 haproxy/metadata.json create mode 100644 haskell/metadata.json create mode 100644 haxe/metadata.json create mode 100644 hello-world/metadata.json create mode 100644 hitch/metadata.json create mode 100644 httpd/metadata.json create mode 100644 hylang/metadata.json create mode 100644 ibm-semeru-runtimes/metadata.json create mode 100644 ibmjava/metadata.json create mode 100644 influxdb/metadata.json create mode 100644 irssi/metadata.json create mode 100644 jetty/metadata.json create mode 100644 jobber/metadata.json create mode 100644 joomla/metadata.json create mode 100644 jruby/metadata.json create mode 100644 julia/metadata.json create mode 100644 kapacitor/metadata.json create mode 100644 kibana/metadata.json create mode 100644 kong/metadata.json create mode 100644 lightstreamer/metadata.json create mode 100644 liquibase/metadata.json create mode 100644 logstash/metadata.json create mode 100644 mageia/metadata.json create mode 100644 mariadb/metadata.json create mode 100644 matomo/metadata.json create mode 100644 maven/metadata.json create mode 100644 mediawiki/metadata.json create mode 100644 memcached/metadata.json create mode 100644 mongo-express/metadata.json create mode 100644 mongo/metadata.json create mode 100644 monica/metadata.json create mode 100644 mono/metadata.json create mode 100644 mysql/metadata.json create mode 100644 nats-streaming/metadata.json create mode 100644 nats/metadata.json create mode 100644 neo4j/metadata.json create mode 100644 neurodebian/metadata.json create mode 100644 nextcloud/metadata.json create mode 100644 nginx/metadata.json create mode 100644 node/metadata.json create mode 100644 notary/metadata.json create mode 100644 odoo/metadata.json create mode 100644 open-liberty/metadata.json create mode 100644 openjdk/metadata.json create mode 100644 oraclelinux/metadata.json create mode 100644 orientdb/metadata.json create mode 100644 percona/metadata.json create mode 100644 perl/metadata.json create mode 100644 photon/metadata.json create mode 100644 php-zendserver/metadata.json create mode 100644 php/metadata.json create mode 100644 phpmyadmin/metadata.json create mode 100644 plone/metadata.json create mode 100644 postfixadmin/metadata.json create mode 100644 postgres/metadata.json create mode 100644 pypy/metadata.json create mode 100644 python/metadata.json create mode 100644 r-base/metadata.json create mode 100644 rabbitmq/metadata.json create mode 100644 rakudo-star/metadata.json create mode 100644 redis/metadata.json create mode 100644 redmine/metadata.json create mode 100644 registry/metadata.json create mode 100644 rethinkdb/metadata.json create mode 100644 rocket.chat/metadata.json create mode 100644 rockylinux/metadata.json create mode 100644 ros/metadata.json create mode 100644 ruby/metadata.json create mode 100644 rust/metadata.json create mode 100644 sapmachine/metadata.json create mode 100644 satosa/metadata.json create mode 100644 scratch/metadata.json create mode 100644 silverpeas/metadata.json create mode 100644 sl/metadata.json create mode 100644 solr/metadata.json create mode 100644 sonarqube/metadata.json create mode 100644 spark/metadata.json create mode 100644 spiped/metadata.json create mode 100644 storm/metadata.json create mode 100644 swift/metadata.json create mode 100644 swipl/metadata.json create mode 100644 teamspeak/metadata.json create mode 100644 telegraf/metadata.json create mode 100644 tomcat/metadata.json create mode 100644 tomee/metadata.json create mode 100644 traefik/metadata.json create mode 100644 ubuntu/metadata.json create mode 100644 unit/metadata.json create mode 100644 varnish/metadata.json create mode 100644 vault/metadata.json create mode 100644 websphere-liberty/metadata.json create mode 100644 wordpress/metadata.json create mode 100644 xwiki/metadata.json create mode 100644 yourls/metadata.json create mode 100644 znc/metadata.json create mode 100644 zookeeper/metadata.json diff --git a/adminer/metadata.json b/adminer/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/adminer/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/aerospike/metadata.json b/aerospike/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/aerospike/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/almalinux/metadata.json b/almalinux/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/almalinux/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/alpine/metadata.json b/alpine/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/alpine/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/alt/metadata.json b/alt/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/alt/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/amazoncorretto/metadata.json b/amazoncorretto/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/amazoncorretto/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/amazonlinux/metadata.json b/amazonlinux/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/amazonlinux/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/api-firewall/metadata.json b/api-firewall/metadata.json new file mode 100644 index 000000000000..f1e52700787d --- /dev/null +++ b/api-firewall/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "security" + ] + } +} diff --git a/arangodb/metadata.json b/arangodb/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/arangodb/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/archlinux/metadata.json b/archlinux/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/archlinux/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/backdrop/metadata.json b/backdrop/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/backdrop/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/bash/metadata.json b/bash/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/bash/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/bonita/metadata.json b/bonita/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/bonita/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/buildpack-deps/metadata.json b/buildpack-deps/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/buildpack-deps/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/busybox/metadata.json b/busybox/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/busybox/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/caddy/metadata.json b/caddy/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/caddy/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/cassandra/metadata.json b/cassandra/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/cassandra/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/centos/metadata.json b/centos/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/centos/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/chronograf/metadata.json b/chronograf/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/chronograf/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/cirros/metadata.json b/cirros/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/cirros/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/clearlinux/metadata.json b/clearlinux/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/clearlinux/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/clefos/metadata.json b/clefos/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/clefos/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/clojure/metadata.json b/clojure/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/clojure/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/composer/metadata.json b/composer/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/composer/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/consul/metadata.json b/consul/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/consul/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/convertigo/metadata.json b/convertigo/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/convertigo/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/couchbase/metadata.json b/couchbase/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/couchbase/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/couchdb/metadata.json b/couchdb/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/couchdb/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/crate/metadata.json b/crate/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/crate/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/dart/metadata.json b/dart/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/dart/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/debian/metadata.json b/debian/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/debian/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/docker/metadata.json b/docker/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/docker/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/drupal/metadata.json b/drupal/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/drupal/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/eclipse-mosquitto/metadata.json b/eclipse-mosquitto/metadata.json new file mode 100644 index 000000000000..66ae22756c7e --- /dev/null +++ b/eclipse-mosquitto/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "message-queues" + ] + } +} diff --git a/eclipse-temurin/metadata.json b/eclipse-temurin/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/eclipse-temurin/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/eggdrop/metadata.json b/eggdrop/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/eggdrop/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/elasticsearch/metadata.json b/elasticsearch/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/elasticsearch/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/elixir/metadata.json b/elixir/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/elixir/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/emqx/metadata.json b/emqx/metadata.json new file mode 100644 index 000000000000..66ae22756c7e --- /dev/null +++ b/emqx/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "message-queues" + ] + } +} diff --git a/erlang/metadata.json b/erlang/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/erlang/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/express-gateway/metadata.json b/express-gateway/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/express-gateway/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/fedora/metadata.json b/fedora/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/fedora/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/flink/metadata.json b/flink/metadata.json new file mode 100644 index 000000000000..2b3b7cd7c11f --- /dev/null +++ b/flink/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "data-science" + ] + } +} diff --git a/fluentd/metadata.json b/fluentd/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/fluentd/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/friendica/metadata.json b/friendica/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/friendica/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/gazebo/metadata.json b/gazebo/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/gazebo/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/gcc/metadata.json b/gcc/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/gcc/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/geonetwork/metadata.json b/geonetwork/metadata.json new file mode 100644 index 000000000000..2b3b7cd7c11f --- /dev/null +++ b/geonetwork/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "data-science" + ] + } +} diff --git a/ghost/metadata.json b/ghost/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/ghost/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/golang/metadata.json b/golang/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/golang/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/gradle/metadata.json b/gradle/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/gradle/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/groovy/metadata.json b/groovy/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/groovy/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/haproxy/metadata.json b/haproxy/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/haproxy/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/haskell/metadata.json b/haskell/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/haskell/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/haxe/metadata.json b/haxe/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/haxe/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/hello-world/metadata.json b/hello-world/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/hello-world/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/hitch/metadata.json b/hitch/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/hitch/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/httpd/metadata.json b/httpd/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/httpd/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/hylang/metadata.json b/hylang/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/hylang/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/ibm-semeru-runtimes/metadata.json b/ibm-semeru-runtimes/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/ibm-semeru-runtimes/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/ibmjava/metadata.json b/ibmjava/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/ibmjava/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/influxdb/metadata.json b/influxdb/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/influxdb/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/irssi/metadata.json b/irssi/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/irssi/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/jetty/metadata.json b/jetty/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/jetty/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/jobber/metadata.json b/jobber/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/jobber/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/joomla/metadata.json b/joomla/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/joomla/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/jruby/metadata.json b/jruby/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/jruby/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/julia/metadata.json b/julia/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/julia/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/kapacitor/metadata.json b/kapacitor/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/kapacitor/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/kibana/metadata.json b/kibana/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/kibana/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/kong/metadata.json b/kong/metadata.json new file mode 100644 index 000000000000..538442b9d959 --- /dev/null +++ b/kong/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "api-management" + ] + } +} diff --git a/lightstreamer/metadata.json b/lightstreamer/metadata.json new file mode 100644 index 000000000000..66ae22756c7e --- /dev/null +++ b/lightstreamer/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "message-queues" + ] + } +} diff --git a/liquibase/metadata.json b/liquibase/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/liquibase/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/logstash/metadata.json b/logstash/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/logstash/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/mageia/metadata.json b/mageia/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/mageia/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/mariadb/metadata.json b/mariadb/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/mariadb/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/matomo/metadata.json b/matomo/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/matomo/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/maven/metadata.json b/maven/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/maven/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/mediawiki/metadata.json b/mediawiki/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/mediawiki/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/memcached/metadata.json b/memcached/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/memcached/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/mongo-express/metadata.json b/mongo-express/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/mongo-express/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/mongo/metadata.json b/mongo/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/mongo/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/monica/metadata.json b/monica/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/monica/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/mono/metadata.json b/mono/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/mono/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/mysql/metadata.json b/mysql/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/mysql/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/nats-streaming/metadata.json b/nats-streaming/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/nats-streaming/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/nats/metadata.json b/nats/metadata.json new file mode 100644 index 000000000000..66ae22756c7e --- /dev/null +++ b/nats/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "message-queues" + ] + } +} diff --git a/neo4j/metadata.json b/neo4j/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/neo4j/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/neurodebian/metadata.json b/neurodebian/metadata.json new file mode 100644 index 000000000000..2b3b7cd7c11f --- /dev/null +++ b/neurodebian/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "data-science" + ] + } +} diff --git a/nextcloud/metadata.json b/nextcloud/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/nextcloud/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/nginx/metadata.json b/nginx/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/nginx/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/node/metadata.json b/node/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/node/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/notary/metadata.json b/notary/metadata.json new file mode 100644 index 000000000000..f1e52700787d --- /dev/null +++ b/notary/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "security" + ] + } +} diff --git a/odoo/metadata.json b/odoo/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/odoo/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/open-liberty/metadata.json b/open-liberty/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/open-liberty/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/openjdk/metadata.json b/openjdk/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/openjdk/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/oraclelinux/metadata.json b/oraclelinux/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/oraclelinux/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/orientdb/metadata.json b/orientdb/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/orientdb/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/percona/metadata.json b/percona/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/percona/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/perl/metadata.json b/perl/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/perl/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/photon/metadata.json b/photon/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/photon/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/php-zendserver/metadata.json b/php-zendserver/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/php-zendserver/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/php/metadata.json b/php/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/php/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/phpmyadmin/metadata.json b/phpmyadmin/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/phpmyadmin/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/plone/metadata.json b/plone/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/plone/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/postfixadmin/metadata.json b/postfixadmin/metadata.json new file mode 100644 index 000000000000..67e782480585 --- /dev/null +++ b/postfixadmin/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "developer-tools" + ] + } +} diff --git a/postgres/metadata.json b/postgres/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/postgres/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/pypy/metadata.json b/pypy/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/pypy/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/python/metadata.json b/python/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/python/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/r-base/metadata.json b/r-base/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/r-base/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/rabbitmq/metadata.json b/rabbitmq/metadata.json new file mode 100644 index 000000000000..66ae22756c7e --- /dev/null +++ b/rabbitmq/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "message-queues" + ] + } +} diff --git a/rakudo-star/metadata.json b/rakudo-star/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/rakudo-star/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/redis/metadata.json b/redis/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/redis/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/redmine/metadata.json b/redmine/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/redmine/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/registry/metadata.json b/registry/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/registry/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/rethinkdb/metadata.json b/rethinkdb/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/rethinkdb/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/rocket.chat/metadata.json b/rocket.chat/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/rocket.chat/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/rockylinux/metadata.json b/rockylinux/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/rockylinux/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/ros/metadata.json b/ros/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/ros/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/ruby/metadata.json b/ruby/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/ruby/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/rust/metadata.json b/rust/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/rust/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/sapmachine/metadata.json b/sapmachine/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/sapmachine/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/satosa/metadata.json b/satosa/metadata.json new file mode 100644 index 000000000000..f1e52700787d --- /dev/null +++ b/satosa/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "security" + ] + } +} diff --git a/scratch/metadata.json b/scratch/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/scratch/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/silverpeas/metadata.json b/silverpeas/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/silverpeas/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/sl/metadata.json b/sl/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/sl/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/solr/metadata.json b/solr/metadata.json new file mode 100644 index 000000000000..3d3937b21fb1 --- /dev/null +++ b/solr/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "databases-and-storage" + ] + } +} diff --git a/sonarqube/metadata.json b/sonarqube/metadata.json new file mode 100644 index 000000000000..4e2e34b2be0e --- /dev/null +++ b/sonarqube/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "integration-and-delivery" + ] + } +} diff --git a/spark/metadata.json b/spark/metadata.json new file mode 100644 index 000000000000..f61c8e7547e7 --- /dev/null +++ b/spark/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "machine-learning-and-ai" + ] + } +} diff --git a/spiped/metadata.json b/spiped/metadata.json new file mode 100644 index 000000000000..f1e52700787d --- /dev/null +++ b/spiped/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "security" + ] + } +} diff --git a/storm/metadata.json b/storm/metadata.json new file mode 100644 index 000000000000..2b3b7cd7c11f --- /dev/null +++ b/storm/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "data-science" + ] + } +} diff --git a/swift/metadata.json b/swift/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/swift/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/swipl/metadata.json b/swipl/metadata.json new file mode 100644 index 000000000000..39ac749c7f11 --- /dev/null +++ b/swipl/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "languages-and-frameworks" + ] + } +} diff --git a/teamspeak/metadata.json b/teamspeak/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/teamspeak/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/telegraf/metadata.json b/telegraf/metadata.json new file mode 100644 index 000000000000..5f9ae9afb8e1 --- /dev/null +++ b/telegraf/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "monitoring-and-observability" + ] + } +} diff --git a/tomcat/metadata.json b/tomcat/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/tomcat/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/tomee/metadata.json b/tomee/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/tomee/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/traefik/metadata.json b/traefik/metadata.json new file mode 100644 index 000000000000..296c4ec2a848 --- /dev/null +++ b/traefik/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "networking" + ] + } +} diff --git a/ubuntu/metadata.json b/ubuntu/metadata.json new file mode 100644 index 000000000000..df07586b5b35 --- /dev/null +++ b/ubuntu/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "operating-systems" + ] + } +} diff --git a/unit/metadata.json b/unit/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/unit/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/varnish/metadata.json b/varnish/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/varnish/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/vault/metadata.json b/vault/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/vault/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/websphere-liberty/metadata.json b/websphere-liberty/metadata.json new file mode 100644 index 000000000000..1f306a0037fd --- /dev/null +++ b/websphere-liberty/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "web-servers" + ] + } +} diff --git a/wordpress/metadata.json b/wordpress/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/wordpress/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/xwiki/metadata.json b/xwiki/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/xwiki/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/yourls/metadata.json b/yourls/metadata.json new file mode 100644 index 000000000000..180157012a86 --- /dev/null +++ b/yourls/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "content-management-system" + ] + } +} diff --git a/znc/metadata.json b/znc/metadata.json new file mode 100644 index 000000000000..e90624aca4ca --- /dev/null +++ b/znc/metadata.json @@ -0,0 +1,5 @@ +{ + "hub": { + "categories": [] + } +} diff --git a/zookeeper/metadata.json b/zookeeper/metadata.json new file mode 100644 index 000000000000..66ae22756c7e --- /dev/null +++ b/zookeeper/metadata.json @@ -0,0 +1,7 @@ +{ + "hub": { + "categories": [ + "message-queues" + ] + } +} From ae120b38432a4014ff9919420f37d97b711e2937 Mon Sep 17 00:00:00 2001 From: Joseph Ferguson Date: Thu, 16 May 2024 11:21:11 -0700 Subject: [PATCH 3/7] Adjustments following tianon's review --- get-categories.sh | 17 +++---- metadata.sh | 114 +++++++++++++++++++++++----------------------- push.pl | 11 +++-- 3 files changed, 70 insertions(+), 72 deletions(-) diff --git a/get-categories.sh b/get-categories.sh index 540a1f19e5ce..7d678f700757 100755 --- a/get-categories.sh +++ b/get-categories.sh @@ -7,15 +7,10 @@ workdir="$(dirname "$workdir")" jsonFile='metadata.json' canonicalMetadataFile="$workdir/$jsonFile" -allCategories="$(curl -fsSL https://hub.docker.com/v2/categories)" -export allCategories - # add categories slugs to canonicalMetadataFile without losing other keys there -json="$( - jq --sort-keys ' - (env.allCategories | fromjson) as $allCategories - | .hub.categories = ( [ $allCategories[].slug ] | sort ) - ' "$canonicalMetadataFile" -)" - -echo "$json" | tee "$canonicalMetadataFile" +curl -fsSL https://hub.docker.com/v2/categories | jq -s --sort-keys ' + .[0] as $allCategories + | .[1] + | .hub.categories = ( [ $allCategories[].slug ] | sort ) +' - "$canonicalMetadataFile" | tee "$canonicalMetadataFile.new" +mv "$canonicalMetadataFile.new" "$canonicalMetadataFile" diff --git a/metadata.sh b/metadata.sh index 64ac61c9178c..a2492afffb12 100755 --- a/metadata.sh +++ b/metadata.sh @@ -3,28 +3,28 @@ set -Eeuo pipefail workdir="$(readlink -f "$BASH_SOURCE")" workdir="$(dirname "$workdir")" -#cd "$workdir" +cd "$workdir" jsonFile='metadata.json' -canonicalMetadataFile="$workdir/$jsonFile" -maxCategories=3 +canonicalMetadataFile="./$jsonFile" +export maxCategories=3 self="$(basename "$0")" usage() { cat <&2 && false; })" +opts="$(getopt -o 'cdhw' --long 'categories,diff,help,write' -- "$@" || { usage >&2 && false; })" eval set -- "$opts" categories= diff= -fmt= +write= while true; do flag="$1" shift case "$flag" in - --categories|-c) categories=1 ;; - --diff|-d) diff=1 ;; - --fmt|--format|-f) fmt=1 ;; - --help|-h) usage && exit 0 ;; + --categories | -c) categories=1 ;; + --diff | -d) diff=1 ;; + --help | -h) usage && exit 0 ;; + --write | -w) write=1 ;; --) break ;; *) { @@ -60,7 +60,7 @@ while true; do done # default to print diff -if [ -z "$diff" ] && [ -z "$categories" ] && [ -z "$fmt" ]; then +if [ -z "$diff" ] && [ -z "$categories" ] && [ -z "$write" ]; then diff=1 fi @@ -70,37 +70,30 @@ if [ "${#repos[@]}" -eq 0 ]; then fi repos=( "${repos[@]%/}" ) -canonicalMetadataFileJson="$(cat "$canonicalMetadataFile")" -export canonicalMetadataFileJson - -failure= +failures=0 for repo in "${repos[@]}"; do - repoFile="$workdir/$repo/$jsonFile" - if [ ! -f "$repoFile" ]; then - failure=1 - echo "error file does not exist: $repo/$jsonFile" + repoFile="$repo/$jsonFile" + if [ ! -e "$repoFile" ]; then + echo >&2 "error: $repoFile does not exist" + (( failures++ )) || : continue fi - repoFile="$(readlink -f "$repoFile")" - if [ -n "$diff" ] || [ -n "$fmt" ]; then + if [ -n "$diff" ] || [ -n "$write" ]; then # sort object keys and pretty print with jq as our "cannonical json" - # sort categories array - if ! repoFilejson="$(jq --sort-keys '.hub.categories |= sort' "$repoFile")"; then - echo "error $repo/$jsonFile improper json" - failure=1 + # sort categories array, no duplicates + if ! repoFileJson="$(jq --sort-keys '.hub.categories |= unique' "$repoFile")"; then + echo >&2 "error parsing '$repoFile'; invalid JSON?" + (( failures++ )) || : continue fi - if ! filediff="$(diff -u "$repoFile" <(echo "$repoFilejson"))"; then + if ! filediff="$(diff -u "$repoFile" <(cat <<<"$repoFileJson"))"; then if [ -n "$diff" ]; then - echo >&2 "$repoFile" - # skip diff headers - echo "$filediff" | tail -n +3 - failure=1 + cat <<<"$filediff" + [ -n "write" ] || (( failures++ )) || : fi - if [ -n "$fmt" ]; then - # TODO should fmt + categories remove invalid or categories over max? - echo "$repoFilejson" > "$repoFile" + if [ -n "$write" ]; then + cat <<<"$repoFileJson" > "$repoFile" fi fi fi @@ -109,32 +102,39 @@ for repo in "${repos[@]}"; do if [ -n "$categories" ]; then # the canonicalMetadataFile doesn't have too many categories since it is the source of categories # all other metadata.json files must not be more than maxCategories - if [ "$canonicalMetadataFile" != "$repoFile" ]; then - tooManyCategories="$(jq --raw-output ' + if [ "$repoFile" != "$canonicalMetadataFile" ]; then + if tooManyCategories="$(jq --raw-output ' .hub.categories - | if length > '"$maxCategories"' then - length + | length + | if . > (env.maxCategories | tonumber) then + . else empty end - ' "$repoFile")" - if [ -n "$tooManyCategories" ]; then - echo >&2 "$repo, error too many Docker Hub categories: $tooManyCategories, max $maxCategories" - failure=1 + ' "$repoFile")"; then + if [ -n "$tooManyCategories" ]; then + echo >&2 "error: $repoFile: too many categories: $tooManyCategories (max $maxCategories)" + (( failures++ )) || : + fi + else + echo >&2 "error parsing '$repoFile'; invalid JSON?" + (( failures++ )) || : + continue fi + fi # check for categories that aren't in the canonical set - extraCategories="$(jq -c ' - (env.canonicalMetadataFileJson | fromjson | .hub.categories) as $canonicalCategories - | .hub.categories - | map(. as $cat | select($canonicalCategories | index($cat) < 0)) - | if length > 0 then . else empty end - ' "$repoFile")" - if [ -n "$extraCategories" ]; then - echo >&2 "$repo, error unkown categories: $extraCategories" - failure=1 + if extraCategories="$(jq -c --slurpfile canonical "$canonicalMetadataFile" ' + .hub.categories - $canonical[0].hub.categories + ' "$repoFile")"; then + if [ "$extraCategories" != '[]' ]; then + echo >&2 "error: $repoFile: unkown categories: $extraCategories" + (( failures++ )) || : + fi + else + echo >&2 "error parsing '$repoFile'; invalid JSON?" + (( failures++ )) || : + continue fi fi done -if [ "$failure" ]; then - exit 1 -fi +exit "$failures" diff --git a/push.pl b/push.pl index eb6c1d37a3db..f5d69dd98494 100755 --- a/push.pl +++ b/push.pl @@ -213,17 +213,17 @@ sub prompt_for_edit { $repoDetails->{description} //= ''; $repoDetails->{full_description} //= ''; $repoDetails->{categories} //= []; - my @repoCategories = sort map { $_->{slug} } @{$repoDetails->{categories}}; + my @repoCategories = sort map { $_->{slug} } @{ $repoDetails->{categories} }; # read local categories from metadata.json my $repoMetadataBytes = Mojo::File->new($repoName . '/metadata.json')->slurp; my $repoMetadataJson = decode_json $repoMetadataBytes; - my @localRepoCategories = sort @{$repoMetadataJson->{hub}{categories}}; + my @localRepoCategories = sort @{ $repoMetadataJson->{hub}{categories} }; # check if the local categories differ in length or items from the remote my $needCat = @localRepoCategories != @repoCategories; if (! $needCat) { - foreach my $i (0..@localRepoCategories) { + foreach my $i (0 .. @localRepoCategories) { last if ! defined $repoCategories[$i]; # length difference already covered, so we can bail if ($localRepoCategories[$i] ne $repoCategories[$i]) { $needCat = 1; @@ -234,7 +234,10 @@ sub prompt_for_edit { if ($needCat) { say 'updating ' . $repoName . ' categories'; my $catsPatch = $ua->patch($repoUrl . 'categories/' => { %$authorizationHeader, Accept => 'application/json' } => json => [ - map { { slug => $_ => name => 'All those moments will be lost in time, like tears in rain... Time to die.' } } @{$repoMetadataJson->{hub}{categories}} + map { { + slug => $_, + name => 'All those moments will be lost in time, like tears in rain... Time to die.', + } } @{ $repoMetadataJson->{hub}{categories} } ]); die 'patch to categories failed: ' . $catsPatch->res->text unless $catsPatch->res->is_success; } From af088807dd6d7f4d98aeaa7b365873bf73dc9f23 Mon Sep 17 00:00:00 2001 From: Joseph Ferguson Date: Thu, 16 May 2024 15:02:58 -0700 Subject: [PATCH 4/7] Simplify metadata.sh use cases (CI or interactive); just diff and check all the time Update README.md about metadata.sh usage --- .ci/check-metadata.sh | 2 +- README.md | 2 +- metadata.sh | 107 ++++++++++++++++++------------------------ 3 files changed, 47 insertions(+), 64 deletions(-) diff --git a/.ci/check-metadata.sh b/.ci/check-metadata.sh index 06a9408412be..23ba1754cd83 100755 --- a/.ci/check-metadata.sh +++ b/.ci/check-metadata.sh @@ -6,4 +6,4 @@ cd "$(dirname "$(readlink -f "$BASH_SOURCE")")/.." # metadata.sh takes directories with a 'metadata.json' in them # metadata.json is expected in every repo # "." so that the canonical source metadata.json is checked too -./metadata.sh -d -c */ . +./metadata.sh */ . diff --git a/README.md b/README.md index d02275a7110f..a8011f384a0d 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ This file should contain a link to the maintainers of the Dockerfile. ## `metadata.json` -This file contains data about the repo for Docker Hub. The minimum file is defined below. `./metadata.sh [repo-name]` must be used to correctly format it (use `-f` to apply its suggested changes). There is a limit to the number of Docker Hub categories allowed; run with `-c` to check the limit and categories. `metadata.json` in the root contains the list of categories to choose from. +This file contains data about the repo for Docker Hub. The minimum file is defined below. `./metadata.sh [repo-name]` must be used to correctly format it (use `-w` to apply its suggested format changes). Only three sorted unique Docker Hub categories are allowed. `metadata.json` in the root contains the list of categories to choose from. ```json { diff --git a/metadata.sh b/metadata.sh index a2492afffb12..5e3b18940bc2 100755 --- a/metadata.sh +++ b/metadata.sh @@ -14,38 +14,31 @@ self="$(basename "$0")" usage() { cat <&2 && false; })" +opts="$(getopt -o 'hw' --long 'help,write' -- "$@" || { usage >&2 && false; })" eval set -- "$opts" -categories= -diff= write= while true; do flag="$1" shift case "$flag" in - --categories | -c) categories=1 ;; - --diff | -d) diff=1 ;; --help | -h) usage && exit 0 ;; --write | -w) write=1 ;; --) break ;; @@ -59,11 +52,6 @@ while true; do esac done -# default to print diff -if [ -z "$diff" ] && [ -z "$categories" ] && [ -z "$write" ]; then - diff=1 -fi - repos=( "$@" ) if [ "${#repos[@]}" -eq 0 ]; then repos=( */ ) @@ -73,60 +61,41 @@ repos=( "${repos[@]%/}" ) failures=0 for repo in "${repos[@]}"; do repoFile="$repo/$jsonFile" - if [ ! -e "$repoFile" ]; then - echo >&2 "error: $repoFile does not exist" + if [ ! -s "$repoFile" ]; then + echo >&2 "error: $repoFile does not exist or is empty" (( failures++ )) || : continue fi - if [ -n "$diff" ] || [ -n "$write" ]; then - # sort object keys and pretty print with jq as our "cannonical json" - # sort categories array, no duplicates - if ! repoFileJson="$(jq --sort-keys '.hub.categories |= unique' "$repoFile")"; then - echo >&2 "error parsing '$repoFile'; invalid JSON?" + # sort object keys and pretty print with jq as our "cannonical json" + # sort categories array, no duplicates + if ! repoFileJson="$(jq -s --sort-keys '.[0] | .hub.categories |= unique' "$repoFile")"; then + echo >&2 "error parsing '$repoFile'; invalid JSON?" + (( failures++ )) || : + continue + fi + if ! filediff="$(diff -u "$repoFile" <(cat <<<"$repoFileJson"))"; then + cat <<<"$filediff" + if [ -n "$write" ]; then + cat <<<"$repoFileJson" > "$repoFile" + else (( failures++ )) || : - continue - fi - if ! filediff="$(diff -u "$repoFile" <(cat <<<"$repoFileJson"))"; then - if [ -n "$diff" ]; then - cat <<<"$filediff" - [ -n "write" ] || (( failures++ )) || : - fi - if [ -n "$write" ]; then - cat <<<"$repoFileJson" > "$repoFile" - fi fi fi # TODO also check for required keys and/or types? - if [ -n "$categories" ]; then - # the canonicalMetadataFile doesn't have too many categories since it is the source of categories - # all other metadata.json files must not be more than maxCategories - if [ "$repoFile" != "$canonicalMetadataFile" ]; then - if tooManyCategories="$(jq --raw-output ' - .hub.categories - | length - | if . > (env.maxCategories | tonumber) then - . - else empty end - ' "$repoFile")"; then - if [ -n "$tooManyCategories" ]; then - echo >&2 "error: $repoFile: too many categories: $tooManyCategories (max $maxCategories)" - (( failures++ )) || : - fi - else - echo >&2 "error parsing '$repoFile'; invalid JSON?" - (( failures++ )) || : - continue - fi - - fi - # check for categories that aren't in the canonical set - if extraCategories="$(jq -c --slurpfile canonical "$canonicalMetadataFile" ' - .hub.categories - $canonical[0].hub.categories + # the canonicalMetadataFile doesn't have too many categories since it is the source of categories + # all other metadata.json files must not be more than maxCategories + if [ "$repoFile" != "$canonicalMetadataFile" ]; then + if tooManyCategories="$(jq --raw-output ' + .hub.categories + | length + | if . > (env.maxCategories | tonumber) then + . + else empty end ' "$repoFile")"; then - if [ "$extraCategories" != '[]' ]; then - echo >&2 "error: $repoFile: unkown categories: $extraCategories" + if [ -n "$tooManyCategories" ]; then + echo >&2 "error: $repoFile: too many categories: $tooManyCategories (max $maxCategories)" (( failures++ )) || : fi else @@ -135,6 +104,20 @@ for repo in "${repos[@]}"; do continue fi fi + + # check for categories that aren't in the canonical set + if extraCategories="$(jq -c --slurpfile canonical "$canonicalMetadataFile" ' + .hub.categories - $canonical[0].hub.categories + ' "$repoFile")"; then + if [ "$extraCategories" != '[]' ]; then + echo >&2 "error: $repoFile: unkown categories: $extraCategories" + (( failures++ )) || : + fi + else + echo >&2 "error parsing '$repoFile'; invalid JSON?" + (( failures++ )) || : + continue + fi done exit "$failures" From 34ce97a3aec05492457648affa5944562bb4be5a Mon Sep 17 00:00:00 2001 From: Joseph Ferguson Date: Thu, 16 May 2024 15:42:06 -0700 Subject: [PATCH 5/7] Unify the categories checks into one jq expressions --- metadata.sh | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/metadata.sh b/metadata.sh index 5e3b18940bc2..29feeb0e876a 100755 --- a/metadata.sh +++ b/metadata.sh @@ -85,17 +85,26 @@ for repo in "${repos[@]}"; do # TODO also check for required keys and/or types? # the canonicalMetadataFile doesn't have too many categories since it is the source of categories - # all other metadata.json files must not be more than maxCategories + # all other metadata.json files must not be more than maxCategories or have categories that aren't in the canonical set if [ "$repoFile" != "$canonicalMetadataFile" ]; then - if tooManyCategories="$(jq --raw-output ' + export repoFile + if errorText="$(jq -r --slurpfile canonical "$canonicalMetadataFile" ' .hub.categories - | length - | if . > (env.maxCategories | tonumber) then - . - else empty end + | ( + length + | if . > (env.maxCategories | tonumber) then + "error: \(env.repoFile): too many categories: \(.) (max \(env.maxCategories))" + else empty end + ), + ( + . - $canonical[0].hub.categories + | if length > 0 then + "error: \(env.repoFile): unknown categories \(.)" + else empty end + ) ' "$repoFile")"; then - if [ -n "$tooManyCategories" ]; then - echo >&2 "error: $repoFile: too many categories: $tooManyCategories (max $maxCategories)" + if [ -n "$errorText" ]; then + echo >&2 "$errorText" (( failures++ )) || : fi else @@ -104,20 +113,6 @@ for repo in "${repos[@]}"; do continue fi fi - - # check for categories that aren't in the canonical set - if extraCategories="$(jq -c --slurpfile canonical "$canonicalMetadataFile" ' - .hub.categories - $canonical[0].hub.categories - ' "$repoFile")"; then - if [ "$extraCategories" != '[]' ]; then - echo >&2 "error: $repoFile: unkown categories: $extraCategories" - (( failures++ )) || : - fi - else - echo >&2 "error parsing '$repoFile'; invalid JSON?" - (( failures++ )) || : - continue - fi done exit "$failures" From 9e3ee0ff117e31c2fc51e56627eb743fe0baa869 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Thu, 16 May 2024 17:10:54 -0700 Subject: [PATCH 6/7] Update initial categories --- api-firewall/metadata.json | 2 +- drupal/metadata.json | 2 +- open-liberty/metadata.json | 2 +- satosa/metadata.json | 2 +- spark/metadata.json | 2 +- vault/metadata.json | 4 +++- zookeeper/metadata.json | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/api-firewall/metadata.json b/api-firewall/metadata.json index f1e52700787d..538442b9d959 100644 --- a/api-firewall/metadata.json +++ b/api-firewall/metadata.json @@ -1,7 +1,7 @@ { "hub": { "categories": [ - "security" + "api-management" ] } } diff --git a/drupal/metadata.json b/drupal/metadata.json index 39ac749c7f11..180157012a86 100644 --- a/drupal/metadata.json +++ b/drupal/metadata.json @@ -1,7 +1,7 @@ { "hub": { "categories": [ - "languages-and-frameworks" + "content-management-system" ] } } diff --git a/open-liberty/metadata.json b/open-liberty/metadata.json index df07586b5b35..1f306a0037fd 100644 --- a/open-liberty/metadata.json +++ b/open-liberty/metadata.json @@ -1,7 +1,7 @@ { "hub": { "categories": [ - "operating-systems" + "web-servers" ] } } diff --git a/satosa/metadata.json b/satosa/metadata.json index f1e52700787d..538442b9d959 100644 --- a/satosa/metadata.json +++ b/satosa/metadata.json @@ -1,7 +1,7 @@ { "hub": { "categories": [ - "security" + "api-management" ] } } diff --git a/spark/metadata.json b/spark/metadata.json index f61c8e7547e7..2b3b7cd7c11f 100644 --- a/spark/metadata.json +++ b/spark/metadata.json @@ -1,7 +1,7 @@ { "hub": { "categories": [ - "machine-learning-and-ai" + "data-science" ] } } diff --git a/vault/metadata.json b/vault/metadata.json index e90624aca4ca..f1e52700787d 100644 --- a/vault/metadata.json +++ b/vault/metadata.json @@ -1,5 +1,7 @@ { "hub": { - "categories": [] + "categories": [ + "security" + ] } } diff --git a/zookeeper/metadata.json b/zookeeper/metadata.json index 66ae22756c7e..3d3937b21fb1 100644 --- a/zookeeper/metadata.json +++ b/zookeeper/metadata.json @@ -1,7 +1,7 @@ { "hub": { "categories": [ - "message-queues" + "databases-and-storage" ] } } From 55152c546d2131e20a6536794fd32b12e3a0ad98 Mon Sep 17 00:00:00 2001 From: Joseph Ferguson Date: Fri, 17 May 2024 11:20:28 -0700 Subject: [PATCH 7/7] Link to Docker docs for categories; minor categories script adjustments --- README.md | 2 +- metadata.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a8011f384a0d..f5c063314991 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ This file should contain a link to the maintainers of the Dockerfile. ## `metadata.json` -This file contains data about the repo for Docker Hub. The minimum file is defined below. `./metadata.sh [repo-name]` must be used to correctly format it (use `-w` to apply its suggested format changes). Only three sorted unique Docker Hub categories are allowed. `metadata.json` in the root contains the list of categories to choose from. +This file contains data about the repo for Docker Hub. The minimum file is defined below. `./metadata.sh [repo-name]` must be used to correctly format it (use `-w` to apply its suggested format changes). Only three sorted unique Docker Hub categories are allowed. `metadata.json` in the root contains the list of categories to choose from. See descriptions for the categories on the [Docker docs site](https://docs.docker.com/docker-hub/repos/categories/). ```json { diff --git a/metadata.sh b/metadata.sh index 29feeb0e876a..cc215de796f9 100755 --- a/metadata.sh +++ b/metadata.sh @@ -14,8 +14,8 @@ self="$(basename "$0")" usage() { cat <