diff --git a/autogen.sh b/autogen.sh index bfebce9..b2522ba 100755 --- a/autogen.sh +++ b/autogen.sh @@ -25,12 +25,14 @@ declare -r SRCDIR="${TEST_SRCDIR:-$(dirname $0)}" -LICENSE="${SRCDIR}/licenses/apache-2.0.txt" +LICENSE_NAME="apache" +LICENSE_FILE="${SRCDIR}/licenses/apache-2.0.txt" COPYRIGHT_HOLDER="Google Inc." YEAR="${YEAR:-$(date +%Y)}" +MODIFY_FILE_INPLACE=0 function printLicenseWithYear() { - cat "${LICENSE}" \ + cat "${LICENSE_FILE}" \ | sed "s/%YEAR%/${YEAR}/" \ | sed "s/%COPYRIGHT_HOLDER%/${COPYRIGHT_HOLDER}/" } @@ -43,6 +45,18 @@ function printLicenseHashComment() { printLicenseWithYear | sed -E "s/^/# /;s/ +$//" } +# Prepend piped-in text to a file in-place. +# +# Args: +# $1: filename to modify +function prependToFileInPlace() { + local -r target="${1}" + local -r tempfile="$(mktemp /tmp/$(basename $0).XXXXXX)" + cat - "${target}" > "${tempfile}" + mv -f "${tempfile}" "${target}" + rm -f "${tempfile}" +} + readonly TODO_COMMENT="TODO: High-level file comment." function printFileCommentTemplate() { local comment=$1 @@ -54,40 +68,45 @@ function printFileCommentTemplate() { echo "$comment ${TODO_COMMENT}" } -while getopts c:l:y: opt ; do +while getopts c:il:y: opt ; do case "${opt}" in c) COPYRIGHT_HOLDER="${OPTARG}" ;; + i) + MODIFY_FILE_INPLACE=1 + ;; + l) - case "${OPTARG}" in + LICENSE_NAME="${OPTARG}" + case "${LICENSE_NAME}" in apache) - LICENSE="${SRCDIR}/licenses/apache-2.0.txt" + LICENSE_FILE="${SRCDIR}/licenses/apache-2.0.txt" ;; bsd2|bsd-2) - LICENSE="${SRCDIR}/licenses/bsd-2-clause.txt" + LICENSE_FILE="${SRCDIR}/licenses/bsd-2-clause.txt" ;; bsd3|bsd-3) - LICENSE="${SRCDIR}/licenses/bsd-3-clause.txt" + LICENSE_FILE="${SRCDIR}/licenses/bsd-3-clause.txt" ;; bsd4|bsd-4) - LICENSE="${SRCDIR}/licenses/bsd-4-clause.txt" + LICENSE_FILE="${SRCDIR}/licenses/bsd-4-clause.txt" ;; gpl2|gpl-2) - LICENSE="${SRCDIR}/licenses/gpl-2.txt" + LICENSE_FILE="${SRCDIR}/licenses/gpl-2.txt" ;; gpl3|gpl-3) - LICENSE="${SRCDIR}/licenses/gpl-3.txt" + LICENSE_FILE="${SRCDIR}/licenses/gpl-3.txt" ;; lgpl|lgpl2|lgpl-2|lgpl2.1|lgpl-2.1) - LICENSE="${SRCDIR}/licenses/lgpl-2.1.txt" + LICENSE_FILE="${SRCDIR}/licenses/lgpl-2.1.txt" ;; mit) - LICENSE="${SRCDIR}/licenses/mit.txt" + LICENSE_FILE="${SRCDIR}/licenses/mit.txt" ;; *) - echo "Invalid license selected: ${OPTARG}" >&2 + echo "Invalid license selected: ${LICENSE_NAME}" >&2 exit 1 esac ;; @@ -104,9 +123,10 @@ if [[ $# -eq 0 ]]; then Syntax: $0 [options] Options: - -c [copyright holder] - -l [license] - -y [year] + -c [copyright holder] set copyright holder (default: "${COPYRIGHT_HOLDER}") + -i modify the given file in-place + -l [license] choose the license (default: "${LICENSE_NAME}") + -y [year] choose the year (default: ${YEAR}) Licenses: apache: Apache 2.0 @@ -120,7 +140,20 @@ Licenses: exit 1 fi -case "$1" in +declare -r FILE="$1" + +# Re-run this script with all the same flags, minus the in-place flag. +if [[ "${MODIFY_FILE_INPLACE}" -eq 1 ]]; then + $0 \ + -c "${COPYRIGHT_HOLDER}" \ + -l "${LICENSE_NAME}" \ + -y "${YEAR}" \ + "${FILE}" \ + | prependToFileInPlace "${FILE}" + exit $? +fi + +case "${FILE}" in # TODO(mbrukman): in some projects, *.h are actually C++ files where users # want to use C++ style "//" comments. How can we handle this flexibility? @@ -295,7 +328,7 @@ EOF ;; *) - echo "File type not recognized: $1" >&2 + echo "File type not recognized: ${FILE}" >&2 exit 1 ;; diff --git a/tests/inplace_tests.sh b/tests/inplace_tests.sh new file mode 100644 index 0000000..6fec2ac --- /dev/null +++ b/tests/inplace_tests.sh @@ -0,0 +1,84 @@ +#!/bin/bash -eu +# +# Copyright 2016 Google Inc. +# +# Licensed 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. +# +################################################################################ +# +# Run tests to verify that in-place file modification works as intended. +# TODO(mbrukman): run over the entire test suite's set of file types / licenses. +# +################################################################################ + +set -eu + +declare -r TEST_SRCDIR="$(dirname $0)/.." +declare -r TEST_TMPDIR="$(mktemp -d "/tmp/$(basename $0).XXXXXX")" + +function cleanup() { + rm -rf "${TEST_TMPDIR}" +} + +trap cleanup EXIT INT TERM + +declare -r RANDOM_DATA="$(date | md5)" + +declare -i num_passed=0 +declare -i num_failed=0 + +for ext in sh py rb hs; do + actual_file="${TEST_TMPDIR}/actual.${ext}" + expected_file="${TEST_TMPDIR}/expected.${ext}" + + # Generate the actual file and update it in-place. + echo "${RANDOM_DATA}" > "${actual_file}" + "${TEST_SRCDIR}/autogen.sh" -i "${actual_file}" + + # Generate the expected file using the usual means. + "${TEST_SRCDIR}/autogen.sh" "${expected_file}" > "${expected_file}" + echo "${RANDOM_DATA}" >> "${expected_file}" + + # Compare the two files. + diff -u "${expected_file}" "${actual_file}" + if [[ $? -eq 0 ]]; then + num_passed=$((num_passed+1)) + else + num_failed=$((num_failed+1)) + fi +done + +declare -ir NUM_TOTAL=$((num_passed + num_failed)) + +if [[ ${num_passed} -gt 0 ]]; then + if [ -t 1 ]; then + declare -r PASSED="\033[0;32mPASSED\033[0m" + else + declare -r PASSED="PASSED" + fi + echo -e "${PASSED}: ${num_passed} / ${NUM_TOTAL}" +fi + +if [[ ${num_failed} -gt 0 ]]; then + if [ -t 1 ]; then + declare -r FAILED="\033[0;31mFAILED\033[0m" + else + declare -r FAILED="FAILED" + fi + echo -e "${FAILED}: ${num_failed} / ${NUM_TOTAL}" + declare -r STATUS_CODE=1 +else + declare -r STATUS_CODE=0 +fi + +exit ${STATUS_CODE}