Add a "gn_version" variable.

See "gn_version variable" on gn-dev.

Bug: none
Change-Id: Id2c28c0fc577119cbe40c322e557019d1b3d03ff
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/7420
Commit-Queue: Brett Wilson <brettw@chromium.org>
Commit-Queue: Nico Weber <thakis@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/build/gen.py b/build/gen.py
index 534cf5d..989eb5a 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -138,10 +138,11 @@
 #ifndef OUT_LAST_COMMIT_POSITION_H_
 #define OUT_LAST_COMMIT_POSITION_H_
 
+#define LAST_COMMIT_POSITION_NUM %s
 #define LAST_COMMIT_POSITION "%s (%s)"
 
 #endif  // OUT_LAST_COMMIT_POSITION_H_
-''' % (mo.group(1), mo.group(2))
+''' % (mo.group(1), mo.group(1), mo.group(2))
 
   # Only write/touch this file if the commit position has changed.
   old_contents = ''
diff --git a/src/gn/scope_per_file_provider.cc b/src/gn/scope_per_file_provider.cc
index e30162e..3110a8f 100644
--- a/src/gn/scope_per_file_provider.cc
+++ b/src/gn/scope_per_file_provider.cc
@@ -12,6 +12,8 @@
 #include "gn/value.h"
 #include "gn/variables.h"
 
+#include "last_commit_position.h"
+
 ScopePerFileProvider::ScopePerFileProvider(Scope* scope, bool allow_target_vars)
     : ProgrammaticProvider(scope), allow_target_vars_(allow_target_vars) {}
 
@@ -23,6 +25,8 @@
     return GetCurrentToolchain();
   if (ident == variables::kDefaultToolchain)
     return GetDefaultToolchain();
+  if (ident == variables::kGnVersion)
+    return GetGnVersion();
   if (ident == variables::kPythonPath)
     return GetPythonPath();
 
@@ -61,6 +65,14 @@
   return default_toolchain_.get();
 }
 
+const Value* ScopePerFileProvider::GetGnVersion() {
+  if (!gn_version_) {
+    gn_version_ = std::make_unique<Value>(
+        nullptr, static_cast<int64_t>(LAST_COMMIT_POSITION_NUM));
+  }
+  return gn_version_.get();
+}
+
 const Value* ScopePerFileProvider::GetPythonPath() {
   if (!python_path_) {
     python_path_ = std::make_unique<Value>(
diff --git a/src/gn/scope_per_file_provider.h b/src/gn/scope_per_file_provider.h
index 16496e5..228bac3 100644
--- a/src/gn/scope_per_file_provider.h
+++ b/src/gn/scope_per_file_provider.h
@@ -26,6 +26,7 @@
  private:
   const Value* GetCurrentToolchain();
   const Value* GetDefaultToolchain();
+  const Value* GetGnVersion();
   const Value* GetPythonPath();
   const Value* GetRootBuildDir();
   const Value* GetRootGenDir();
@@ -38,6 +39,7 @@
   // All values are lazily created.
   std::unique_ptr<Value> current_toolchain_;
   std::unique_ptr<Value> default_toolchain_;
+  std::unique_ptr<Value> gn_version_;
   std::unique_ptr<Value> python_path_;
   std::unique_ptr<Value> root_build_dir_;
   std::unique_ptr<Value> root_gen_dir_;
diff --git a/src/gn/scope_per_file_provider_unittest.cc b/src/gn/scope_per_file_provider_unittest.cc
index 8c22666..8e38903 100644
--- a/src/gn/scope_per_file_provider_unittest.cc
+++ b/src/gn/scope_per_file_provider_unittest.cc
@@ -31,6 +31,9 @@
     EXPECT_EQ("//out/Debug", GPV(variables::kRootOutDir));
     EXPECT_EQ("//out/Debug/gen/source", GPV(variables::kTargetGenDir));
     EXPECT_EQ("//out/Debug/obj/source", GPV(variables::kTargetOutDir));
+
+    EXPECT_GE(provider.GetProgrammaticValue(variables::kGnVersion)->int_value(),
+              0);
   }
 
   // Test some with an alternate toolchain.
diff --git a/src/gn/variables.cc b/src/gn/variables.cc
index b6293b4..0d56301 100644
--- a/src/gn/variables.cc
+++ b/src/gn/variables.cc
@@ -10,6 +10,19 @@
 
 // Built-in variables ----------------------------------------------------------
 
+const char kGnVersion[] = "gn_version";
+const char kGnVersion_HelpShort[] =
+    "gn_version: [number] The version of gn.";
+const char kGnVersion_Help[] =
+  R"(gn_version: [number] The version of gn.
+
+  Corresponds to the number printed by `gn --version`.
+
+Example
+
+  assert(gn_version >= 1700, "need GN version 1700 for the frobulate feature")
+)";
+
 const char kHostCpu[] = "host_cpu";
 const char kHostCpu_HelpShort[] =
     "host_cpu: [string] The processor architecture that GN is running on.";
@@ -2188,6 +2201,7 @@
     INSERT_VARIABLE(CurrentOs)
     INSERT_VARIABLE(CurrentToolchain)
     INSERT_VARIABLE(DefaultToolchain)
+    INSERT_VARIABLE(GnVersion)
     INSERT_VARIABLE(HostCpu)
     INSERT_VARIABLE(HostOs)
     INSERT_VARIABLE(Invoker)
@@ -2196,9 +2210,9 @@
     INSERT_VARIABLE(RootGenDir)
     INSERT_VARIABLE(RootOutDir)
     INSERT_VARIABLE(TargetCpu)
-    INSERT_VARIABLE(TargetOs)
     INSERT_VARIABLE(TargetGenDir)
     INSERT_VARIABLE(TargetName)
+    INSERT_VARIABLE(TargetOs)
     INSERT_VARIABLE(TargetOutDir)
   }
   return info_map;
diff --git a/src/gn/variables.h b/src/gn/variables.h
index c684caf..df30632 100644
--- a/src/gn/variables.h
+++ b/src/gn/variables.h
@@ -36,6 +36,10 @@
 extern const char kDefaultToolchain_HelpShort[];
 extern const char kDefaultToolchain_Help[];
 
+extern const char kGnVersion[];
+extern const char kGnVersion_HelpShort[];
+extern const char kGnVersion_Help[];
+
 extern const char kInvoker[];
 extern const char kInvoker_HelpShort[];
 extern const char kInvoker_Help[];