diff --git a/developer/bin/cask-switch-https b/developer/bin/cask-switch-https new file mode 100755 index 0000000000..8b8c57e4b7 --- /dev/null +++ b/developer/bin/cask-switch-https @@ -0,0 +1,188 @@ +#!/bin/bash + +set -o pipefail + +readonly program="$(basename "$0")" +skip_curl_head=0 +verbose=0 + +syntax_error() { + echo "$program: $1" >&2 + echo "Try \`$program --help\` for more information." >&2 + exit 1 +} + +usage() { + echo " + This script changes the url, appcast and homepage stanzas to https + + After changing to https a http head request is performed to verify if the url is reachable. + If the https url is not reachable it is reverted to the previous version. + + Known Issues: If multiple url/appcast stanzas are present, all urls are changed but only + those for the current os are verified. + + If no cask name is given the current work directory is scanned with the given options. + + usage: $program [options] [] + options: + -s, --skip-verify Skip checking for a HTTP 200 Status Code using curl head. + --verbose Show more verbose output. + -h, --help Show this help. + + Based on: https://github.com/vitorgalvao/tiny-scripts/blob/master/cask-repair + " | sed -E 's/^ {4}//' +} + +# available flags +while [[ "$1" ]]; do + case "$1" in + -h | --help) + usage + exit 0 + ;; + -s | --skip-verify) + skip_curl_head=1 + ;; + --verbose) + verbose=1 + ;; + -*) + syntax_error "unrecognized option: $1" + ;; + *) + break + ;; + esac + shift +done + +# define function to check if given URL exists and is reachable using HTTPS +check_url_for_https() { + cask_url="$1" + verbose_option="" + + [[ ${verbose} -ne 0 ]] && verbose_option="-v " + + # check if the URL sends a 200 HTTP code, else abort + browser_headers="User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36" + cask_status=$(curl --silent ${verbose_option}--head --max-time 10 --proto =https --location --header "${browser_headers}" "${cask_url}") + exit_code=$? + + if [[ exit_code -ne 0 ]]; then + echo "curl returned ${exit_code}: FAIL for ${cask_url}" + return 1 + fi + + cask_status=$(echo ${cask_status} | grep '^HTTP' | tail -1 | perl -pe 's|.* (\d{3}) .*|\1|') + + if [[ "${cask_status}" != '200' ]]; then + if [[ -z "${cask_status}" ]]; then + echo "URL ${cask_url} is not reachable!" + return 2 + else + echo "Download URL returned ${cask_status}" + return 3 + fi + fi + + return 0 +} + +# define function to modify part of stanza +replace_protocol_of_stanza() { + cask_file="$1" + stanza="$2" + old_value="$3" + new_value="$4" + + sed "s|${stanza} \(['\"]\)${old_value}://|${stanza} \1${new_value}://|g" "${cask_file}" > tmpfile + mv tmpfile "${cask_file}" +} + +# define abort function, that will reset the state +finish() { + # show message + if [[ "$1" == 'abort' ]]; then + echo -e "$(tput setaf 1)$2$(tput sgr0)\n" + [[ ! -z "${cask_file}" ]] && git checkout -- "${cask_file}" + exit 1 + elif [[ "$1" == 'success' ]]; then + echo -e "$(tput setaf 2)Updated: ${cask_name} is now using HTTPS$(tput sgr0)\n" + exit 0 + fi +} + +# cleanup if aborted with ⌃C +trap 'finish abort "You aborted"' SIGINT + +# exit if not inside a 'homebrew-*/Casks' directory +casks_dir=$(pwd | perl -ne 'print m{homebrew-[^/]+/Casks}') +if [[ -z "${casks_dir}" ]]; then + echo -e "\n$(tput setaf 1)You need to be inside a '/homebrew-*/Casks' directory$(tput sgr0)\n" + exit 1 +fi + +# exit if no argument was given: Run in current directory +if [[ -z "$1" ]]; then + options="" + [[ ${skip_curl_head} -ne 0 ]] && options+=" --skip-verify" + [[ ${verbose} -ne 0 ]] && options+=" --verbose" + + for file in *.rb; + do + ${program} ${options} ${file} + done + + exit 0 +fi + +# clean the cask's name, and check if it is valid +cask_name="$1" +[[ "${cask_name}" == *'.rb' ]] && cask_name=$(echo "${cask_name}" | sed 's|\.rb$||') +cask_file="./${cask_name}.rb" +[[ ! -f "${cask_file}" ]] && finish abort 'There is no such cask' + +# initial tasks +git checkout -- "${cask_file}" + +# check if a http url exists +cask_contains_http=$(grep "['\"]http://" "${cask_file}") +if [[ -z ${cask_contains_http} ]]; then + echo -e "Skipped ${cask_name} no http found\n" + exit 0 +fi + +updated_stanzas=0 +for stanza in url appcast homepage; do + # Check if the stanza exists + stanza_contained=$(grep "${stanza} ['\"]" "${cask_file}") + [[ -z ${stanza_contained} ]] && continue + + stanza_contains_https=$(grep "${stanza} ['\"]http://" "${cask_file}") + if [[ -z ${stanza_contains_https} ]]; then +# echo "Skipped stanza ${stanza} in ${cask_name} no http url found" + continue + fi + + replace_protocol_of_stanza ${cask_file} ${stanza} "http" "https" + + if [[ ${skip_curl_head} -eq 0 ]]; then + check_url_for_https $(brew cask _stanza ${stanza} "${cask_name}") + else + true + fi + + if [[ $? -ne 0 ]]; then + echo "Restored original value for stanza ${stanza} as curl head failed" + replace_protocol_of_stanza ${cask_file} ${stanza} "https" "http" + else + updated_stanzas=$((updated_stanzas+1)) + fi +done + +if [[ ${updated_stanzas} -ne 0 ]]; then + finish success +else + finish abort "no updated stanzas after verify for ${cask_name}" +fi