in include/poac/subcmd/publish.hpp [94:199]
int _main(VS&& argv) {
namespace fs = boost::filesystem;
namespace exception = core::exception;
namespace cli = io::cli;
check_arguments(argv);
check_requirements();
const bool yes = util::argparse::use(argv, "-y", "--yes");
if (!yes) {
std::cout << "Are you sure publish this package? [Y/n] ";
std::string yes_or_no;
std::cin >> yes_or_no;
std::transform(yes_or_no.begin(), yes_or_no.end(), yes_or_no.begin(), ::tolower);
if (!(yes_or_no == "yes" || yes_or_no == "y")) {
std::cout << "canceled." << std::endl;
return EXIT_FAILURE;
}
}
const bool verbose = util::argparse::use(argv, "-v", "--verbose");
// TODO: poac.ymlに,system: manualが含まれている場合はpublishできない
// TODO: ヘッダの名前衝突が起きそうな気がしました、#include <package_name/header_name.hpp>だと安心感がある
// TODO: descriptionに,TODOが含まれてたらエラーではなく,**TODO: Add description**と完全一致ならエラー
const std::string project_dir = fs::absolute(fs::current_path()).string();
cli::echo(cli::status, "Packaging ", project_dir, "...");
const std::string output_dir = compress_project(project_dir);
if (verbose) std::cout << output_dir << std::endl;
// Get token
boost::property_tree::ptree json;
std::string token;
if (const auto token_opt = io::file::path::read_file(io::file::path::poac_token_dir)) {
const std::string temp = *token_opt;
const std::string temp_path(temp, 0, temp.size()-1); // delete \n
token = temp_path;
json.put("token", token);
}
else {
throw exception::error("Could not read token");
}
{
const auto node = io::file::yaml::load_config("owners");
boost::property_tree::ptree children;
for (const auto& s : node.at("owners").as<std::vector<std::string>>()) {
boost::property_tree::ptree child;
child.put("", s);
children.push_back(std::make_pair("", child));
}
json.add_child("owners", children);
}
std::string json_s;
{
std::stringstream ss;
boost::property_tree::json_parser::write_json(ss, json, false);
json_s = ss.str();
}
// Validating
cli::echo(cli::to_status("Validating..."));
if (verbose) {
std::cout << json_s << std::endl;
}
if (io::network::post(POAC_TOKENS_VALIDATE_API, json_s) == "err") {
throw exception::error("Token verification failed.\n"
"Please check the following check lists.\n"
"1. Does token really belong to you?\n"
"2. Is the user ID described `owners` in poac.yml\n"
" the same as that of GitHub account?");
}
const auto node = io::file::yaml::load_config("name", "version");
const auto node_name = node.at("name").as<std::string>();
const auto node_version = node.at("version").as<std::string>();
if (io::network::get(POAC_PACKAGES_API + node_name + "/" + node_version + "/exists") == "true") {
throw exception::error(node_name + ": " + node_version + " already exists");
}
// Post tarball to API.
cli::echo(cli::to_status("Uploading..."));
if (!fs::exists("poac.yml")) {
throw exception::error("poac.yml does not exists");
}
if (const auto res = io::network::post_file(token, output_dir); res != "ok") {
throw exception::error(res); // TODO: Check exists packageは飛ばして,Delete fileはしてほしい
}
// Check exists package
io::network::Headers headers;
headers.emplace(io::network::http::field::cache_control, "no-cache");
const std::string target = POAC_PACKAGES_API + node_name + "/" + node_version + "/exists";
const std::string res = io::network::get(target, POAC_API_HOST, headers);
if (res != "true") {
std::cerr << io::cli::to_red("ERROR: ") << "Could not create package." << std::endl;
}
// Delete file
cli::echo(cli::to_status("Cleanup..."));
fs::remove_all(fs::path(output_dir).parent_path());
cli::echo(cli::to_status("Done."));
return EXIT_SUCCESS;
}