From 45484b31bbe736d6effb630ca0bc642856e883d1 Mon Sep 17 00:00:00 2001
From: David Garcia Quintas <dgq@google.com>
Date: Thu, 14 Jan 2016 18:59:20 -0800
Subject: [PATCH] Added sanity check for trailing newlines

---
 .../Grpc.Core.Tests/Internal/AsyncCallTest.cs |  2 +-
 src/csharp/Grpc.Core/Internal/AsyncCall.cs    |  2 +-
 .../Grpc.Core/Internal/AsyncCallBase.cs       |  2 +-
 .../Grpc.Core/Internal/AsyncCallServer.cs     |  2 +-
 .../Grpc.Core/Internal/AsyncCompletion.cs     |  2 +-
 .../Internal/BatchContextSafeHandle.cs        |  2 +-
 .../Grpc.Core/Internal/CallSafeHandle.cs      |  2 +-
 .../Grpc.Core/Properties/AssemblyInfo.cs      |  2 +-
 .../HealthClientServerTest.cs                 |  2 +-
 .../Properties/AssemblyInfo.cs                |  2 +-
 src/node/test/echo_service.proto              |  2 +-
 src/node/test/test_messages.proto             |  2 +-
 src/node/test/test_service.proto              |  2 +-
 src/proto/grpc/health/v1alpha/health.proto    |  2 +-
 test/cpp/qps/client_async.cc                  |  2 +-
 test/cpp/qps/client_sync.cc                   |  2 +-
 .../generic_async_streaming_ping_pong_test.cc |  2 +-
 test/cpp/qps/qps_driver.cc                    |  2 +-
 test/cpp/qps/qps_worker.cc                    |  2 +-
 test/cpp/qps/server_async.cc                  |  2 +-
 test/cpp/util/subprocess.cc                   |  2 +-
 tools/distrib/check_trailing_newlines.sh      | 67 +++++++++++++++++++
 tools/run_tests/check_sources_and_headers.py  |  2 +-
 tools/run_tests/run_sanity.sh                 |  2 +-
 24 files changed, 90 insertions(+), 23 deletions(-)
 create mode 100755 tools/distrib/check_trailing_newlines.sh

diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
index 246072bff1..543f6375df 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
@@ -219,4 +219,4 @@ namespace Grpc.Core.Internal.Tests
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index e3ecc47282..1423145b9e 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -456,4 +456,4 @@ namespace Grpc.Core.Internal
             streamingCallFinishedTcs.SetResult(null);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 92f8d77e85..13d75a826b 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -356,4 +356,4 @@ namespace Grpc.Core.Internal
             FireCompletion(origCompletionDelegate, msg, null);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 0c805097f9..36f2fed82c 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -215,4 +215,4 @@ namespace Grpc.Core.Internal
             finishedServersideTcs.SetResult(null);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
index c88cae98fe..7e86fddb4d 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
@@ -91,4 +91,4 @@ namespace Grpc.Core.Internal
             tcs.SetException(error);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 3a96414bea..150e2115b3 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -263,4 +263,4 @@ namespace Grpc.Core.Internal
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 69dbdfea5e..bbd8001492 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -273,4 +273,4 @@ namespace Grpc.Core.Internal
             return buffered ? 0 : GRPC_WRITE_BUFFER_HINT;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
index 29db85d7aa..bde74945fb 100644
--- a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
@@ -18,4 +18,4 @@ using System.Runtime.CompilerServices;
     "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
 #else
 [assembly: InternalsVisibleTo("Grpc.Core.Tests")]
-#endif
\ No newline at end of file
+#endif
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index d90f21c2e1..c7e1547144 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -93,4 +93,4 @@ namespace Grpc.HealthCheck.Tests
 
         // TODO(jtattermusch): add test with timeout once timeouts are supported
     }
-}
\ No newline at end of file
+}
diff --git a/src/csharp/Grpc.HealthCheck/Properties/AssemblyInfo.cs b/src/csharp/Grpc.HealthCheck/Properties/AssemblyInfo.cs
index 41a54a98bc..4d7b33c669 100644
--- a/src/csharp/Grpc.HealthCheck/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.HealthCheck/Properties/AssemblyInfo.cs
@@ -8,4 +8,4 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyProduct("")]
 [assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
 [assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
\ No newline at end of file
+[assembly: AssemblyCulture("")]
diff --git a/src/node/test/echo_service.proto b/src/node/test/echo_service.proto
index b2c7e3dc23..fc941a2904 100644
--- a/src/node/test/echo_service.proto
+++ b/src/node/test/echo_service.proto
@@ -36,4 +36,4 @@ message EchoMessage {
 
 service EchoService {
   rpc Echo (EchoMessage) returns (EchoMessage);
-}
\ No newline at end of file
+}
diff --git a/src/node/test/test_messages.proto b/src/node/test/test_messages.proto
index 685e9482bd..1b611b82a7 100644
--- a/src/node/test/test_messages.proto
+++ b/src/node/test/test_messages.proto
@@ -35,4 +35,4 @@ message LongValues {
   sint64 sint_64 = 3;
   fixed64 fixed_64 = 4;
   sfixed64 sfixed_64 = 5;
-}
\ No newline at end of file
+}
diff --git a/src/node/test/test_service.proto b/src/node/test/test_service.proto
index 564169829c..c86ce51d91 100644
--- a/src/node/test/test_service.proto
+++ b/src/node/test/test_service.proto
@@ -49,4 +49,4 @@ service TestService {
 
   rpc BidiStream (stream Request) returns (stream Response) {
   }
-}
\ No newline at end of file
+}
diff --git a/src/proto/grpc/health/v1alpha/health.proto b/src/proto/grpc/health/v1alpha/health.proto
index 28786c4427..e6214c5691 100644
--- a/src/proto/grpc/health/v1alpha/health.proto
+++ b/src/proto/grpc/health/v1alpha/health.proto
@@ -48,4 +48,4 @@ message HealthCheckResponse {
 
 service Health {
   rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
-}
\ No newline at end of file
+}
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 3e2317c6d4..f270cd0987 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -599,4 +599,4 @@ std::unique_ptr<Client> CreateGenericAsyncStreamingClient(
 }
 
 }  // namespace testing
