You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by zh...@apache.org on 2022/06/22 13:20:24 UTC

[kudu] branch master updated: [Doc][Format] Format help document support using Enter Key

This is an automated email from the ASF dual-hosted git repository.

zhangyifan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new 554edeca2 [Doc][Format] Format help document support using Enter Key
554edeca2 is described below

commit 554edeca2cb47ee14c73f84a228be670faf342f2
Author: xinghuayu007 <14...@qq.com>
AuthorDate: Thu May 26 15:31:58 2022 +0800

    [Doc][Format] Format help document support using Enter Key
    
    Kudu uses Function:AppendHardWrapped to format a description
    of a command, which will split the string when it's length is
    more than 78. But this function don't handle Enter key in the
    string, the formatted result is indent.
    
    For example:
    Original string:
    "Attempts to create on-disk metadata that can be used by master.\n"
    "It also can be used by a replicated tserver\n"
    
    Old function output:
    Attempts to create on-disk metadata that can be used by master.
    It also can be
    used by a replicated tserver
    
    New function output:
    Attempts to create on-disk metadata that can be used by master.
    It also can be used by a replicated tserver
    
    The new Function will split the string using '\n', then split
    every line when it's length is more than 78.
    
    Change-Id: I1bd15bd2de292f534e90ac24e925bf605ddf6d7b
    Reviewed-on: http://gerrit.cloudera.org:8080/18566
    Tested-by: Kudu Jenkins
    Reviewed-by: Yifan Zhang <ch...@163.com>
---
 src/kudu/tools/tool_action-test.cc   | 100 +++++++++++++++++++++++++++++++++++
 src/kudu/tools/tool_action.cc        |  79 ++++++++++++++-------------
 src/kudu/tools/tool_action.h         |   8 ++-
 src/kudu/tools/tool_action_master.cc |  48 ++++++++---------
 4 files changed, 172 insertions(+), 63 deletions(-)

diff --git a/src/kudu/tools/tool_action-test.cc b/src/kudu/tools/tool_action-test.cc
index 13ff2da44..0c4d0de66 100644
--- a/src/kudu/tools/tool_action-test.cc
+++ b/src/kudu/tools/tool_action-test.cc
@@ -150,5 +150,105 @@ TEST(ToolActionTest, TestMasterAddressesToSet) {
   ASSERT_NE(std_set, bad_host_set);
 }
 
