Line data Source code
1 : /*! 2 : * \file esys/repo/configfileimpl.cpp 3 : * \brief 4 : * 5 : * \cond 6 : * __legal_b__ 7 : * 8 : * Copyright (c) 2020-2022 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/configfileimpl.h" 20 : 21 : #include <boost/filesystem.hpp> 22 : 23 : #include <fstream> 24 : #include <iomanip> 25 : 26 : namespace esys::repo 27 : { 28 : 29 106 : ConfigFileImpl::ConfigFileImpl(ConfigFile *self) 30 106 : : m_self(self) 31 : { 32 106 : } 33 : 34 212 : ConfigFileImpl::~ConfigFileImpl() = default; 35 : 36 66 : Result ConfigFileImpl::open(const std::string &path) 37 : { 38 198 : if (self()->get_config() == nullptr) self()->set_config(std::make_shared<Config>()); 39 : 40 66 : std::ifstream fin(path); 41 66 : json obj; 42 : 43 66 : if (!fin.is_open()) return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE, path); 44 : 45 66 : try 46 : { 47 66 : fin >> obj; 48 : } 49 0 : catch (json::parse_error &) 50 : { 51 0 : return ESYSREPO_RESULT(ResultCode::CFGFILE_ERROR_PARSING_FILE, path); 52 0 : } 53 : 54 66 : if (!obj.contains("manifest_type")) return ESYSREPO_RESULT(ResultCode::CFGFILE_NO_MANIFEST_TYPE, path); 55 : 56 66 : manifest::Type type = manifest::Type::NOT_SET; 57 : 58 66 : std::string value = obj["manifest_type"]; 59 66 : Result result = manifest::convert(value, type); 60 66 : if (result.error()) return ESYSREPO_RESULT(result, ResultCode::CFGFILE_UNKNOWN_MANIFEST_TYPE, value); 61 : 62 66 : self()->get_config()->set_manifest_type(type); 63 : 64 66 : const bool has_url = obj.contains("manifest_url"); 65 66 : const bool has_local = obj.contains("manifest_local"); 66 66 : if (!has_url && !has_local) return ESYSREPO_RESULT(ResultCode::CFGFILE_NO_MANIFEST_URL, path); 67 237 : if (has_url) self()->get_config()->set_manifest_url(obj["manifest_url"]); 68 93 : if (has_local) self()->get_config()->set_manifest_local(obj["manifest_local"]); 69 : 70 66 : if (obj.contains("manifest_path")) 71 : { 72 264 : self()->get_config()->set_manifest_path(obj["manifest_path"]); 73 : } 74 : 75 66 : if (obj.contains("manifest_kind")) 76 : { 77 66 : manifest::Kind kind; 78 : 79 66 : std::string value = obj["manifest_kind"]; 80 66 : auto result = convert(value, kind); 81 66 : if (result.error()) return ESYSREPO_RESULT(result, ResultCode::CFGFILE_UNKNOWN_MANIFEST_KIND, value); 82 : 83 66 : self()->get_config()->set_manifest_kind(kind); 84 66 : } 85 : 86 66 : if (obj.contains("manifest_format")) 87 : { 88 66 : manifest::Format format; 89 : 90 66 : std::string value = obj["manifest_format"]; 91 66 : auto result = convert(value, format); 92 66 : if (result.error()) return ESYSREPO_RESULT(result, ResultCode::CFGFILE_UNKNOWN_MANIFEST_FORMAT, value); 93 : 94 66 : self()->get_config()->set_manifest_format(format); 95 66 : } 96 : 97 66 : if (obj.contains("revision_set")) 98 : { 99 4 : self()->get_config()->set_revision_set(obj["revision_set"]); 100 : } 101 : 102 66 : if (obj.contains("prefer_branch")) 103 : { 104 20 : self()->get_config()->set_prefer_branch(obj["prefer_branch"]); 105 : } 106 : 107 66 : if (obj.contains("parse_mode") || obj.contains("grepo_parse_mode")) 108 : { 109 66 : manifest::ParseMode mode = manifest::k_default_parse_mode; 110 66 : std::string value = obj.contains("parse_mode") ? obj["parse_mode"] : obj["grepo_parse_mode"]; 111 66 : Result mode_result = manifest::convert(value, mode); 112 66 : if (mode_result.error()) return ESYSREPO_RESULT(mode_result, value); 113 66 : self()->get_config()->set_parse_mode(mode); 114 66 : } 115 66 : return ESYSREPO_RESULT(ResultCode::OK); 116 132 : } 117 : 118 40 : Result ConfigFileImpl::write(const std::string &path) 119 : { 120 80 : if (self()->get_config() == nullptr) return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 121 : 122 40 : auto cfg = self()->get_config(); 123 : 124 40 : if (cfg == nullptr) return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 125 : 126 40 : json cfg_json; 127 40 : std::string text; 128 40 : Result result = manifest::convert(cfg->get_manifest_type(), text); 129 40 : if (result.error()) return ESYSREPO_RESULT(result); 130 : 131 80 : cfg_json["manifest_type"] = text; 132 80 : if (!cfg->get_manifest_path().empty()) cfg_json["manifest_path"] = cfg->get_manifest_path(); 133 74 : if (!cfg->get_manifest_url().empty()) cfg_json["manifest_url"] = cfg->get_manifest_url(); 134 46 : if (!cfg->get_manifest_local().empty()) cfg_json["manifest_local"] = cfg->get_manifest_local(); 135 : 136 40 : std::string kind; 137 40 : result = convert(cfg->get_manifest_kind(), kind); 138 40 : if (result.error()) return ESYSREPO_RESULT(result); 139 80 : cfg_json["manifest_kind"] = kind; 140 : 141 40 : std::string format; 142 40 : result = convert(cfg->get_manifest_format(), format); 143 40 : if (result.error()) return ESYSREPO_RESULT(result); 144 80 : cfg_json["manifest_format"] = format; 145 : 146 41 : if (!cfg->get_revision_set().empty()) cfg_json["revision_set"] = cfg->get_revision_set(); 147 46 : if (!cfg->get_prefer_branch().empty()) cfg_json["prefer_branch"] = cfg->get_prefer_branch(); 148 : 149 40 : std::string parse_mode; 150 40 : result = manifest::convert(cfg->get_parse_mode(), parse_mode); 151 40 : if (result.error()) return ESYSREPO_RESULT(result); 152 : // Persist for grepo/esysrepo workspaces (and whenever Strict was chosen) so sync uses the same mode. 153 40 : if (cfg->get_manifest_type() == manifest::Type::GOOGLE_MANIFEST 154 18 : || cfg->get_manifest_type() == manifest::Type::RAW_GOOGLE_MANIFEST 155 18 : || cfg->get_manifest_type() == manifest::Type::ESYSREPO_MANIFEST 156 40 : || cfg->get_parse_mode() != manifest::k_default_parse_mode) 157 : { 158 80 : cfg_json["parse_mode"] = parse_mode; 159 : } 160 : 161 40 : std::ofstream ofs; 162 : 163 40 : if (boost::filesystem::exists(path)) 164 4 : ofs.open(path.c_str(), std::ios_base::trunc); 165 : else 166 36 : ofs.open(path.c_str(), std::ios_base::out); 167 : 168 40 : if (!ofs.is_open()) return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE, path); 169 : 170 40 : ofs << std::setw(4); 171 : 172 40 : ofs << cfg_json; 173 : 174 40 : ofs.close(); 175 : 176 40 : return ESYSREPO_RESULT(ResultCode::OK); 177 240 : } 178 : 179 614 : ConfigFile *ConfigFileImpl::self() 180 : { 181 614 : return m_self; 182 : } 183 : 184 0 : const ConfigFile *ConfigFileImpl::self() const 185 : { 186 0 : return m_self; 187 : } 188 : 189 : } // namespace esys::repo