-}  // namespace grpc
\ No newline at end of file
+}  // namespace grpc
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 1045915b83..92fbf240ce 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -172,4 +172,4 @@ std::unique_ptr<Client> CreateSynchronousStreamingClient(
 }
 
 }  // namespace testing
-}  // namespace grpc
\ No newline at end of file
+}  // namespace grpc
diff --git a/test/cpp/qps/generic_async_streaming_ping_pong_test.cc b/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
index 7a1275054a..2b2e1c820f 100644
--- a/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
@@ -79,4 +79,4 @@ int main(int argc, char** argv) {
 
   grpc::testing::RunGenericAsyncStreamingPingPong();
   return 0;
-}
\ No newline at end of file
+}
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index c70db188d9..eb0a7a5f4e 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -184,4 +184,4 @@ int main(int argc, char** argv) {
   grpc::testing::QpsDriver();
 
   return 0;
-}
\ No newline at end of file
+}
diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc
index e7714c0bb3..bed867e1a4 100644
--- a/test/cpp/qps/qps_worker.cc
+++ b/test/cpp/qps/qps_worker.cc
@@ -239,4 +239,4 @@ QpsWorker::QpsWorker(int driver_port) {
 QpsWorker::~QpsWorker() {}
 
 }  // namespace testing
-}  // namespace grpc
\ No newline at end of file
+}  // namespace grpc
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 1ae88d7323..d530dac86b 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -397,4 +397,4 @@ std::unique_ptr<Server> CreateAsyncGenericServer(const ServerConfig &config) {
 }
 
 }  // namespace testing
-}  // namespace grpc
\ No newline at end of file
+}  // namespace grpc
diff --git a/test/cpp/util/subprocess.cc b/test/cpp/util/subprocess.cc
index d758f629ac..c31802b9a3 100644
--- a/test/cpp/util/subprocess.cc
+++ b/test/cpp/util/subprocess.cc
@@ -56,4 +56,4 @@ int SubProcess::Join() { return gpr_subprocess_join(subprocess_); }
 
 void SubProcess::Interrupt() { gpr_subprocess_interrupt(subprocess_); }
 
-}  // namespace grpc
\ No newline at end of file
+}  // namespace grpc
diff --git a/tools/distrib/check_trailing_newlines.sh b/tools/distrib/check_trailing_newlines.sh
new file mode 100755
index 0000000000..0be21f0cff
--- /dev/null
+++ b/tools/distrib/check_trailing_newlines.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# change to root directory
+cd $(dirname $0)/../..
+
+function find_without_newline() {
+  find . -type f -not -path './third_party/*' -and \(  \
+                             -name '*.c'               \
+                         -or -name '*.cc'              \
+                         -or -name '*.proto'           \
+                         -or -name '*.rb'              \
+                         -or -name '*.py'              \
+                         -or -name '*.cs'              \
+                         -or -name '*.sh' \) -print0   \
+                         | while IFS= read -r -d '' f; do
+    if [[ ! -z $f ]]; then
+      if [[ $(tail -c 1 "$f") != $NEWLINE ]]; then
+        echo "Error: file '$f' is missing a trailing newline character."
+        if $2; then  # fix
+          sed -i -e '$a\' $f
+          echo 'Fixed!'
+        fi
+      fi
+    fi
+  done
+}
+
+if [[ $# == 1 && $1 == '--fix' ]]; then
+  ERRORS=$(find_without_newline true)
+else
+  ERRORS=$(find_without_newline false)
+fi
+
+if [[ "$ERRORS" != '' ]]; then
+  echo "$ERRORS"
+  if ! $FIX; then
+    exit 1
+  fi
+fi
diff --git a/tools/run_tests/check_sources_and_headers.py b/tools/run_tests/check_sources_and_headers.py
index cee32888dc..6f4c5a8657 100755
--- a/tools/run_tests/check_sources_and_headers.py
+++ b/tools/run_tests/check_sources_and_headers.py
@@ -80,4 +80,4 @@ for target in js:
 							target['name'], fn, m.group(1)))
 					errors += 1
 
-assert errors == 0
\ No newline at end of file
+assert errors == 0
diff --git a/tools/run_tests/run_sanity.sh b/tools/run_tests/run_sanity.sh
index 690332daae..467f06edd7 100755
--- a/tools/run_tests/run_sanity.sh
+++ b/tools/run_tests/run_sanity.sh
@@ -60,4 +60,4 @@ fi
 ./tools/buildgen/generate_projects.sh
 ./tools/distrib/check_copyright.py
 ./tools/distrib/clang_format_code.sh
-
+./tools/distrib/check_trailing_newlines.sh
-- 
GitLab