32 #include <boost/program_options.hpp>
33 #include <boost/algorithm/string.hpp>
39 namespace po = boost::program_options;
46 po::variables_map& vm);
56 bool quiet = (vm.count(
"quiet")==1);
61 bool package_given =
false;
62 bool deps_only =
false;
67 bool zombie_only =
false;
68 std::string length_str;
70 if(vm.count(
"command"))
71 command = vm[
"command"].as<std::string>();
73 if(vm.count(
"-h") && command.empty())
78 rp.
logError( std::string(
"no command given. Try '") + rp.
getName() +
" help'");
84 if((command ==
"profile") ||
85 (command ==
"depends-on") ||
86 (command ==
"depends-on1") ||
87 (command ==
"langs") ||
88 (command ==
"list-duplicates"))
91 if(vm.count(
"package"))
93 package = vm["package"].as<std::string>();
101 if(vm.count(
"deps-only"))
104 lang = vm[
"lang"].as<std::string>();
105 if(vm.count(
"attrib"))
106 attrib = vm[
"attrib"].as<std::string>();
108 top = vm[
"top"].as<std::string>();
109 if(vm.count(
"target"))
110 target = vm[
"target"].as<std::string>();
111 if(vm.count(
"zombie-only"))
113 if(vm.count(
"length"))
115 length_str = vm[
"length"].as<std::string>();
116 length = atoi(length_str.c_str());
127 if(command ==
"help" || vm.count(
"help"))
129 if(package_given || (command !=
"help" && vm.count(
"help"))) {
130 if (command ==
"help") {
131 command = vm[
"package"].as<std::string>();
133 output.append(
"Usage: rospack ");
134 output.append(command);
135 if(command ==
"help")
136 output.append(
"[command]\n\nPrint help message.");
137 else if(command ==
"find")
138 output.append(
"\n\nPrint absolute path to the package");
139 else if(command ==
"list")
140 output.append(
"\n\nPrint newline-separated list <package-name> <package-dir> for all packages.");
141 else if(command ==
"list-names")
142 output.append(
"\n\nPrint newline-separated list of packages names for all packages.");
143 else if(command ==
"list-duplicates")
144 output.append(
"\n\nPrint newline-separated list of names of packages that are found more than once during the search.");
145 else if(command ==
"langs")
146 output.append(
"\n\nPrint space-separated list of available language-specific client libraries.");
147 else if(command ==
"depends" || command ==
"deps")
148 output.append(
"[package]\n\nPrint newline-separated, ordered list of all dependencies of the package.");
149 else if(command ==
"depends1" || command ==
"deps1")
150 output.append(
"[package]\n\nPrint newline-separated, ordered list of immediate dependencies of the package.");
151 else if(command ==
"depends-manifest" || command ==
"deps-manifest")
152 output.append(
"[package]\n\nPrint space-separated, ordered list of manifest.xml files for all dependencies of the package. Used internally by rosbuild.");
153 else if(command ==
"depends-indent" || command ==
"deps-indent")
154 output.append(
"[package]\n\nPrint newline-separated, indented list of the entire dependency chain for the package.");
155 else if(command ==
"depends-why" || command ==
"deps-why")
156 output.append(
"--target=TARGET [package]\n\nPrint newline-separated presentation of all dependency chains from the package to TARGET. ");
157 else if(command ==
"depends-msgsrv" || command ==
"deps-msgsrv")
158 output.append(
"[package]\n\nPrint space-separated list of message-generation marker files for all dependencies of the package. Used internally by rosbuild.");
159 else if(command ==
"rosdep" || command ==
"rosdeps")
160 output.append(
"[package]\n\nPrint newline-separated list of all [rosdep] tags from the manifest.xml of the package and all of its dependencies.");
161 else if(command ==
"rosdep0" || command ==
"rosdeps0")
162 output.append(
"[package]\n\nPrint newline-separated list of all [rosdep] tags from the manifest.xml of just the package itself.");
163 else if(command ==
"vcs")
164 output.append(
"[package]\n\nPrint newline-separated list of all [versioncontrol] tags from the manifest.xml of the package and all of its dependencies.");
165 else if(command ==
"vcs0")
166 output.append(
"[package]\n\nPrint newline-separated list of all [versioncontrol] tags from the manifest.xml of just the package itself.");
167 else if(command ==
"depends-on")
168 output.append(
"[package]\n\nPrint newline-separated list of all packages that depend on the package. ");
169 else if(command ==
"depends-on1")
170 output.append(
"[package]\n\nPrint newline-separated list of all packages that directly depend on the package.");
171 else if(command ==
"export")
172 output.append(
"[--deps-only] --lang=<lang> --attrib=<attrib> [package]\n\nPrint Space-separated list of [export][LANGUAGE ATTRIBUTE=\"\"/][/export] values from the manifest.xml of the package and its dependencies.\n\nIf --deps-only is provided, then the package itself is excluded.");
173 else if(command ==
"plugins")
174 output.append(
"--attrib=<attrib> [--top=<toppkg>] [package]\n\nExamine packages that depend directly on the given package, giving name and the exported attribute with the name <attrib>\n\nIf --top=<toppkg> is given, then in addition to depending directly on the given package, to be scanned for exports, a package must also be a dependency of <toppkg>, or be <toppkg> itself.");
175 else if(command ==
"cflags-only-I")
176 output.append(
"[--deps-only] [package]\n\nPrint Space-separated list of [export][LANGUAGE ATTRIBUTE=\"\"/][/export] values from the manifest.xml of the package and its dependencies.\n\nIf --deps-only is provided, then the package itself is excluded.");
177 else if(command ==
"cflags-only-other")
178 output.append(
"[--deps-only] [package]\n\nPrint space-separated list of export/cpp/cflags that don't start with -I.\n\nIf --deps-only is provided, then the package itself is excluded.");
179 else if(command ==
"libs-only-L")
180 output.append(
"[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that start with -L.\n\nIf --deps-only is provided, then the package itself is excluded.");
181 else if(command ==
"libs-only-l")
182 output.append(
"[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that start with -l.\n\nIf --deps-only is provided, then the package itself is excluded.");
183 else if(command ==
"libs-only-other")
184 output.append(
"[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that don't start with -l or -L.\n\nIf --deps-only is provided, then the package itself is excluded.");
185 else if(command ==
"profile")
186 output.append(
"[--length=<length>] [--zombie-only]\n\nForce a full crawl of package directories and report the directories that took the longest time to crawl.\n\n--length=N how many directories to display\n\n--zombie-only Only print directories that do not have any manifests.");
189 output.append(rp.
usage());
194 std::vector<std::string> search_path;
199 if(command ==
"profile")
201 if(package_given || target.size() || top.size() ||
202 deps_only || lang.size() || attrib.size())
204 rp.
logError(
"invalid option(s) given");
207 std::vector<std::string> dirs;
208 if(rp.
profile(search_path, zombie_only, length, dirs))
210 for(std::vector<std::string>::const_iterator it = dirs.begin();
213 output.append((*it) +
"\n");
218 rp.
crawl(search_path, force);
221 if(command ==
"find")
228 if(target.size() || top.size() || length_str.size() ||
229 zombie_only || deps_only || lang.size() || attrib.size())
231 rp.
logError(
"invalid option(s) given");
237 output.append(path +
"\n");
241 else if(command ==
"list")
243 if(package_given || target.size() || top.size() || length_str.size() ||
244 zombie_only || deps_only || lang.size() || attrib.size())
246 rp.
logError(
"invalid option(s) given");
249 std::set<std::pair<std::string, std::string> > list;
251 for(std::set<std::pair<std::string, std::string> >::const_iterator it = list.begin();
255 output.append(it->first +
" " + it->second +
"\n");
260 else if(command ==
"list-names")
262 if(package_given || target.size() || top.size() || length_str.size() ||
263 zombie_only || deps_only || lang.size() || attrib.size())
265 rp.
logError(
"invalid option(s) given");
268 std::set<std::pair<std::string, std::string> > list;
270 for(std::set<std::pair<std::string, std::string> >::const_iterator it = list.begin();
274 output.append(it->first +
"\n");
279 else if(command ==
"list-duplicates")
281 if(package_given || target.size() || top.size() || length_str.size() ||
282 zombie_only || deps_only || lang.size() || attrib.size())
284 rp.
logError(
"invalid option(s) given");
287 std::map<std::string, std::vector<std::string> > dups;
290 for(std::map<std::string, std::vector<std::string> >::const_iterator it = dups.begin();
294 output.append(it->first +
"\n");
295 for(std::vector<std::string>::const_iterator jt = it->second.begin();
296 jt != it->second.end();
299 output.append(
"- " + *jt +
"\n");
307 if(package_given || target.size() || top.size() || length_str.size() ||
308 zombie_only || deps_only || lang.size() || attrib.size())
310 rp.
logError(
"invalid option(s) given");
313 std::vector<std::string> deps;
314 bool result = rp.
depsOn(
"roslang",
true, deps);
315 const char* ros_lang_disable;
316 if((ros_lang_disable = getenv(
"ROS_LANG_DISABLE")))
318 std::vector<std::string> disable_langs;
322 const char *path_delim =
";";
324 const char *path_delim = ":";
326 boost::split(disable_langs, ros_lang_disable,
327 boost::is_any_of(path_delim),
328 boost::token_compress_on);
329 std::vector<std::string>::iterator it = deps.begin();
330 while(it != deps.end())
332 if(std::find(disable_langs.begin(), disable_langs.end(), *it) !=
339 for(std::vector<std::string>::const_iterator it = deps.begin();
343 if(it != deps.begin())
351 else if(command ==
"depends" || command ==
"deps" ||
352 command ==
"depends1" || command ==
"deps1")
359 if(target.size() || top.size() || length_str.size() ||
360 zombie_only || deps_only || lang.size() || attrib.size())
362 rp.
logError(
"invalid option(s) given");
365 std::vector<std::string> deps;
366 bool result = rp.
deps(
package, (command ==
"depends1" || command ==
"deps1"), deps);
367 for(std::vector<std::string>::const_iterator it = deps.begin();
370 output.append(*it +
"\n");
374 else if(command ==
"depends-manifests" || command ==
"deps-manifests")
381 if(target.size() || top.size() || length_str.size() ||
382 zombie_only || deps_only || lang.size() || attrib.size())
384 rp.
logError(
"invalid option(s) given");
387 std::vector<std::string> manifests;
389 for(std::vector<std::string>::const_iterator it = manifests.begin();
390 it != manifests.end();
393 if(it != manifests.begin())
402 (command ==
"depends-msgsrv" || command ==
"deps-msgsrv"))
409 if(target.size() || top.size() || length_str.size() ||
410 zombie_only || deps_only || lang.size() || attrib.size())
412 rp.
logError(
"invalid option(s) given");
415 std::vector<std::string> gens;
417 for(std::vector<std::string>::const_iterator it = gens.begin();
421 if(it != gens.begin())
429 else if(command ==
"depends-indent" || command ==
"deps-indent")
436 if(target.size() || top.size() || length_str.size() ||
437 zombie_only || deps_only || lang.size() || attrib.size())
439 rp.
logError(
"invalid option(s) given");
442 std::vector<std::string> deps;
444 for(std::vector<std::string>::const_iterator it = deps.begin();
447 output.append(*it +
"\n");
451 else if(command ==
"depends-why" || command ==
"deps-why")
453 if(!
package.size() || !target.size())
458 if(top.size() || length_str.size() ||
459 zombie_only || deps_only || lang.size() || attrib.size())
461 rp.
logError(
"invalid option(s) given");
464 std::string why_output;
466 output.append(why_output);
472 (command ==
"rosdep" || command ==
"rosdeps" ||
473 command ==
"rosdep0" || command ==
"rosdeps0"))
480 if(target.size() || top.size() || length_str.size() ||
481 zombie_only || deps_only || lang.size() || attrib.size())
483 rp.
logError(
"invalid option(s) given");
486 std::set<std::string> rosdeps;
487 bool result = rp.
rosdeps(
package, (command ==
"rosdep0" || command ==
"rosdeps0"), rosdeps);
488 for(std::set<std::string>::const_iterator it = rosdeps.begin();
491 output.append(*it +
"\n");
497 (command ==
"vcs" || command ==
"vcs0"))
504 if(target.size() || top.size() || length_str.size() ||
505 zombie_only || deps_only || lang.size() || attrib.size())
507 rp.
logError(
"invalid option(s) given");
510 std::vector<std::string> vcs;
511 bool result = rp.
vcs(
package, (command ==
"vcs0"), vcs);
512 for(std::vector<std::string>::const_iterator it = vcs.begin();
515 output.append(*it +
"\n");
520 else if(command ==
"depends-on" || command ==
"depends-on1")
527 if(target.size() || top.size() || length_str.size() ||
528 zombie_only || deps_only || lang.size() || attrib.size())
530 rp.
logError(
"invalid option(s) given");
533 std::vector<std::string> deps;
534 bool result = rp.
depsOn(
package, (command ==
"depends-on1"), deps);
535 for(std::vector<std::string>::const_iterator it = deps.begin();
538 output.append(*it +
"\n");
544 if(!
package.size() || !lang.size() || !attrib.size())
546 rp.
logError(
"no package / lang / attrib given");
549 if(target.size() || top.size() || length_str.size() || zombie_only)
551 rp.
logError(
"invalid option(s) given");
554 std::vector<std::string> flags;
555 bool result = rp.
exports(
package, lang, attrib, deps_only, flags);
556 for(std::vector<std::string>::const_iterator it = flags.begin();
560 if(it != flags.begin())
570 if(!
package.size() || !attrib.size())
572 rp.
logError(
"no package / attrib given");
575 if(target.size() || length_str.size() || zombie_only)
577 rp.
logError(
"invalid option(s) given");
580 std::vector<std::string> flags;
583 for(std::vector<std::string>::const_iterator it = flags.begin();
586 output.append(*it +
"\n");
597 if(target.size() || top.size() || length_str.size() || zombie_only)
599 rp.
logError(
"invalid option(s) given");
602 std::vector<std::pair<std::string, bool> > flags;
606 std::string dry_combined;
607 std::string wet_combined;
608 for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
612 std::string& combined = it->second ? wet_combined : dry_combined;
613 if(!combined.empty())
614 combined.append(
" ");
615 combined.append(it->first);
618 std::string dry_result;
620 output.append(dry_result);
622 std::string wet_result;
624 if(!dry_result.empty() && !wet_result.empty())
628 output.append(wet_result +
"\n");
639 if(target.size() || top.size() || length_str.size() || zombie_only)
641 rp.
logError(
"invalid option(s) given");
644 std::vector<std::pair<std::string, bool> > flags;
647 std::string combined;
648 for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
652 if(it != flags.begin())
653 combined.append(
" ");
654 combined.append(it->first);
658 output.append(result +
"\n");
669 if(target.size() || top.size() || length_str.size() || zombie_only)
671 rp.
logError(
"invalid option(s) given");
674 std::vector<std::pair<std::string, bool> > flags;
678 std::string dry_combined;
679 std::string wet_combined;
680 for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
684 std::string& combined = it->second ? wet_combined : dry_combined;
685 if(!combined.empty())
686 combined.append(
" ");
687 combined.append(it->first);
690 std::string dry_result;
692 output.append(dry_result);
694 std::string wet_result;
696 if(!dry_result.empty() && !wet_result.empty())
700 output.append(wet_result +
"\n");
711 if(target.size() || top.size() || length_str.size() || zombie_only)
713 rp.
logError(
"invalid option(s) given");
716 std::vector<std::pair<std::string, bool> > flags;
719 std::string combined;
720 for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
724 if(it != flags.begin())
725 combined.append(
" ");
726 combined.append(it->first);
730 output.append(result +
"\n");
741 if(target.size() || top.size() || length_str.size() || zombie_only)
743 rp.
logError(
"invalid option(s) given");
746 std::vector<std::pair<std::string, bool> > flags;
749 std::string combined;
750 for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
754 if(it != flags.begin())
755 combined.append(
" ");
756 combined.append(it->first);
758 std::string intermediate;
762 output.append(result +
"\n");
773 if(target.size() || top.size() || length_str.size() ||
774 zombie_only || deps_only || lang.size() || attrib.size())
776 rp.
logError(
"invalid option(s) given");
780 std::set<std::string> packages;
782 for(std::set<std::string>::const_iterator it = packages.begin();
783 it != packages.end();
785 output.append(*it +
"\n");
790 ((command ==
"contains") || (command ==
"contains-path")))
797 if(target.size() || top.size() || length_str.size() ||
798 zombie_only || deps_only || lang.size() || attrib.size())
800 rp.
logError(
"invalid option(s) given");
803 std::string name, path;
806 if(command ==
"contains")
807 output.append(name +
"\n");
809 output.append(path +
"\n");
814 rp.
logError(std::string(
"command ") + command +
" not implemented");
823 po::options_description desc(
"Allowed options");
825 (
"command", po::value<std::string>(),
"command")
826 (
"package", po::value<std::string>(),
"package")
827 (
"target", po::value<std::string>(),
"target")
828 (
"deps-only",
"deps-only")
829 (
"lang", po::value<std::string>(),
"lang")
830 (
"attrib", po::value<std::string>(),
"attrib")
831 (
"top", po::value<std::string>(),
"top")
832 (
"length", po::value<std::string>(),
"length")
833 (
"zombie-only",
"zombie-only")
836 (
"quiet,q",
"quiet");
838 po::positional_options_description pd;
839 pd.add(
"command", 1).add(
"package", 1);
842 po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm);
844 catch(boost::program_options::error e)
846 rp.
logError( std::string(
"failed to parse command-line options: ") + e.what());