only upload changed templates
This commit is contained in:
@@ -158,6 +158,38 @@ static bool check_file_exists(const std::string& server_url, const std::string&
|
|||||||
output.find("\"exists\": true") != std::string::npos;
|
output.find("\"exists\": true") != std::string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get unpacked hash for a template:tag from server metadata
|
||||||
|
// Returns empty string if not found or error
|
||||||
|
static std::string get_remote_unpacked_hash(const std::string& server_url, const std::string& labeltag) {
|
||||||
|
std::string cmd = "curl -s \"" + server_url + "/meta/" + labeltag + "\"";
|
||||||
|
std::string output;
|
||||||
|
int http_code;
|
||||||
|
|
||||||
|
if (!run_curl(cmd, output, http_code) || http_code != 200) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse unpackedhash from JSON response
|
||||||
|
// Look for "unpackedhash":"<hash>" or "unpackedhash": "<hash>"
|
||||||
|
size_t pos = output.find("\"unpackedhash\"");
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the colon and opening quote
|
||||||
|
pos = output.find(':', pos);
|
||||||
|
if (pos == std::string::npos) return "";
|
||||||
|
|
||||||
|
pos = output.find('"', pos);
|
||||||
|
if (pos == std::string::npos) return "";
|
||||||
|
|
||||||
|
pos++; // skip opening quote
|
||||||
|
size_t end = output.find('"', pos);
|
||||||
|
if (end == std::string::npos) return "";
|
||||||
|
|
||||||
|
return output.substr(pos, end - pos);
|
||||||
|
}
|
||||||
|
|
||||||
// Upload a new file to the server
|
// Upload a new file to the server
|
||||||
static bool upload_file(const std::string& server_url, const std::string& token,
|
static bool upload_file(const std::string& server_url, const std::string& token,
|
||||||
const std::string& file_path, const std::vector<std::string>& labeltags,
|
const std::string& file_path, const std::vector<std::string>& labeltags,
|
||||||
@@ -275,9 +307,9 @@ static bool is_valid_template_dir(const std::filesystem::path& dir_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Publish a single template directory
|
// Publish a single template directory
|
||||||
// Returns: 0 = success, 1 = error, 2 = skipped (not a template)
|
// Returns: 0 = success, 1 = error, 2 = skipped (not a template), 3 = unchanged (already up to date)
|
||||||
static int publish_single_template(const std::string& template_dir, const std::string& server_url,
|
static int publish_single_template(const std::string& template_dir, const std::string& server_url,
|
||||||
const std::string& token, bool quiet = false) {
|
const std::string& token, bool quiet = false, bool skip_if_unchanged = false) {
|
||||||
std::filesystem::path dir_path(template_dir);
|
std::filesystem::path dir_path(template_dir);
|
||||||
std::string template_name = dir_path.filename().string();
|
std::string template_name = dir_path.filename().string();
|
||||||
|
|
||||||
@@ -305,6 +337,18 @@ static int publish_single_template(const std::string& template_dir, const std::s
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!quiet) info << " Hash: " << unpacked_hash << std::endl;
|
if (!quiet) info << " Hash: " << unpacked_hash << std::endl;
|
||||||
|
|
||||||
|
// Check if unchanged (compare with remote :latest)
|
||||||
|
if (skip_if_unchanged) {
|
||||||
|
std::string remote_hash = get_remote_unpacked_hash(server_url, template_name + ":latest");
|
||||||
|
if (!remote_hash.empty() && remote_hash == unpacked_hash) {
|
||||||
|
if (!quiet) {
|
||||||
|
info << " ✓ Unchanged (matches remote)" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
return 3; // unchanged
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!quiet) std::cout << std::endl;
|
if (!quiet) std::cout << std::endl;
|
||||||
|
|
||||||
// Create temp directory and tarball
|
// Create temp directory and tarball
|
||||||
@@ -502,13 +546,16 @@ int publish_template_handler(const CommandContext& ctx) {
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
int success_count = 0;
|
int success_count = 0;
|
||||||
|
int unchanged_count = 0;
|
||||||
int fail_count = 0;
|
int fail_count = 0;
|
||||||
std::vector<std::string> failed_templates;
|
std::vector<std::string> failed_templates;
|
||||||
|
|
||||||
for (const auto& tdir : template_dirs) {
|
for (const auto& tdir : template_dirs) {
|
||||||
int result = publish_single_template(tdir.string(), server_url, effective_token, false);
|
int result = publish_single_template(tdir.string(), server_url, effective_token, false, true);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
success_count++;
|
success_count++;
|
||||||
|
} else if (result == 3) {
|
||||||
|
unchanged_count++;
|
||||||
} else {
|
} else {
|
||||||
fail_count++;
|
fail_count++;
|
||||||
failed_templates.push_back(tdir.filename().string());
|
failed_templates.push_back(tdir.filename().string());
|
||||||
@@ -518,9 +565,14 @@ int publish_template_handler(const CommandContext& ctx) {
|
|||||||
// Summary
|
// Summary
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
maketitle("Publish Summary");
|
maketitle("Publish Summary");
|
||||||
info << "Successfully published: " << success_count << " template(s)" << std::endl;
|
if (success_count > 0) {
|
||||||
|
info << "Published: " << success_count << " template(s)" << std::endl;
|
||||||
|
}
|
||||||
|
if (unchanged_count > 0) {
|
||||||
|
info << "Unchanged: " << unchanged_count << " template(s)" << std::endl;
|
||||||
|
}
|
||||||
if (fail_count > 0) {
|
if (fail_count > 0) {
|
||||||
error << "Failed to publish: " << fail_count << " template(s)" << std::endl;
|
error << "Failed: " << fail_count << " template(s)" << std::endl;
|
||||||
for (const auto& name : failed_templates) {
|
for (const auto& name : failed_templates) {
|
||||||
error << " - " << name << std::endl;
|
error << " - " << name << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user