aboutsummaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'Tools')
-rw-r--r--Tools/scripts/ai-master-prompt.md53
-rwxr-xr-xTools/scripts/git-diff-ports.sh31
-rwxr-xr-xTools/scripts/git-get-latest-remote-version.sh46
-rwxr-xr-xTools/scripts/hackage-get-latest-version.sh49
-rwxr-xr-xTools/scripts/installed-ports-by-origin.sh21
-rwxr-xr-xTools/scripts/npmjs-fetch-with-dependencies.sh122
-rwxr-xr-xTools/scripts/npmjs-get-latest-version.sh45
-rwxr-xr-xTools/scripts/pypi-get-latest-version.sh6
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