diff options
Diffstat (limited to 'libs/common')
-rwxr-xr-x | libs/common | 238 |
1 files changed, 145 insertions, 93 deletions
diff --git a/libs/common b/libs/common index 8f1379ee..fd001a5d 100755 --- a/libs/common +++ b/libs/common @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr> # @@ -35,12 +35,17 @@ BLOBS_IGNORE="blobs-ignore" BLOBS_DISCOVER="blobs-discover" DOTEPOCH=".epoch" +DOTRNDSEED=".rndseed" DOTVERSION=".version" DOTREVISION=".revision" DOTTARFILES=".tarfiles" -TAR_XZ="tar.xz" -SHA256SUM="sha256sum" -ASC="asc" +ARCHIVE="tar.xz" +CHECKSUM="sha256sum" +DSIG="asc" + +CONFIG_SHELL="${CONFIG_SHELL:-$(which bash)}" +EDITOR="${EDITOR:-$(which vi || true)}" +TASKS="${TASKS:-1}" function_check() { local function=$1 @@ -59,32 +64,73 @@ arguments_list() { for argument in "$@" do - echo "$argument" + printf '%s\n' "$argument" done } +download_wrapper() { + local download_dir="$1" + shift + local uris=($@) + + local wget_options=( + '--config=/dev/null' + '--secure-protocol=PFS' + "--directory-prefix=$download_dir" + '--continue' + '--' + ) + + local curl_options=( + '-q' + '--continue-at -' + '--remote-name' + '--retry 20' + '--ssl' + '--tlsv1.2' + '--' + ) + + if hash wget > /dev/null 2>&1; then + + wget "${wget_options[@]}" "${uris[@]}" + + elif hash curl > /dev/null 2>&1; then + ( + cd "$download_dir" + + curl "${curl_options[@]}" "${uris[@]}" + ) + else + printf '\n%s\n\n' 'Error: Neither wget nor curl were found' 1>&2 + + return 1 + fi +} + diff_patch_file() { local repository_path="$1" local patch_file_path="$2" - local filename_in_diff="$(sed -rne 's/^-{3} {1}(.*)$/\1/p' <"${patch_file_path}")" + # TODO: Improve handling of filenames to avoid gotchas w/ \n, \t, etc. + local filename_in_diff="$(sed -rne 's/^-{3}\s+([^ \r\n]*).*/\1/p' "$patch_file_path")" local source_file_path - if ! ( grep -E '^-{3}.*/' <"${patch_file_path}" >/dev/null 2>&1 ); then - source_file_path="${repository_path}/${filename_in_diff##\ }" + if ! ( grep -E '^-{3}.*/' "$patch_file_path" >/dev/null 2>&1 ); then + source_file_path="$repository_path/$filename_in_diff" else - source_file_path="${repository_path}/${filename_in_diff##*/}" + source_file_path="$repository_path/${filename_in_diff##*/}" fi - patch "${source_file_path}" "${patch_file_path}" + patch "$source_file_path" "$patch_file_path" } path_wildcard_expand() { local path=$@ # Evaluation fails with unescaped whitespaces. - path=$( echo "$path" | sed "s/ /\\\ /g" ) + path=$( printf '%s\n' "$path" | sed "s/ /\\\ /g" ) eval "arguments_list "$path"" } @@ -92,7 +138,7 @@ path_wildcard_expand() { file_checksum_create() { local path=$1 - local checksum_path="$path.$SHA256SUM" + local checksum_path="$path.$CHECKSUM" local name=$( basename "$path" ) local directory_path=$( dirname "$path" ) @@ -105,13 +151,13 @@ file_checksum_create() { file_checksum_check() { local path=$1 - local checksum_path="$path.$SHA256SUM" + local checksum_path="$path.$CHECKSUM" local name=$( basename "$path" ) local directory_path=$( dirname "$path" ) if ! [ -f "$checksum_path" ] then - printf "Could not verify file checksum!\n" >&2 + printf '%s\n' 'Could not verify file checksum!' >&2 return 1 fi @@ -124,7 +170,7 @@ file_checksum_check() { file_signature_create() { local path=$1 - local signature_path="$path.$ASC" + local signature_path="$path.$DSIG" if [ -z "$RELEASE_KEY" ] then @@ -137,11 +183,11 @@ file_signature_create() { file_signature_check() { local path=$1 - local signature_path="$path.$ASC" + local signature_path="$path.$DSIG" if ! [ -f "$signature_path" ] then - printf "Could not verify file signature!\n" >&2 + printf '%s\n' 'Could not verify file signature!' >&2 return 1 fi @@ -180,145 +226,151 @@ directory_filled_check() { } archive_files_create() { - local source_path=$1 + local source_path="$1" - local directory=$( basename "$source_path" ) + local directory="$(basename "$source_path")" local tarfiles_path="$source_path/$DOTTARFILES" local revision_path="$source_path/$DOTREVISION" local version_path="$source_path/$DOTVERSION" + local epoch_path="$source_path/$DOTEPOCH" + local rnd_seed_path="$source_path/$DOTRNDSEED" - if git_check "$source_path" - then - git_files "$source_path" | tr -d '\0' > "$tarfiles_path" - echo "$DOTTARFILES" | tr -d '\0' >> "$tarfiles_path" + # Files in "$tarfiles_path" are NUL terminated. + # `tr '\0' '\n'` for human-readable output. + if git_check "$source_path"; then + git_files "$source_path" > "$tarfiles_path" + printf '%s\0' "$DOTTARFILES" >> "$tarfiles_path" else - touch "$tarfiles_path" - - ( - cd "$source_path" - find - ) | LC_ALL=C sort | sed "s,^./,," | grep -vP "^\.$" > "$tarfiles_path" - fi - - if [ -f "$revision_path" ] - then - echo "$DOTREVISION" | tr -d '\0' >> "$tarfiles_path" + find "$source_path" -print0 | env LC_ALL='C.UTF-8' sort -z | sed -z "1d;s,^$source_path/\\?,,;/^$DOTTARFILES\$/d" > "$tarfiles_path" fi - if [ -f "$version_path" ] - then - echo "$DOTVERSION" | tr -d '\0' >> "$tarfiles_path" - fi - - if [ -f "$epoch_path" ] - then - echo "$DOTEPOCH" | tr -d '\0' >> "$tarfiles_path" - fi + for dotfile in "$revision_path" \ + "$version_path" \ + "$epoch_path" \ + "$rnd_seed_path" + do + if [[ -f "$dotfile" ]]; then + printf '%s\0' ".${dotfile##*.}" >> "$tarfiles_path" + fi + done } archive_files_date() { - local source_path=$1 + local source_path="$1" local epoch_path="$source_path/$DOTEPOCH" - if ! [ -z "$SOURCE_DATE_EPOCH" ] - then - ( - cd "$source_path" - find -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} \; - ) + if [[ -n "$SOURCE_DATE_EPOCH" ]]; then + find "$source_path" -execdir touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} + fi } archive_create() { - local archive_path=$1 - local source_path=$2 - local directory=$3 + local archive_path="$1" + local source_path="$2" + local directory="$3" local tarfiles_path="$source_path/$DOTTARFILES" - local directory_path=$( dirname "$archive_path" ) + local directory_path="$(dirname "$archive_path")" mkdir -p "$directory_path" - if [ -z "$directory" ] - then - directory=$( basename "$source_path" ) + if [[ -z "$directory" ]]; then + directory="$(basename "$source_path")" fi archive_files_create "$source_path" archive_files_date "$source_path" + local tar_options=( + --create + --xz + --file="$archive_path" + --files-from="$tarfiles_path" + --transform="s,^,$directory/,S" + --no-recursion + --warning=no-filename-with-nuls + --null + --owner=0 + --group=0 + --numeric-owner + ) + ( cd "$source_path" - tar -cJf "$archive_path" --no-recursion -T "$tarfiles_path" --transform="s,^,$directory/,S" --owner=root --group=root --numeric-owner + tar "${tar_options[@]}" ) } archive_extract() { - local archive_path=$1 - local destination_path=$2 + local archive_path="$1" + local destination_path="$2" - if [ -z "$destination_path" ] - then - destination_path=$( dirname "$archive_path" ) + if [[ -z "$destination_path" ]]; then + destination_path="$(dirname "$archive_path")" fi tar -xf "$archive_path" -ps -C "$destination_path" } rootfs_files_create() { - local source_path=$1 + local source_path="$1" - local directory=$( basename "$source_path" ) + local directory="$(basename "$source_path")" local tarfiles_path="$source_path/$DOTTARFILES" - touch "$tarfiles_path" - - ( - cd "$source_path" - execute_root find - ) | LC_ALL=C sort | sed "s,^./,," | grep -vP "^$DOTTARFILES|^\.$" > "$tarfiles_path" + # Files in "$tarfiles_path" are NUL terminated. + # `tr '\0' '\n'` for human-readable output. + execute_root find "$source_path" -print0 | env LC_ALL='C.UTF-8' sort -z | sed -z "1d;s,^$source_path/\\?,,;/^$DOTTARFILES\$/d" > "$tarfiles_path" } rootfs_files_date() { - local source_path=$1 + local source_path="$1" local epoch_path="$source_path/$DOTEPOCH" - if ! [ -z "$SOURCE_DATE_EPOCH" ] - then - ( - cd "$source_path" - execute_root find -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} \; - ) + if [[ -n "$SOURCE_DATE_EPOCH" ]]; then + execute_root find "$source_path" -execdir touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} + fi } rootfs_create() { - local rootfs_path=$1 - local source_path=$2 - local directory=$3 + local rootfs_path="$1" + local source_path="$2" + local directory="$3" local tarfiles_path="$source_path/$DOTTARFILES" - local directory_path=$( dirname "$rootfs_path" ) + local directory_path="$(dirname "$rootfs_path")" mkdir -p "$directory_path" - if [ -z "$directory" ] - then - directory=$( basename "$source_path" ) + if [[ -z "$directory" ]]; then + directory="$(basename "$source_path")" fi rootfs_files_create "$source_path" rootfs_files_date "$source_path" + local tar_options=( + --create + --xz + --file="$rootfs_path" + --files-from="$tarfiles_path" + --no-recursion + --warning=no-filename-with-nuls + --null + --owner=0 + --group=0 + --numeric-owner + ) + ( cd "$source_path" - execute_root tar -cJf "$rootfs_path" --no-recursion -T "$tarfiles_path" --numeric-owner + execute_root tar "${tar_options[@]}" ) execute_root chmod 644 "$rootfs_path" - execute_root chown $USER:$USER "$rootfs_path" + execute_root chown "$USER:$USER" "$rootfs_path" } requirements() { @@ -331,7 +383,7 @@ requirements() { if [ -z "$requirement_path" ] then - printf "Missing requirement: $requirement\n" >&2 + printf '%s\n' "Missing requirement: $requirement" >&2 exit 1 fi done @@ -348,7 +400,7 @@ requirements_root() { if [ -z "$requirement_path" ] then - printf "Missing requirement: $requirement\n" >&2 + printf '%s\n' "Missing requirement: $requirement" >&2 exit 1 fi done @@ -370,22 +422,22 @@ arguments_concat() { fi done - echo "$concat" + printf '%s\n' "$concat" } execute_root() { local sudo=$( which sudo 2> /dev/null || true ) local arguments - printf "Running command as root: " >&2 - echo "$@" >&2 + printf '%s' 'Running command as root: ' >&2 + printf '%b\n' "$*" >&2 if ! [ -z "$sudo" ] then sudo "$@" else # Quote arguments for eval through su. - arguments=$( printf "%q " "$@" ) + arguments=$( printf '%q ' "$@" ) su -c "$arguments" fi } |