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