+TEST(ToolActionTest, TestAppendHardWrapped) {
+  // Case 1: string is empty.
+  const string& msg1 = "";
+  string formated_msg1;
+  AppendHardWrapped(msg1, 0, &formated_msg1);
+  ASSERT_EQ("", formated_msg1);
+
+  // Case 2: string is a blank space.
+  const string& msg3 = " ";
+  string formated_msg3;
+  AppendHardWrapped(msg3, 0, &formated_msg3);
+  ASSERT_EQ(" ", formated_msg3);
+
+  // Case 3: string length is less than 78.
+  const string& msg2 = "Attempts to create on-disk metadata";
+  string formated_msg2;
+  AppendHardWrapped(msg2, 0, &formated_msg2);
+  ASSERT_EQ("Attempts to create on-disk metadata", formated_msg2);
+
+  // Case 4: string length is more than 78 a little.
+  const string& msg4 = "Attempts to create on-disk metadata "
+                       "that can be used by a non-replicated master";
+  string formated_msg4;
+  AppendHardWrapped(msg4, 0, &formated_msg4);
+  const string& expected_output4 = "Attempts to create on-disk metadata "
+                                   "that can be used by a non-replicated \nmaster";
+  // Contains one '\n'.
+  ASSERT_EQ(expected_output4, formated_msg4);
+
+  // Case 5: string length is less than 78 with one '\n' in the end.
+  const string& msg5 = "Attempts to create on-disk metadata\n";
+  string formated_msg5;
+  AppendHardWrapped(msg5, 0, &formated_msg5);
+  // Contains one '\n'
+  ASSERT_EQ("Attempts to create on-disk metadata\n", formated_msg5);
+
+  // Case 6: string length is more than 78 with one '\n' in the middle.
+  const string& msg6 = "Attempts to create on-disk metadata \n"
+                       "that can be used by a non-replicated master";
+  string formated_msg6;
+  AppendHardWrapped(msg6, 0, &formated_msg6);
+  const string& expected_output6 = "Attempts to create on-disk metadata \n"
+                                   "that can be used by a non-replicated master";
+  // Contains one '\n'
+  ASSERT_EQ(expected_output6, formated_msg6);
+
+  // Case 7: string length is more than 78 with one '\n' in the end.
+  const string& msg7 = "Attempts to create on-disk metadata "
+                       "that can be used by a non-replicated master\n";
+  string formated_msg7;
+  AppendHardWrapped(msg7, 0, &formated_msg7);
+  const string& expected_output7 = "Attempts to create on-disk metadata "
+                                   "that can be used by a non-replicated \nmaster\n";
+  // Contains two '\n'
+  ASSERT_EQ(expected_output7, formated_msg7);
+
+  // Case 8: 2 '\n' in the end.
+  const string& msg8 = "Attempts to create on-disk metadata "
+                       "that can be used by a non-replicated master\n\n";
+  string formated_msg8;
+  AppendHardWrapped(msg8, 0, &formated_msg8);
+  const string& expected_output8 = "Attempts to create on-disk metadata "
+                                   "that can be used by a non-replicated \nmaster\n\n";
+  // contains 3 '\n'.
+  ASSERT_EQ(expected_output8, formated_msg8);
+
+  // Case 9: string is '\n'.
+  const string& msg9 = "\n";
+  string formated_msg9;
+  AppendHardWrapped(msg9, 0, &formated_msg9);
+  ASSERT_EQ("\n", formated_msg9);
+
+  // Case 10: string length is more than 78,
+  // dst is not null and does not contain '\n'.
+  // The old string in dst will be a new line.
+  const string& msg10 = "New line to create on-disk metadata";
+  string formated_msg10 = "Old line to create on-disk metadata. "
+                          "that can be used by a non-replicated master";
+  AppendHardWrapped(msg10, 0, &formated_msg10);
+  const string& expected_output10 = "Old line to create on-disk metadata. "
+                                  "that can be used by a non-replicated master\n"
+                                  "New line to create on-disk metadata";
+  ASSERT_EQ(expected_output10, formated_msg10);
+
+  // Case 11: dst and to_append are all empty.
+  const string& msg11 = "";
+  string formated_msg11 = "";
+  AppendHardWrapped(msg11, 0, &formated_msg11);
+  ASSERT_EQ("", formated_msg11);
+
+  // Case 12: string length is more than 78,
+  // continue indent is 2.
+  const string& msg12 = "Old line to create on-disk metadata. "
+                        "that can be used by a non-replicated master";
+  string formated_msg12;
+  AppendHardWrapped(msg12, 2, &formated_msg12);
+  const string& expected_output12 = "Old line to create on-disk metadata. "
+                "that can be used by a non-replicated \n  master";
+  ASSERT_EQ(expected_output12, formated_msg12);
+}
 } // namespace tools
 } // namespace kudu
diff --git a/src/kudu/tools/tool_action.cc b/src/kudu/tools/tool_action.cc
index b1ed9ab1f..6f2d01fc7 100644
--- a/src/kudu/tools/tool_action.cc
+++ b/src/kudu/tools/tool_action.cc
@@ -18,6 +18,7 @@
 #include "kudu/tools/tool_action.h"
 
 #include <algorithm>
+#include <cstddef>
 #include <memory>
 #include <ostream>
 #include <string>
@@ -73,44 +74,6 @@ string BuildUsageString(const vector<Mode*>& chain) {
   return JoinMapped(chain, [](Mode* a){ return a->name(); }, " ");
 }
 
