From 7f5e660395c13d2529127208f84706a40a87c2a2 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Wed, 10 Mar 2021 21:47:37 +0100 Subject: [PATCH] LUCENE-9375: some build file cleanups. (#10) --- build.gradle | 1 - gradle/ant-compat/artifact-naming.gradle | 21 -- gradle/ant-compat/force-versions.gradle | 37 --- gradle/maven/defaults-maven.gradle | 86 +------ gradle/testing/randomization.gradle | 8 +- .../randomization/policies/solr-tests.policy | 217 ---------------- gradle/validation/precommit.gradle | 1 - gradle/validation/validate-log-calls.gradle | 235 ------------------ 8 files changed, 6 insertions(+), 600 deletions(-) delete mode 100644 gradle/ant-compat/artifact-naming.gradle delete mode 100644 gradle/ant-compat/force-versions.gradle delete mode 100644 gradle/testing/randomization/policies/solr-tests.policy delete mode 100644 gradle/validation/validate-log-calls.gradle diff --git a/build.gradle b/build.gradle index aca6fc223bd..8f02892eef5 100644 --- a/build.gradle +++ b/build.gradle @@ -146,7 +146,6 @@ apply from: file('gradle/validation/rat-sources.gradle') apply from: file('gradle/validation/owasp-dependency-check.gradle') apply from: file('gradle/validation/ecj-lint.gradle') apply from: file('gradle/validation/gradlew-scripts-tweaked.gradle') -apply from: file('gradle/validation/validate-log-calls.gradle') apply from: file('gradle/validation/check-broken-links.gradle') if (!skipLucene) { diff --git a/gradle/ant-compat/artifact-naming.gradle b/gradle/ant-compat/artifact-naming.gradle deleted file mode 100644 index 8a0c253537a..00000000000 --- a/gradle/ant-compat/artifact-naming.gradle +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -// Stick to previous artifact names (not identical to path/ folders). -configure(subprojects.findAll { it.path.contains(':solr:contrib:') }) { - project.archivesBaseName = project.archivesBaseName.replace("-contrib-", "-") -} diff --git a/gradle/ant-compat/force-versions.gradle b/gradle/ant-compat/force-versions.gradle deleted file mode 100644 index 1af573f0cf7..00000000000 --- a/gradle/ant-compat/force-versions.gradle +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - */ - - -// Force versions of certain components to align them with ant build. - -project(":solr").subprojects { - plugins.withType(JavaPlugin) { - dependencies { - implementation enforcedPlatform('org.slf4j:slf4j-api:1.7.24') - implementation enforcedPlatform('commons-logging:commons-logging:1.1.3') - } - } -} - -configure(project(":solr:server")) { - afterEvaluate { - dependencies { - libExt enforcedPlatform('org.slf4j:slf4j-api:1.7.24') - libExt enforcedPlatform('commons-logging:commons-logging:1.1.3') - } - } -} \ No newline at end of file diff --git a/gradle/maven/defaults-maven.gradle b/gradle/maven/defaults-maven.gradle index b80297f9e2f..575668b0028 100644 --- a/gradle/maven/defaults-maven.gradle +++ b/gradle/maven/defaults-maven.gradle @@ -55,19 +55,7 @@ configure(rootProject) { ":lucene:spatial-extras", ":lucene:spatial3d", ":lucene:suggest", - ":lucene:test-framework", - - ":solr:core", - ":solr:solrj", - ":solr:contrib:analysis-extras", - ":solr:contrib:analytics", - ":solr:contrib:clustering", - ":solr:contrib:extraction", - ":solr:contrib:langid", - ":solr:contrib:jaegertracer-configurator", - ":solr:contrib:prometheus-exporter", - ":solr:contrib:scripting", - ":solr:test-framework", + ":lucene:test-framework" ] apacheNexusSnapshots = "https://repository.apache.org/content/repositories/snapshots" @@ -123,9 +111,7 @@ configure(subprojects.findAll { it.path in rootProject.published }) { prj -> // in gradle or just complex relationships between lazy collection hooks. gradle.projectsEvaluated { publishing { - def configurePom; - if (project.path.startsWith(":lucene")) { - configurePom = { + def configurePom = { name = "Apache Lucene (module: ${project.name})" description = name url = 'https://lucene.apache.org/' @@ -150,13 +136,6 @@ configure(subprojects.findAll { it.path in rootProject.published }) { prj -> } mailingLists { - mailingList { - name = "General List" - subscribe = "general-subscribe@lucene.apache.org" - unsubscribe = "general-unsubscribe@lucene.apache.org" - archive = "https://mail-archives.apache.org/mod_mbox/lucene-general/" - } - mailingList { name = "Java User List" subscribe = "java-user-subscribe@lucene.apache.org" @@ -180,65 +159,10 @@ configure(subprojects.findAll { it.path in rootProject.published }) { prj -> } scm { - connection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene-solr.git' - developerConnection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene-solr.git' - url = 'https://gitbox.apache.org/repos/asf?p=lucene-solr.git' + connection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene.git' + developerConnection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene.git' + url = 'https://gitbox.apache.org/repos/asf?p=lucene.git' } - } - } else { - configurePom = { - name = "Apache Solr (module: ${project.name})" - description = name - url = 'https://lucene.apache.org/solr/' - - licenses { - license { - name = 'Apache 2' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - - inceptionYear = "2006" - - issueManagement { - system = "JIRA" - url = "https://issues.apache.org/jira/browse/SOLR" - } - - ciManagement { - system = "Jenkins" - url = "https://builds.apache.org/job/Lucene/" - } - - mailingLists { - mailingList { - name = "Solr User List" - subscribe = "solr-user-subscribe@lucene.apache.org" - unsubscribe = "solr-user-unsubscribe@lucene.apache.org" - archive = "https://mail-archives.apache.org/mod_mbox/solr-user/" - } - - mailingList { - name = "Java Developer List" - subscribe = "dev-subscribe@lucene.apache.org" - unsubscribe = "dev-unsubscribe@lucene.apache.org" - archive = "https://mail-archives.apache.org/mod_mbox/lucene-dev/" - } - - mailingList { - name = "Java Commits List" - subscribe = "commits-subscribe@lucene.apache.org" - unsubscribe = "commits-unsubscribe@lucene.apache.org" - archive = "https://mail-archives.apache.org/mod_mbox/lucene-java-commits/" - } - } - - scm { - connection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene-solr.git' - developerConnection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene-solr.git' - url = 'https://gitbox.apache.org/repos/asf?p=lucene-solr.git' - } - } } publications { diff --git a/gradle/testing/randomization.gradle b/gradle/testing/randomization.gradle index ee73e1bf94f..9aabb1be3b0 100644 --- a/gradle/testing/randomization.gradle +++ b/gradle/testing/randomization.gradle @@ -189,15 +189,9 @@ allprojects { } else if (project.path.startsWith(":lucene")) { systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager" systemProperty 'java.security.policy', file("${resources}/policies/tests.policy") - } else { - systemProperty 'common-solr.dir', commonSolrDir - systemProperty 'java.security.manager', "org.apache.lucene.util.TestSecurityManager" - systemProperty 'java.security.policy', file("${resources}/policies/solr-tests.policy") } - if (!skipLucene) { - systemProperty 'common.dir', commonDir - } + systemProperty 'common.dir', commonDir def gradleUserHome = project.gradle.getGradleUserHomeDir() systemProperty 'gradle.lib.dir', Paths.get(project.class.location.toURI()).parent.toAbsolutePath().toString().replace('\\', '/') diff --git a/gradle/testing/randomization/policies/solr-tests.policy b/gradle/testing/randomization/policies/solr-tests.policy deleted file mode 100644 index fa51ca4719e..00000000000 --- a/gradle/testing/randomization/policies/solr-tests.policy +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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. - */ - -// Policy file for solr. Please keep minimal and avoid wildcards. - -// permissions needed for tests to pass, based on properties set by the build system -// NOTE: if the property is not set, the permission entry is ignored. -grant { - // 3rd party jar resources (where symlinks are not supported), test-files/ resources - permission java.io.FilePermission "${common.dir}${/}-", "read"; - permission java.io.FilePermission "${common-solr.dir}${/}-", "read"; - - // system jar resources - permission java.io.FilePermission "${java.home}${/}-", "read"; - - // Test launchers (randomizedtesting, etc.) - permission java.io.FilePermission "${java.io.tmpdir}", "read,write"; - permission java.io.FilePermission "${java.io.tmpdir}${/}-", "read,write,delete"; - - permission java.io.FilePermission "${tests.linedocsfile}", "read"; - // DirectoryFactoryTest messes with these (wtf?) - permission java.io.FilePermission "/tmp/inst1/conf/solrcore.properties", "read"; - permission java.io.FilePermission "/path/to/myinst/conf/solrcore.properties", "read"; - // TestConfigSets messes with these (wtf?) - permission java.io.FilePermission "/path/to/solr/home/lib", "read"; - - permission java.nio.file.LinkPermission "hard"; - - // all possibilities of accepting/binding/connections on localhost with ports >=1024: - permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect,resolve"; - permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve"; - permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve"; - // "dead hosts", we try to keep it fast - permission java.net.SocketPermission "[::1]:4", "connect,resolve"; - permission java.net.SocketPermission "[::1]:6", "connect,resolve"; - permission java.net.SocketPermission "[::1]:8", "connect,resolve"; - - // Basic permissions needed for Lucene to work: - permission java.util.PropertyPermission "*", "read,write"; - - // needed by randomizedtesting runner to identify test methods. - permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; - permission java.lang.RuntimePermission "accessDeclaredMembers"; - // needed by certain tests to redirect sysout/syserr: - permission java.lang.RuntimePermission "setIO"; - // needed by randomized runner to catch failures from other threads: - permission java.lang.RuntimePermission "setDefaultUncaughtExceptionHandler"; - // needed by randomized runner getTopThreadGroup: - permission java.lang.RuntimePermission "modifyThreadGroup"; - // needed by tests e.g. shutting down executors: - permission java.lang.RuntimePermission "modifyThread"; - // needed for tons of test hacks etc - permission java.lang.RuntimePermission "getStackTrace"; - // needed for mock filesystems in tests - permission java.lang.RuntimePermission "fileSystemProvider"; - // needed by IndexFetcher - permission java.lang.RuntimePermission "getFileStoreAttributes"; - // analyzers/uima: needed by lucene expressions' JavascriptCompiler - permission java.lang.RuntimePermission "createClassLoader"; - // needed to test unmap hack on platforms that support it - permission java.lang.RuntimePermission "accessClassInPackage.sun.misc"; - // needed by jacoco to dump coverage - permission java.lang.RuntimePermission "shutdownHooks"; - // needed by org.apache.logging.log4j - permission java.lang.RuntimePermission "getenv.*"; - permission java.lang.RuntimePermission "getClassLoader"; - permission java.lang.RuntimePermission "setContextClassLoader"; - permission java.lang.RuntimePermission "getStackWalkerWithClassReference"; - // needed by bytebuddy - permission java.lang.RuntimePermission "defineClass"; - // needed by mockito - permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect"; - permission java.lang.RuntimePermission "reflectionFactoryAccess"; - // needed by SolrResourceLoader - permission java.lang.RuntimePermission "closeClassLoader"; - // needed by HttpSolrClient - permission java.lang.RuntimePermission "getFileSystemAttributes"; - // needed by hadoop auth (TODO: there is a cleaner way to handle this) - permission java.lang.RuntimePermission "loadLibrary.jaas"; - permission java.lang.RuntimePermission "loadLibrary.jaas_unix"; - permission java.lang.RuntimePermission "loadLibrary.jaas_nt"; - // needed by hadoop common RawLocalFileSystem for java nio getOwner - permission java.lang.RuntimePermission "accessUserInformation"; - // needed by hadoop hdfs - permission java.lang.RuntimePermission "readFileDescriptor"; - permission java.lang.RuntimePermission "writeFileDescriptor"; - // needed by hadoop http - permission java.lang.RuntimePermission "getProtectionDomain"; - - // These two *have* to be spelled out a separate - permission java.lang.management.ManagementPermission "control"; - permission java.lang.management.ManagementPermission "monitor"; - - // needed by hadoop htrace - permission java.net.NetPermission "getNetworkInformation"; - - // needed by DIH - possibly even after DIH is a package - permission java.sql.SQLPermission "deregisterDriver"; - - permission java.util.logging.LoggingPermission "control"; - - // needed by solr mbeans feature/tests - // TODO: can we remove wildcard for class names/members? - permission javax.management.MBeanPermission "*", "getAttribute"; - permission javax.management.MBeanPermission "*", "getMBeanInfo"; - permission javax.management.MBeanPermission "*", "queryMBeans"; - permission javax.management.MBeanPermission "*", "queryNames"; - permission javax.management.MBeanPermission "*", "registerMBean"; - permission javax.management.MBeanPermission "*", "unregisterMBean"; - permission javax.management.MBeanServerPermission "createMBeanServer"; - permission javax.management.MBeanServerPermission "findMBeanServer"; - permission javax.management.MBeanServerPermission "releaseMBeanServer"; - permission javax.management.MBeanTrustPermission "register"; - - // needed by hadoop auth - permission javax.security.auth.AuthPermission "getSubject"; - permission javax.security.auth.AuthPermission "modifyPrincipals"; - permission javax.security.auth.AuthPermission "doAs"; - permission javax.security.auth.AuthPermission "getLoginConfiguration"; - permission javax.security.auth.AuthPermission "setLoginConfiguration"; - permission javax.security.auth.AuthPermission "modifyPrivateCredentials"; - permission javax.security.auth.AuthPermission "modifyPublicCredentials"; - permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"", "read"; - - // needed by hadoop security - permission java.security.SecurityPermission "putProviderProperty.SaslPlainServer"; - permission java.security.SecurityPermission "insertProvider"; - - permission javax.xml.bind.JAXBPermission "setDatatypeConverter"; - - // SSL related properties for Solr tests - permission javax.net.ssl.SSLPermission "setDefaultSSLContext"; - - // SASL/Kerberos related properties for Solr tests - permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KerberosTicket * \"*\"", "read"; - - // may only be necessary with Java 7? - permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab * \"*\"", "read"; - permission javax.security.auth.PrivateCredentialPermission "sun.security.jgss.krb5.Krb5Util$KeysFromKeyTab * \"*\"", "read"; - - permission javax.security.auth.kerberos.ServicePermission "*", "initiate"; - permission javax.security.auth.kerberos.ServicePermission "*", "accept"; - permission javax.security.auth.kerberos.DelegationPermission "\"*\" \"krbtgt/EXAMPLE.COM@EXAMPLE.COM\""; - - // java 8 accessibility requires this perm - should not after 8 I believe (rrd4j is the root reason we hit an accessibility code path) - permission java.awt.AWTPermission "*"; - - // used by solr to create sandboxes (e.g. script execution) - permission java.security.SecurityPermission "createAccessControlContext"; -}; - -// additional permissions based on system properties set by /bin/solr -// NOTE: if the property is not set, the permission entry is ignored. -grant { - permission java.io.FilePermission "${hadoop.security.credential.provider.path}", "read,write,delete,readlink"; - permission java.io.FilePermission "${hadoop.security.credential.provider.path}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.jetty.keystore}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.jetty.keystore}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.jetty.truststore}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.jetty.truststore}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.install.dir}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.install.dir}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${jetty.home}", "read,write,delete,readlink"; - permission java.io.FilePermission "${jetty.home}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.solr.home}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.solr.home}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.data.home}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.data.home}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.default.confdir}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.default.confdir}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${solr.log.dir}", "read,write,delete,readlink"; - permission java.io.FilePermission "${solr.log.dir}${/}-", "read,write,delete,readlink"; - - permission java.io.FilePermission "${log4j.configurationFile}", "read,write,delete,readlink"; - - // expanded to a wildcard if set, allows all networking everywhere - permission java.net.SocketPermission "${solr.internal.network.permission}", "accept,listen,connect,resolve"; -}; - -// Grant all permissions to Gradle test runner classes. - -grant codeBase "file:${gradle.lib.dir}${/}-" { - permission java.security.AllPermission; -}; - -grant codeBase "file:${gradle.worker.jar}" { - permission java.security.AllPermission; -}; - -grant { - // Allow reading gradle worker JAR. - permission java.io.FilePermission "${gradle.worker.jar}", "read"; - // Allow reading from classpath JARs (resources). - permission java.io.FilePermission "${gradle.user.home}${/}-", "read"; -}; diff --git a/gradle/validation/precommit.gradle b/gradle/validation/precommit.gradle index 27c87b55905..4a042012afe 100644 --- a/gradle/validation/precommit.gradle +++ b/gradle/validation/precommit.gradle @@ -36,7 +36,6 @@ configure(rootProject) { "javadoc", "rat", "ecjLint", - "validateLogCalls", "validateSourcePatterns", "spotlessCheck" ]} diff --git a/gradle/validation/validate-log-calls.gradle b/gradle/validation/validate-log-calls.gradle deleted file mode 100644 index d759c74435e..00000000000 --- a/gradle/validation/validate-log-calls.gradle +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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. - */ - -import org.apache.tools.ant.BuildException - -// Checks logging calls to keep from using patterns that might be expensive -// either in CPU or unnecessary object creation. Some of the checks are a little -// over-zealous, but it's worth a bit of aggravation to catch the egregious -// mistakes before they accrue. - -// This all started with Java Flight Recorder showing a massive number of -// objects allocated and garbage collected. Tracing a bunch of them down showed -// that we have a number of calls like: -// log.debug("some string" + very_expensive_object_to_make_a_string). -// which _always_ constructed the very expensive ojbect even if the log level -// was INFO or more severe. Rather than leave lots of confusing formats laying -// about or expecting people to remember the rules, we opted to make this -// check part of Gradle precommit. It will be included by default in Solr -// 9.0. - -// See the associated help task "gradlew helpValidateLogCalls" - -configure(subprojects.findAll { it.path.startsWith(':solr') }) { - plugins.withType(JavaPlugin) { - task validateLogCalls(type: ValidateLogCallsTask) { task -> - description "Checks that log calls are either validated or conform to efficient patterns." - group "verification" - - // This task has no proper outputs. - setupDummyOutputs(task) - - sourceFiles = files(sourceSets*.java) - } - - // Add log validation to per-project checks as well. - check.dependsOn validateLogCalls - } -} - -class ValidateLogCallsTask extends DefaultTask { - def logLevels = ["log.trace", "log.debug", "log.info", "log.warn", "log.error", "log.fatal"] - - def errsFound = 0; - def violations = new ArrayList(); - - def reportViolation(String msg) { - violations.add(System.lineSeparator + msg); - errsFound++; - } - - // We have a log.something line, check for patterns we're not fond of. - def checkLine(File file, String line, int lineNumber, String previous) { - boolean violation = false - - // If the line has been explicitly OK'd, then it's OK! - if (line.replaceAll("\\s", "").toLowerCase().contains("//nowarn")) { - return - } - // Strip all of the comments, things in quotes and the like. - def stripped = - line.replaceFirst("//.*", " ") // remove comment to EOL. May be fragile due to the possibility of embedded double slashes - .replaceFirst(/.*?\(/, " ") // Get rid of "log.whatever(" - .replaceFirst(/\);/, " ") // get rid of the closing ");" - .replaceFirst("/\\*.*?\\*/", " ") // replace embedded comments "/*....*/" - .replaceAll(/".*?"/, '""') // remove anything between quotes. This is a bit fragile if there are embedded double quotes. - .replaceAll(/timeLeft\(.*?\)/, " ") // used all over tests, it's benign - .replaceAll(/TimeUnit\..*?\.convert\(.*?\)/, " ") // again, a pattern that's efficient - .replaceAll("\\s", "") - - // The compiler will pre-assemble patterns like 'log.info("string const1 {}" + " string const2 {}", obj1, obj2)' - // to log.info("string const1 {} string const2 {}", obj1, obj2)', so don't worry about any plus preceded and - // followed by double quotes, otherwise flag it. - def hasPlus = false - for (int idx = 0; idx < stripped.length(); ++idx) { - if (stripped.charAt(idx) == '+') { - if (idx == 0 || idx == stripped.length() - 1 - || stripped.charAt(idx - 1) != '"' || stripped.charAt(idx + 1) != '"') { - hasPlus = true - break - } - } - } - //TODO remove me - String cause = "" - // Get the level of this log message. - // We don't really care about checking for method calls for WARN and more severe, the presumption - // is that they _should_ always be reported. - - def level = "" - def lev = (line =~ "log\\.(.*?)\\(") - if (lev.find()) { - level = lev.group(1).toLowerCase().trim() - } - if (logLevels.contains("log." + level) == false) { - reportViolation(String.format("Found an unexpected log level: %s, file: %s:%d" - , level, file.getAbsolutePath(), lineNumber)) - } - boolean persnicketyLevel = !(level.equals("fatal") || level.equals("error") || level.equals("warn")) - - // Check that previous line isn't an if statement for always-reported log levels. - // There's a convention to declare a member variable for whether a level is enabled and check that rather than - // isDebugEnabled so we need to check both. - String prevLine = previous.replaceAll("\\s+", "").toLowerCase() - boolean prevLineNotIf = ((prevLine.contains("if(log.is" + level + "enabled") == false - && prevLine.contains("if(" + level + ")") == false)) - - if (hasPlus) { - cause = "hasPlus: " + hasPlus - violation = true - } - if (violation == false) { - def m = stripped =~ "\\(.*?\\)" - def hasParens = m.find() - - if (hasParens && prevLineNotIf && persnicketyLevel) { - cause = "hasParens " + hasParens + " prevLineNotIf " + prevLineNotIf + " pernicketyLevel " + persnicketyLevel - violation = true - } - } - - // Always report toString(). Note, this over-reports some constructs - // but just add //nowarn if it's really OK. - if (violation == false) { - if (line.contains("toString(") == true && prevLineNotIf) { - cause = "Line contains toString" - violation = true - } - } - if (stripped.contains("getMessage()") || stripped.contains("getCause()")) { - cause = "getMessage or getCause in log line"; - violation = true; - } - if (violation) { - reportViolation(String.format("cause: '%s' Suspicious logging call, Parameterize and possibly surround with 'if (log.is*Enabled) {..}'. Help at: 'gradlew helpValidateLogCalls' %s %s:%d" - , cause , System.lineSeparator, file.getAbsolutePath(), lineNumber)) - } - return - } - -// Require all our logger definitions lower case "log", except if they have //nowarn - def checkLogName(File file, String line) { - // It's many times faster to do check this way than use a regex - if (line.contains("static ") && line.contains("getLogger") && line.contains(" log ") == false) { - if (line.replaceAll("\\s", "").toLowerCase().contains("//nowarn")) { - return - } - reportViolation("Change the logger name to lower-case 'log' in " + file.name + " " + line + " project" + project) - } - } - - def checkFile(File file) { - int state = 0 - int lineNumber = 0 - StringBuilder sb = new StringBuilder(); - - // We have to assemble line-by-line to get the full log statement. We require that all loggers (except requestLog - // and slowLog) be exactly "log". That will be checked as well. - String prevLine = "" - file.eachLine { String line -> - lineNumber++ - checkLogName(file, line) - switch (state) { - case 0: // Not collecting a logging line. - logLevels.each { - if (line.contains(it)) { - if (line.contains(");")) { - state = 2 - } else { - state = 1 - } - sb.setLength(0) - sb.append(line) - } - } - break - - case 1: // collecting a log line - if (line.replaceFirst("//.*", " ") - .replaceFirst("/\\*.*?\\*/", " ") // replace embedded comments "/*....*/" - .replaceAll(/".*?"/, '""') // remove anything between quotes. This is a bit fragile if there are embedded double quotes. - .trim().endsWith(");")) { - state = 2 - } - sb.append(line) - break - - default: - reportViolation("Bad state, should be 0-1 in the switch statement") // make people aware the code sucks - break - } - - // It's just easier to do this here rather than read another line in the switch above. - if (state == 0) { - // Not collecting a log line - prevLine = line.toLowerCase(); - } else if (state == 1) { - // collecting a logging line. - } else if (state == 2) { - // We've collected the complete log line. - checkLine(file, sb.toString(), lineNumber, prevLine) - state = 0 - } else { - assert false - } - } - } - - @InputFiles - FileCollection sourceFiles - - @TaskAction - def checkLogLines() { - sourceFiles.each { checkFile(it) } - logger.info("Checked: ${sourceFiles.files.size()}") - - if (errsFound > 0) { - throw new BuildException(String.format(Locale.ENGLISH, 'Found %d violations in source files (%s).', - errsFound, violations.join(', '))); - } - } -}