Adding fork support to the scripts

Shared
* Moved version parsing/detection to a separate function
* Added path/version parameters to various functions
* Fixed whitespace metacharacters so they work on both macOS and Linux
* Updated tag generation logic to account for forks

generate-stackbrew-library.sh
* Updated sort algorithm to sort the non-fork versions first

test_build.sh
* Fixed a bug where it could only handle one version

update.sh
* Added support for configurable node download URIs
* Added some informational and error output
* Updated it to use the templates for each fork
This commit is contained in:
Kyle Farnung 2018-01-05 17:43:28 -08:00
parent 25f26146ac
commit 2cf732a291
5 changed files with 194 additions and 45 deletions

1
config Normal file
View File

@ -0,0 +1 @@
baseuri https://nodejs.org/dist

View File

@ -2,6 +2,17 @@
# Utlity functions
info() {
printf "%s\\n" "$@"
}
fatal() {
printf "**********\\n"
printf "Fatal Error: %s\\n" "$@"
printf "**********\\n"
exit 1
}
# Get system architecture
#
# This is used to get the target architecture for docker image.
@ -40,10 +51,14 @@ function get_arch() {
# <architecutre 1> <supported variant 1 >,<supported variant 2>...
# <architecutre 2> <supported variant 1 >,<supported variant 2>...
function get_variants() {
local dir
dir=${1:-.}
shift
local arch
arch=$(get_arch)
local variants
variants=$(grep "^$arch" architectures | sed -E 's/'"$arch"'\s*//' | sed -E 's/,/ /g')
variants=$(grep "^$arch" "$dir/architectures" | sed -E 's/'"$arch"'[[:space:]]*//' | sed -E 's/,/ /g')
echo "$variants"
}
@ -58,15 +73,146 @@ function get_supported_arches () {
local version
local variant
local arches
local lines
local line
version="$1"; shift
variant="$1"; shift
# Get default supported arches
arches=$( grep "$variant" architectures 2>/dev/null | cut -d' ' -f1 )
lines=$( grep "$variant" "$(dirname "$version")"/architectures 2>/dev/null | cut -d' ' -f1 )
# Get version specific supported architectures if there is specialized information
if [ -a "$version"/architectures ]; then
arches=$( grep "$variant" "$version"/architectures 2>/dev/null | cut -d' ' -f1 )
lines=$( grep "$variant" "$version"/architectures 2>/dev/null | cut -d' ' -f1 )
fi
echo "$arches"
while IFS='' read -r line; do
arches+=( "$line" )
done <<< "$lines"
echo "${arches[@]}"
}
# Get configuration values from the config file
#
# The configuration entries are simple key/value pairs which are whitespace separated.
function get_config () {
local dir
dir=${1:-.}
shift
local name
name=$1
shift
local value
value=$(grep "^$name" "$dir/config" | sed -E 's/'"$name"'[[:space:]]*//')
echo "$value"
}
# Get available versions for a given path
#
# If full or partial versions are provided then they are processed and
# validated. e.g. "4 chakracore" returns "4 chakracore/8" since it processed the
# chakracore entry and found it to be a fork rather than a complete version.
#
# The result is a list of valid versions.
function get_versions () {
local prefix
prefix=${1:-.}
shift
local versions
local dirs=( "$@" )
if [ ${#dirs[@]} -eq 0 ]; then
IFS=' ' read -ra dirs <<< "$(echo "${prefix%/}/"*/)"
fi
for dir in "${dirs[@]}"; do
if [ -a "$dir/config" ]; then
local subdirs
IFS=' ' read -ra subdirs <<< "$(get_versions "${dir#./}")"
for subdir in "${subdirs[@]}"; do
versions+=( "$subdir" )
done
elif [ -a "$dir/Dockerfile" ]; then
versions+=( "${dir#./}" )
fi
done
if [ ${#versions[@]} -gt 0 ]; then
echo "${versions[@]%/}"
fi
}
function get_fork_name () {
local version
version=$1
shift
IFS='/' read -ra versionparts <<< "$version"
if [ ${#versionparts[@]} -gt 1 ]; then
echo "${versionparts[0]}"
fi
}
function get_full_version () {
local version
version=$1
shift
grep -m1 'ENV NODE_VERSION ' "$version/Dockerfile" | cut -d' ' -f3
}
function get_major_minor_version () {
local version
version=$1
shift
local fullversion
fullversion=$(get_full_version "$version")
echo "$(echo "$fullversion" | cut -d'.' -f1).$(echo "$fullversion" | cut -d'.' -f2)"
}
function get_tag () {
local version
version=$1
shift
local versiontype
versiontype=${1:-full}
shift
local tagversion
if [ "$versiontype" = full ]; then
tagversion=$(get_full_version "$version")
elif [ "$versiontype" = majorminor ]; then
tagversion=$(get_major_minor_version "$version")
fi
local tagparts
IFS=' ' read -ra tagparts <<< "$(get_fork_name "$version") $tagversion"
IFS='-'; echo "${tagparts[*]}"; unset IFS
}
function sort_versions () {
local versions=( "$@" )
local sorted
local lines
local line
IFS=$'\n'
lines="${versions[*]}"
unset IFS
while IFS='' read -r line; do
sorted+=( "$line" )
done <<< "$(echo "$lines" | grep "^[0-9]" | sort -r)"
while IFS='' read -r line; do
sorted+=( "$line" )
done <<< "$(echo "$lines" | grep -v "^[0-9]" | sort -r)"
echo "${sorted[@]}"
}

View File

@ -18,13 +18,10 @@ cd "$(cd "${0%/*}" && pwd -P)";
self="$(basename "${BASH_SOURCE[0]}")"
versions=( */ )
versions=( "${versions[@]%/}" )
IFS=' ' read -ra versions <<< "$(get_versions)"
IFS=' ' read -ra versions <<< "$(sort_versions "${versions[@]}")"
url='https://github.com/nodejs/docker-node'
# sort version numbers with highest first
IFS=$'\n'; versions=( $(echo "${versions[*]}" | sort -r) ); unset IFS
# get the most recent commit which modified any of "$@"
fileCommit() {
git log -1 --format='format:%H' HEAD -- "$@"
@ -43,18 +40,25 @@ join() {
echo "${out#$sep}"
}
get_stub() {
local version="$1"; shift
IFS='/' read -ra versionparts <<< "$version"
local stub; eval stub="$(join '_' "${versionparts[@]}" | awk -F. '{ print "$array_" $1 }')";
echo "$stub"
}
for version in "${versions[@]}"; do
# Skip "docs" and other non-docker directories
[ -f "$version/Dockerfile" ] || continue
eval stub="$(echo "$version" | awk -F. '{ print "$array_" $1 }')";
stub=$(get_stub "$version")
commit="$(fileCommit "$version")"
fullVersion="$(grep -m1 'ENV NODE_VERSION ' "$version/Dockerfile" | cut -d' ' -f3)"
minorVersion="$(echo "$fullVersion" | cut -d'.' -f2)"
fullVersion="$(get_tag "$version" full)"
majorMinorVersion="$(get_tag "$version" majorminor)"
versionAliases=( $fullVersion $version.$minorVersion ${stub} )
IFS=' ' read -ra versionAliases <<< "$fullVersion $majorMinorVersion $stub"
# Get supported architectures for a specific version. See details in function.sh
supportedArches=( $(get_supported_arches "$version" "default") )
IFS=' ' read -ra supportedArches <<< "$(get_supported_arches "$version" "default")"
echo "Tags: $(join ', ' "${versionAliases[@]}")"
echo "Architectures: $(join ', ' "${supportedArches[@]}")"
@ -64,7 +68,7 @@ for version in "${versions[@]}"; do
# Get supported variants according to the target architecture.
# See details in function.sh
variants=$(get_variants | tr ' ' '\n')
variants=$(get_variants "$(dirname "$version")")
for variant in $variants; do
# Skip non-docker directories
[ -f "$version/$variant/Dockerfile" ] || continue
@ -76,7 +80,7 @@ for version in "${versions[@]}"; do
variantAliases=( "${variantAliases[@]//latest-/}" )
# Get supported architectures for a specific version and variant.
# See details in function.sh
supportedArches=( $(get_supported_arches "$version" "$variant") )
IFS=' ' read -ra supportedArches <<< "$(get_supported_arches "$version" "$variant")"
echo "Tags: $(join ', ' "${variantAliases[@]}")"
echo "Architectures: $(join ', ' "${supportedArches[@]}")"

View File

@ -3,34 +3,22 @@
# Run a test build for all images.
set -uo pipefail
IFS=$'\n\t'
. functions.sh
info() {
printf "%s\n" "$@"
}
fatal() {
printf "**********\n"
printf "%s\n" "$@"
printf "**********\n"
exit 1
}
cd "$(cd "${0%/*}" && pwd -P)" || exit;
versions=( "$@" )
IFS=' ' read -ra versions <<< "$(get_versions . "$@")"
if [ ${#versions[@]} -eq 0 ]; then
versions=( */ )
fatal "No valid versions found!"
fi
versions=( "${versions[@]%/}" )
for version in "${versions[@]}"; do
# Skip "docs" and other non-docker directories
[ -f "$version/Dockerfile" ] || continue
tag=$(grep "ENV NODE_VERSION" "$version/Dockerfile" | cut -d' ' -f3)
tag=$(get_tag "$version")
full_version=$(get_full_version "$version")
info "Building $tag..."
@ -40,14 +28,14 @@ for version in "${versions[@]}"; do
info "Build of $tag succeeded."
OUTPUT=$(docker run --rm -it node:"$tag" node -e "process.stdout.write(process.versions.node)")
if [ "$OUTPUT" != "$tag" ]; then
if [ "$OUTPUT" != "$full_version" ]; then
fatal "Test of $tag failed!"
fi
info "Test of $tag succeeded."
# Get supported variants according to the target architecture.
# See details in function.sh
variants=$(get_variants | tr ' ' '\n')
variants=$(get_variants "$(dirname "$version")")
for variant in $variants; do
# Skip non-docker directories
@ -61,7 +49,7 @@ for version in "${versions[@]}"; do
info "Build of $tag-$variant succeeded."
OUTPUT=$(docker run --rm -it node:"$tag-$variant" node -e "process.stdout.write(process.versions.node)")
if [ "$OUTPUT" != "$tag" ]; then
if [ "$OUTPUT" != "$full_version" ]; then
fatal "Test of $tag-$variant failed!"
fi
info "Test of $tag-$variant succeeded."

View File

@ -1,15 +1,14 @@
#!/bin/bash
set -e
set -ue
. functions.sh
cd "$(cd "${0%/*}" && pwd -P)";
versions=( "$@" )
IFS=' ' read -ra versions <<< "$(get_versions . "$@")"
if [ ${#versions[@]} -eq 0 ]; then
versions=( */ )
fatal "No valid versions found!"
fi
versions=( "${versions[@]%/}" )
# Global variables
# Get architecure and use this as target architecture for docker image
@ -21,6 +20,10 @@ yarnVersion="$(curl -sSL --compressed https://yarnpkg.com/latest-version)"
function update_node_version {
local baseuri=$1
shift
local version=$1
shift
local template=$1
shift
local dockerfile=$1
@ -31,12 +34,12 @@ function update_node_version {
shift
fi
fullVersion="$(curl -sSL --compressed 'https://nodejs.org/dist' | grep '<a href="v'"$version." | sed -E 's!.*<a href="v([^"/]+)/?".*!\1!' | cut -d'.' -f2,3| sort -n | tail -1)"
fullVersion="$(curl -sSL --compressed "$baseuri" | grep '<a href="v'"$version." | sed -E 's!.*<a href="v([^"/]+)/?".*!\1!' | cut -d'.' -f2,3| sort -n | tail -1)"
(
cp "$template" "$dockerfile"
local fromprefix=
if [[ "$arch" != "amd64" && "$variant" != "onbuild" ]]; then
fromprefix="$arch\/"
fromprefix="$arch\\/"
fi
sed -E -i.bak 's/^FROM (.*)/FROM '"$fromprefix"'\1/' "$dockerfile" && rm "$dockerfile".bak
@ -53,16 +56,23 @@ for version in "${versions[@]}"; do
# Skip "docs" and other non-docker directories
[ -f "$version/Dockerfile" ] || continue
update_node_version "Dockerfile.template" "$version/Dockerfile"
info "Updating version $version..."
parentpath=$(dirname "$version")
versionnum=$(basename "$version")
baseuri=$(get_config "$parentpath" "baseuri")
update_node_version "$baseuri" "$versionnum" "$parentpath/Dockerfile.template" "$version/Dockerfile"
# Get supported variants according the target architecture
# See details in function.sh
variants=$(get_variants)
variants=$(get_variants "$parentpath")
for variant in $variants; do
# Skip non-docker directories
[ -f "$version/$variant/Dockerfile" ] || continue
update_node_version "Dockerfile-$variant.template" "$version/$variant/Dockerfile" "$variant"
update_node_version "$baseuri" "$versionnum" "$parentpath/Dockerfile-$variant.template" "$version/$variant/Dockerfile" "$variant"
done
done
info "Done!"