diff options
Diffstat (limited to 'Tools')
| -rw-r--r-- | Tools/scripts/ai-master-prompt.md | 53 | ||||
| -rwxr-xr-x | Tools/scripts/git-diff-ports.sh | 31 | ||||
| -rwxr-xr-x | Tools/scripts/git-get-latest-remote-version.sh | 46 | ||||
| -rwxr-xr-x | Tools/scripts/hackage-get-latest-version.sh | 49 | ||||
| -rwxr-xr-x | Tools/scripts/installed-ports-by-origin.sh | 21 | ||||
| -rwxr-xr-x | Tools/scripts/npmjs-fetch-with-dependencies.sh | 122 | ||||
| -rwxr-xr-x | Tools/scripts/npmjs-get-latest-version.sh | 45 | ||||
| -rwxr-xr-x | Tools/scripts/pypi-get-latest-version.sh | 6 |
8 files changed, 371 insertions, 2 deletions
diff --git a/Tools/scripts/ai-master-prompt.md b/Tools/scripts/ai-master-prompt.md new file mode 100644 index 000000000000..e14f45c92651 --- /dev/null +++ b/Tools/scripts/ai-master-prompt.md @@ -0,0 +1,53 @@ +<!-- +ai-master-prompt.md: master prompt file for AI assistants to know how to perform + various simple operations on ports and ports tree. + AI assistants find it by using the .env file in the root of + the repository, or by using relevant environment variables. + For example, the Google's gemini AI assistant can use + GEMINI_SYSTEM_MD to find this file. + +MAINTAINER: yuri@FreeBSD.org +--> + +# Project Context: FreeBSD ports + +## General Instructions +- Individual port directories are under category directories: {category}/{port directory} +- In order to perform operations on an individual port you need to change directory into this port. +- In every port's directory there is a Makefile. +- WRKDIR of every port can be determined by the command 'make -V WRKDIR' +- WRKSRC of every port can be determined by the command 'make -V WRKSRC' +- When any port is updated, the distinfo file can be regenerated using the 'make makesum' command. +- Any port can download and extract the source files using the 'make patch' command. +- Working directory can be removed (cleaned) using the 'make clean' command. +- PORTREVISION should be removed when DISTVERSION or PORTVERSION is updated. +- Any FreeBSD package that is needed can be installed using the command 'sudo pkg install -A {package name}'. +- In case if any work* directories are present in the port directory before the port update such directories should be removed by the 'make clean' command. +- The USES variable in port's Makefile defines what type of port this is. + - When USES contains the word 'gmake' this is a port that is built using GNU Make (using the the gmake executable). + - When USES contains the word 'cmake' this is a port that is built using cmake. + - When USES contains the word 'python' this is a Python based port. + - When USES contains the word 'cargo' this is a Rust based port. + - When USES contains the word 'cabal' this is a Haskell based port. +- Port uses GitHub to fetch distfiles if it has the USE_GITHUB=yes line. +- Every port has a maintainer, maintainer's e-mail address is in the MAINTAINER variable. + +### Instructions for ports that use GitHub to fetch distfiles +- GitHub account name of such ports is in GH_ACCOUNT, or otherwise PORTNAME is used as an account name. +- GitHub project name of such ports is in GH_PROJECT, or otherwise PORTNAME is used as a project name. +- The GitHub git URL is constructed as https://github.com/{GH_ACCOUNT}/{GH_PROJECT}.git +- The latest released version of a git URL can be determined using the command '../../Tools/scripts/git-get-latest-remote-version.sh {Git-URL} {DISTVERSIONPREFIX}' + +### Instructions for Python based ports +- The latest released version of the software can be determined using the command '../../Tools/scripts/pypi-get-latest-version.sh {python project name}' +- Dependencies need to be updated when the port is updated. They need to be compared with the dependency requirements set in the project. +- setuptools build dependency should never be added to BUILD_DEPENDS, and instead the distutils element should be present in USE_PYTHON. +- numpy dependency should be added as ${PYNUMPY} instead of the usual syntax. No version information should be added in this case. +- pillow dependency should be added as ${PY_PILLOW} instead of the usual syntax. No version information should be added in this case. +- The cython build dependency should never be added to BUILD_DEPENDS. Instead, the cython element should be added to USE_PYTHON for cython dependencies of versions 1.x or 2.x, and the cython3 element should be added to USE_PYTHON for cython dependencies of versions 3.x +- Do not add upper version limits for Python based ports. +- Always replace exact version comparison in dependencies with >=. + +### Instructions for Haskell based ports +- Directories of all Haskell ports have the prefix "hs-". +- The latest released version of the software can be determined using the command '../../Tools/scripts/haskell-get-latest-version.sh {haskell project name}' diff --git a/Tools/scripts/git-diff-ports.sh b/Tools/scripts/git-diff-ports.sh new file mode 100755 index 000000000000..f13ed0779064 --- /dev/null +++ b/Tools/scripts/git-diff-ports.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# MAINTAINER: yuri@FreeBSD.org + +set -e +set -o pipefail + +export LC_ALL=C + +## +## git-diff-ports.sh: returns the list of ports with uncommitted changes in the repository +## + +# check that packaged dependencies are installed + +for dep in git; do + if ! which -s $dep; then + echo "error: the '$dep' dependency is missing" + if [ $dep = "git" ]; then + echo "... please install the 'git' package" + fi + exit 1 + fi +done + + +# MAIN + +git diff HEAD "$@" | + awk -F / '/^diff/ && $2 !~ /[[:upper:]]/ && $3 !~ /^Makefile/ { print $2 "/" $3 }' | + sort -u diff --git a/Tools/scripts/git-get-latest-remote-version.sh b/Tools/scripts/git-get-latest-remote-version.sh new file mode 100755 index 000000000000..692a4fb1c8ef --- /dev/null +++ b/Tools/scripts/git-get-latest-remote-version.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# MAINTAINER: yuri@FreeBSD.org + +set -e +set -o pipefail + +export LC_ALL=C + +## +## git-get-latest-remote-version.sh: retrieves the latest version of a remote project at the given Git URL +## + +# args + +REPOSITORY_URL="$1" # mandatory +TAG_PREFIX="$2" # optional + +if [ -z "$REPOSITORY_URL" ]; then + echo "Usage: $0 <repository-url> <tag-prefix>" + exit 1 +fi + +# check that packaged dependencies are installed + +for dep in git version_sort; do + if ! which -s $dep; then + echo "error: the '$dep' dependency is missing" + if [ $dep = "git" ]; then + echo "... please install the 'git' package" + elif [ $dep = "version_sort" ]; then + echo "... please install the 'libversion' package" + fi + exit 1 + fi +done + + +# MAIN + +git ls-remote --refs --tags $REPOSITORY_URL 2>/dev/null | + grep "refs/tags/$TAG_PREFIX" | + sed -e "s|.*refs/tags/$TAG_PREFIX||" | + version_sort | + tail -1 || + ! echo "failed to find the git project '$REPOSITORY_URL' or tags in it" diff --git a/Tools/scripts/hackage-get-latest-version.sh b/Tools/scripts/hackage-get-latest-version.sh new file mode 100755 index 000000000000..3ad21fcbd73a --- /dev/null +++ b/Tools/scripts/hackage-get-latest-version.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# MAINTAINER: yuri@FreeBSD.org + +set -e +set -o pipefail + +export LC_ALL=C + +## +## hackage-get-latest-version.sh: retrieves the latest version of a given Haskell package as registered on https://hackage.haskell.org +## + +# args + +PACKAGE_NAME="$1" + +if [ -z "$PACKAGE_NAME" ]; then + echo "Usage: $0 <package-name>" + echo "Example: $0 cryptol" + echo "Example: $0 ShellCheck" + exit 1 +fi + +# check that packaged dependencies are installed + +for dep in curl jq version_sort; do + if ! which -s $dep; then + echo "error: the '$dep' dependency is missing" + if [ $dep = "curl" ]; then + echo "... please install the 'curl' package" + elif [ $dep = "jq" ]; then + echo "... please install the 'jq' package" + elif [ $dep = "version_sort" ]; then + echo "... please install the 'libversion' package" + fi + exit 1 + fi +done + + +# MAIN + +curl -H "Accept: application/json" https://hackage.haskell.org/package/$PACKAGE_NAME 2>/dev/null | + grep -v "Package not found: No such package in package index" | + jq -r 'keys[]' | + version_sort | + tail -1 || + ! echo "failed to find the Haskell package '$PACKAGE_NAME'" diff --git a/Tools/scripts/installed-ports-by-origin.sh b/Tools/scripts/installed-ports-by-origin.sh new file mode 100755 index 000000000000..5d0d4434fbea --- /dev/null +++ b/Tools/scripts/installed-ports-by-origin.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Contributed by Ralf van der Enden <tremere@cainites.net> +# Public domain. + +# Print a list of all installed ports by origin with flavour. +# This is similar to pkg info -qoa, but prints a flavour if the +# package has one. + +sqlite3 /var/db/pkg/local.sqlite \ + "select origin || coalesce('@' || ( + select t4.annotation as annotation + from packages t1 + inner join pkg_annotation t2 on t1.id = t2.package_id + inner join annotation t3 on t2.tag_id = t3.annotation_id + and t3.annotation = 'flavor' + inner join annotation t4 on t2.value_id = t4.annotation_id + and t2.tag_id = t3.annotation_id + and t3.annotation = 'flavor' + where t1.origin = t0.origin), '') + from packages t0;" diff --git a/Tools/scripts/npmjs-fetch-with-dependencies.sh b/Tools/scripts/npmjs-fetch-with-dependencies.sh new file mode 100755 index 000000000000..5650addbf715 --- /dev/null +++ b/Tools/scripts/npmjs-fetch-with-dependencies.sh @@ -0,0 +1,122 @@ +#!/bin/sh +# +# MAINTAINER: yuri@FreeBSD.org + +# This script is intended to be used in fetch targets of Node.js ports. +# It fetches a given Node.js package from npmjs.org along with all its dependencies, +# and creates a tarball with the package and all its dependencies. +# It doesn't build or install the package, just fetches it and its dependencies, +# such that the subsequent build step wouldn't require network access. +# This script generates a package-lock.json file for reproducible builds +# if it doesn't already exist. + + +set -eu -o pipefail +set -o pipefail + +export LC_ALL=C + +## +## npmjs-get-latest-version.sh: retrieves the latest version of a given Node.js package as registered on https://registry.npmjs.org +## + +# args and env + +PACKAGE_NAME="$1" +PACKAGE_VERSION="$2" +PACKAGE_LOCK_JSON="$3" +PACKAGE_TARBALL_OUTPUT="$4" + +if [ -z "$PACKAGE_NAME" ] || [ -z "$PACKAGE_VERSION" ] || [ -z "$PACKAGE_LOCK_JSON" ] || [ -z "$PACKAGE_TARBALL_OUTPUT" ]; then + echo "Usage: $0 <package name> <package version> <package-lock.json> <package tarball output>" + echo "Example: $0 sharp 0.34.4 outdir/sharp-package-lock.json outdir/sharp-0.34.4.tar.gz" + exit 1 +fi + +PACKAGE_NAME_PURE="$(echo $PACKAGE_NAME | sed 's|.*/||')" + +if [ -z "$TMPDIR" ]; then + TMPDIR="/tmp" +fi + + +# check that packaged dependencies are installed + +for dep in npm jq; do + if ! which $dep >/dev/null 2>&1; then + echo "error: the '$dep' dependency is missing" + if [ $dep = "npm" ]; then + echo "... please install the 'npm' package" + elif [ $dep = "jq" ]; then + echo "... please install the 'jq' package" + fi + exit 1 + fi +done + + +# MAIN + +# to full paths +if ! echo "${PACKAGE_LOCK_JSON}" | grep -q "^/"; then + PACKAGE_LOCK_JSON="`pwd`/${PACKAGE_LOCK_JSON}" +fi +if ! echo "${PACKAGE_TARBALL_OUTPUT}" | grep -q "^/"; then + PACKAGE_TARBALL_OUTPUT="`pwd`/${PACKAGE_TARBALL_OUTPUT}" +fi +if ! echo "${TMPDIR}" | grep -q "^/"; then + TMPDIR="`pwd`/${TMPDIR}" +fi + +# create dirs for output files +mkdir -p "$(dirname "${PACKAGE_LOCK_JSON}")" +mkdir -p "$(dirname "${PACKAGE_TARBALL_OUTPUT}")" +mkdir -p "${TMPDIR}" + +# create build dir and change to there +BUILD_DIR="${TMPDIR}/${PACKAGE_NAME_PURE}-${PACKAGE_VERSION}" +rm -rf ${BUILD_DIR} +mkdir ${BUILD_DIR} +cd ${BUILD_DIR} + +# either just fetch, or regenarate package-lock.json and fetch +if [ -f $PACKAGE_LOCK_JSON ]; then + # fail if package-lock.json does not contain the requested package and version + JSON_NAME=$(jq -r ".packages | .\"node_modules/${PACKAGE_NAME}\" .version" $PACKAGE_LOCK_JSON) + if [ "$JSON_NAME" != "$PACKAGE_VERSION" ]; then + echo "error: the existing package-lock.json ($PACKAGE_LOCK_JSON) does not contain the requested package ${PACKAGE_NAME}@${PACKAGE_VERSION}" + echo " please delete the existing package-lock.json ($PACKAGE_LOCK_JSON) and re-run this script to regenerate it" + exit 1 + fi + + # fetch dependencies + echo "{\"name\":\"${PACKAGE_NAME}-installer\",\"version\":\"1.0.0\",\"dependencies\":{\"${PACKAGE_NAME}\":\"${PACKAGE_VERSION}\"}}" > package.json + cp $PACKAGE_LOCK_JSON package-lock.json + HOME=${TMPDIR} npm ci --ignore-scripts --global-style --legacy-peer-deps --omit=dev +else + # info + echo "INFO: the file $PACKAGE_LOCK_JSON does not exist, we will attempt to generate it" + + # generate package-lock.json + echo "{\"name\":\"${PACKAGE_NAME}-installer\",\"version\":\"1.0.0\"}" > package.json + npm install --package-lock-only --global-style --legacy-peer-deps ${PACKAGE_NAME}@${PACKAGE_VERSION} + + # copy generated package-lock.json to the expected location + cp package-lock.json ${PACKAGE_LOCK_JSON} + + # info + echo "INFO: ${PACKAGE_LOCK_JSON} did not exist and was generated" + + # fetch dependencies + HOME=${TMPDIR} npm ci --ignore-scripts --global-style --legacy-peer-deps --omit=dev +fi + +# generate tarball with all dependencies + +cd ${TMPDIR} + +find ${PACKAGE_NAME_PURE}-${PACKAGE_VERSION} -and -exec touch -h -d 1970-01-01T00:00:00Z {} \; +find ${PACKAGE_NAME_PURE}-${PACKAGE_VERSION} -print0 | sort -z | \ + tar czf ${PACKAGE_TARBALL_OUTPUT} --format=bsdtar --gid 0 --uid 0 --options gzip:!timestamp --no-recursion --null -T - +rm -rf ${PACKAGE_NAME_PURE}-${PACKAGE_VERSION} +echo "INFO: created package tarball with dependencies at: ${PACKAGE_TARBALL_OUTPUT}" diff --git a/Tools/scripts/npmjs-get-latest-version.sh b/Tools/scripts/npmjs-get-latest-version.sh new file mode 100755 index 000000000000..122211f03df8 --- /dev/null +++ b/Tools/scripts/npmjs-get-latest-version.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# MAINTAINER: yuri@FreeBSD.org + +set -e +set -o pipefail + +export LC_ALL=C + +## +## npmjs-get-latest-version.sh: retrieves the latest version of a given Node.js package as registered on https://registry.npmjs.org +## + +# args + +PACKAGE_NAME="$1" + +if [ -z "$PACKAGE_NAME" ]; then + echo "Usage: $0 <package-name>" + echo "Example: $0 @github/copilot" + echo "Example: $0 express" + exit 1 +fi + +# check that packaged dependencies are installed + +for dep in curl jq; do + if ! which $dep >/dev/null 2>&1; then + echo "error: the '$dep' dependency is missing" + if [ $dep = "curl" ]; then + echo "... please install the 'curl' package" + elif [ $dep = "jq" ]; then + echo "... please install the 'jq' package" + fi + exit 1 + fi +done + + +# MAIN + +curl -H "Accept: application/json" https://registry.npmjs.org/$PACKAGE_NAME/latest 2>/dev/null | + grep -v "Not Found" | + jq -r '.version' || + ! echo "failed to find the Node.js package '$PACKAGE_NAME'" diff --git a/Tools/scripts/pypi-get-latest-version.sh b/Tools/scripts/pypi-get-latest-version.sh index 3083eb60764f..580aa282248d 100755 --- a/Tools/scripts/pypi-get-latest-version.sh +++ b/Tools/scripts/pypi-get-latest-version.sh @@ -17,6 +17,8 @@ PACKAGE_NAME="$1" if [ -z "$PACKAGE_NAME" ]; then echo "Usage: $0 <package-name>" + echo "Example: $0 numpy" + echo "Example: $0 scipy" exit 1 fi @@ -25,9 +27,9 @@ fi for dep in jq version_sort; do if ! which -s $dep; then echo "error: the '$dep' dependency is missing" - if [ $dep == "jq" ]; then + if [ $dep = "jq" ]; then echo "... please install the 'jq' package" - elif [ $dep == "version_sort" ]; then + elif [ $dep = "version_sort" ]; then echo "... please install the 'libversion' package" fi exit 1 |
