1 |
commit: 7f6c20a9ef87ec5377f0d7758f7cdce20da11831 |
2 |
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu May 5 06:53:14 2011 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun May 8 12:55:51 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=7f6c20a9 |
7 |
|
8 |
Utils: reimplement instruo with libbash |
9 |
|
10 |
With the help of instruo from Paludis, we can setup variables to |
11 |
bash env needed for metadata generation. In the meanwhile, we can |
12 |
compare the original instruo utility with our implementation. |
13 |
|
14 |
--- |
15 |
.gitignore | 2 + |
16 |
Makefile.am | 15 ++- |
17 |
configure.ac | 2 + |
18 |
src/libbash.cpp | 5 + |
19 |
src/libbash.h | 3 +- |
20 |
utils/command_line.cpp | 88 +++++++++ |
21 |
utils/command_line.h | 62 ++++++ |
22 |
utils/instruo.cpp | 251 ++++++++++++++++++++++++ |
23 |
utils/{metadata_generator.cpp => metadata.cpp} | 35 +--- |
24 |
src/libbash.h => utils/metadata.h | 31 +--- |
25 |
utils/metadata_generator.cpp | 84 +-------- |
26 |
11 files changed, 445 insertions(+), 133 deletions(-) |
27 |
|
28 |
diff --git a/.gitignore b/.gitignore |
29 |
index 10b4131..79e3a80 100644 |
30 |
--- a/.gitignore |
31 |
+++ b/.gitignore |
32 |
@@ -2,6 +2,7 @@ |
33 |
*.swo |
34 |
*.o |
35 |
*.la |
36 |
+*.a |
37 |
*.lo |
38 |
*.log |
39 |
*.class |
40 |
@@ -21,6 +22,7 @@ cppunittests |
41 |
variable_printer |
42 |
metadata_generator |
43 |
ast_printer |
44 |
+instruo |
45 |
long.sh |
46 |
massif.out |
47 |
libbash.g |
48 |
|
49 |
diff --git a/Makefile.am b/Makefile.am |
50 |
index a3890bb..95beba6 100644 |
51 |
--- a/Makefile.am |
52 |
+++ b/Makefile.am |
53 |
@@ -113,13 +113,24 @@ cppunittests_LDFLAGS = -static |
54 |
|
55 |
endif |
56 |
|
57 |
-noinst_PROGRAMS = variable_printer metadata_generator ast_printer |
58 |
+noinst_LIBRARIES = libmetadata.a |
59 |
+ |
60 |
+libmetadata_a_SOURCES = utils/metadata.h utils/metadata.cpp |
61 |
+libmetadata_a_CPPFLAGS = $(AM_CPPFLAGS) -Iutils |
62 |
+ |
63 |
+noinst_PROGRAMS = variable_printer metadata_generator ast_printer instruo |
64 |
|
65 |
variable_printer_SOURCES = utils/variable_printer.cpp |
66 |
variable_printer_LDADD = libcppbash.la |
67 |
|
68 |
metadata_generator_SOURCES = utils/metadata_generator.cpp |
69 |
-metadata_generator_LDADD = libcppbash.la |
70 |
+metadata_generator_LDADD = libcppbash.la libmetadata.a |
71 |
+metadata_generator_CPPFLAGS = $(AM_CPPFLAGS) -Iutils |
72 |
+ |
73 |
+instruo_SOURCES = utils/instruo.cpp utils/command_line.cpp utils/command_line.h |
74 |
+instruo_LDADD = libcppbash.la @PALUDIS_LIBS@ libmetadata.a |
75 |
+instruo_CPPFLAGS = $(AM_CPPFLAGS) @PALUDIS_CFLAGS@ -Iutils |
76 |
+instruo_CXXFLAGS = $(AM_CXXFLAGS) -Wno-extra |
77 |
|
78 |
ast_printer_SOURCES = utils/ast_printer.cpp |
79 |
ast_printer_LDADD = libcppbash.la $(BOOST_PROGRAM_OPTIONS_LIB) |
80 |
|
81 |
diff --git a/configure.ac b/configure.ac |
82 |
index b710a97..3563013 100644 |
83 |
--- a/configure.ac |
84 |
+++ b/configure.ac |
85 |
@@ -29,6 +29,8 @@ AC_ARG_ENABLE([developer], |
86 |
[AS_HELP_STRING([--enable-developer],[enables various QA checks])]) |
87 |
AM_CONDITIONAL([DEVELOPER_MODE],[test "x$enable_developer" = xyes]) |
88 |
|
89 |
+PKG_CHECK_MODULES([PALUDIS], [paludis]) |
90 |
+ |
91 |
AS_IF([test "x$enable_developer" = xyes],[boost_version="1.46.1"],[boost_version="1.43.0"]) |
92 |
AX_BOOST_BASE([$boost_version],[:], |
93 |
[AC_MSG_ERROR([Needed boost not found])]) |
94 |
|
95 |
diff --git a/src/libbash.cpp b/src/libbash.cpp |
96 |
index 4fb4102..f04064d 100644 |
97 |
--- a/src/libbash.cpp |
98 |
+++ b/src/libbash.cpp |
99 |
@@ -39,6 +39,11 @@ namespace libbash |
100 |
if(!input) |
101 |
throw interpreter_exception("Unable to create fstream for script: " + path); |
102 |
interpreter walker; |
103 |
+ |
104 |
+ // Initialize bash environment |
105 |
+ for(auto iter = variables.begin(); iter != variables.end(); ++iter) |
106 |
+ walker.set_value(iter->first, (iter->second)[0]); |
107 |
+ |
108 |
bash_ast ast(input); |
109 |
ast.interpret_with(walker); |
110 |
|
111 |
|
112 |
diff --git a/src/libbash.h b/src/libbash.h |
113 |
index ca8cdaa..3f903e9 100644 |
114 |
--- a/src/libbash.h |
115 |
+++ b/src/libbash.h |
116 |
@@ -39,7 +39,8 @@ namespace libbash |
117 |
/// \brief interpret a script specifid by path, return a map filled with |
118 |
/// variables defined in the script |
119 |
/// \param the path of target script |
120 |
- /// \param the map to store variables |
121 |
+ /// \param[in, out] we use the map to initialize bash environment and store the result |
122 |
+ /// \param[out] store the names of the functions defined in the script |
123 |
void LIBBASH_API interpret(const std::string& path, |
124 |
std::unordered_map<std::string, std::vector<std::string>>& variables, |
125 |
std::vector<std::string>& functions); |
126 |
|
127 |
diff --git a/utils/command_line.cpp b/utils/command_line.cpp |
128 |
new file mode 100644 |
129 |
index 0000000..8d238b4 |
130 |
--- /dev/null |
131 |
+++ b/utils/command_line.cpp |
132 |
@@ -0,0 +1,88 @@ |
133 |
+/* This file was copied from Paludis src/clients/instruo/command_line.cc that is licensed as follows: */ |
134 |
+ |
135 |
+/* |
136 |
+ * Copyright (c) 2007, 2008, 2009, 2010 Ciaran McCreesh |
137 |
+ * |
138 |
+ * This file is part of the Paludis package manager. Paludis is free software; |
139 |
+ * you can redistribute it and/or modify it under the terms of the GNU General |
140 |
+ * Public License version 2, as published by the Free Software Foundation. |
141 |
+ * |
142 |
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY |
143 |
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
144 |
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
145 |
+ * details. |
146 |
+ * |
147 |
+ * You should have received a copy of the GNU General Public License along with |
148 |
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
149 |
+ * Place, Suite 330, Boston, MA 02111-1307 USA |
150 |
+ */ |
151 |
+ |
152 |
+#include "command_line.h" |
153 |
+#include <paludis/util/singleton-impl.hh> |
154 |
+ |
155 |
+using namespace paludis; |
156 |
+ |
157 |
+template class paludis::Singleton<CommandLine>; |
158 |
+ |
159 |
+CommandLine::CommandLine() : |
160 |
+ ArgsHandler(), |
161 |
+ |
162 |
+ action_args(main_options_section(), "Actions", |
163 |
+ "Selects which basic action to perform. Exactly one action should " |
164 |
+ "be specified."), |
165 |
+ a_generate_cache(&action_args, "generate-cache", 'g', "Generate cache", false), |
166 |
+ a_version(&action_args, "version", 'V', "Display program version", false), |
167 |
+ a_help(&action_args, "help", 'h', "Display program help", false), |
168 |
+ |
169 |
+ general_args(main_options_section(), "General options", |
170 |
+ "Options which are relevant for most or all actions."), |
171 |
+ a_log_level(&general_args, "log-level", '\0'), |
172 |
+ a_no_colour(&general_args, "no-colour", '\0', "Do not use colour", false), |
173 |
+ a_no_color(&a_no_colour, "no-color"), |
174 |
+ a_force_colour(&general_args, "force-colour", '\0', "Force the use of colour", false), |
175 |
+ a_force_color(&a_force_colour, "force-color"), |
176 |
+ a_repository_directory(&general_args, "repository-dir", 'D', |
177 |
+ "Where to find the repository (default: current directory)"), |
178 |
+ a_output_directory(&general_args, "output-dir", 'o', |
179 |
+ "Where to place generated metadata (default: current directory)"), |
180 |
+ a_master_repository_name(&general_args, "master-repository-name", '\0', |
181 |
+ "Use the specified name for the master repository. Specify the location using --extra-repository-dir. " |
182 |
+ "Only for repositories with no metadata/layout.conf."), |
183 |
+ a_extra_repository_dir(&general_args, "extra-repository-dir", '\0', |
184 |
+ "Also include the repository at this location. May be specified multiple times, in creation order."), |
185 |
+ a_report_file(&general_args, "report-file", 'r', |
186 |
+ "Write report to the specified file, rather than stdout") |
187 |
+{ |
188 |
+ add_usage_line("--generate-cache [ at least one of --repository-dir /dir or --output-dir /dir ]"); |
189 |
+ |
190 |
+ add_description_line("instruo is configured purely from the command line. It does not use any user " |
191 |
+ "configuration files."); |
192 |
+ |
193 |
+ add_environment_variable("INSTRUO_OPTIONS", "Default command-line options."); |
194 |
+ add_environment_variable("INSTRUO_THREADS", "Number of threads to use. Default: 5"); |
195 |
+} |
196 |
+ |
197 |
+std::string |
198 |
+CommandLine::app_name() const |
199 |
+{ |
200 |
+ return "instruo"; |
201 |
+} |
202 |
+ |
203 |
+std::string |
204 |
+CommandLine::app_synopsis() const |
205 |
+{ |
206 |
+ return "Metadata generation client for Paludis"; |
207 |
+} |
208 |
+ |
209 |
+std::string |
210 |
+CommandLine::app_description() const |
211 |
+{ |
212 |
+ return |
213 |
+ "instruo is a metadata generation client for Paludis. It generates metadata cache for every ID in a " |
214 |
+ "given repository and produces a report of any failures."; |
215 |
+} |
216 |
+ |
217 |
+CommandLine::~CommandLine() |
218 |
+{ |
219 |
+} |
220 |
+ |
221 |
|
222 |
diff --git a/utils/command_line.h b/utils/command_line.h |
223 |
new file mode 100644 |
224 |
index 0000000..2fdb10b |
225 |
--- /dev/null |
226 |
+++ b/utils/command_line.h |
227 |
@@ -0,0 +1,62 @@ |
228 |
+/* This file was copied from Paludis src/clients/instruo/command_line.hh that is licensed as follows: */ |
229 |
+ |
230 |
+/* |
231 |
+ * Copyright (c) 2007, 2008, 2010 Ciaran McCreesh |
232 |
+ * |
233 |
+ * This file is part of the Paludis package manager. Paludis is free software; |
234 |
+ * you can redistribute it and/or modify it under the terms of the GNU General |
235 |
+ * Public License version 2, as published by the Free Software Foundation. |
236 |
+ * |
237 |
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY |
238 |
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
239 |
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
240 |
+ * details. |
241 |
+ * |
242 |
+ * You should have received a copy of the GNU General Public License along with |
243 |
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
244 |
+ * Place, Suite 330, Boston, MA 02111-1307 USA |
245 |
+ */ |
246 |
+ |
247 |
+#ifndef PALUDIS_GUARD_SRC_CLIENTS_INSTRUO_COMMAND_LINE_HH |
248 |
+#define PALUDIS_GUARD_SRC_CLIENTS_INSTRUO_COMMAND_LINE_HH 1 |
249 |
+ |
250 |
+#include <paludis/args/args.hh> |
251 |
+#include <paludis/util/singleton.hh> |
252 |
+#include <paludis/args/log_level_arg.hh> |
253 |
+ |
254 |
+class CommandLine : |
255 |
+ public paludis::args::ArgsHandler, |
256 |
+ public paludis::Singleton<CommandLine> |
257 |
+{ |
258 |
+ friend class paludis::Singleton<CommandLine>; |
259 |
+ |
260 |
+ private: |
261 |
+ CommandLine(); |
262 |
+ ~CommandLine(); |
263 |
+ |
264 |
+ public: |
265 |
+ virtual std::string app_name() const; |
266 |
+ virtual std::string app_synopsis() const; |
267 |
+ virtual std::string app_description() const; |
268 |
+ |
269 |
+ paludis::args::ArgsGroup action_args; |
270 |
+ |
271 |
+ paludis::args::SwitchArg a_generate_cache; |
272 |
+ paludis::args::SwitchArg a_version; |
273 |
+ paludis::args::SwitchArg a_help; |
274 |
+ |
275 |
+ paludis::args::ArgsGroup general_args; |
276 |
+ |
277 |
+ paludis::args::LogLevelArg a_log_level; |
278 |
+ paludis::args::SwitchArg a_no_colour; |
279 |
+ paludis::args::AliasArg a_no_color; |
280 |
+ paludis::args::SwitchArg a_force_colour; |
281 |
+ paludis::args::AliasArg a_force_color; |
282 |
+ paludis::args::StringArg a_repository_directory; |
283 |
+ paludis::args::StringArg a_output_directory; |
284 |
+ paludis::args::StringArg a_master_repository_name; |
285 |
+ paludis::args::StringSequenceArg a_extra_repository_dir; |
286 |
+ paludis::args::StringArg a_report_file; |
287 |
+}; |
288 |
+ |
289 |
+#endif |
290 |
|
291 |
diff --git a/utils/instruo.cpp b/utils/instruo.cpp |
292 |
new file mode 100644 |
293 |
index 0000000..bd1c981 |
294 |
--- /dev/null |
295 |
+++ b/utils/instruo.cpp |
296 |
@@ -0,0 +1,251 @@ |
297 |
+/* This file was partly copied from Paludis src/clients/instruo/instruo.cc. |
298 |
+ * The metadata generation logic is reimplemented with libbash. This file is |
299 |
+ * licensed as follows: */ |
300 |
+ |
301 |
+/* |
302 |
+ * Copyright (c) 2007, 2008, 2009, 2010 Ciaran McCreesh |
303 |
+ * |
304 |
+ * This file is part of the Paludis package manager. Paludis is free software; |
305 |
+ * you can redistribute it and/or modify it under the terms of the GNU General |
306 |
+ * Public License version 2, as published by the Free Software Foundation. |
307 |
+ * |
308 |
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY |
309 |
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
310 |
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
311 |
+ * details. |
312 |
+ * |
313 |
+ * You should have received a copy of the GNU General Public License along with |
314 |
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
315 |
+ * Place, Suite 330, Boston, MA 02111-1307 USA |
316 |
+ */ |
317 |
+ |
318 |
+#include <algorithm> |
319 |
+#include <fstream> |
320 |
+#include <functional> |
321 |
+#include <iostream> |
322 |
+#include <map> |
323 |
+ |
324 |
+#include <paludis/args/do_help.hh> |
325 |
+#include <paludis/about.hh> |
326 |
+#include <paludis/action.hh> |
327 |
+#include <paludis/package_id.hh> |
328 |
+#include <paludis/generator.hh> |
329 |
+#include <paludis/filter.hh> |
330 |
+#include <paludis/filtered_generator.hh> |
331 |
+#include <paludis/selection.hh> |
332 |
+#include <paludis/util/system.hh> |
333 |
+#include <paludis/util/join.hh> |
334 |
+#include <paludis/util/log.hh> |
335 |
+#include <paludis/util/sequence.hh> |
336 |
+#include <paludis/util/map.hh> |
337 |
+#include <paludis/util/visitor_cast.hh> |
338 |
+#include <paludis/util/set.hh> |
339 |
+#include <paludis/util/make_named_values.hh> |
340 |
+#include <paludis/util/mutex.hh> |
341 |
+#include <paludis/util/thread_pool.hh> |
342 |
+#include <paludis/util/destringify.hh> |
343 |
+#include <paludis/util/safe_ofstream.hh> |
344 |
+#include <paludis/util/pretty_print.hh> |
345 |
+#include <paludis/util/indirect_iterator-impl.hh> |
346 |
+#include <paludis/util/timestamp.hh> |
347 |
+#include <paludis/util/accept_visitor.hh> |
348 |
+#include <paludis/environments/no_config/no_config_environment.hh> |
349 |
+#include <paludis/package_database.hh> |
350 |
+#include <paludis/metadata_key.hh> |
351 |
+ |
352 |
+#include "command_line.h" |
353 |
+#include "libbash.h" |
354 |
+#include "utils/metadata.h" |
355 |
+ |
356 |
+using namespace paludis; |
357 |
+using std::cout; |
358 |
+using std::cerr; |
359 |
+using std::endl; |
360 |
+ |
361 |
+void worker(const std::shared_ptr<PackageIDSequence> &ids) |
362 |
+{ |
363 |
+ std::unordered_map<std::string, std::vector<std::string>> variables; |
364 |
+ |
365 |
+ std::shared_ptr<const PackageID> id; |
366 |
+ unsigned total(0); |
367 |
+ CategoryNamePart old_cat("OLDCAT"); |
368 |
+ while(!ids->empty()) |
369 |
+ { |
370 |
+ id = *ids->begin(); |
371 |
+ ids->pop_front(); |
372 |
+ if (id->name().category() != old_cat) |
373 |
+ { |
374 |
+ std::cout << "Processing " << stringify(id->name().category()) << "..." << std::endl; |
375 |
+ old_cat = id->name().category(); |
376 |
+ FSPath(CommandLine::get_instance()->a_output_directory.argument() + "/" + |
377 |
+ stringify(id->name().category())).mkdir(0755, {fspmkdo_ok_if_exists}); |
378 |
+ ++total; |
379 |
+ } |
380 |
+ |
381 |
+ Context i_context("When generating metadata for ID '" + stringify(*id) + "':"); |
382 |
+ |
383 |
+ variables.clear(); |
384 |
+ variables["PN"].push_back(stringify(id->name().package())); |
385 |
+ variables["PV"].push_back(stringify(id->version().remove_revision())); |
386 |
+ variables["P"].push_back(stringify(id->name().package()) + "-" + |
387 |
+ stringify(id->version().remove_revision())); |
388 |
+ variables["PR"].push_back(id->version().revision_only()); |
389 |
+ variables["PVR"].push_back(stringify(id->version())); |
390 |
+ variables["PF"].push_back(stringify(id->name().package()) + "-" + stringify(id->version())); |
391 |
+ variables["CATEGORY"].push_back(stringify(id->name().category())); |
392 |
+ std::vector<std::string> functions; |
393 |
+ |
394 |
+ std::string ebuild_path(CommandLine::get_instance()->a_repository_directory.argument() + |
395 |
+ variables["CATEGORY"][0] + "/" + |
396 |
+ variables["PN"][0] + "/" + |
397 |
+ variables["PN"][0] + "-" + |
398 |
+ variables["PVR"][0] + ".ebuild"); |
399 |
+ try |
400 |
+ { |
401 |
+ libbash::interpret(ebuild_path, variables, functions); |
402 |
+ } |
403 |
+ catch(const interpreter_exception& e) |
404 |
+ { |
405 |
+ cerr << "Exception occurred while interpreting " << ebuild_path << ". The error message is:\n" |
406 |
+ << e.what() << endl; |
407 |
+ continue; |
408 |
+ } |
409 |
+ |
410 |
+ std::string output_path(CommandLine::get_instance()->a_output_directory.argument() + "/" + |
411 |
+ variables["CATEGORY"][0] + "/" + |
412 |
+ variables["PN"][0] + "-" + |
413 |
+ variables["PVR"][0]); |
414 |
+ FSPath(output_path).dirname().mkdir(0755, {fspmkdo_ok_if_exists}); |
415 |
+ std::ofstream output(output_path, std::ofstream::out | std::ofstream::trunc); |
416 |
+ write_metadata(output, variables, functions); |
417 |
+ } |
418 |
+} |
419 |
+ |
420 |
+int main(int argc, char** argv) |
421 |
+{ |
422 |
+ try |
423 |
+ { |
424 |
+ std::string options(paludis::getenv_with_default("INSTRUO_OPTIONS", "")); |
425 |
+ if (! options.empty()) |
426 |
+ options = "(" + options + ") "; |
427 |
+ options += join(argv + 1, argv + argc, " "); |
428 |
+ |
429 |
+ Context context(std::string("In program ") + argv[0] + " " + options + ":"); |
430 |
+ |
431 |
+ CommandLine::get_instance()->run(argc, argv, "instruo", "INSTRUO_OPTIONS", "INSTRUO_CMDLINE"); |
432 |
+ |
433 |
+ if (CommandLine::get_instance()->a_help.specified()) |
434 |
+ throw args::DoHelp(); |
435 |
+ |
436 |
+ if (CommandLine::get_instance()->a_log_level.specified()) |
437 |
+ Log::get_instance()->set_log_level(CommandLine::get_instance()->a_log_level.option()); |
438 |
+ else |
439 |
+ Log::get_instance()->set_log_level(ll_qa); |
440 |
+ |
441 |
+ if (1 < ( |
442 |
+ CommandLine::get_instance()->a_generate_cache.specified() + |
443 |
+ CommandLine::get_instance()->a_version.specified() |
444 |
+ )) |
445 |
+ throw args::DoHelp("you should specify exactly one action"); |
446 |
+ |
447 |
+ if (! CommandLine::get_instance()->a_repository_directory.specified()) |
448 |
+ CommandLine::get_instance()->a_repository_directory.set_argument(stringify(FSPath::cwd())); |
449 |
+ |
450 |
+ if (CommandLine::get_instance()->a_version.specified()) |
451 |
+ { |
452 |
+ cout << "instruo, part of " << PALUDIS_PACKAGE << " " << PALUDIS_VERSION_MAJOR << "." |
453 |
+ << PALUDIS_VERSION_MINOR << "." << PALUDIS_VERSION_MICRO << PALUDIS_VERSION_SUFFIX; |
454 |
+ if (! std::string(PALUDIS_GIT_HEAD).empty()) |
455 |
+ cout << " git " << PALUDIS_GIT_HEAD; |
456 |
+ cout << endl << endl; |
457 |
+ cout << "Paludis comes with ABSOLUTELY NO WARRANTY. Paludis is free software, and you" << endl; |
458 |
+ cout << "are welcome to redistribute it under the terms of the GNU General Public" << endl; |
459 |
+ cout << "License, version 2." << endl; |
460 |
+ |
461 |
+ return EXIT_SUCCESS; |
462 |
+ } |
463 |
+ |
464 |
+ if (( |
465 |
+ CommandLine::get_instance()->a_repository_directory.specified() + |
466 |
+ CommandLine::get_instance()->a_output_directory.specified() |
467 |
+ ) < 1) |
468 |
+ throw args::DoHelp("at least one of '--" + CommandLine::get_instance()->a_repository_directory.long_name() + "' or '--" |
469 |
+ + CommandLine::get_instance()->a_output_directory.long_name() + "' must be specified"); |
470 |
+ |
471 |
+ if (! CommandLine::get_instance()->a_output_directory.specified()) |
472 |
+ CommandLine::get_instance()->a_output_directory.set_argument(stringify(FSPath::cwd())); |
473 |
+ |
474 |
+ std::shared_ptr<FSPathSequence> extra_repository_dirs(std::make_shared<FSPathSequence>()); |
475 |
+ for (args::StringSequenceArg::ConstIterator d(CommandLine::get_instance()->a_extra_repository_dir.begin_args()), |
476 |
+ d_end(CommandLine::get_instance()->a_extra_repository_dir.end_args()) ; |
477 |
+ d != d_end ; ++d) |
478 |
+ extra_repository_dirs->push_back(FSPath(*d)); |
479 |
+ |
480 |
+ std::shared_ptr<Map<std::string, std::string> > keys(std::make_shared<Map<std::string, std::string>>()); |
481 |
+ keys->insert("append_repository_name_to_write_cache", "false"); |
482 |
+ NoConfigEnvironment env(make_named_values<no_config_environment::Params>( |
483 |
+ n::accept_unstable() = true, |
484 |
+ n::disable_metadata_cache() = true, |
485 |
+ n::extra_accept_keywords() = "", |
486 |
+ n::extra_params() = keys, |
487 |
+ n::extra_repository_dirs() = extra_repository_dirs, |
488 |
+ n::master_repository_name() = CommandLine::get_instance()->a_master_repository_name.argument(), |
489 |
+ n::profiles_if_not_auto() = "", |
490 |
+ n::repository_dir() = CommandLine::get_instance()->a_repository_directory.argument(), |
491 |
+ n::repository_type() = no_config_environment::ncer_ebuild, |
492 |
+ n::write_cache() = CommandLine::get_instance()->a_output_directory.argument() |
493 |
+ )); |
494 |
+ |
495 |
+ FSPath(CommandLine::get_instance()->a_output_directory.argument()).mkdir(0755, {fspmkdo_ok_if_exists}); |
496 |
+ |
497 |
+ std::shared_ptr<PackageIDSequence> ids(env[selection::AllVersionsSorted( |
498 |
+ generator::InRepository(env.main_repository()->name()))]); |
499 |
+ worker(ids); |
500 |
+ } |
501 |
+ catch (const paludis::args::ArgsError & e) |
502 |
+ { |
503 |
+ cerr << "Usage error: " << e.message() << endl; |
504 |
+ cerr << "Try " << argv[0] << " --help" << endl; |
505 |
+ return EXIT_FAILURE; |
506 |
+ } |
507 |
+ catch (const args::DoHelp & h) |
508 |
+ { |
509 |
+ if (h.message.empty()) |
510 |
+ { |
511 |
+ cout << "Usage: " << argv[0] << " [options]" << endl; |
512 |
+ cout << endl; |
513 |
+ cout << *CommandLine::get_instance(); |
514 |
+ return EXIT_SUCCESS; |
515 |
+ } |
516 |
+ else |
517 |
+ { |
518 |
+ cerr << "Usage error: " << h.message << endl; |
519 |
+ cerr << "Try " << argv[0] << " --help" << endl; |
520 |
+ return EXIT_FAILURE; |
521 |
+ } |
522 |
+ } |
523 |
+ catch (const Exception & e) |
524 |
+ { |
525 |
+ cout << endl; |
526 |
+ cerr << "Unhandled exception:" << endl |
527 |
+ << " * " << e.backtrace("\n * ") |
528 |
+ << e.message() << " (" << e.what() << ")" << endl; |
529 |
+ return EXIT_FAILURE; |
530 |
+ } |
531 |
+ catch (const std::exception & e) |
532 |
+ { |
533 |
+ cout << endl; |
534 |
+ cerr << "Unhandled exception:" << endl |
535 |
+ << " * " << e.what() << endl; |
536 |
+ return EXIT_FAILURE; |
537 |
+ } |
538 |
+ catch (...) |
539 |
+ { |
540 |
+ cout << endl; |
541 |
+ cerr << "Unhandled exception:" << endl |
542 |
+ << " * Unknown exception type. Ouch..." << endl; |
543 |
+ return EXIT_FAILURE; |
544 |
+ } |
545 |
+ |
546 |
+ return EXIT_SUCCESS; |
547 |
+} |
548 |
|
549 |
diff --git a/utils/metadata_generator.cpp b/utils/metadata.cpp |
550 |
similarity index 83% |
551 |
copy from utils/metadata_generator.cpp |
552 |
copy to utils/metadata.cpp |
553 |
index 52b4590..600f9e4 100644 |
554 |
--- a/utils/metadata_generator.cpp |
555 |
+++ b/utils/metadata.cpp |
556 |
@@ -17,21 +17,18 @@ |
557 |
along with libbash. If not, see <http://www.gnu.org/licenses/>. |
558 |
*/ |
559 |
/// |
560 |
-/// \file metadata_generator.cpp |
561 |
+/// \file metadata.cpp |
562 |
/// \author Mu Qiao |
563 |
-/// \brief a simple utility for generating metadata |
564 |
+/// \brief a helper for printing metadata content |
565 |
/// |
566 |
-#include <iostream> |
567 |
#include <set> |
568 |
-#include <string> |
569 |
-#include <vector> |
570 |
|
571 |
#include <boost/spirit/include/karma.hpp> |
572 |
#include <boost/algorithm/string/classification.hpp> |
573 |
#include <boost/algorithm/string/split.hpp> |
574 |
#include <boost/algorithm/string/trim.hpp> |
575 |
|
576 |
-#include "libbash.h" |
577 |
+#include "utils/metadata.h" |
578 |
|
579 |
static const std::vector<std::string> metadata_names = {"DEPEND", "RDEPEND", "SLOT", "SRC_URI", |
580 |
"RESTRICT", "HOMEPAGE", "LICENSE", "DESCRIPTION", |
581 |
@@ -56,20 +53,10 @@ static const std::unordered_map<std::string, std::string> phases = { |
582 |
{"pkg_nofetch", "nofetch"} |
583 |
}; |
584 |
|
585 |
-int main(int argc, char** argv) |
586 |
+void write_metadata(std::ostream& output, |
587 |
+ std::unordered_map<std::string, std::vector<std::string>>& variables, |
588 |
+ std::vector<std::string>& functions) |
589 |
{ |
590 |
- using namespace boost::spirit::karma; |
591 |
- |
592 |
- if(argc != 2) |
593 |
- { |
594 |
- std::cerr<<"Please provide your script as an argument"<<std::endl; |
595 |
- exit(EXIT_FAILURE); |
596 |
- } |
597 |
- |
598 |
- std::unordered_map<std::string, std::vector<std::string>> variables; |
599 |
- std::vector<std::string> functions; |
600 |
- libbash::interpret(argv[1], variables, functions); |
601 |
- |
602 |
for(auto iter_name = metadata_names.begin(); iter_name != metadata_names.end(); ++iter_name) |
603 |
{ |
604 |
auto iter_value = variables.find(*iter_name); |
605 |
@@ -106,7 +93,8 @@ int main(int argc, char** argv) |
606 |
value, |
607 |
boost::is_any_of(" \t\n"), |
608 |
boost::token_compress_on); |
609 |
- std::cout << format(string % ' ', splitted_value) << std::endl; |
610 |
+ using namespace boost::spirit::karma; |
611 |
+ output << format(string % ' ', splitted_value) << std::endl; |
612 |
} |
613 |
|
614 |
// Print defined phases |
615 |
@@ -117,10 +105,9 @@ int main(int argc, char** argv) |
616 |
if(iter_phase != phases.end()) |
617 |
sorted_phases.insert(iter_phase->second); |
618 |
} |
619 |
- std::cout << format(string % ' ', sorted_phases) << std::endl; |
620 |
+ using namespace boost::spirit::karma; |
621 |
+ output << format(string % ' ', sorted_phases) << std::endl; |
622 |
|
623 |
// Print empty lines |
624 |
- std::cout << std::endl << std::endl << std::endl << std::endl << std::endl; |
625 |
- |
626 |
- return EXIT_SUCCESS; |
627 |
+ output << std::endl << std::endl << std::endl << std::endl << std::endl; |
628 |
} |
629 |
|
630 |
diff --git a/src/libbash.h b/utils/metadata.h |
631 |
similarity index 55% |
632 |
copy from src/libbash.h |
633 |
copy to utils/metadata.h |
634 |
index ca8cdaa..cb7f559 100644 |
635 |
--- a/src/libbash.h |
636 |
+++ b/utils/metadata.h |
637 |
@@ -15,34 +15,17 @@ |
638 |
|
639 |
You should have received a copy of the GNU General Public License |
640 |
along with libbash. If not, see <http://www.gnu.org/licenses/>. |
641 |
-*/ |
642 |
+ */ |
643 |
/// |
644 |
-/// \file libbash.h |
645 |
+/// \file metadata.h |
646 |
/// \author Mu Qiao |
647 |
-/// \brief public interface for libbash |
648 |
+/// \brief a helper for printing metadata content |
649 |
/// |
650 |
- |
651 |
-#ifndef LIBBASH_LIBBASH_H_ |
652 |
-#define LIBBASH_LIBBASH_H_ |
653 |
- |
654 |
-#include <memory> |
655 |
+#include <iostream> |
656 |
#include <string> |
657 |
#include <unordered_map> |
658 |
#include <vector> |
659 |
|
660 |
-#include "common.h" |
661 |
-#include "core/interpreter_exception.h" |
662 |
- |
663 |
-namespace libbash |
664 |
-{ |
665 |
- /// |
666 |
- /// \brief interpret a script specifid by path, return a map filled with |
667 |
- /// variables defined in the script |
668 |
- /// \param the path of target script |
669 |
- /// \param the map to store variables |
670 |
- void LIBBASH_API interpret(const std::string& path, |
671 |
- std::unordered_map<std::string, std::vector<std::string>>& variables, |
672 |
- std::vector<std::string>& functions); |
673 |
-} |
674 |
- |
675 |
-#endif |
676 |
+void write_metadata(std::ostream& output, |
677 |
+ std::unordered_map<std::string, std::vector<std::string>>& variables, |
678 |
+ std::vector<std::string>& functions); |
679 |
|
680 |
diff --git a/utils/metadata_generator.cpp b/utils/metadata_generator.cpp |
681 |
index 52b4590..14602f2 100644 |
682 |
--- a/utils/metadata_generator.cpp |
683 |
+++ b/utils/metadata_generator.cpp |
684 |
@@ -22,44 +22,14 @@ |
685 |
/// \brief a simple utility for generating metadata |
686 |
/// |
687 |
#include <iostream> |
688 |
-#include <set> |
689 |
#include <string> |
690 |
#include <vector> |
691 |
|
692 |
-#include <boost/spirit/include/karma.hpp> |
693 |
-#include <boost/algorithm/string/classification.hpp> |
694 |
-#include <boost/algorithm/string/split.hpp> |
695 |
-#include <boost/algorithm/string/trim.hpp> |
696 |
- |
697 |
#include "libbash.h" |
698 |
- |
699 |
-static const std::vector<std::string> metadata_names = {"DEPEND", "RDEPEND", "SLOT", "SRC_URI", |
700 |
- "RESTRICT", "HOMEPAGE", "LICENSE", "DESCRIPTION", |
701 |
- "KEYWORDS", "INHERITED", "IUSE", "REQUIRED_USE", |
702 |
- "PDEPEND", "PROVIDE", "EAPI", "PROPERTIES"}; |
703 |
- |
704 |
-static const std::unordered_map<std::string, std::string> phases = { |
705 |
- {"pkg_pretend", "ppretend"}, |
706 |
- {"pkg_setup", "setup"}, |
707 |
- {"src_unpack", "unpack"}, |
708 |
- {"src_prepare", "prepare"}, |
709 |
- {"src_configure", "configure"}, |
710 |
- {"src_compile", "compile"}, |
711 |
- {"src_test", "test"}, |
712 |
- {"src_install", "install"}, |
713 |
- {"pkg_preinst", "preinst"}, |
714 |
- {"pkg_postinst", "postinst"}, |
715 |
- {"pkg_prerm", "prerm"}, |
716 |
- {"pkg_postrm", "postrm"}, |
717 |
- {"pkg_config", "config"}, |
718 |
- {"pkg_info", "info"}, |
719 |
- {"pkg_nofetch", "nofetch"} |
720 |
-}; |
721 |
+#include "utils/metadata.h" |
722 |
|
723 |
int main(int argc, char** argv) |
724 |
{ |
725 |
- using namespace boost::spirit::karma; |
726 |
- |
727 |
if(argc != 2) |
728 |
{ |
729 |
std::cerr<<"Please provide your script as an argument"<<std::endl; |
730 |
@@ -70,57 +40,7 @@ int main(int argc, char** argv) |
731 |
std::vector<std::string> functions; |
732 |
libbash::interpret(argv[1], variables, functions); |
733 |
|
734 |
- for(auto iter_name = metadata_names.begin(); iter_name != metadata_names.end(); ++iter_name) |
735 |
- { |
736 |
- auto iter_value = variables.find(*iter_name); |
737 |
- std::string value; |
738 |
- |
739 |
- if(iter_value != variables.end()) |
740 |
- value = iter_value->second[0]; |
741 |
- |
742 |
- // Check if global is defined |
743 |
- auto iter_global = variables.find("E_" + *iter_name); |
744 |
- if(iter_global != variables.end()) |
745 |
- { |
746 |
- boost::trim_if(iter_global->second[0], boost::is_any_of(" \t\n")); |
747 |
- std::vector<std::string> splitted_global; |
748 |
- boost::split(splitted_global, |
749 |
- iter_global->second[0], |
750 |
- boost::is_any_of(" \t\n"), |
751 |
- boost::token_compress_on); |
752 |
- |
753 |
- // Append the global value to 'value' if it doesn't cause duplication |
754 |
- for(auto iter_splitted_global = splitted_global.begin(); |
755 |
- iter_splitted_global != splitted_global.end(); |
756 |
- ++iter_splitted_global) |
757 |
- { |
758 |
- if(value.find(*iter_splitted_global) == std::string::npos) |
759 |
- value += " " + *iter_splitted_global; |
760 |
- } |
761 |
- } |
762 |
- |
763 |
- boost::trim_if(value, boost::is_any_of(" \t\n")); |
764 |
- |
765 |
- std::vector<std::string> splitted_value; |
766 |
- boost::split(splitted_value, |
767 |
- value, |
768 |
- boost::is_any_of(" \t\n"), |
769 |
- boost::token_compress_on); |
770 |
- std::cout << format(string % ' ', splitted_value) << std::endl; |
771 |
- } |
772 |
- |
773 |
- // Print defined phases |
774 |
- std::set<std::string> sorted_phases; |
775 |
- for(auto iter = functions.begin(); iter != functions.end(); ++iter) |
776 |
- { |
777 |
- auto iter_phase = phases.find(*iter); |
778 |
- if(iter_phase != phases.end()) |
779 |
- sorted_phases.insert(iter_phase->second); |
780 |
- } |
781 |
- std::cout << format(string % ' ', sorted_phases) << std::endl; |
782 |
- |
783 |
- // Print empty lines |
784 |
- std::cout << std::endl << std::endl << std::endl << std::endl << std::endl; |
785 |
+ write_metadata(std::cout, variables, functions); |
786 |
|
787 |
return EXIT_SUCCESS; |
788 |
} |