$darkmode
main_check.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
25 #pragma once
26 
27 #include <iostream> // for ostream, cout
28 #include <string> // for string
29 #include <vector> // for vector<>
30 
31 #include "main_stack.hpp" // for Stack, StackOptions, new_stack
32 
33 namespace engine {
34 
35 struct CheckOptions {
36  cloe::StackOptions stack_options;
37  std::ostream& output = std::cout;
38  std::string delimiter = ",";
39 
40  // Flags:
41  bool distinct = false;
42  bool summarize = false;
43  bool output_json = false;
44  int json_indent = 2;
45 };
46 
53 inline void check_stack(const cloe::StackOptions& opt, const std::vector<std::string>& files,
54  bool* ok = nullptr) {
55  if (ok) {
56  *ok = false;
57  }
58  cloe::Stack s = cloe::new_stack(opt, files);
60  if (ok) {
61  *ok = true;
62  }
63 }
64 
70 inline std::string check_summary(const CheckOptions& opt, const std::vector<std::string>& files,
71  bool* ok = nullptr) {
72  cloe::StackOptions stack_opt = opt.stack_options;
73  stack_opt.error = boost::none;
74 
75  try {
76  check_stack(stack_opt, files, ok);
77  return "OK";
78  } catch (cloe::StackIncompleteError& e) {
79  return "INCOMPLETE (" + std::string(e.what()) + ")";
80  } catch (cloe::ConfError& e) {
81  return "INVALID (" + std::string(e.what()) + ")";
82  } catch (std::exception& e) {
83  return "ERROR (" + std::string(e.what()) + ")";
84  }
85 }
86 
91 inline cloe::Json check_json(const CheckOptions& opt, const std::vector<std::string>& files,
92  bool* ok = nullptr) {
93  cloe::StackOptions stack_opt = opt.stack_options;
94  stack_opt.error = boost::none;
95 
96  if (opt.summarize) {
97  return check_summary(opt, files, ok);
98  } else {
99  try {
100  check_stack(stack_opt, files, ok);
101  return nullptr;
102  } catch (cloe::SchemaError& e) {
103  return e;
104  } catch (cloe::ConfError& e) {
105  return e;
106  } catch (std::exception& e) {
107  return cloe::Json{
108  {"error", e.what()},
109  };
110  }
111  }
112 }
113 
114 inline int check_merged(const CheckOptions& opt, const std::vector<std::string>& filepaths) {
115  bool ok = false;
116  if (opt.output_json) {
117  opt.output << check_json(opt, filepaths, &ok).dump(opt.json_indent) << std::endl;
118  } else if (opt.summarize) {
119  opt.output << check_summary(opt, filepaths, &ok) << std::endl;
120  } else {
121  try {
122  check_stack(opt.stack_options, filepaths, &ok);
123  } catch (cloe::ConcludedError&) {
124  } catch (std::exception& e) {
125  opt.output << e.what() << std::endl;
126  }
127  }
128 
129  return ok ? EXIT_SUCCESS : EXIT_FAILURE;
130 }
131 
132 inline int check_distinct(const CheckOptions& opt, const std::vector<std::string>& filepaths) {
133  int exit_code = EXIT_SUCCESS;
134  auto check_each = [&](std::function<void(const std::string&, bool*)> func) {
135  for (const auto& x : filepaths) {
136  bool ok = true;
137  func(x, &ok);
138  if (!ok) {
139  exit_code = EXIT_FAILURE;
140  }
141  }
142  };
143 
144  if (opt.output_json) {
145  // Output for each file a summary
146  cloe::Json output;
147  check_each([&](const auto& f, bool* ok) {
148  output[f] = check_json(opt, std::vector<std::string>{f}, ok);
149  });
150  opt.output << output.dump(opt.json_indent) << std::endl;
151  } else if (opt.summarize) {
152  check_each([&](const auto& f, bool* ok) {
153  opt.output << f << ": " << check_summary(opt, std::vector<std::string>{f}, ok) << std::endl;
154  });
155  } else {
156  check_each([&](const auto& f, bool* ok) {
157  try {
158  check_stack(opt.stack_options, std::vector<std::string>{f}, ok);
159  } catch (cloe::ConcludedError&) {
160  } catch (std::exception& e) {
161  opt.output << f << ": " << e.what() << std::endl;
162  }
163  });
164  }
165 
166  return exit_code;
167 }
168 
169 inline int check(const CheckOptions& opt, const std::vector<std::string>& filepaths) {
170  if (opt.distinct) {
171  return check_distinct(opt, filepaths);
172  } else {
173  return check_merged(opt, filepaths);
174  }
175 }
176 
177 } // namespace engine
Definition: error.hpp:80
Definition: stack.hpp:888
Definition: stack.hpp:901
void check_completeness() const
Definition: stack.cpp:729
Definition: error.hpp:60
Definition: error.hpp:149
void check_stack(const cloe::StackOptions &opt, const std::vector< std::string > &files, bool *ok=nullptr)
Definition: main_check.hpp:53
cloe::Json check_json(const CheckOptions &opt, const std::vector< std::string > &files, bool *ok=nullptr)
Definition: main_check.hpp:91
std::string check_summary(const CheckOptions &opt, const std::vector< std::string > &files, bool *ok=nullptr)
Definition: main_check.hpp:70
Definition: main_stack.hpp:38
Definition: main_check.hpp:35