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 99 : ConfigFileImpl::ConfigFileImpl(ConfigFile *self) 30 99 : : m_self(self) 31 : { 32 99 : } 33 : 34 198 : ConfigFileImpl::~ConfigFileImpl() = default; 35 : 36 61 : Result ConfigFileImpl::open(const std::string &path) 37 : { 38 183 : if (self()->get_config() == nullptr) self()->set_config(std::make_shared<Config>()); 39 : 40 61 : std::ifstream fin(path); 41 61 : json obj; 42 : 43 61 : if (!fin.is_open()) return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE, path); 44 : 45 61 : try 46 : { 47 61 : 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 61 : if (!obj.contains("manifest_type")) return ESYSREPO_RESULT(ResultCode::CFGFILE_NO_MANIFEST_TYPE, path); 55 : 56 61 : manifest::Type type = manifest::Type::NOT_SET; 57 : 58 61 : std::string value = obj["manifest_type"]; 59 61 : Result result = manifest::convert(value, type); 60 61 : if (result.error()) return ESYSREPO_RESULT(result, ResultCode::CFGFILE_UNKNOWN_MANIFEST_TYPE, value); 61 : 62 61 : self()->get_config()->set_manifest_type(type); 63 : 64 61 : const bool has_url = obj.contains("manifest_url"); 65 61 : const bool has_local = obj.contains("manifest_local"); 66 61 : if (!has_url && !has_local) return ESYSREPO_RESULT(ResultCode::CFGFILE_NO_MANIFEST_URL, path); 67 232 : if (has_url) self()->get_config()->set_manifest_url(obj["manifest_url"]); 68 73 : if (has_local) self()->get_config()->set_manifest_local(obj["manifest_local"]); 69 : 70 61 : if (obj.contains("manifest_path")) 71 : { 72 244 : self()->get_config()->set_manifest_path(obj["manifest_path"]); 73 : } 74 : 75 61 : if (obj.contains("manifest_kind")) 76 : { 77 61 : manifest::Kind kind; 78 : 79 61 : std::string value = obj["manifest_kind"]; 80 61 : auto result = convert(value, kind); 81 61 : if (result.error()) return ESYSREPO_RESULT(result, ResultCode::CFGFILE_UNKNOWN_MANIFEST_KIND, value); 82 : 83 61 : self()->get_config()->set_manifest_kind(kind); 84 61 : } 85 : 86 61 : if (obj.contains("manifest_format")) 87 : { 88 61 : manifest::Format format; 89 : 90 61 : std::string value = obj["manifest_format"]; 91 61 : auto result = convert(value, format); 92 61 : if (result.error()) return ESYSREPO_RESULT(result, ResultCode::CFGFILE_UNKNOWN_MANIFEST_FORMAT, value); 93 : 94 61 : self()->get_config()->set_manifest_format(format); 95 61 : } 96 : 97 61 : if (obj.contains("revision_set")) 98 : { 99 4 : self()->get_config()->set_revision_set(obj["revision_set"]); 100 : } 101 : 102 61 : if (obj.contains("prefer_branch")) 103 : { 104 20 : self()->get_config()->set_prefer_branch(obj["prefer_branch"]); 105 : } 106 : 107 61 : if (obj.contains("parse_mode") || obj.contains("grepo_parse_mode")) 108 : { 109 61 : manifest::ParseMode mode = manifest::k_default_parse_mode; 110 61 : std::string value = obj.contains("parse_mode") ? obj["parse_mode"] : obj["grepo_parse_mode"]; 111 61 : Result mode_result = manifest::convert(value, mode); 112 61 : if (mode_result.error()) return ESYSREPO_RESULT(mode_result, value); 113 61 : self()->get_config()->set_parse_mode(mode); 114 61 : } 115 61 : return ESYSREPO_RESULT(ResultCode::OK); 116 122 : } 117 : 118 38 : Result ConfigFileImpl::write(const std::string &path) 119 : { 120 76 : if (self()->get_config() == nullptr) return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 121 : 122 38 : auto cfg = self()->get_config(); 123 : 124 38 : if (cfg == nullptr) return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 125 : 126 38 : json cfg_json; 127 38 : std::string text; 128 38 : Result result = manifest::convert(cfg->get_manifest_type(), text); 129 38 : if (result.error()) return ESYSREPO_RESULT(result); 130 : 131 76 : cfg_json["manifest_type"] = text; 132 76 : if (!cfg->get_manifest_path().empty()) cfg_json["manifest_path"] = cfg->get_manifest_path(); 133 72 : if (!cfg->get_manifest_url().empty()) cfg_json["manifest_url"] = cfg->get_manifest_url(); 134 42 : if (!cfg->get_manifest_local().empty()) cfg_json["manifest_local"] = cfg->get_manifest_local(); 135 : 136 38 : std::string kind; 137 38 : result = convert(cfg->get_manifest_kind(), kind); 138 38 : if (result.error()) return ESYSREPO_RESULT(result); 139 76 : cfg_json["manifest_kind"] = kind; 140 : 141 38 : std::string format; 142 38 : result = convert(cfg->get_manifest_format(), format); 143 38 : if (result.error()) return ESYSREPO_RESULT(result); 144 76 : cfg_json["manifest_format"] = format; 145 : 146 39 : if (!cfg->get_revision_set().empty()) cfg_json["revision_set"] = cfg->get_revision_set(); 147 44 : if (!cfg->get_prefer_branch().empty()) cfg_json["prefer_branch"] = cfg->get_prefer_branch(); 148 : 149 38 : std::string parse_mode; 150 38 : result = manifest::convert(cfg->get_parse_mode(), parse_mode); 151 38 : 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 38 : if (cfg->get_manifest_type() == manifest::Type::GOOGLE_MANIFEST 154 16 : || cfg->get_manifest_type() == manifest::Type::RAW_GOOGLE_MANIFEST 155 16 : || cfg->get_manifest_type() == manifest::Type::ESYSREPO_MANIFEST 156 38 : || cfg->get_parse_mode() != manifest::k_default_parse_mode) 157 : { 158 76 : cfg_json["parse_mode"] = parse_mode; 159 : } 160 : 161 38 : std::ofstream ofs; 162 : 163 38 : if (boost::filesystem::exists(path)) 164 4 : ofs.open(path.c_str(), std::ios_base::trunc); 165 : else 166 34 : ofs.open(path.c_str(), std::ios_base::out); 167 : 168 38 : if (!ofs.is_open()) return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE, path); 169 : 170 38 : ofs << std::setw(4); 171 : 172 38 : ofs << cfg_json; 173 : 174 38 : ofs.close(); 175 : 176 38 : return ESYSREPO_RESULT(ResultCode::OK); 177 228 : } 178 : 179 570 : ConfigFile *ConfigFileImpl::self() 180 : { 181 570 : return m_self; 182 : } 183 : 184 0 : const ConfigFile *ConfigFileImpl::self() const 185 : { 186 0 : return m_self; 187 : } 188 : 189 : } // namespace esys::repo