-
-// Append 'to_append' to 'dst', but hard-wrapped at 78 columns.
-// After any newline, 'continuation_indent' spaces are prepended.
-void AppendHardWrapped(StringPiece to_append,
-                       int continuation_indent,
-                       string* dst) {
-  const int kWrapColumns = 78;
-  DCHECK_LT(continuation_indent, kWrapColumns);
-
-  // The string we're appending to might not be already at a newline.
-  int last_line_length = 0;
-  auto newline_pos = dst->rfind('\n');
-  if (newline_pos != string::npos) {
-    last_line_length = dst->size() - newline_pos;
-  }
-
-  // Iterate through the words deciding where to wrap.
-  vector<StringPiece> words = strings::Split(to_append, " ");
-  if (words.empty()) return;
-
-  for (const auto& word : words) {
-    // If the next word won't fit on this line, break before we append it.
-    if (last_line_length + word.size() > kWrapColumns) {
-      dst->push_back('\n');
-      for (int i = 0; i < continuation_indent; i++) {
-        dst->push_back(' ');
-      }
-      last_line_length = continuation_indent;
-    }
-    word.AppendToString(dst);
-    dst->push_back(' ');
-    last_line_length += word.size() + 1;
-  }
-
-  // Remove the extra space that we added at the end.
-  dst->resize(dst->size() - 1);
-}
-
 string SpacePad(StringPiece s, int len) {
   if (s.size() >= len) {
     return s.ToString();
@@ -424,5 +387,45 @@ void Action::SetOptionalParameterDefaultValues() const {
   }
 }
 
+void AppendHardWrapped(StringPiece to_append,
+                       int continuation_indent,
+                       string* dst) {
+  constexpr int kWrapColumns = 78;
+  DCHECK_LT(continuation_indent, kWrapColumns);
+
+  if (to_append.empty() && dst->empty()) return;
+
+  // The string we're appending to might not be already at a newline.
+  size_t last_line_length = dst->size();
+  auto newline_pos = dst->rfind('\n');
+  if (newline_pos != string::npos) {
+    last_line_length = dst->size() - newline_pos;
+  }
+  vector<StringPiece> lines = strings::Split(to_append, "\n");
+  for (const auto& line : lines) {
+    // Iterate through the words deciding where to wrap.
+    vector<StringPiece> words = strings::Split(line, " ");
+    if (words.empty()) continue;
+    for (const auto& word : words) {
+      // If the next word won't fit on this line, break before we append it.
+      if (last_line_length + word.size() > kWrapColumns) {
+        dst->push_back('\n');
+        for (int i = 0; i < continuation_indent; i++) {
+          dst->push_back(' ');
+        }
+        last_line_length = continuation_indent;
+      }
+      word.AppendToString(dst);
+      dst->push_back(' ');
+      last_line_length += word.size() + 1;
+    }
+    // Remove the extra space that we added at the end.
+    dst->resize(dst->size() - 1);
+    dst->push_back('\n');
+    last_line_length = continuation_indent;
+  }
+  // Remove the extra Enter key that we added at the end.
+  dst->resize(dst->size() - 1);
+}
 } // namespace tools
 } // namespace kudu
diff --git a/src/kudu/tools/tool_action.h b/src/kudu/tools/tool_action.h
index 21399a8a4..1dd27b385 100644
--- a/src/kudu/tools/tool_action.h
+++ b/src/kudu/tools/tool_action.h
@@ -24,7 +24,7 @@
 #include <vector>
 
 #include <boost/optional/optional.hpp>
