Permalink
Switch branches/tags
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 303 lines (271 sloc) 8.5 KB
#!/bin/bash
#
# Licensed to Julian Hyde under one or more contributor license
# agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership.
#
# Julian Hyde 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.
#
# ==============================================================================
# Checks that a file is valid.
# The file is deemed to be valid if this command produces no output.
#
# Usage:
# checkFile [ --depotPath <depotPath> ] <file>
#
usage() {
echo "checkFile [ <options> ] --depotPath <depotPath> <file>"
echo " Checks a temporary file. depotPath is the full path of"
echo " the file stored in perforce, for error reporting; file"
echo " holds the actual file contents."
echo "checkFile [ <options> ] <file>..."
echo " Checks a list of files."
echo "checkFile [ <options> ] --opened"
echo " Checks all files that are opened in git. Implies --strict."
echo "checkFile [ <options> ] --under <dir>"
echo " Recursively checks all files under a given directory."
echo "checkFile --help"
echo " Prints this help."
echo
echo "Options:"
echo "--lenient"
echo " Does not apply rules to components which are not known to"
echo " be in compliance. The perforce trigger uses this option."
echo "--strict"
echo " Stricter than usual; the opposite of lenient."
}
doCheck() {
filePath="$1"
file="$2"
maxLineLength="$3"
# CHECKFILE_IGNORE is an environment variable that contains a callback
# to decide whether to check this file. The command or function should
# succeed (that is, return 0) if checkFile is to ignore the file, fail
# (that is, return 1 or other non-zero value) otherwise.
if [ "$CHECKFILE_IGNORE" ]; then
if eval $CHECKFILE_IGNORE "$filePath"; then
return
fi
fi
# Exceptions for mondrian
case "$filePath" in
*/mondrian/util/Base64.java| \
*/mondrian/olap/MondrianDef.java| \
*/mondrian/gui/MondrianGuiDef.java| \
*/mondrian/xmla/DataSourcesConfig.java| \
*/mondrian/rolap/aggmatcher/DefaultDef.java| \
*/mondrian/resource/MondrianResource*.java| \
*/mondrian/olap/Parser.java| \
*/mondrian/olap/ParserSym.java)
# mondrian.util.Base64 is checked in as is, so don't check it
# Other files above are generated.
return
;;
# Exceptions for olap4j
*/org/olap4j/mdx/parser/impl/*.java| \
*/org/olap4j/impl/Base64.java)
return
;;
# Exceptions for farrago
*/farrago/classes/* | \
*/farrago/catalog/* | \
*/farrago/examples/rng/src/net/sf/farrago/rng/parserimpl/*.java | \
*/farrago/examples/rng/src/net/sf/farrago/rng/resource/FarragoRngResource*.java | \
*/farrago/examples/rng/catalog/net/sf/farrago/rng/rngmodel/* | \
*/farrago/examples/rng/catalog/java/* | \
*/farrago/jdbc4/*.java | \
*/farrago/src/net/sf/farrago/FarragoMetadataFactoryImpl.java | \
*/farrago/src/net/sf/farrago/FarragoMetadataFactory.java | \
*/farrago/src/net/sf/farrago/parser/impl/*.java | \
*/farrago/src/net/sf/farrago/resource/FarragoResource*.java | \
*/farrago/src/net/sf/farrago/resource/FarragoInternalQuery*.java | \
*/farrago/src/net/sf/farrago/test/FarragoSqlTestWrapper.java | \
*/farrago/src/org/eigenbase/jdbc4/*.java | \
*/farrago/src/org/eigenbase/lurql/parser/*.java | \
*/farrago/src/com/lucidera/lurql/parser/*.java | \
*/farrago/src/org/eigenbase/resource/EigenbaseResource*.java | \
*/farrago/src/org/eigenbase/sql/parser/impl/*.java)
return
;;
# Exceptions for fennel
*/fennel/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp | \
*/fennel/disruptivetech/calc/CalcGrammar.tab.cpp | \
*/fennel/disruptivetech/calc/CalcGrammar.cpp | \
*/fennel/disruptivetech/calc/CalcGrammar.h | \
*/fennel/disruptivetech/calc/CalcLexer.cpp | \
*/fennel/disruptivetech/calc/CalcLexer.h | \
*/fennel/calculator/CalcGrammar.tab.cpp | \
*/fennel/calculator/CalcGrammar.cpp | \
*/fennel/calculator/CalcGrammar.h | \
*/fennel/calculator/CalcLexer.cpp | \
*/fennel/calculator/CalcLexer.h | \
*/fennel/common/FemGeneratedEnums.h | \
*/fennel/common/FennelResource.cpp | \
*/fennel/common/FennelResource.h | \
*/fennel/config.h | \
*/fennel/farrago/FemGeneratedClasses.h | \
*/fennel/farrago/FemGeneratedMethods.h | \
*/fennel/farrago/NativeMethods.h)
return
;;
# Skip our own test files, unless we are testing.
*/util/test/CheckFile1.*)
if [ ! "$test" ]; then
return
fi
;;
# Only validate .java and .jj files at present.
*.java|*.h|*.cpp)
;;
*)
return
;;
esac
# Set maxLineLength if it is not already set. ('checkFile --opened'
# sets it to the strictest value, 80).
if [ ! "$maxLineLength" ]; then
maxLineLength=80
fi
# Check whether there are tabs, or lines end with spaces
# todo: check for ' ;'
# todo: check that every file has copyright/license header
# todo: check that every class has javadoc
# todo: check that every top-level class has @author and @version
# todo: check c++ files
if test "$deferred" ; then
echo "$file" >> "${deferred_file}"
else
gawk -f "$CHECKFILE_AWK" \
-v fname="$filePath" \
-v strict="$strict" \
-v maxLineLength="$maxLineLength" \
"$file"
fi
}
doCheckDeferred() {
if [ -s "${deferred_file}" ]; then
maxLineLength=80
cat "${deferred_file}" |
xargs -P $(expr ${CORE_COUNT} \* 2) -n 100 gawk -f "$CHECKFILE_AWK" \
-v strict="$strict" \
-v maxLineLength="$maxLineLength"
fi
rm -f "${deferred_file}"
}
function guessCoreCount() {
if [ -f /proc/cpuinfo ]; then
cat /proc/cpuinfo | awk '$1 == "processor"' | wc -l
else
# File doe not exist on Darwin or cygwin
echo 2
fi
}
export CORE_COUNT=$(guessCoreCount)
export deferred=true
# 'test' is an undocumented flag, overriding the default behavior which is
# to ignore our own test files
test=
if [ "$1" == --test ]; then
test=true
shift
fi
strict=1
if [ "$1" == --lenient ]; then
strict=0
shift
fi
if [ "$1" == --help ]; then
usage
exit 0
fi
if [ "$1" == --strict ]; then
strict=2
shift
fi
depotPath=
if [ "$1" == --depotPath ]; then
depotPath="$2"
deferred=
shift 2
fi
opened=
if [ "$1" == --opened ]; then
opened=true
deferred=
strict=2
shift
fi
under=
if [ "$1" == --under ]; then
if [ "$opened" ]; then
echo "Cannot specify both --under and --opened"
exit 1
fi
if [ ! -d "$2" ]; then
echo "--under requires a directory; '$2' not found"
exit 1
fi
under="$2"
shift 2
fi
if [ "$1" == --opened ]; then
echo "Cannot specify both --under and --opened"
exit 1
fi
if [ ! -f "$CHECKFILE_AWK" ]
then
case $(uname) in
(Darwin)
export CHECKFILE_AWK="$(cd $(dirname $0); pwd -P)/checkFile.awk";;
(*)
export CHECKFILE_AWK="$(dirname $(readlink -f $0))/checkFile.awk";;
esac
fi
export deferred_file=/tmp/checkFile_deferred_$$.txt
rm -f "${deferred_file}"
(
if [ "$under" ]; then
find "$under" -type f |
while read file; do
filePath="$file"
if [ "$depotPath" ]; then
filePath="$depotPath"
fi
doCheck "$filePath" "$file" ""
done
elif [ "$opened" ]; then
git checkout |
gawk '$1 != "D" {print $2}' |
while read file; do
doCheck "$file" "$file" "80"
done
else
for file in "$@"; do
filePath="$file"
if [ "$depotPath" ]; then
filePath="$depotPath"
fi
doCheck "$filePath" "$file" ""
done
fi
if test "$deferred"; then
doCheckDeferred
fi
) | tee /tmp/checkFile_output_$$.txt
status=0
if [ -s /tmp/checkFile_output_$$.txt ]; then
status=1
fi
rm -f /tmp/checkFile_output_$$.txt
exit $status
# End checkFile.sh