/src/CMake/Source/cmDiscoverTestsCommand.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #include "cmDiscoverTestsCommand.h" |
4 | | |
5 | | #include <cstddef> |
6 | | #include <ostream> |
7 | | #include <utility> |
8 | | #include <vector> |
9 | | |
10 | | #include <cm/memory> |
11 | | #include <cmext/string_view> |
12 | | |
13 | | #include "cmArgumentParser.h" |
14 | | #include "cmArgumentParserTypes.h" |
15 | | #include "cmExecutionStatus.h" |
16 | | #include "cmGeneratorExpression.h" |
17 | | #include "cmListFileCache.h" |
18 | | #include "cmLocalGenerator.h" |
19 | | #include "cmMakefile.h" |
20 | | #include "cmScriptGenerator.h" |
21 | | #include "cmTestDiscovery.h" |
22 | | #include "cmTestGenerator.h" |
23 | | |
24 | | namespace { |
25 | | |
26 | | struct Arguments : cmTestDiscoveryArgs |
27 | | { |
28 | | bool CommandExpandLists = false; |
29 | | ArgumentParser::MaybeEmpty<std::vector<std::string>> Configurations; |
30 | | }; |
31 | | |
32 | | class DiscoveryGenerator : public cmTestGenerator |
33 | | { |
34 | | public: |
35 | | DiscoveryGenerator(Arguments arguments, cmListFileBacktrace backtrace) |
36 | 0 | : cmTestGenerator(nullptr, arguments.Configurations) |
37 | 0 | , Args{ std::move(arguments) } |
38 | 0 | , Backtrace{ std::move(backtrace) } |
39 | 0 | { |
40 | 0 | } |
41 | | |
42 | | private: |
43 | | void GenerateProperties(std::ostream& os, Indent indent, |
44 | | std::vector<std::string> const& props, |
45 | | std::string const& config, cmGeneratorExpression& ge) |
46 | 0 | { |
47 | 0 | for (std::size_t i = 0; i < props.size(); i += 2) { |
48 | 0 | os << '\n' |
49 | 0 | << indent << Quote(props[i]) << ' ' |
50 | 0 | << Quote(ge.Parse(props[i + 1])->Evaluate(this->LG, config)); |
51 | 0 | } |
52 | 0 | } |
53 | | |
54 | | void GenerateScriptForConfig(std::ostream& os, std::string const& config, |
55 | | Indent indent) override |
56 | 0 | { |
57 | | // Set up generator expression evaluation context. |
58 | 0 | cmGeneratorExpression ge(*this->LG->GetMakefile()->GetCMakeInstance(), |
59 | 0 | this->Backtrace); |
60 | |
|
61 | 0 | auto const in = indent.Next(); |
62 | 0 | os << indent << "discover_tests(COMMAND "; |
63 | 0 | this->GenerateCommand(os, this->Args.Command, config, |
64 | 0 | this->Args.CommandExpandLists, ge); |
65 | 0 | os << '\n' << in << "DISCOVERY_ARGS"; |
66 | 0 | for (auto const& arg : this->Args.DiscoveryArgs) { |
67 | 0 | os << ' ' << Quote(arg); |
68 | 0 | } |
69 | 0 | os << '\n' << in << "DISCOVERY_MATCH " << Quote(this->Args.DiscoveryMatch); |
70 | 0 | if (!this->Args.DiscoveryProperties.empty()) { |
71 | 0 | os << '\n' << in << "DISCOVERY_PROPERTIES"; |
72 | 0 | this->GenerateProperties(os, in.Next(), this->Args.DiscoveryProperties, |
73 | 0 | config, ge); |
74 | 0 | } |
75 | 0 | os << '\n' << in << "TEST_NAME " << Quote(this->Args.TestName); |
76 | 0 | os << '\n' << in << "TEST_ARGS"; |
77 | 0 | for (auto const& arg : this->Args.TestArgs) { |
78 | 0 | os << ' ' << Quote(arg); |
79 | 0 | } |
80 | 0 | os << '\n' << in << "TEST_PROPERTIES"; |
81 | 0 | this->GenerateProperties(os, in.Next(), this->Args.TestProperties, config, |
82 | 0 | ge); |
83 | 0 | os << '\n' << in.Next(); |
84 | 0 | this->GenerateBacktrace(os, this->Backtrace); |
85 | 0 | os << '\n' << in << ")\n"; |
86 | 0 | } |
87 | | |
88 | | Arguments Args; |
89 | | cmListFileBacktrace Backtrace; |
90 | | }; |
91 | | |
92 | | } // namespace |
93 | | |
94 | | bool cmDiscoverTestsCommand(std::vector<std::string> const& args, |
95 | | cmExecutionStatus& status) |
96 | 0 | { |
97 | 0 | static auto const parser = |
98 | 0 | cmArgumentParser<Arguments>{ cmTestDiscoveryParser<Arguments>() } |
99 | 0 | .Bind("COMMAND_EXPAND_LISTS"_s, &Arguments::CommandExpandLists) |
100 | 0 | .Bind("CONFIGURATIONS"_s, &Arguments::Configurations); |
101 | |
|
102 | 0 | auto unparsed = std::vector<std::string>{}; |
103 | 0 | Arguments arguments = parser.Parse(args, &unparsed); |
104 | 0 | if (arguments.MaybeReportError(status.GetMakefile())) { |
105 | 0 | return true; |
106 | 0 | } |
107 | | |
108 | 0 | if (!unparsed.empty()) { |
109 | 0 | status.SetError(" given unknown argument \"" + unparsed.front() + "\"."); |
110 | 0 | return false; |
111 | 0 | } |
112 | | |
113 | 0 | cmMakefile& mf = status.GetMakefile(); |
114 | 0 | mf.AddTestGenerator(cm::make_unique<DiscoveryGenerator>(std::move(arguments), |
115 | 0 | mf.GetBacktrace())); |
116 | 0 | return true; |
117 | 0 | } |