CheckPrecommit.java revision 2efcb9667318c099d8723dd578f198c16b4a22c4
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * CDDL HEADER START
1d753fdeb00e3867c6bbf94ab3c36cd6734dd447vboxsync * The contents of this file are subject to the terms of the
1d753fdeb00e3867c6bbf94ab3c36cd6734dd447vboxsync * Common Development and Distribution License, Version 1.0 only
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * (the "License"). You may not use this file except in compliance
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * with the License.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * You can obtain a copy of the license at
d14682a025d2c801f1e777f491092d2ebbe78c3cvboxsync * trunk/opends/resource/legal-notices/OpenDS.LICENSE
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * See the License for the specific language governing permissions
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * and limitations under the License.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * When distributing Covered Code, include this CDDL HEADER in each
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * file and include the License file at
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * add the following below this CDDL HEADER, with the fields enclosed
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * by brackets "[]" replaced with your own identifying information:
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync * Portions Copyright [yyyy] [name of copyright owner]
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync * CDDL HEADER END
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Copyright 2008 Sun Microsystems, Inc.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * Portions copyright 2012 ForgeRock AS.
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * This class provides an implementation of an Ant task that may be used to
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * perform various checks to deteermine whether a file is suitable to be
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * committed. This includes:
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * <LI>Make sure that the file has the correct "svn:eol-style" property
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * value.</LI>
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * <LI>If a file contains a line that appears to be a comment and includes the
5a07658d13590eba51dd98ef335a73d2a11edaa7vboxsync * word "copyright", then it should contain the current year.</LI>
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * The name of the system property that may be used to prevent copyright date
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * problems from failing the build.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync public static final String IGNORE_COPYRIGHT_ERRORS_PROPERTY =
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync "org.opends.server.IgnoreCopyrightDateErrors";
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * The name of the system property that may be used to prevent svn eol-style
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * problems from failing the build.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync public static final String IGNORE_EOLSTYLE_ERRORS_PROPERTY =
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync "org.opends.server.IgnoreEOLStyleErrors";
e6e69eb2216092b564f920a6214f5103333ce54cvboxsync public static final HashSet<String> CHECKED_EXTENSIONS =
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync // The path to the directory that is the base of the workspace.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync // The set of files that appear to have problems with the EOL style.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync private LinkedList<String> eolStyleProblemFiles = new LinkedList<String>();
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync // The set of files that appear to have problems with the copyright date.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync private LinkedList<String> copyrightProblemFiles = new LinkedList<String>();
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync // The path to the root of the Subversion workspace to check.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync // The string representation of the current year.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync // The overall SVN Client Manager. required with svnkit 1.2.x
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync // The property client used to look at file properties.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * Specifies the path to the root of the Subversion workspace for which to
56db633f06f3070f792e84b806b77873e3e98404vboxsync * retrieve the revision number.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * @param workspace The path to the root of the Subversion workspace for
18745d2ecb6a9d5f83c1c7a6f823847b9c3b4f57vboxsync * which to retrieve the revision number.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * Performs the appropriate processing needed for this task. In this case,
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * it uses SVNKit to identify all modified files in the current workspace.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * For all source files, look for comment lines containing the word
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * "copyright" and make sure at least one of them contains the current year.
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync public void execute()
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync if ((workspace == null) || (workspace.length() == 0))
610972deee47d5e5229ccdb6c86cbb332d2b4626vboxsync // Get the year to use in the determination.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync GregorianCalendar calendar = new GregorianCalendar();
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync // Process the base directory and all of its subdirectories.
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync ourClientManager.getStatusClient().doStatus(workspacePath, SVNRevision.WORKING,
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync SVNDepth.INFINITY, false, false, false, false, this, null);
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync System.err.println("WARNING: Encountered an error while examining " +
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync "Subversion status: " + e);
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync System.err.println("No further checks will be performed.");
bcd589d9db90b68d3af5d6839c1d613bb64d4c04vboxsync boolean fail = false;
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync System.err.println("WARNING: Potential svn:eol-style updates needed " +
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync "for the following files:");
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync getProject().getProperty(IGNORE_EOLSTYLE_ERRORS_PROPERTY);
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync if ((ignoreProp == null) || (! ignoreProp.equalsIgnoreCase("true")))
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync System.err.println("Fix svn:eol-style problems before proceeding, or " +
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync "=true' to ignore svn eol-style warnings.");
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync System.err.println("WARNING: Potential copyright year updates needed " +
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync "for the following files:");
da7386fee6ea74052fdce065965f745d7bc9522dvboxsync getProject().getProperty(IGNORE_COPYRIGHT_ERRORS_PROPERTY);
aa4cd5b56e5cf2c510a42ddc153bd0f1f0c64fbavboxsync if ((ignoreProp == null) || (! ignoreProp.equalsIgnoreCase("true")))
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync System.err.println("Fix copyright date problems before proceeding, " +
7c19e11502220292d5270519296442234c2493cdvboxsync "=true' to ignore copyright warnings.");
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * Examines the provided status item to determine whether the associated file
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync * is acceptable.
7c19e11502220292d5270519296442234c2493cdvboxsync * @param status The SVN status information for the file of interest.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // The file doesn't exist (which probably means it's been deleted) or
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // isn't a regular file, so we'll ignore it.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync String extension = fileName.substring(lastPeriodPos+1);
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync if (! CHECKED_EXTENSIONS.contains(extension.toLowerCase()))
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // The file doesn't have an extension that we care about, so skip it.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // The file doesn't have an extension. We'll still want to check it if
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // it's in a resource/bin directory.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync if (filePath.startsWith(workspacePath.getPath() + "/"))
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync filePath = filePath.substring(workspacePath.getPath().length() + 1);
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // Check to make sure that the file has the correct EOL style.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync propertyClient.doGetProperty(file, "svn:eol-style",
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync (! propertyData.getValue().getString().equals("native")))
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // This could happen if the file isn't under version control. If so, then
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // we can't check the eol-style but we should at least be able to check
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // the copyright dates, so keep going.
892e4404b22b024dd58b9561787a5ac46a02b6c5vboxsync // Check to see whether the file has a comment line containing a copyright
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync // without the current year.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync boolean copyrightFound = false;
cbc215af8423a8326b27143c59c5d8fc9ffb0279vboxsync boolean correctYearFound = false;
ece707b8d97e63ed54d4b48d7a8d841187e0023cvboxsync System.err.println("ERROR: Could not read file " + filePath +
ece707b8d97e63ed54d4b48d7a8d841187e0023cvboxsync " to check copyright date.");
ece707b8d97e63ed54d4b48d7a8d841187e0023cvboxsync System.err.println("No further copyright date checking will be " +
ece707b8d97e63ed54d4b48d7a8d841187e0023cvboxsync "performed.");
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync } catch (Exception e) {}
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * Indicates whether the provided line appears to be a comment line. It will
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * check for a number of common comment indicators in Java source files,
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * shell scripts, XML files, and LDIF files.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * @param lowerLine The line to be checked. It should have been coverted to
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * all lowercase characters and any leading spaces
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * @return {@code true} if it appears that the line is a comment line, or
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync * {@code false} if not.
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync private static boolean isCommentLine(String lowerLine)
3a45119099f0df5230e8304145168aa5e2a3f1a1vboxsync return true;
6ba96ad7028e4d559a5998de4bab0b71a8251c99vboxsync return false;