-
+#include "kudu/gutil/strings/stringpiece.h"
 #include "kudu/util/status.h"
 
 namespace kudu {
@@ -322,6 +322,12 @@ class Action {
   ActionArgsDescriptor args_;
 };
 
+// Append 'to_append' to 'dst', but hard-wrapped at 78 columns.
+// After any newline, 'continuation_indent' spaces are prepended.
+void AppendHardWrapped(StringPiece to_append,
+                       int continuation_indent,
+                       std::string* dst);
+
 // Returns new nodes for each major mode.
 std::unique_ptr<Mode> BuildClusterMode();
 std::unique_ptr<Mode> BuildDiagnoseMode();
diff --git a/src/kudu/tools/tool_action_master.cc b/src/kudu/tools/tool_action_master.cc
index 5739281d5..bc7e1d64c 100644
--- a/src/kudu/tools/tool_action_master.cc
+++ b/src/kudu/tools/tool_action_master.cc
@@ -906,30 +906,30 @@ unique_ptr<Mode> BuildMasterMode() {
   }
 
   {
-    const char* rebuild_extra_description = "Attempts to create on-disk metadata\n"
-        "that can be used by a non-replicated master to recover a Kudu cluster\n"
-        "that has permanently lost its masters. It has a number of limitations:\n"
-        " - Security metadata like cryptographic keys are not rebuilt. Tablet servers\n"
-        "   and clients must be restarted before starting the new master in order to\n"
-        "   communicate with the new master.\n"
-        " - Table IDs are known only by the masters. Reconstructed tables will have\n"
-        "   new IDs.\n"
-        " - If a create, delete, or alter table was in progress when the masters were lost,\n"
-        "   it may not be possible to restore the table.\n"
-        " - If all replicas of a tablet are missing, it may not be able to recover the\n"
-        "   table fully. Moreover, the rebuild tool cannot detect that a tablet is\n"
-        "   missing.\n"
-        " - It's not possible to determine the replication factor of a table from tablet\n"
-        "   server metadata. The rebuild tool sets the replication factor of each\n"
-        "   table to --default_num_replicas instead.\n"
-        " - It's not possible to determine the next column id for a table from tablet\n"
-        "   server metadata. Instead, the rebuilt tool sets the next column id to\n"
-        "   a very large number.\n"
-        " - Table metadata like comments, owners, and configurations are not stored on\n"
-        "   tablet servers and are thus not restored.\n"
-        "WARNING: This tool is potentially unsafe. Only use it when there is no\n"
-        "possibility of recovering the original masters, and you know what you\n"
-        "are doing.";
+    const char* rebuild_extra_description = "Attempts to create on-disk metadata "
+        "that can be used by a non-replicated master to recover a Kudu cluster "
+        "that has permanently lost its masters. It has a number of limitations:\n\n"
+        " - Security metadata like cryptographic keys are not rebuilt. Tablet servers "
+        "and clients must be restarted before starting the new master in order to "
+        "communicate with the new master.\n\n"
+        " - Table IDs are known only by the masters. Reconstructed tables will have "
+        "new IDs.\n\n"
+        " - If a create, delete, or alter table was in progress when the masters were lost, "
+        "it may not be possible to restore the table.\n\n"
+        " - If all replicas of a tablet are missing, it may not be able to recover the "
+        "table fully. Moreover, the rebuild tool cannot detect that a tablet is "
+        "missing.\n\n"
+        " - It's not possible to determine the replication factor of a table from tablet "
+        "server metadata. The rebuild tool sets the replication factor of each "
+        "table to --default_num_replicas instead.\n\n"
+        " - It's not possible to determine the next column id for a table from tablet "
+        "server metadata. Instead, the rebuilt tool sets the next column id to "
+        "a very large number.\n\n"
+        " - Table metadata like comments, owners, and configurations are not stored on "
+        "tablet servers and are thus not restored.\n\n"
+        "WARNING: This tool is potentially unsafe. Only use it when there is no "
+        "possibility of recovering the original masters, and you know what you "
+        "are doing.\n";
     unique_ptr<Action> unsafe_rebuild =
         ActionBuilder("unsafe_rebuild", &RebuildMaster)
         .Description("Rebuild a Kudu master from tablet server metadata")