Line data Source code
1 : /*! 2 : * \file esys/repo/configfolder.cpp 3 : * \brief 4 : * 5 : * \cond 6 : * __legal_b__ 7 : * 8 : * Copyright (c) 2020 Michel Gillet 9 : * Distributed under the MIT License. 10 : * (See accompanying file LICENSE.txt or 11 : * copy at https://opensource.org/licenses/MIT) 12 : * 13 : * __legal_e__ 14 : * \endcond 15 : * 16 : */ 17 : 18 : #include "esys/repo/esysrepo_prec.h" 19 : #include "esys/repo/configfolder.h" 20 : #include "esys/repo/manifest/base.h" 21 : #include "esys/repo/grepo/manifest.h" 22 : 23 : #include <boost/filesystem.hpp> 24 : 25 : namespace esys::repo 26 : { 27 : 28 95 : ConfigFolder::ConfigFolder() 29 95 : : log::User() 30 : { 31 95 : } 32 : 33 341 : ConfigFolder::~ConfigFolder() = default; 34 : 35 126 : void ConfigFolder::set_workspace_path(const std::string &parent_path) 36 : { 37 126 : boost::filesystem::path path = parent_path; 38 : 39 252 : boost::filesystem::absolute(path).make_preferred(); 40 : 41 378 : m_parent_path = boost::filesystem::absolute(path).make_preferred().string(); 42 126 : } 43 : 44 907 : const std::string &ConfigFolder::get_workspace_path() const 45 : { 46 907 : return m_parent_path; 47 : } 48 : 49 126 : void ConfigFolder::populate_all_pathes() 50 : { 51 126 : boost::filesystem::path path = get_workspace_path(); 52 126 : boost::filesystem::path temp; 53 126 : boost::filesystem::path config_file; 54 : 55 126 : path /= ".esysrepo"; 56 126 : m_path = path.string(); 57 : 58 126 : temp = path; 59 126 : temp /= "temp"; 60 126 : m_temp_path = temp.string(); 61 : 62 126 : config_file = path; 63 126 : config_file /= "config.json"; 64 126 : m_config_file_path = config_file.string(); 65 : 66 126 : boost::filesystem::path pins_file = path; 67 126 : pins_file /= "pins.json"; 68 252 : m_pins_file_path = pins_file.string(); 69 126 : } 70 : 71 34 : Result ConfigFolder::create(const std::string &parent_path, bool ok_if_exists) 72 : { 73 34 : if (!parent_path.empty()) set_workspace_path(parent_path); 74 : 75 34 : boost::filesystem::path rel_parent_path = boost::filesystem::relative(get_workspace_path()); 76 : 77 34 : if (!boost::filesystem::exists(get_workspace_path())) 78 : { 79 2 : bool result = boost::filesystem::create_directories(get_workspace_path()); 80 2 : if (result) 81 : { 82 4 : info("Created folder : " + rel_parent_path.string()); 83 : } 84 : else 85 : { 86 0 : error("Couldn't create output folder : " + rel_parent_path.string()); 87 0 : return ESYSREPO_RESULT(ResultCode::FOLDER_CREATION_ERROR, get_workspace_path()); 88 : } 89 : } 90 : 91 34 : populate_all_pathes(); 92 : 93 34 : boost::filesystem::path rel_path = boost::filesystem::relative(get_path()); 94 : 95 34 : if (!boost::filesystem::exists(get_path())) 96 : { 97 34 : bool result = boost::filesystem::create_directory(get_path()); 98 34 : if (!result) 99 : { 100 0 : error("The following folder couldn't be created : " + rel_path.string()); 101 0 : return ESYSREPO_RESULT(ResultCode::FOLDER_CREATION_ERROR, get_path()); 102 : } 103 : else 104 68 : info("Created folder : " + rel_path.string()); 105 : } 106 : else 107 : { 108 0 : if (!ok_if_exists) 109 : { 110 0 : error("The following folder already exits : " + rel_path.string()); 111 0 : return ESYSREPO_RESULT(ResultCode::FOLDER_ALREADY_EXISTS, get_path()); 112 : } 113 : else 114 0 : warn("The following folder already exits : " + rel_path.string()); 115 : } 116 : 117 34 : boost::filesystem::path rel_temp_path = boost::filesystem::relative(get_temp_path()); 118 34 : if (!boost::filesystem::exists(get_temp_path())) 119 : { 120 34 : bool result = boost::filesystem::create_directory(get_temp_path()); 121 34 : if (!result) 122 : { 123 0 : error("The following folder couldn't be created : " + rel_temp_path.string()); 124 0 : return ESYSREPO_RESULT(ResultCode::FOLDER_CREATION_ERROR, get_temp_path()); 125 : } 126 : else 127 68 : info("Created folder : " + rel_temp_path.string()); 128 : } 129 : else 130 : { 131 0 : if (!ok_if_exists) 132 : { 133 0 : error("The following folder already exits : " + rel_temp_path.string()); 134 0 : return ESYSREPO_RESULT(ResultCode::FOLDER_ALREADY_EXISTS, get_temp_path()); 135 : } 136 : else 137 0 : warn("The following folder already exits : " + rel_temp_path.string()); 138 : } 139 34 : return ESYSREPO_RESULT(ResultCode::OK); 140 68 : } 141 : 142 92 : Result ConfigFolder::open(const std::string &parent_path, bool print_error) 143 : { 144 92 : if (!parent_path.empty()) set_workspace_path(parent_path); 145 : 146 92 : populate_all_pathes(); 147 : 148 92 : boost::filesystem::path rel_path = boost::filesystem::relative(get_path()); 149 92 : if (!boost::filesystem::exists(get_path())) 150 : { 151 31 : if (print_error) error("The following folder is not existing : " + rel_path.string()); 152 31 : return ESYSREPO_RESULT(ResultCode::PATH_NOT_EXISTING, get_path()); 153 : } 154 : 155 61 : boost::filesystem::path rel_config_file_path = boost::filesystem::relative(get_config_file_path()); 156 61 : if (!boost::filesystem::exists(get_config_file_path())) 157 : { 158 0 : if (print_error) error("The esysrepo config file can't be found : " + rel_config_file_path.string()); 159 0 : return ESYSREPO_RESULT(ResultCode::PATH_NOT_EXISTING, get_config_file_path()); 160 : } 161 : 162 61 : m_config_file = std::make_shared<ConfigFile>(); 163 61 : Result result = m_config_file->open(get_config_file_path()); 164 61 : if (result.error()) 165 : { 166 0 : if (print_error) error("The esysrepo config file couldn't opened : " + rel_config_file_path.string()); 167 0 : return ESYSREPO_RESULT(result); 168 : } 169 61 : set_config(m_config_file->get_config()); 170 : 171 61 : Result pins_result = load_pins_file(); 172 61 : if (pins_result.error()) return ESYSREPO_RESULT(pins_result); 173 : 174 61 : return ESYSREPO_RESULT(ResultCode::OK); 175 153 : } 176 : 177 0 : int ConfigFolder::write(const std::string &parent_path) 178 : { 179 0 : if (!parent_path.empty()) set_workspace_path(parent_path); 180 : 181 0 : return -1; 182 : } 183 : 184 483 : const std::string &ConfigFolder::get_path() const 185 : { 186 483 : return m_path; 187 : } 188 : 189 145 : const std::string &ConfigFolder::get_temp_path() const 190 : { 191 145 : return m_temp_path; 192 : } 193 : 194 253 : const std::string &ConfigFolder::get_config_file_path() const 195 : { 196 253 : return m_config_file_path; 197 : } 198 : 199 25 : std::string ConfigFolder::get_manifest_repo_path() const 200 : { 201 25 : boost::filesystem::path repo_path = get_path(); 202 50 : if (get_config() == nullptr) return ""; 203 : 204 25 : repo_path /= get_config()->get_manifest_path(); 205 75 : repo_path = repo_path.parent_path().lexically_normal().make_preferred(); 206 : 207 25 : return repo_path.string(); 208 25 : } 209 : 210 0 : std::string ConfigFolder::get_manifest_rel_file_name() const 211 : { 212 0 : assert(get_config() != nullptr); 213 : 214 0 : std::string folder_name; 215 : 216 0 : switch (get_config()->get_manifest_type()) 217 : { 218 0 : case manifest::Type::ESYSREPO_MANIFEST: folder_name = manifest::Base::get_folder_name(); break; 219 0 : case manifest::Type::GOOGLE_MANIFEST: folder_name = grepo::Manifest::get_folder_name(); break; 220 0 : default: return ""; 221 : } 222 : 223 0 : boost::filesystem::path manifest_path = get_config()->get_manifest_path(); 224 : 225 0 : auto rel_folder_path = boost::filesystem::relative(manifest_path, folder_name); 226 0 : return rel_folder_path.string(); 227 0 : } 228 : 229 647 : std::shared_ptr<Config> ConfigFolder::get_config() const 230 : { 231 647 : return m_config; 232 : } 233 : 234 102 : void ConfigFolder::set_config(std::shared_ptr<Config> config) 235 : { 236 102 : m_config = config; 237 102 : } 238 : 239 34 : std::shared_ptr<Config> ConfigFolder::get_or_new_config() 240 : { 241 34 : auto cfg = get_config(); 242 : 243 64 : if (cfg != nullptr) return cfg; 244 : 245 30 : set_config(std::make_shared<Config>()); 246 : 247 30 : return get_config(); 248 34 : } 249 : 250 35 : Result ConfigFolder::write_config_file() 251 : { 252 35 : m_config_file = std::make_shared<ConfigFile>(); 253 35 : m_config_file->set_config(get_config()); 254 35 : Result result = m_config_file->write(get_config_file_path()); 255 35 : boost::filesystem::path rel_config_file_path = boost::filesystem::relative(get_config_file_path()); 256 35 : if (result.error()) 257 0 : error("Couldn't write the esysrepo config file : " + rel_config_file_path.string()); 258 : else 259 70 : debug(0, "Wrote the esysrepo config file : " + rel_config_file_path.string()); 260 35 : return result; 261 35 : } 262 : 263 89 : const std::string &ConfigFolder::get_pins_file_path() const 264 : { 265 89 : return m_pins_file_path; 266 : } 267 : 268 0 : std::shared_ptr<RevisionPins> ConfigFolder::get_revision_pins() const 269 : { 270 0 : return m_revision_pins; 271 : } 272 : 273 87 : void ConfigFolder::set_revision_pins(std::shared_ptr<RevisionPins> pins) 274 : { 275 87 : m_revision_pins = pins; 276 87 : } 277 : 278 28 : std::shared_ptr<RevisionPins> ConfigFolder::get_or_new_revision_pins() 279 : { 280 28 : if (m_revision_pins == nullptr) m_revision_pins = std::make_shared<RevisionPins>(); 281 28 : return m_revision_pins; 282 : } 283 : 284 87 : Result ConfigFolder::load_pins_file() 285 : { 286 87 : PinsFile pins_file; 287 87 : Result result = pins_file.open(get_pins_file_path()); 288 87 : if (result.error()) return result; 289 87 : set_revision_pins(pins_file.get_or_new_pins()); 290 87 : return ESYSREPO_RESULT(ResultCode::OK); 291 87 : } 292 : 293 1 : Result ConfigFolder::write_pins_file() 294 : { 295 1 : PinsFile pins_file; 296 1 : pins_file.set_pins(get_or_new_revision_pins()); 297 1 : Result result = pins_file.write(get_pins_file_path()); 298 1 : boost::filesystem::path rel_path = boost::filesystem::relative(get_pins_file_path()); 299 1 : if (result.error()) 300 0 : error("Couldn't write the esysrepo pins file : " + rel_path.string()); 301 : else 302 2 : debug(0, "Wrote the esysrepo pins file : " + rel_path.string()); 303 2 : return result; 304 1 : } 305 : 306 39 : bool ConfigFolder::is_config_folder(const std::string &path) 307 : { 308 39 : boost::filesystem::path folder = path; 309 39 : folder /= ".esysrepo"; 310 39 : return boost::filesystem::exists(folder); 311 39 : } 312 : 313 : } // namespace esys::repo