17 #include "addon/manager.hpp" 24 #include <boost/algorithm/string.hpp> 27 #define ERR_CFG LOG_STREAM(err , log_config) 28 #define LOG_CFG LOG_STREAM(info, log_config) 29 #define WRN_CFG LOG_STREAM(warn, log_config) 32 #define ERR_FS LOG_STREAM(err , log_filesystem) 35 #define ERR_NET LOG_STREAM(err , log_network) 36 #define LOG_NET LOG_STREAM(info, log_network) 39 std::string get_pbl_file_path(
const std::string& addon_name)
43 const std::string exterior = parentd +
"/" + addon_name +
".pbl";
44 const std::string interior = parentd +
"/" + addon_name +
"/_server.pbl";
48 inline std::string get_info_file_path(
const std::string& addon_name)
71 const std::string& pbl_path = get_pbl_file_path(addon_name);
95 const std::string& info_path = get_info_file_path(addon_name);
102 read(envelope, *stream);
104 cfg = std::move(
info);
107 ERR_CFG <<
"Failed to read add-on installation information for '" 108 << addon_name <<
"' from " << info_path <<
":\n" 115 LOG_CFG <<
"Writing version info for add-on '" << addon_name <<
"'\n";
117 const auto& info_path = get_info_file_path(addon_name);
121 <<
"# File automatically generated by Wesnoth to keep track\n" 122 <<
"# of version information on installed add-ons. DO NOT EDIT!\n" 127 write(*out, envelope);
134 LOG_CFG <<
"removing local add-on: " << addon <<
'\n';
137 ERR_CFG <<
"Failed to delete directory/file: " << addon_dir <<
'\n';
138 ERR_CFG <<
"removal of add-on " << addon <<
" failed!" << std::endl;
154 std::vector<std::string> res;
155 std::vector<std::string> addon_dirnames;
160 for(
const auto& addon_name : addon_dirnames) {
164 res.emplace_back(addon_name);
175 return enumerate_addons_internal(ADDON_HAS_PBL);
180 return enumerate_addons_internal(ADDON_ANY);
185 std::map<std::string, std::string> addons;
192 addons[addon_id] =
"Invalid pbl file, version unknown";
197 addons[addon_id] = !info_cfg.
empty() ? info_cfg[
"version"].str() :
"Unknown";
199 addons[addon_id] =
"Unknown";
211 static inline bool IsCR(
const char&
c)
216 static std::string
strip_cr(std::string str,
bool strip)
221 str.erase(new_end, str.end());
228 const std::string ign_file = parentd +
"/" + addon_name +
"/_server.ign";
231 LOG_CFG <<
"searching for .ign file for '" << addon_name <<
"'...\n";
233 LOG_CFG <<
"no .ign file found for '" << addon_name <<
"'\n" 234 <<
"using default ignore patterns...\n";
237 LOG_CFG <<
"found .ign file: " << ign_file <<
'\n';
240 while (std::getline(*stream, line)) {
242 const std::size_t l = line.size();
244 if (l == 0 || !line.compare(0,2,
"# "))
continue;
245 if (line[l - 1] ==
'/') {
257 const bool is_cfg = (fname.size() > 4 ? (fname.substr(fname.size() - 4) ==
".cfg") :
false);
263 cfg[
"name"] = dirname;
264 const std::string dir = path +
'/' + dirname;
266 std::vector<std::string> files, dirs;
268 for(
const std::string& name : files) {
275 for(
const std::string& name : dirs) {
276 bool valid = !ignore_patterns.
match_dir(name);
299 if (cfg[
"name"].empty())
302 dir = path +
'/' + cfg[
"name"].str();
324 if(removelist[
"name"].empty())
327 dir = path +
'/' + removelist[
"name"].str();
353 std::map< std::string, version_info > version_info_cache;
358 version_info_cache.clear();
360 LOG_CFG <<
"refreshing add-on versions cache\n";
367 std::vector<std::string> addon_info_files(addons.size());
369 std::transform(addons.begin(), addons.end(),
370 addon_info_files.begin(), get_info_file_path);
372 for(std::size_t
i = 0;
i < addon_info_files.size(); ++
i) {
373 assert(
i < addons.size());
375 const std::string& addon = addons[
i];
376 const std::string& info_file = addon_info_files[
i];
382 if(info_cfg.
empty()) {
386 const std::string& version = info_cfg[
"version"].str();
387 LOG_CFG <<
"cached add-on version: " << addon <<
" [" << version <<
"]\n";
389 version_info_cache[addon] = version;
392 WRN_CFG <<
"add-on '" << addon <<
"' has no _info.cfg; cannot read version info" << std::endl;
401 return entry != version_info_cache.end() ? entry->second : nil;
bool delete_directory(const std::string &dirname, const bool keep_pbl)
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Interfaces for manipulating version numbers of engine, add-ons, etc.
void purge_addon(const config &removelist)
Removes the listed files from the addon.
bool delete_file(const std::string &filename)
bool looks_like_pbl(const std::string &file)
void add_directory_pattern(const std::string &pattern)
void write_addon_install_info(const std::string &addon_name, const config &cfg)
Exception thrown when the WML parser fails to read a .pbl file.
std::string encode_binary(const std::string &str)
static bool file_exists(const bfs::path &fpath)
std::string unencode_binary(const std::string &str)
bool is_addon_installed(const std::string &addon_name)
Check whether the specified add-on is currently installed.
child_itors child_range(config_key_type key)
filesystem::scoped_istream istream_file(const std::string &fname, bool treat_failure_as_error)
static bool IsCR(const char &c)
void get_addon_install_info(const std::string &addon_name, config &cfg)
Gets the installation info (_info.cfg) for an add-on.
static std::string strip_cr(std::string str, bool strip)
static lg::log_domain log_network("network")
bool have_addon_in_vcs_tree(const std::string &addon_name)
Returns whether the specified add-on appears to be managed by a VCS or not.
filesystem::scoped_ostream ostream_file(const std::string &fname, std::ios_base::openmode mode, bool create_directory)
static void purge_dir(const std::string &path, const config &removelist)
version_info get_addon_version_info(const std::string &addon)
Returns a particular installed add-on's version information.
std::vector< std::string > available_addons()
Returns a list of local add-ons that can be published.
bool have_addon_install_info(const std::string &addon_name)
Returns true if there is a local installation info (_info.cfg) file for the add-on.
static void archive_file(const std::string &path, const std::string &fname, config &cfg)
void write(std::ostream &out, const configr_of &cfg, unsigned int level)
bool match_file(const std::string &name) const
static void unarchive_file(const std::string &path, const config &cfg)
void read(config &cfg, std::istream &in, abstract_validator *validator)
void write_file(const std::string &fname, const std::string &data)
Throws io_exception if an error occurs.
void get_files_in_dir(const std::string &dir, std::vector< std::string > *files, std::vector< std::string > *dirs, name_mode mode, filter_mode filter, reorder_mode reorder, file_tree_checksum *checksum)
Get a list of all files and/or directories in a given directory.
void set_addon_pbl_info(const std::string &addon_name, const config &cfg)
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
std::unique_ptr< std::istream > scoped_istream
std::vector< std::string > installed_addons()
Retrieves the names of all installed add-ons.
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on's version information structs.
bool remove_local_addon(const std::string &addon)
Removes the specified add-on, deleting its full directory structure.
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
config get_addon_pbl_info(const std::string &addon_name)
Gets the publish information for an add-on.
void add_file_pattern(const std::string &pattern)
static lg::log_domain log_filesystem("filesystem")
std::unique_ptr< std::ostream > scoped_ostream
int dir_size(const std::string &pname)
Returns the sum of the sizes of the files contained in a directory.
bool have_addon_pbl_info(const std::string &addon_name)
Returns whether a .pbl file is present for the specified add-on or not.
void archive_addon(const std::string &addon_name, config &cfg)
Archives an add-on into a config object for campaignd transactions.
static lg::log_domain log_config("config")
bool make_directory(const std::string &dirname)
static filesystem::blacklist_pattern_list read_ignore_patterns(const std::string &addon_name)
Declarations for File-IO.
static void archive_dir(const std::string &path, const std::string &dirname, config &cfg, const filesystem::blacklist_pattern_list &ignore_patterns)
Represents version numbers.
config & add_child(config_key_type key)
void unarchive_addon(const config &cfg)
std::string get_addons_dir()
Standard logging facilities (interface).
void trim(std::string_view &s)
bool match_dir(const std::string &name) const
A config object defines a single node in a WML file, with access to child nodes.
std::string::const_iterator iterator
static void unarchive_dir(const std::string &path, const config &cfg)
std::map< std::string, std::string > installed_addons_and_versions()
Retrieves the ids and versions of all installed add-ons.
static const blacklist_pattern_list default_blacklist