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")