list, list-names, deps, and deps1 are working
This commit is contained in:
parent
500d283b49
commit
4e374754e8
|
@ -29,6 +29,7 @@
|
||||||
#include "tinyxml-2.5.3/tinyxml.h"
|
#include "tinyxml-2.5.3/tinyxml.h"
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -55,31 +56,55 @@ static const std::string ROSPACK_CACHE_NAME = "rospack_cache";
|
||||||
static const std::string ROSSTACK_CACHE_NAME = "rosstack_cache";
|
static const std::string ROSSTACK_CACHE_NAME = "rosstack_cache";
|
||||||
static const std::string DOTROS_NAME = ".ros";
|
static const std::string DOTROS_NAME = ".ros";
|
||||||
static const int MAX_CRAWL_DEPTH = 1000;
|
static const int MAX_CRAWL_DEPTH = 1000;
|
||||||
|
static const int MAX_DEPENDENCY_DEPTH = 1000;
|
||||||
static const double DEFAULT_MAX_CACHE_AGE = 60.0;
|
static const double DEFAULT_MAX_CACHE_AGE = 60.0;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
class Exception : public std::runtime_error
|
||||||
// Stackage methods
|
|
||||||
/////////////////////////////////////////////////////////////
|
|
||||||
Stackage::Stackage(const std::string& name,
|
|
||||||
const std::string& path,
|
|
||||||
const std::string& manifest_path) :
|
|
||||||
name_(name),
|
|
||||||
path_(path),
|
|
||||||
manifest_path_(manifest_path)
|
|
||||||
{
|
{
|
||||||
}
|
public:
|
||||||
|
Exception(const std::string& what)
|
||||||
|
: std::runtime_error(what)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Stackage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// \brief name of the stackage
|
||||||
|
std::string name_;
|
||||||
|
// \brief absolute path to the stackage
|
||||||
|
std::string path_;
|
||||||
|
// \brief absolute path to the stackage manifest
|
||||||
|
std::string manifest_path_;
|
||||||
|
// \brief have we already loaded the manifest?
|
||||||
|
bool manifest_loaded_;
|
||||||
|
// \brief TinyXML structure, filled in during parsing
|
||||||
|
rospack_tinyxml::TiXmlDocument manifest_;
|
||||||
|
std::vector<Stackage*> deps;
|
||||||
|
bool deps_computed_;
|
||||||
|
|
||||||
|
Stackage(const std::string& name,
|
||||||
|
const std::string& path,
|
||||||
|
const std::string& manifest_path) :
|
||||||
|
name_(name),
|
||||||
|
path_(path),
|
||||||
|
manifest_path_(manifest_path),
|
||||||
|
manifest_loaded_(false),
|
||||||
|
deps_computed_(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
// Rosstackage methods (public/protected)
|
// Rosstackage methods (public/protected)
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
Rosstackage::Rosstackage(std::string manifest_name,
|
Rosstackage::Rosstackage(std::string manifest_name,
|
||||||
std::string cache_name,
|
std::string cache_name,
|
||||||
crawl_direction_t crawl_dir,
|
crawl_direction_t crawl_dir):
|
||||||
int max_crawl_depth) :
|
|
||||||
manifest_name_(manifest_name),
|
manifest_name_(manifest_name),
|
||||||
cache_name_(cache_name),
|
cache_name_(cache_name),
|
||||||
crawl_dir_(crawl_dir),
|
crawl_dir_(crawl_dir),
|
||||||
max_crawl_depth_(max_crawl_depth),
|
|
||||||
crawled_(false)
|
crawled_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -87,7 +112,7 @@ Rosstackage::Rosstackage(std::string manifest_name,
|
||||||
void
|
void
|
||||||
Rosstackage::debug_dump()
|
Rosstackage::debug_dump()
|
||||||
{
|
{
|
||||||
for(std::map<std::string, Stackage*>::const_iterator it = stackages_.begin();
|
for(std::tr1::unordered_map<std::string, Stackage*>::const_iterator it = stackages_.begin();
|
||||||
it != stackages_.end();
|
it != stackages_.end();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
|
@ -122,14 +147,59 @@ Rosstackage::crawl(const std::vector<std::string>& search_path,
|
||||||
writeCache();
|
writeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
bool
|
||||||
Rosstackage::find(const std::string& name)
|
Rosstackage::find(const std::string& name, std::string& path)
|
||||||
{
|
{
|
||||||
std::map<std::string, Stackage*>::const_iterator it = stackages_.find(name);
|
std::tr1::unordered_map<std::string, Stackage*>::const_iterator it = stackages_.find(name);
|
||||||
if(it != stackages_.end())
|
if(it != stackages_.end())
|
||||||
return it->second->path_;
|
{
|
||||||
|
path = it->second->path_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return "";
|
{
|
||||||
|
log_error("librospack", std::string("package ") + name + " not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Rosstackage::list(std::vector<std::pair<std::string, std::string> >& list)
|
||||||
|
{
|
||||||
|
list.resize(stackages_.size());
|
||||||
|
int i = 0;
|
||||||
|
for(std::tr1::unordered_map<std::string, Stackage*>::const_iterator it = stackages_.begin();
|
||||||
|
it != stackages_.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
list[i].first = it->first;
|
||||||
|
list[i].second = it->second->path_;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Rosstackage::deps(const std::string& name, bool direct,
|
||||||
|
std::vector<std::string>& deps)
|
||||||
|
{
|
||||||
|
if(!stackages_.count(name))
|
||||||
|
{
|
||||||
|
log_error("librospack", std::string("no such package ") + name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Stackage* stackage = stackages_[name];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
computeDeps(stackage);
|
||||||
|
std::tr1::unordered_set<std::string> deps_hash;
|
||||||
|
gatherDeps(stackage, direct, 0, deps_hash, deps);
|
||||||
|
}
|
||||||
|
catch(Exception& e)
|
||||||
|
{
|
||||||
|
log_error("librospack", e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
@ -171,8 +241,6 @@ Rosstackage::addStackage(const std::string& path)
|
||||||
}
|
}
|
||||||
fs::path manifest_path = fs::path(path) / manifest_name_;
|
fs::path manifest_path = fs::path(path) / manifest_name_;
|
||||||
stackages_[name] = new Stackage(name, path, manifest_path.string());
|
stackages_[name] = new Stackage(name, path, manifest_path.string());
|
||||||
// TODO
|
|
||||||
loadManifest(stackages_[name]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -180,8 +248,8 @@ Rosstackage::crawlDetail(const std::string& path,
|
||||||
bool force,
|
bool force,
|
||||||
int depth)
|
int depth)
|
||||||
{
|
{
|
||||||
if(depth > max_crawl_depth_)
|
if(depth > MAX_CRAWL_DEPTH)
|
||||||
throw Exception("Maximum depth exceeded during crawl");
|
throw Exception("maximum depth exceeded during crawl");
|
||||||
|
|
||||||
if(!fs::is_directory(path))
|
if(!fs::is_directory(path))
|
||||||
return;
|
return;
|
||||||
|
@ -218,13 +286,90 @@ Rosstackage::loadManifest(Stackage* stackage)
|
||||||
|
|
||||||
if(!stackage->manifest_.LoadFile(stackage->manifest_path_))
|
if(!stackage->manifest_.LoadFile(stackage->manifest_path_))
|
||||||
{
|
{
|
||||||
std::string errmsg = std::string("Error parsing manifest of package ") +
|
std::string errmsg = std::string("error parsing manifest of package ") +
|
||||||
stackage->name_ + " at [" + stackage->manifest_path_ + "]";
|
stackage->name_ + " at " + stackage->manifest_path_;
|
||||||
throw Exception(errmsg);
|
throw Exception(errmsg);
|
||||||
}
|
}
|
||||||
stackage->manifest_loaded_ = true;
|
stackage->manifest_loaded_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rospack_tinyxml::TiXmlElement*
|
||||||
|
Rosstackage::getManifestRoot(Stackage* stackage)
|
||||||
|
{
|
||||||
|
loadManifest(stackage);
|
||||||
|
rospack_tinyxml::TiXmlElement* ele = stackage->manifest_.RootElement();
|
||||||
|
if(!ele)
|
||||||
|
{
|
||||||
|
std::string errmsg = std::string("error parsing manifest of package ") +
|
||||||
|
stackage->name_ + " at " + stackage->manifest_path_;
|
||||||
|
throw Exception(errmsg);
|
||||||
|
}
|
||||||
|
return ele;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Rosstackage::computeDeps(Stackage* stackage)
|
||||||
|
{
|
||||||
|
if(stackage->deps_computed_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
stackage->deps_computed_ = true;
|
||||||
|
|
||||||
|
rospack_tinyxml::TiXmlElement* root = getManifestRoot(stackage);
|
||||||
|
rospack_tinyxml::TiXmlNode *dep_node = NULL;
|
||||||
|
while((dep_node = root->IterateChildren("depend", dep_node)))
|
||||||
|
{
|
||||||
|
rospack_tinyxml::TiXmlElement *dep_ele = dep_node->ToElement();
|
||||||
|
const char* dep_pkgname = dep_ele->Attribute("package");
|
||||||
|
if(!dep_pkgname)
|
||||||
|
{
|
||||||
|
std::string errmsg = std::string("bad depend syntax (no 'package' attribute) in manifest ") + stackage->name_ + " at " + stackage->manifest_path_;
|
||||||
|
throw Exception(errmsg);
|
||||||
|
}
|
||||||
|
else if(dep_pkgname == stackage->name_)
|
||||||
|
{
|
||||||
|
std::string errmsg = std::string("package ") + stackage->name_ + " depends on itself";
|
||||||
|
throw Exception(errmsg);
|
||||||
|
}
|
||||||
|
else if(!stackages_.count(dep_pkgname))
|
||||||
|
{
|
||||||
|
std::string errmsg = std::string("package ") + stackage->name_ + " depends on non-existent package " + dep_pkgname;
|
||||||
|
throw Exception(errmsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stackage* dep = stackages_[dep_pkgname];
|
||||||
|
stackage->deps.push_back(dep);
|
||||||
|
computeDeps(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-condition: computeDeps(stackage) succeeded
|
||||||
|
void
|
||||||
|
Rosstackage::gatherDeps(Stackage* stackage, bool direct, int depth,
|
||||||
|
std::tr1::unordered_set<std::string>& deps_hash,
|
||||||
|
std::vector<std::string>& deps)
|
||||||
|
{
|
||||||
|
if(depth > MAX_DEPENDENCY_DEPTH)
|
||||||
|
throw Exception("maximum dependency depth exceeded (likely circular dependency)");
|
||||||
|
|
||||||
|
for(std::vector<Stackage*>::const_iterator it = stackage->deps.begin();
|
||||||
|
it != stackage->deps.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
if(deps_hash.find((*it)->name_) == deps_hash.end())
|
||||||
|
{
|
||||||
|
deps_hash.insert((*it)->name_);
|
||||||
|
if(!direct)
|
||||||
|
gatherDeps(*it, direct, depth+1, deps_hash, deps);
|
||||||
|
// We maintain the vector because the original rospack guaranteed
|
||||||
|
// ordering in dep reporting.
|
||||||
|
deps.push_back((*it)->name_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Rosstackage::getCachePath()
|
Rosstackage::getCachePath()
|
||||||
{
|
{
|
||||||
|
@ -265,7 +410,7 @@ Rosstackage::getCachePath()
|
||||||
}
|
}
|
||||||
catch(fs::filesystem_error& e)
|
catch(fs::filesystem_error& e)
|
||||||
{
|
{
|
||||||
rospack_warn("librospack",
|
log_warn("librospack",
|
||||||
std::string("cannot create rospack cache directory ") +
|
std::string("cannot create rospack cache directory ") +
|
||||||
cache_path.string() + ": " + e.what());
|
cache_path.string() + ": " + e.what());
|
||||||
}
|
}
|
||||||
|
@ -313,7 +458,7 @@ Rosstackage::writeCache()
|
||||||
std::string cache_path = getCachePath();
|
std::string cache_path = getCachePath();
|
||||||
if(!cache_path.size())
|
if(!cache_path.size())
|
||||||
{
|
{
|
||||||
rospack_warn("librospack",
|
log_warn("librospack",
|
||||||
"no location available to write cache file. Try setting ROS_HOME or HOME.");
|
"no location available to write cache file. Try setting ROS_HOME or HOME.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -342,7 +487,7 @@ Rosstackage::writeCache()
|
||||||
int fd = open(tmp_cache_path, O_RDWR | O_EXCL | _O_CREAT, 0644);
|
int fd = open(tmp_cache_path, O_RDWR | O_EXCL | _O_CREAT, 0644);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
rospack_warn("librospack",
|
log_warn("librospack",
|
||||||
std::string("unable to create temporary cache file ") +
|
std::string("unable to create temporary cache file ") +
|
||||||
tmp_cache_path, true);
|
tmp_cache_path, true);
|
||||||
}
|
}
|
||||||
|
@ -383,7 +528,7 @@ Rosstackage::writeCache()
|
||||||
|
|
||||||
char *rpp = getenv("ROS_PACKAGE_PATH");
|
char *rpp = getenv("ROS_PACKAGE_PATH");
|
||||||
fprintf(cache, "#ROS_PACKAGE_PATH=%s\n", (rpp ? rpp : ""));
|
fprintf(cache, "#ROS_PACKAGE_PATH=%s\n", (rpp ? rpp : ""));
|
||||||
for(std::map<std::string, Stackage*>::const_iterator it = stackages_.begin();
|
for(std::tr1::unordered_map<std::string, Stackage*>::const_iterator it = stackages_.begin();
|
||||||
it != stackages_.end();
|
it != stackages_.end();
|
||||||
++it)
|
++it)
|
||||||
fprintf(cache, "%s\n", it->second->path_.c_str());
|
fprintf(cache, "%s\n", it->second->path_.c_str());
|
||||||
|
@ -460,8 +605,7 @@ Rosstackage::validateCache()
|
||||||
Rospack::Rospack() :
|
Rospack::Rospack() :
|
||||||
Rosstackage(ROSPACK_MANIFEST_NAME,
|
Rosstackage(ROSPACK_MANIFEST_NAME,
|
||||||
ROSPACK_CACHE_NAME,
|
ROSPACK_CACHE_NAME,
|
||||||
CRAWL_DOWN,
|
CRAWL_DOWN)
|
||||||
MAX_CRAWL_DEPTH)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,8 +621,7 @@ void Rospack::crawl(const std::vector<std::string>& search_path,
|
||||||
Rosstack::Rosstack() :
|
Rosstack::Rosstack() :
|
||||||
Rosstackage(ROSSTACK_MANIFEST_NAME,
|
Rosstackage(ROSSTACK_MANIFEST_NAME,
|
||||||
ROSSTACK_CACHE_NAME,
|
ROSSTACK_CACHE_NAME,
|
||||||
CRAWL_UP,
|
CRAWL_UP)
|
||||||
MAX_CRAWL_DEPTH)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,11 +631,35 @@ void Rosstack::crawl(const std::vector<std::string>& search_path,
|
||||||
Rosstackage::crawl(search_path, force);
|
Rosstackage::crawl(search_path, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
get_search_path_from_env(std::vector<std::string>& sp)
|
||||||
|
{
|
||||||
|
char* rr = getenv("ROS_ROOT");
|
||||||
|
char* rpp = getenv("ROS_PACKAGE_PATH");
|
||||||
|
|
||||||
|
if(rr)
|
||||||
|
sp.push_back(rr);
|
||||||
|
if(rpp)
|
||||||
|
{
|
||||||
|
std::vector<std::string> rpp_strings;
|
||||||
|
boost::split(rpp_strings, rpp,
|
||||||
|
boost::is_any_of(":"),
|
||||||
|
boost::token_compress_on);
|
||||||
|
for(std::vector<std::string>::const_iterator it = rpp_strings.begin();
|
||||||
|
it != rpp_strings.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
sp.push_back(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Simple console output helpers
|
// Simple console output helpers
|
||||||
void rospack_log(const std::string& name,
|
void log(const std::string& name,
|
||||||
const std::string& level,
|
const std::string& level,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
bool append_errno)
|
bool append_errno)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "[%s] %s: %s",
|
fprintf(stderr, "[%s] %s: %s",
|
||||||
name.c_str(), level.c_str(), msg.c_str());
|
name.c_str(), level.c_str(), msg.c_str());
|
||||||
|
@ -501,17 +668,17 @@ void rospack_log(const std::string& name,
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void rospack_warn(const std::string& name,
|
void log_warn(const std::string& name,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
bool append_errno)
|
bool append_errno)
|
||||||
{
|
{
|
||||||
rospack_log(name, "Warning", msg, append_errno);
|
log(name, "Warning", msg, append_errno);
|
||||||
}
|
}
|
||||||
void rospack_error(const std::string& name,
|
void log_error(const std::string& name,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
bool append_errno)
|
bool append_errno)
|
||||||
{
|
{
|
||||||
rospack_log(name, "Error", msg, append_errno);
|
log(name, "Error", msg, append_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace rospack
|
} // namespace rospack
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
#include "tinyxml-2.5.3/tinyxml.h"
|
#include "tinyxml-2.5.3/tinyxml.h"
|
||||||
|
|
||||||
|
#include <boost/tr1/unordered_set.hpp>
|
||||||
|
#include <boost/tr1/unordered_map.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -39,46 +41,14 @@
|
||||||
namespace rospack
|
namespace rospack
|
||||||
{
|
{
|
||||||
|
|
||||||
class Stackage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// \brief name of the stackage
|
|
||||||
std::string name_;
|
|
||||||
// \brief absolute path to the stackage
|
|
||||||
std::string path_;
|
|
||||||
// \brief absolute path to the stackage manifest
|
|
||||||
std::string manifest_path_;
|
|
||||||
// \brief have we already loaded the manifest?
|
|
||||||
bool manifest_loaded_;
|
|
||||||
// \brief TinyXML structure, filled in during parsing
|
|
||||||
rospack_tinyxml::TiXmlDocument manifest_;
|
|
||||||
|
|
||||||
Stackage(const std::string& name,
|
|
||||||
const std::string& path,
|
|
||||||
const std::string& manifest_path);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Package : public Stackage
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
class Stack : public Stackage
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CRAWL_UP,
|
CRAWL_UP,
|
||||||
CRAWL_DOWN
|
CRAWL_DOWN
|
||||||
} crawl_direction_t;
|
} crawl_direction_t;
|
||||||
|
|
||||||
class Exception : public std::runtime_error
|
class Stackage;
|
||||||
{
|
class rospack_tinyxml::TiXmlElement;
|
||||||
public:
|
|
||||||
Exception(const std::string& what)
|
|
||||||
: std::runtime_error(what)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Rosstackage
|
class Rosstackage
|
||||||
{
|
{
|
||||||
|
@ -86,7 +56,6 @@ class Rosstackage
|
||||||
std::string manifest_name_;
|
std::string manifest_name_;
|
||||||
std::string cache_name_;
|
std::string cache_name_;
|
||||||
crawl_direction_t crawl_dir_;
|
crawl_direction_t crawl_dir_;
|
||||||
int max_crawl_depth_;
|
|
||||||
|
|
||||||
bool crawled_;
|
bool crawled_;
|
||||||
bool isStackage(const std::string& path);
|
bool isStackage(const std::string& path);
|
||||||
|
@ -95,22 +64,28 @@ class Rosstackage
|
||||||
bool force,
|
bool force,
|
||||||
int depth);
|
int depth);
|
||||||
void loadManifest(Stackage* stackage);
|
void loadManifest(Stackage* stackage);
|
||||||
|
void computeDeps(Stackage* stackage);
|
||||||
|
void gatherDeps(Stackage* stackage, bool direct, int depth,
|
||||||
|
std::tr1::unordered_set<std::string>& deps_hash,
|
||||||
|
std::vector<std::string>& deps);
|
||||||
|
rospack_tinyxml::TiXmlElement* getManifestRoot(Stackage* stackage);
|
||||||
std::string getCachePath();
|
std::string getCachePath();
|
||||||
bool readCache();
|
bool readCache();
|
||||||
void writeCache();
|
void writeCache();
|
||||||
bool validateCache();
|
bool validateCache();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::map<std::string, Stackage*> stackages_;
|
std::tr1::unordered_map<std::string, Stackage*> stackages_;
|
||||||
void crawl(const std::vector<std::string>& search_path, bool force);
|
void crawl(const std::vector<std::string>& search_path, bool force);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Rosstackage(std::string manifest_name,
|
Rosstackage(std::string manifest_name,
|
||||||
std::string cache_name,
|
std::string cache_name,
|
||||||
crawl_direction_t crawl_dir,
|
crawl_direction_t crawl_dir);
|
||||||
int max_crawl_depth);
|
|
||||||
|
|
||||||
std::string find(const std::string& name);
|
bool find(const std::string& name, std::string& path);
|
||||||
|
void list(std::vector<std::pair<std::string, std::string> >& list);
|
||||||
|
bool deps(const std::string& name, bool direct, std::vector<std::string>& deps);
|
||||||
|
|
||||||
void debug_dump();
|
void debug_dump();
|
||||||
};
|
};
|
||||||
|
@ -133,14 +108,15 @@ class Rosstack : public Rosstackage
|
||||||
Rosstack();
|
Rosstack();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void get_search_path_from_env(std::vector<std::string>& sp);
|
||||||
|
|
||||||
// Simple console output helpers
|
// Simple console output helpers
|
||||||
void rospack_warn(const std::string& name,
|
void log_warn(const std::string& name,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
bool append_errno = false);
|
bool append_errno = false);
|
||||||
void rospack_error(const std::string& name,
|
void log_error(const std::string& name,
|
||||||
const std::string& msg,
|
const std::string& msg,
|
||||||
bool append_errno = false);
|
bool append_errno = false);
|
||||||
|
|
||||||
} // namespace rospack
|
} // namespace rospack
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,47 @@
|
||||||
|
|
||||||
#include "rp.h"
|
#include "rp.h"
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
using namespace rospack;
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
|
const char* usage()
|
||||||
|
{
|
||||||
|
return "USAGE: rospack <command> [options] [package]\n"
|
||||||
|
" Allowed commands:\n"
|
||||||
|
" help\n"
|
||||||
|
" find [package]\n"
|
||||||
|
" list\n"
|
||||||
|
" list-names\n"
|
||||||
|
" list-duplicates\n"
|
||||||
|
" langs\n"
|
||||||
|
" depends [package] (alias: deps)\n"
|
||||||
|
" depends-manifests [package] (alias: deps-manifests)\n"
|
||||||
|
" depends-msgsrv [package] (alias: deps-msgsrv)\n"
|
||||||
|
" depends1 [package] (alias: deps1)\n"
|
||||||
|
" depends-indent [package] (alias: deps-indent)\n"
|
||||||
|
" depends-why --target=<target> [package] (alias: deps-why)\n"
|
||||||
|
" rosdep [package] (alias: rosdeps)\n"
|
||||||
|
" rosdep0 [package] (alias: rosdeps0)\n"
|
||||||
|
" vcs [package]\n"
|
||||||
|
" vcs0 [package]\n"
|
||||||
|
" depends-on [package]\n"
|
||||||
|
" depends-on1 [package]\n"
|
||||||
|
" export [--deps-only] --lang=<lang> --attrib=<attrib> [package]\n"
|
||||||
|
" plugins --attrib=<attrib> [--top=<toppkg>] [package]\n"
|
||||||
|
" cflags-only-I [--deps-only] [package]\n"
|
||||||
|
" cflags-only-other [--deps-only] [package]\n"
|
||||||
|
" libs-only-L [--deps-only] [package]\n"
|
||||||
|
" libs-only-l [--deps-only] [package]\n"
|
||||||
|
" libs-only-other [--deps-only] [package]\n"
|
||||||
|
" profile [--length=<length>] [--zombie-only]\n"
|
||||||
|
" Extra options:\n"
|
||||||
|
" -q Quiets error reports.\n\n"
|
||||||
|
" If [package] is omitted, the current working directory\n"
|
||||||
|
" is used (if it contains a manifest.xml).\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
parse_args(int argc, char** argv, po::variables_map& vm)
|
parse_args(int argc, char** argv, po::variables_map& vm)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +91,7 @@ parse_args(int argc, char** argv, po::variables_map& vm)
|
||||||
}
|
}
|
||||||
catch(boost::program_options::error e)
|
catch(boost::program_options::error e)
|
||||||
{
|
{
|
||||||
rospack_error("rospack", std::string("failed to parse command-line options: ") + e.what());
|
rospack::log_error("rospack", std::string("failed to parse command-line options: ") + e.what());
|
||||||
// TODO: print USAGE
|
// TODO: print USAGE
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -66,29 +100,6 @@ parse_args(int argc, char** argv, po::variables_map& vm)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
get_search_path_from_env(std::vector<std::string>& sp)
|
|
||||||
{
|
|
||||||
char* rr = getenv("ROS_ROOT");
|
|
||||||
char* rpp = getenv("ROS_PACKAGE_PATH");
|
|
||||||
|
|
||||||
if(rr)
|
|
||||||
sp.push_back(rr);
|
|
||||||
if(rpp)
|
|
||||||
{
|
|
||||||
std::vector<std::string> rpp_strings;
|
|
||||||
boost::split(rpp_strings, rpp,
|
|
||||||
boost::is_any_of(":"),
|
|
||||||
boost::token_compress_on);
|
|
||||||
for(std::vector<std::string>::const_iterator it = rpp_strings.begin();
|
|
||||||
it != rpp_strings.end();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
sp.push_back(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
@ -99,9 +110,9 @@ main(int argc, char** argv)
|
||||||
if(ret)
|
if(ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
Rospack rp;
|
rospack::Rospack rp;
|
||||||
std::vector<std::string> search_path;
|
std::vector<std::string> search_path;
|
||||||
get_search_path_from_env(search_path);
|
rospack::get_search_path_from_env(search_path);
|
||||||
rp.crawl(search_path, false);
|
rp.crawl(search_path, false);
|
||||||
|
|
||||||
std::string command;
|
std::string command;
|
||||||
|
@ -110,10 +121,14 @@ main(int argc, char** argv)
|
||||||
command = vm["command"].as<std::string>();
|
command = vm["command"].as<std::string>();
|
||||||
if(vm.count("package"))
|
if(vm.count("package"))
|
||||||
package = vm["package"].as<std::string>();
|
package = vm["package"].as<std::string>();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: try to determine package from directory context
|
||||||
|
}
|
||||||
|
|
||||||
if(!command.size())
|
if(!command.size())
|
||||||
{
|
{
|
||||||
rospack_error("rospack", "no command given");
|
rospack::log_error("rospack", "no command given");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,16 +136,76 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if(!package.size())
|
if(!package.size())
|
||||||
{
|
{
|
||||||
rospack_error("rospack", "no package given for find command");
|
rospack::log_error("rospack", "no package given for find command");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
std::string path = rp.find(package);
|
std::string path;
|
||||||
printf("%s\n", path.c_str());
|
if(!rp.find(package, path))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s\n", path.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(command == "list")
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, std::string> > list;
|
||||||
|
rp.list(list);
|
||||||
|
for(std::vector<std::pair<std::string, std::string> >::const_iterator it = list.begin();
|
||||||
|
it != list.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
printf("%s %s\n", it->first.c_str(), it->second.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(command == "list-names")
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, std::string> > list;
|
||||||
|
rp.list(list);
|
||||||
|
for(std::vector<std::pair<std::string, std::string> >::const_iterator it = list.begin();
|
||||||
|
it != list.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
printf("%s\n", it->first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(command == "list-duplicates")
|
||||||
|
{
|
||||||
|
rospack::log_error("rospack",
|
||||||
|
std::string("command ") + command + " not implemented");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if(command == "langs")
|
||||||
|
{
|
||||||
|
rospack::log_error("rospack",
|
||||||
|
std::string("command ") + command + " not implemented");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if(command == "depends" || command == "deps" ||
|
||||||
|
command == "depends1" || command == "deps1")
|
||||||
|
{
|
||||||
|
std::vector<std::string> deps;
|
||||||
|
if(!rp.deps(package, (command == "depends1" || command == "deps1"), deps))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(std::vector<std::string>::const_iterator it = deps.begin();
|
||||||
|
it != deps.end();
|
||||||
|
++it)
|
||||||
|
printf("%s\n", it->c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(command == "help")
|
||||||
|
{
|
||||||
|
printf("%s", usage());
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rospack_error("rospack",
|
rospack::log_error("rospack",
|
||||||
std::string("command ") + command + " not implemented");
|
std::string("command ") + command + " not implemented");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue