#!/usr/bin/env sh # ------------------------------------------------------------------------------ # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Hugo Wrapper (v1.1.0) # # Hugo Wrapper is a POSIX-style shell script which acts as a wrapper to download # and execute Hugo binary for your platform. It can be executed in variety of # Operating Systems and Command Shells. As a result, hugow has very minimal # number of dependencies: # # downloader: wget or curl # checksum : sha256sum or shasum or cksum # tarball : tar # # https://github.com/khos2ow/hugo-wrapper # ------------------------------------------------------------------------------ set -e VERSION_NUMBER="v1.1.0" # hugo-wrapper command available flags get_version="" get_latest=false get_extended=false upgrade=false version=false show_help=false # hugo related commands to pass through the actual binary HUGO_ARGS="" while [ -n "$1" ]; do case "$1" in --get-version) get_version=$2; shift 2 ;; --get-latest) get_latest=true; shift 1 ;; --get-extended) get_extended=true; shift 1 ;; --upgrade) upgrade=true; shift 1 ;; --version) version=true; shift 1 ;; -h | --help) show_help=true; shift 1 ;; *) HUGO_ARGS="$HUGO_ARGS $1"; shift 1 ;; esac done set -- $HUGO_ARGS if [ "$upgrade" = true ]; then if [ "$get_extended" = true -o "$get_latest" = true -o -n "$get_version" ]; then echo "Error: Flag --upgrade cannot be used together with --get-extended, --get-version or --get-latest" exit 1 fi else if [ "$get_latest" = true -a -n "$get_version" ]; then echo "Error: Flags --get-version and --get-latest cannot be used together" exit 1 fi fi # normalizing get_version get_version_base="$(echo "$get_version" | cut -d "/" -f1)" get_version_extended="$(echo "$get_version" | cut -d "/" -f2)" get_version="$get_version_base" if [ "$get_version_extended" = "extended" ]; then get_extended=true fi # check which download command (wget or curl) is available. DOWNLOAD_COMMAND="" DOWNLOAD_OUTPUT="" DOWNLOAD_SILENT="" DOWNLOAD_REDIRECT="" if command -v wget > /dev/null; then DOWNLOAD_COMMAND="wget" DOWNLOAD_OUTPUT="-O" DOWNLOAD_SILENT="-q" DOWNLOAD_REDIRECT="" elif command -v curl > /dev/null; then DOWNLOAD_COMMAND="curl" DOWNLOAD_OUTPUT="-o" DOWNLOAD_SILENT="-s" DOWNLOAD_REDIRECT="-L" else echo "Error: Unable to find 'wget' or 'curl' command." exit 1 fi # OS type os_type="" case "`uname -s`" in Darwin) os_type="macOS" ;; Linux) os_type="Linux" ;; DragonFly) os_type="DragonFlyBSD" ;; FreeBSD) os_type="FreeBSD" ;; NetBSD) os_type="NetBSD" ;; OpenBSD) os_type="OpenBSD" ;; # CYGWIN* os_type="Windows" ;; # MINGW*) os_type="Windows" ;; # Windows_NT) os_type="Windows" ;; esac # OS architecture os_arch="" case "`uname -m`" in x86) os_arch="32bit" ;; x86_64) os_arch="64bit" ;; amd64) os_arch="64bit" ;; armv7l) os_arch="ARM" ;; armv8) os_arch="ARM64" ;; esac if [ -z "$os_type" -o -z "$os_arch" ]; then echo "Error: Unknown OS type or architecture" exit 1 fi # ------------------------------------------------------------------------------ # traverses directory structure from process work directory to filesystem root # first directory with .hugo subdirectory is considered project base directory # ------------------------------------------------------------------------------ find_basedir() { if [ -z "$1" ]; then echo "Error: Path not specified to find_basedir" return 1 fi basedir="$1" wdir="$1" while [ "$wdir" != '/' ]; do if [ -d "$wdir"/.hugo ]; then basedir=$wdir break fi if [ -d "${wdir}" ]; then wdir=`cd "$wdir/.."; pwd` fi done echo "${basedir}" } BASE_DIR=`find_basedir "$(pwd)"` if [ -z "$BASE_DIR" ]; then echo "Error: Unable to find base directory." exit 1 fi if [ ! -d "$BASE_DIR/.hugo" ]; then mkdir -p "$BASE_DIR/.hugo" else if [ -r "$BASE_DIR/.hugo/hugo" -a ! -s "$BASE_DIR/.hugo/hugo" ]; then rm "$BASE_DIR/.hugo/hugo" fi if [ -r "$BASE_DIR/.hugo/version" -a ! -s "$BASE_DIR/.hugo/version" ]; then rm "$BASE_DIR/.hugo/version" fi fi parse_json() { local json="$1" local field="$2" if [ -z "$json" ]; then echo "" elif [ -z "$field" ]; then echo "" fi temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $field` echo ${temp##*|} | sed "s/${field}: //g" } perform_checksum() { if [ -n "$1" ]; then if command -v sha256sum > /dev/null; then echo "$1" | sha256sum --check > /dev/null elif command -v shasum > /dev/null; then echo "$1" | shasum --algorithm 256 --check > /dev/null elif command -v cksum > /dev/null; then echo "$1" | cksum -a SHA256 -c > /dev/null else echo "Error: cannot find any checksum command" exit 1 fi fi } remove_file() { if [ -n "$1" -a "$1" != "/" -a -f "$1" -a -r "$1" ] ; then rm "$1" fi } download_version() { local versionToDownload="$1" local isExtended="$2" if [ -n "$versionToDownload" ]; then local filenamePrefix="hugo" local versionDownloadSuffix="" if [ "$isExtended" = true ]; then filenamePrefix="hugo_extended" versionDownloadSuffix="/extended" fi if [ "$versionToDownload" = "LATEST" ]; then latest_release=`$DOWNLOAD_COMMAND $DOWNLOAD_SILENT $DOWNLOAD_REDIRECT ${DOWNLOAD_OUTPUT}- https://api.github.com/repos/gohugoio/hugo/releases/latest` versionToDownload=`parse_json "$latest_release" "tag_name"` fi # strip down 'v' from begining of the string if exists versionToDownload=`echo $versionToDownload | sed -ne 's/[^0-9]*\(\([0-9]*\.\)\{0,4\}[0-9]*\(\/extended\)*\).*/\1/p'` printf "downloading hugo binary version v${versionToDownload}${versionDownloadSuffix} ... " # download for specific OS and architecture local binaryUrl="https://github.com/gohugoio/hugo/releases/download/v${versionToDownload}/${filenamePrefix}_${versionToDownload}_${os_type}-${os_arch}.tar.gz" local checksumUrl="https://github.com/gohugoio/hugo/releases/download/v${versionToDownload}/${filenamePrefix}_${versionToDownload}_checksums.txt" local tarballName="${filenamePrefix}_${versionToDownload}_${os_type}-${os_arch}.tar.gz" local tarballPath="$BASE_DIR/.hugo/${tarballName}" local checksumName="checksum.txt" local checksumPath="$BASE_DIR/.hugo/${checksumName}" $DOWNLOAD_COMMAND $DOWNLOAD_SILENT $DOWNLOAD_REDIRECT $DOWNLOAD_OUTPUT "$tarballPath" "$binaryUrl" & $DOWNLOAD_COMMAND $DOWNLOAD_SILENT $DOWNLOAD_REDIRECT $DOWNLOAD_OUTPUT "$checksumPath" "$checksumUrl" & wait if [ -s "$tarballPath" -a -s "$checksumPath" ]; then printf "[done]\n" else printf "[failed]\n" remove_file "$checksumPath" remove_file "$tarballPath" exit 1 fi printf "verifying hugo binary version v${versionToDownload}${versionDownloadSuffix} ..... " cd $BASE_DIR/.hugo/ grep "${tarballName}" "$BASE_DIR/.hugo/$checksumName" | perform_checksum cd - > /dev/null 2>&1 wait printf "[done]\n" printf "unzipping hugo binary version v${versionToDownload}${versionDownloadSuffix} ..... " if [ -f "${tarballPath}" -a -r "${tarballPath}" ]; then tar --directory="$BASE_DIR/.hugo/" -xzf "${tarballPath}" 2>&1 wait printf "[done]\n" else printf "[failed]\n" remove_file "$checksumPath" remove_file "$tarballPath" exit 1 fi # save the downloaded binary version into $BASE_DIR/.hugo/version echo "${versionToDownload}${versionDownloadSuffix}" > $BASE_DIR/.hugo/version # cleanup after extraction remove_file "$checksumPath" remove_file "$tarballPath" remove_file "$BASE_DIR/.hugo/LICENSE" remove_file "$BASE_DIR/.hugo/README.md" fi } # ------------------------------------------------------------------------------ # upgrade hugo wrapper binary and save it as ${BASE_DIR}/hugow # ------------------------------------------------------------------------------ if [ "$version" = true ]; then echo "Hugo Wrapper $VERSION_NUMBER" exit fi # ------------------------------------------------------------------------------ # upgrade hugo wrapper binary and save it as ${BASE_DIR}/hugow # ------------------------------------------------------------------------------ if [ "$upgrade" = true ]; then printf "downloading hugow binary ... " latest_release=`$DOWNLOAD_COMMAND $DOWNLOAD_SILENT $DOWNLOAD_REDIRECT ${DOWNLOAD_OUTPUT}- https://api.github.com/repos/khos2ow/hugo-wrapper/releases/latest` versionToDownload=`parse_json "$latest_release" "tag_name"` $DOWNLOAD_COMMAND $DOWNLOAD_SILENT $DOWNLOAD_REDIRECT $DOWNLOAD_OUTPUT "hugow" "https://github.com/khos2ow/hugo-wrapper/releases/download/${versionToDownload}/hugow" & wait printf "[done]\n" chmod +x hugow exit fi # ------------------------------------------------------------------------------ # download hugo binary and save it as ${BASE_DIR}/.hugo/hugo # ------------------------------------------------------------------------------ if [ -r "$BASE_DIR/.hugo/hugo" ]; then current_binary_version="$($BASE_DIR/.hugo/hugo version | sed -ne 's/[^0-9]*\(\([0-9]*\.\)\{0,4\}[0-9]*\(\/extended\)*\).*/\1/p' | sed 's/^ *//;s/ *$//')" if [ "$get_extended" = true ]; then suffix_extended_version="/extended" fi # download hugo binary and save it as ${BASE_DIR}/.hugo/hugo if [ -n "$get_version" ]; then if [ "${get_version}${suffix_extended_version}" != "$current_binary_version" ]; then # specified hugo version download_version "$get_version" $get_extended else echo "hugo binary version ${get_version}${suffix_extended_version} already exists" echo "${get_version}${suffix_extended_version}" > $BASE_DIR/.hugo/version fi elif [ $get_latest = true ]; then latest_release=`$DOWNLOAD_COMMAND $DOWNLOAD_SILENT $DOWNLOAD_REDIRECT ${DOWNLOAD_OUTPUT}- https://api.github.com/repos/gohugoio/hugo/releases/latest` latest_version=`parse_json "$latest_release" "tag_name" | sed -ne 's/[^0-9]*\(\([0-9]*\.\)\{0,4\}[0-9]*\(\/extended\)*\).*/\1/p'` if [ "${latest_version}${suffix_extended_version}" != "$current_binary_version" ]; then # latest hugo version download_version "$latest_version" $get_extended else echo "latest hugo binary version ${latest_version}${suffix_extended_version} already exists" echo "${latest_version}${suffix_extended_version}" > $BASE_DIR/.hugo/version fi elif [ -r "$BASE_DIR/.hugo/version" ]; then current_file_version="$(cat "$BASE_DIR/.hugo/version")" if [ "$current_file_version" != "$current_binary_version" ]; then version_from_file="$(echo "$current_file_version" | cut -d "/" -f1)" extended_from_file="$(echo "$current_file_version" | cut -d "/" -f2)" if [ "${extended_from_file}" = "extended" ]; then isExtended=true else isExtended=false fi # specified hugo version download_version "$version_from_file" $isExtended fi else # save the current binary version into $BASE_DIR/.hugo/version echo "$current_binary_version" > $BASE_DIR/.hugo/version fi else if [ -n "$get_version" ]; then # specified hugo version download_version "$get_version" $get_extended elif [ $get_latest = true ]; then # latest hugo version download_version "LATEST" $get_extended elif [ -r "$BASE_DIR/.hugo/version" ]; then # specified hugo version version_from_file="$(cat "$BASE_DIR/.hugo/version" | cut -d "/" -f1)" extended_from_file="$(cat "$BASE_DIR/.hugo/version" | cut -d "/" -f2)" if [ "${extended_from_file}" = "extended" ]; then isExtended=true else isExtended=false fi download_version "${version_from_file}" $isExtended else # latest hugo version download_version "LATEST" $get_extended fi fi # ------------------------------------------------------------------------------ # only download binary and not execute hugo related command # ------------------------------------------------------------------------------ if [ "$get_latest" = true -o -n "$get_version" ]; then ${BASE_DIR}/.hugo/hugo version exit fi # ------------------------------------------------------------------------------ # Show help, both from hugow and ${BASE_DIR}/.hugo/hugo # ------------------------------------------------------------------------------ if [ $show_help = true ]; then help=$(${BASE_DIR}/.hugo/hugo --help) cat << USAGE hugow is the universal wrapper for hugo main command. Hugo is a Fast and Flexible Static Site Generator built with love by spf13 and friends in Go. Complete documentation is available at http://gohugo.io/. Flags: --get-extended get hugo extended binary --get-latest get latest version of hugo binary --get-version string get specified version of hugo binary --upgrade upgrade hugo wrapper binary itself --version show version of hugo wrapper binary itself -h, --help help for hugo-wrapper -------- $help USAGE exit 0 fi # ------------------------------------------------------------------------------ # pass commands and flags to actual hugo binary # ------------------------------------------------------------------------------ ${BASE_DIR}/.hugo/hugo "$@"