Merge "Fix some namespace formatting"
diff --git a/src/ast_commands.cpp b/src/ast_commands.cpp
index 74aefd5..aa4756a 100644
--- a/src/ast_commands.cpp
+++ b/src/ast_commands.cpp
@@ -14,7 +14,7 @@
bool get_::operator==(const get_& b) const
{
- return this->m_path == b.m_path;
+ return this->m_path == b.m_path && this->m_dsTarget == b.m_dsTarget;
}
bool cd_::operator==(const cd_& b) const
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index 0d7a476..0a474f0 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -152,6 +152,7 @@
/> get
/> get /module:path)";
bool operator==(const get_& b) const;
+ boost::optional<DatastoreTarget> m_dsTarget;
boost::optional<boost::variant<dataPath_, module_>> m_path;
};
@@ -360,7 +361,7 @@
BOOST_FUSION_ADAPT_STRUCT(describe_, m_path)
BOOST_FUSION_ADAPT_STRUCT(help_, m_cmd)
BOOST_FUSION_ADAPT_STRUCT(discard_)
-BOOST_FUSION_ADAPT_STRUCT(get_, m_path)
+BOOST_FUSION_ADAPT_STRUCT(get_, m_dsTarget, m_path)
BOOST_FUSION_ADAPT_STRUCT(copy_, m_source, m_destination)
BOOST_FUSION_ADAPT_STRUCT(move_, m_source, m_destination)
BOOST_FUSION_ADAPT_STRUCT(dump_, m_format)
diff --git a/src/datastore_access.cpp b/src/datastore_access.cpp
index eba90e0..e421274 100644
--- a/src/datastore_access.cpp
+++ b/src/datastore_access.cpp
@@ -31,6 +31,11 @@
}
}
+DatastoreTarget DatastoreAccess::target() const
+{
+ return m_target;
+}
+
void DatastoreAccess::setTarget(const DatastoreTarget target)
{
m_target = target;
diff --git a/src/datastore_access.hpp b/src/datastore_access.hpp
index 3012a7e..a718f14 100644
--- a/src/datastore_access.hpp
+++ b/src/datastore_access.hpp
@@ -57,6 +57,7 @@
virtual void deleteItem(const std::string& path) = 0;
virtual void moveItem(const std::string& path, std::variant<yang::move::Absolute, yang::move::Relative> move) = 0;
virtual Tree execute(const std::string& path, const Tree& input) = 0;
+ DatastoreTarget target() const;
void setTarget(const DatastoreTarget target);
virtual std::shared_ptr<Schema> schema() = 0;
diff --git a/src/grammars.hpp b/src/grammars.hpp
index fd01b5b..4e3b97c 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -15,6 +15,25 @@
#include "leaf_data.hpp"
#include "path_parser.hpp"
+/**
+ * Returns a parser that generates suggestions based on a Completion set.
+ * Usage:
+ * const auto suggestSomeStuff = staticSuggestions({"some", "stuff", "yay"});
+ *
+ * You can use this as a standard parser in a Spirit grammar.
+ */
+auto staticSuggestions(const std::initializer_list<std::string>& strings)
+{
+ std::set<Completion> completions;
+ std::transform(begin(strings), end(strings), std::inserter(completions, completions.end()),
+ [](const auto s) { return Completion{s, " "}; });
+ return as<x3::unused_type>[x3::eps[([completions](auto& ctx) {
+ auto& parserContext = x3::get<parser_context_tag>(ctx);
+ parserContext.m_suggestions = completions;
+ parserContext.m_completionIterator = _where(ctx).begin();
+ })]];
+}
+
#if BOOST_VERSION <= 107700
namespace boost::spirit::x3::traits {
// Backport https://github.com/boostorg/spirit/pull/702
@@ -111,8 +130,22 @@
delete_::name >> space_separator > (presenceContainerPath | listInstancePath | leafListElementPath | writableLeafPath);
#endif
+const auto dsTargetSuggestions = staticSuggestions({"running", "startup", "operational"});
+
+struct ds_target_table : x3::symbols<DatastoreTarget> {
+ ds_target_table()
+ {
+ add
+ ("operational", DatastoreTarget::Operational)
+ ("startup", DatastoreTarget::Startup)
+ ("running", DatastoreTarget::Running);
+ }
+} const ds_target_table;
+
auto const get_def =
- get_::name >> -(space_separator >> getPath);
+ get_::name
+ >> -(space_separator >> "-" > staticSuggestions({"-datastore"}) > "-datastore" > space_separator > dsTargetSuggestions > ds_target_table)
+ >> -(space_separator >> getPath);
auto const set_def =
set_::name >> space_separator > writableLeafPath > space_separator > leaf_data;
@@ -147,11 +180,7 @@
const auto copy_source = x3::rule<class source, Datastore>{"source datastore"} = datastore;
const auto copy_destination = x3::rule<class source, Datastore>{"destination datastore"} = datastore;
-const auto datastoreSuggestions = x3::eps[([](auto& ctx) {
- auto& parserContext = x3::get<parser_context_tag>(ctx);
- parserContext.m_suggestions = {Completion{"running", " "}, Completion{"startup", " "}};
- parserContext.m_completionIterator = _where(ctx).begin();
-})];
+const auto datastoreSuggestions = staticSuggestions({"running", "startup"});
struct copy_args : x3::parser<copy_args> {
using attribute_type = copy_;
@@ -316,24 +345,8 @@
auto const exec_def =
exec_::name > -(space_separator > -as<dataPath_>[RpcActionPath<AllowInput::No>{}]);
-const auto dsTargetSuggestions = x3::eps[([](auto& ctx) {
- auto& parserContext = x3::get<parser_context_tag>(ctx);
- parserContext.m_suggestions = {Completion{"running", " "}, Completion{"startup", " "}, Completion{"operational", " "}};
- parserContext.m_completionIterator = _where(ctx).begin();
-})];
-
-struct ds_target_table : x3::symbols<DatastoreTarget> {
- ds_target_table()
- {
- add
- ("operational", DatastoreTarget::Operational)
- ("startup", DatastoreTarget::Startup)
- ("running", DatastoreTarget::Running);
- }
-} const ds_target_table;
-
auto const switch_rule_def =
- switch_::name > space_separator > as<x3::unused_type>[dsTargetSuggestions] > ds_target_table;
+ switch_::name > space_separator > dsTargetSuggestions > ds_target_table;
auto const cancel_def =
cancel_::name >> x3::attr(cancel_{});
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index 8030f3f..0fe96da 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -10,6 +10,7 @@
#include <boost/mpl/for_each.hpp>
#include <iostream>
#include <sstream>
+#include "UniqueResource.hpp"
#include "datastore_access.hpp"
#include "interpreter.hpp"
#include "utils.hpp"
@@ -83,6 +84,14 @@
void Interpreter::operator()(const get_& get) const
{
+ auto targetSwitcher = make_unique_resource([] {}, [this, oldTarget = m_datastore.target()] {
+ m_datastore.setTarget(oldTarget);
+ });
+
+ if (get.m_dsTarget) {
+ m_datastore.setTarget(*get.m_dsTarget);
+ }
+
auto items = m_datastore.getItems(pathToString(toCanonicalPath(get.m_path)));
printTree(items);
}
diff --git a/src/proxy_datastore.cpp b/src/proxy_datastore.cpp
index 3bd6719..67a3cb3 100644
--- a/src/proxy_datastore.cpp
+++ b/src/proxy_datastore.cpp
@@ -108,6 +108,11 @@
}
}
+DatastoreTarget ProxyDatastore::target() const
+{
+ return m_datastore->target();
+}
+
void ProxyDatastore::setTarget(const DatastoreTarget target)
{
m_datastore->setTarget(target);
diff --git a/src/proxy_datastore.hpp b/src/proxy_datastore.hpp
index 21fbfc5..20a877d 100644
--- a/src/proxy_datastore.hpp
+++ b/src/proxy_datastore.hpp
@@ -28,6 +28,7 @@
void discardChanges();
void copyConfig(const Datastore source, const Datastore destination);
[[nodiscard]] std::string dump(const DataFormat format) const;
+ DatastoreTarget target() const;
void setTarget(const DatastoreTarget target);
void initiate(const std::string& path);
diff --git a/tests/init_datastore.bash.in b/tests/init_datastore.bash.in
index d8eb2c3..1e01346 100755
--- a/tests/init_datastore.bash.in
+++ b/tests/init_datastore.bash.in
@@ -21,6 +21,9 @@
YANG_DIR=$(dirname "$1")
shift
+# Uninstall the module
+"$SYSREPOCTL" --uninstall "$(basename "$MODULE" ".yang")" -v3 || true
+
# Install the module
"$SYSREPOCTL" --search-dirs "$YANG_DIR" --install "$MODULE" -v3
diff --git a/tests/path_completion.cpp b/tests/path_completion.cpp
index 511d922..be676c9 100644
--- a/tests/path_completion.cpp
+++ b/tests/path_completion.cpp
@@ -213,6 +213,27 @@
// The expectedContextLength is 13, because the completion isn't actually generated after the slash.
expectedContextLength = 13;
}
+
+ SECTION("get -")
+ {
+ input = "get -";
+ expectedCompletions = {"-datastore "};
+ expectedContextLength = 0;
+ }
+
+ SECTION("get --datastore ")
+ {
+ input = "get --datastore ";
+ expectedCompletions = {"operational", "running", "startup"};
+ expectedContextLength = 0;
+ }
+
+ SECTION("get --datastore running /second")
+ {
+ input = "get --datastore running /second";
+ expectedCompletions = {"second:amelie/"};
+ expectedContextLength = 6;
+ }
}
SECTION("describe completion")