Line data Source code
1 : /*! 2 : * \file esys/repo/exe/cmdlist.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/exe/cmdlist.h" 20 : #include "esys/repo/exe/nested.h" 21 : #include "esys/repo/manifest/repository.h" 22 : #include "esys/repo/sharing/policy.h" 23 : 24 : #include <nlohmann/json.hpp> 25 : 26 : #include <fstream> 27 : #include <iostream> 28 : #include <sstream> 29 : 30 : namespace esys::repo::exe 31 : { 32 : 33 23 : CmdList::CmdList() 34 46 : : Cmd("List") 35 : { 36 23 : } 37 : 38 23 : CmdList::~CmdList() = default; 39 : 40 1 : void CmdList::set_fullpath(bool fullpath) 41 : { 42 1 : m_fullpath = fullpath; 43 1 : } 44 : 45 5 : bool CmdList::get_fullpath() const 46 : { 47 5 : return m_fullpath; 48 : } 49 : 50 1 : void CmdList::set_name_only(bool name_only) 51 : { 52 1 : m_name_only = name_only; 53 1 : } 54 : 55 5 : bool CmdList::get_name_only() const 56 : { 57 5 : return m_name_only; 58 : } 59 : 60 1 : void CmdList::set_path_only(bool path_only) 61 : { 62 1 : m_path_only = path_only; 63 1 : } 64 : 65 5 : bool CmdList::get_path_only() const 66 : { 67 5 : return m_path_only; 68 : } 69 : 70 4 : void CmdList::set_json(bool json) 71 : { 72 4 : m_json = json; 73 4 : if (json) 74 : { 75 : // Keep stdout clean for tools that parse ``esysrepo list --json``. 76 4 : set_print_cmd_name_by_base(false); 77 4 : set_print_result_summary(false); 78 : } 79 4 : } 80 : 81 15 : bool CmdList::get_json() const 82 : { 83 15 : return m_json; 84 : } 85 : 86 2 : void CmdList::set_json_path(const std::string &path) 87 : { 88 2 : m_json_path = path; 89 2 : } 90 : 91 5 : const std::string &CmdList::get_json_path() const 92 : { 93 5 : return m_json_path; 94 : } 95 : 96 6 : Result CmdList::impl_run() 97 : { 98 6 : if (!get_json()) 99 : { 100 4 : if (get_fullpath()) warn("Option --fullpath is not implemented yet."); 101 4 : if (get_name_only()) warn("Option --name-only is not implemented yet."); 102 4 : if (get_path_only()) warn("Option --path-only is not implemtented yet."); 103 : } 104 : 105 6 : Result result = default_handling_folder_workspace(); 106 6 : if (result.error()) return ESYSREPO_RESULT(result); 107 : 108 6 : result = open_esysrepo_folder(); 109 6 : if (result.error()) return ESYSREPO_RESULT(result); 110 : 111 6 : result = load_manifest(); 112 6 : if (result.error()) return ESYSREPO_RESULT(result); 113 : 114 6 : if (get_json()) 115 : { 116 2 : if (!get_json_path().empty()) 117 : { 118 1 : std::ofstream ofs(get_json_path(), std::ios::binary | std::ios::trunc); 119 1 : if (!ofs) 120 : { 121 0 : error("Failed to open JSON output file: " + get_json_path()); 122 0 : return ESYSREPO_RESULT(ResultCode::ERROR_OPENING_FILE); 123 : } 124 1 : print_json(ofs); 125 1 : if (!ofs) 126 : { 127 0 : error("Failed to write JSON output file: " + get_json_path()); 128 0 : return ESYSREPO_RESULT(ResultCode::GENERIC_ERROR); 129 : } 130 1 : } 131 : else 132 : { 133 1 : std::ostream &os = (get_console_os() != nullptr) ? *get_console_os() : std::cout; 134 1 : print_json(os); 135 : } 136 2 : return ESYSREPO_RESULT(ResultCode::OK); 137 : } 138 : 139 4 : std::ostringstream oss; 140 : 141 4 : oss << "path : name"; 142 : 143 14 : for (auto location : get_manifest()->get_locations()) 144 : { 145 29 : for (auto repo : location->get_repos()) 146 : { 147 69 : print_info(oss, repo); 148 23 : } 149 6 : } 150 : 151 4 : info(oss.str()); 152 : 153 4 : NestedContext nested_scratch; 154 4 : NestedContext *nested_ctx = get_nested_context() != nullptr ? get_nested_context() : &nested_scratch; 155 4 : set_nested_context(nested_ctx); 156 4 : Result nested = for_each_nested(*this, NestedMissingMode::WarnSkip, *nested_ctx, 157 5 : [this](const std::string &child_abs, std::shared_ptr<manifest::Repository>) { 158 1 : CmdList child; 159 1 : prepare_nested_cmd(*this, child, child_abs); 160 1 : child.set_fullpath(get_fullpath()); 161 1 : child.set_name_only(get_name_only()); 162 1 : child.set_path_only(get_path_only()); 163 2 : return child.run(); 164 5 : }); 165 4 : if (nested.error()) return ESYSREPO_RESULT(nested); 166 : 167 4 : return ESYSREPO_RESULT(ResultCode::OK); 168 6 : } 169 : 170 23 : void CmdList::print_info(std::ostream &os, std::shared_ptr<manifest::Repository> repo) 171 : { 172 23 : os << std::endl << repo->get_path() << " : " << repo->get_name(); 173 23 : if (repo->get_sharing().has_value()) 174 0 : os << " [sharing=" << sharing::Config::to_string(repo->get_sharing()->get_policy()) << "]"; 175 23 : if (repo->is_nested_workspace()) os << " [nested]"; 176 23 : } 177 : 178 2 : void CmdList::print_json(std::ostream &os) const 179 : { 180 2 : nlohmann::json root; 181 2 : root["meta"] = nlohmann::json::object(); 182 4 : root["meta"]["schema"] = JSON_SCHEMA; 183 2 : root["meta"]["schema_version"] = JSON_SCHEMA_VERSION; 184 : 185 2 : const auto &workspace = get_workspace_path(); 186 4 : root["workspace_root"] = workspace.empty() ? "." : workspace; 187 : 188 2 : nlohmann::json projects = nlohmann::json::array(); 189 4 : if (get_manifest() != nullptr) 190 : { 191 6 : for (auto location : get_manifest()->get_locations()) 192 : { 193 6 : for (auto repo : location->get_repos()) 194 : { 195 4 : nlohmann::json item; 196 8 : item["path"] = repo->get_path(); 197 8 : item["name"] = repo->get_name(); 198 4 : if (repo->get_sharing().has_value()) 199 0 : item["sharing"] = sharing::Config::to_string(repo->get_sharing()->get_policy()); 200 4 : if (repo->is_nested_workspace()) item["nested"] = true; 201 4 : projects.push_back(item); 202 8 : } 203 2 : } 204 : } 205 2 : root["projects"] = projects; 206 : 207 4 : os << root.dump(2) << std::endl; 208 2 : } 209 : 210 : } // namespace esys::repo::exe