File docs/06-command-list.md changed (mode: 100644) (index eca00e4..c421cb3) |
... |
... |
export |
58 |
58 |
|
|
59 |
59 |
Invokes external script passing item data via argument list. |
Invokes external script passing item data via argument list. |
60 |
60 |
|
|
61 |
|
**Usage: export cmd \<list of conditions\>** |
|
|
61 |
|
**Usage: export (-|cmd) \<list of conditions\>** |
62 |
62 |
|
|
63 |
63 |
Invokes **cmd key1=value1 key2=value2** for each item that matches given list |
Invokes **cmd key1=value1 key2=value2** for each item that matches given list |
64 |
|
of conditions. |
|
|
64 |
|
of conditions or prints out items to standard output with **key=value** fields |
|
65 |
|
terminated by null character and each item also finished by null character. |
65 |
66 |
|
|
66 |
67 |
help |
help |
67 |
68 |
---- |
---- |
File src/cmds/ExportCmd.cpp changed (mode: 100644) (index c175c70..9b952a5) |
39 |
39 |
/** |
/** |
40 |
40 |
* @brief Usage message for "export" command. |
* @brief Usage message for "export" command. |
41 |
41 |
*/ |
*/ |
42 |
|
const char *const USAGE = R"(Usage: export cmd [expr like for ls...] |
|
|
42 |
|
const char *const USAGE = R"(Usage: export (-|cmd) [expr like for ls...] |
43 |
43 |
|
|
44 |
|
The cmd is run once for each item with arguments of the form key=value.)"; |
|
|
44 |
|
Either the cmd is run once for each item with arguments of the form key=value |
|
45 |
|
or items are printed to standard output with key=value fields terminated by null |
|
46 |
|
character and each item also finished by null character.)"; |
45 |
47 |
|
|
46 |
48 |
namespace { |
namespace { |
47 |
49 |
|
|
|
... |
... |
ExportCmd::complete(Project &project, const std::vector<std::string> &args) |
155 |
157 |
void |
void |
156 |
158 |
ExportCmd::exportItem(const std::string &cmd, Item &item) |
ExportCmd::exportItem(const std::string &cmd, Item &item) |
157 |
159 |
{ |
{ |
|
160 |
|
if (const bool toStdOut = (cmd == "-")) { |
|
161 |
|
for (const std::string &key : item.listRecordNames()) { |
|
162 |
|
out() << key << '=' << item.getValue(key) << '\0'; |
|
163 |
|
} |
|
164 |
|
out() << '\0'; |
|
165 |
|
return; |
|
166 |
|
} |
|
167 |
|
|
158 |
168 |
// Compose command-line. |
// Compose command-line. |
159 |
169 |
std::ostringstream cmdLine(cmd, std::ios::out | std::ios::ate); |
std::ostringstream cmdLine(cmd, std::ios::out | std::ios::ate); |
160 |
170 |
for (const std::string &key : item.listRecordNames()) { |
for (const std::string &key : item.listRecordNames()) { |
File tests/cmds/ExportCmd.cpp changed (mode: 100644) (index 79e591d..8d85f36) |
... |
... |
TEST_CASE("Item exporting", "[cmds][export]") |
124 |
124 |
REQUIRE(out.str() == std::string()); |
REQUIRE(out.str() == std::string()); |
125 |
125 |
REQUIRE(err.str() == std::string()); |
REQUIRE(err.str() == std::string()); |
126 |
126 |
} |
} |
|
127 |
|
|
|
128 |
|
TEST_CASE("Stdout destination", "[cmds][export]") |
|
129 |
|
{ |
|
130 |
|
std::unique_ptr<Project> prj = Tests::makeProject(); |
|
131 |
|
Storage &storage = prj->getStorage(); |
|
132 |
|
|
|
133 |
|
Item item = Tests::makeItem("id"); |
|
134 |
|
item.setValue("title", "This's a title"); |
|
135 |
|
item.setValue("bug_number", "22"); |
|
136 |
|
|
|
137 |
|
Tests::storeItem(storage, std::move(item)); |
|
138 |
|
|
|
139 |
|
Command *const cmd = Commands::get("export"); |
|
140 |
|
|
|
141 |
|
std::ostringstream out, err; |
|
142 |
|
Tests::setStreams(out, err); |
|
143 |
|
|
|
144 |
|
boost::optional<int> exitCode = cmd->run(*prj, { "-" }); |
|
145 |
|
REQUIRE(exitCode); |
|
146 |
|
REQUIRE(*exitCode == EXIT_SUCCESS); |
|
147 |
|
|
|
148 |
|
// There must be two trailing zeroes. |
|
149 |
|
const char expectedOut[] = "bug_number=22\0title=This's a title\0"; |
|
150 |
|
REQUIRE(out.str() == std::string(std::begin(expectedOut), |
|
151 |
|
std::end(expectedOut))); |
|
152 |
|
REQUIRE(err.str() == std::string()); |
|
153 |
|
} |