Browse Source

project: warn on metadata arguments missing values

Warn if `DESCRIPTION` or `VERSION` is given without a following value.
Alex Turbov 7 years ago
parent
commit
587bad7ba2

+ 47 - 2
Source/cmProjectCommand.cxx

@@ -3,9 +3,11 @@
 #include "cmProjectCommand.h"
 
 #include "cmsys/RegularExpression.hxx"
+#include <functional>
 #include <sstream>
 #include <stdio.h>
 
+#include "cmAlgorithms.h"
 #include "cmMakefile.h"
 #include "cmPolicies.h"
 #include "cmStateTypes.h"
@@ -69,6 +71,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
   std::string version;
   std::string description;
   std::vector<std::string> languages;
+  std::function<void()> missedValueReporter;
+  auto resetReporter = [&missedValueReporter]() {
+    missedValueReporter = std::function<void()>();
+  };
   enum Doing
   {
     DoingDescription,
@@ -85,7 +91,18 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
         return true;
       }
       haveLanguages = true;
+      if (missedValueReporter) {
+        missedValueReporter();
+      }
       doing = DoingLanguages;
+      if (!languages.empty()) {
+        std::string msg =
+          "the following parameters must be specified after LANGUAGES "
+          "keyword: ";
+        msg += cmJoin(languages, ", ");
+        msg += '.';
+        this->Makefile->IssueMessage(cmake::WARNING, msg);
+      }
     } else if (args[i] == "VERSION") {
       if (haveVersion) {
         this->Makefile->IssueMessage(cmake::FATAL_ERROR,
@@ -94,7 +111,17 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
         return true;
       }
       haveVersion = true;
+      if (missedValueReporter) {
+        missedValueReporter();
+      }
       doing = DoingVersion;
+      missedValueReporter = [this, &resetReporter]() {
+        this->Makefile->IssueMessage(
+          cmake::WARNING,
+          "VERSION keyword not followed by a value or was followed by a "
+          "value that expanded to nothing.");
+        resetReporter();
+      };
     } else if (args[i] == "DESCRIPTION") {
       if (haveDescription) {
         this->Makefile->IssueMessage(
@@ -103,23 +130,41 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
         return true;
       }
       haveDescription = true;
+      if (missedValueReporter) {
+        missedValueReporter();
+      }
       doing = DoingDescription;
+      missedValueReporter = [this, &resetReporter]() {
+        this->Makefile->IssueMessage(
+          cmake::WARNING,
+          "DESCRIPTION keyword not followed by a value or was followed "
+          "by a value that expanded to nothing.");
+        resetReporter();
+      };
     } else if (doing == DoingVersion) {
       doing = DoingLanguages;
       version = args[i];
+      resetReporter();
     } else if (doing == DoingDescription) {
       doing = DoingLanguages;
       description = args[i];
+      resetReporter();
     } else // doing == DoingLanguages
     {
       languages.push_back(args[i]);
     }
   }
 
-  if (haveVersion && !haveLanguages && !languages.empty()) {
+  if (missedValueReporter) {
+    missedValueReporter();
+  }
+
+  if ((haveVersion || haveDescription) && !haveLanguages &&
+      !languages.empty()) {
     this->Makefile->IssueMessage(
       cmake::FATAL_ERROR,
-      "project with VERSION must use LANGUAGES before language names.");
+      "project with VERSION or DESCRIPTION must use LANGUAGES before "
+      "language names.");
     cmSystemTools::SetFatalErrorOccured();
     return true;
   }

+ 1 - 0
Tests/RunCMake/project/LanguagesUnordered-stderr.txt

@@ -0,0 +1 @@
+  the following parameters must be specified after LANGUAGES keyword: C.

+ 1 - 0
Tests/RunCMake/project/LanguagesUnordered.cmake

@@ -0,0 +1 @@
+project(ProjectA C LANGUAGES CXX)

+ 2 - 0
Tests/RunCMake/project/ProjectDescriptionNoArg-stderr.txt

@@ -0,0 +1,2 @@
+  DESCRIPTION keyword not followed by a value or was followed by a value that
+  expanded to nothing.

+ 2 - 0
Tests/RunCMake/project/ProjectDescriptionNoArg.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectDescriptionTest VERSION 1.0.0 DESCRIPTION)

+ 2 - 0
Tests/RunCMake/project/ProjectDescriptionNoArg2-stderr.txt

@@ -0,0 +1,2 @@
+  DESCRIPTION keyword not followed by a value or was followed by a value that
+  expanded to nothing.

+ 2 - 0
Tests/RunCMake/project/ProjectDescriptionNoArg2.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0048 NEW)
+project(ProjectDescriptionTest VERSION 1.0.0 DESCRIPTION LANGUAGES NONE)

+ 3 - 0
Tests/RunCMake/project/RunCMakeTest.cmake

@@ -7,8 +7,11 @@ run_cmake(LanguagesImplicit)
 run_cmake(LanguagesEmpty)
 run_cmake(LanguagesNONE)
 run_cmake(LanguagesTwice)
+run_cmake(LanguagesUnordered)
 run_cmake(ProjectDescription)
 run_cmake(ProjectDescription2)
+run_cmake(ProjectDescriptionNoArg)
+run_cmake(ProjectDescriptionNoArg2)
 run_cmake(VersionAndLanguagesEmpty)
 run_cmake(VersionEmpty)
 run_cmake(VersionInvalid)

+ 2 - 1
Tests/RunCMake/project/VersionMissingLanguages-stderr.txt

@@ -1,4 +1,5 @@
 CMake Error at VersionMissingLanguages.cmake:2 \(project\):
-  project with VERSION must use LANGUAGES before language names.
+  project with VERSION or DESCRIPTION must use LANGUAGES before language
+  names.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/project/VersionMissingValueOkay-stderr.txt

@@ -0,0 +1,2 @@
+  VERSION keyword not followed by a value or was followed by a value that
+  expanded to nothing.