From d759528e52769993ddd84763cc9233158ad9c33f Mon Sep 17 00:00:00 2001 From: Nidhi Nandwani Date: Thu, 2 Jul 2026 06:54:04 +0000 Subject: [PATCH 1/3] feat(storagecontrol): add C++ delete folder recursive sample Adds a C++ code sample demonstrating hierarchical namespace recursive folder delete. Fixes: b/530058946 [Generated-by: AI] --- .../samples/storage_control_folder_samples.cc | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc b/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc index 43e8050f65f4c..f22e4cc13ec28 100644 --- a/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc +++ b/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc @@ -133,6 +133,24 @@ void RenameFolder(google::cloud::storagecontrol_v2::StorageControlClient client, (std::move(client), argv.at(0), argv.at(1), argv.at(2)); } +void DeleteFolderRecursive( + google::cloud::storagecontrol_v2::StorageControlClient client, + std::vector const& argv) { + // [START storage_control_delete_folder_recursive] + namespace storagecontrol = google::cloud::storagecontrol_v2; + [](storagecontrol::StorageControlClient client, + std::string const& bucket_name, std::string const& folder_id) { + auto const name = std::string{"projects/_/buckets/"} + bucket_name + + "/folders/" + folder_id; + auto status = client.DeleteFolderRecursive(name).get(); + if (!status.ok()) throw std::move(status).status(); + + std::cout << "Deleted folder recursively: " << folder_id << "\n"; + } + // [END storage_control_delete_folder_recursive] + (std::move(client), argv.at(0), argv.at(1)); +} + void AutoRun(std::vector const& argv) { namespace examples = google::cloud::testing_util; namespace storagecontrol = google::cloud::storagecontrol_v2; @@ -176,6 +194,33 @@ void AutoRun(std::vector const& argv) { std::cout << "\nRunning DeleteFolder() example" << std::endl; DeleteFolder(client, {bucket_name, dest_folder_id}); + + auto const recursive_parent_id = + prefix + "-recursive-" + + google::cloud::internal::Sample(generator, 16, + "abcdefghijklmnopqrstuvwxyz"); + auto const recursive_child_id = recursive_parent_id + "/child"; + + std::cout << "\nRunning CreateFolder() for recursive test parent" + << std::endl; + CreateFolder(client, {bucket_name, recursive_parent_id}); + + std::cout << "\nRunning CreateFolder() for recursive test child" << std::endl; + CreateFolder(client, {bucket_name, recursive_child_id}); + + std::cout << "\nRunning DeleteFolderRecursive() example" << std::endl; + DeleteFolderRecursive(client, {bucket_name, recursive_parent_id}); + + // Verify deletion by checking that getting the parent folder fails with + // NOT_FOUND. + try { + GetFolder(client, {bucket_name, recursive_parent_id}); + throw std::runtime_error("Parent folder was not deleted recursively"); + } catch (google::cloud::Status const& status) { + if (status.code() != google::cloud::StatusCode::kNotFound) { + throw; + } + } } } // namespace @@ -207,6 +252,8 @@ int main(int argc, char* argv[]) { // NOLINT(bugprone-exception-escape) Example example({ make_entry("create-folder", {"bucket-name", "folder-id"}, CreateFolder), make_entry("delete-folder", {"bucket-name", "folder-id"}, DeleteFolder), + make_entry("delete-folder-recursive", {"bucket-name", "folder-id"}, + DeleteFolderRecursive), make_entry("get-folder", {"bucket-name", "folder-id"}, GetFolder), make_entry("list-folders", {"bucket-name"}, ListFolders), make_entry("rename-folder", From b68189e80be6dbaf29ec1d6b499c6e7d6f3e7779 Mon Sep 17 00:00:00 2001 From: Nidhi Nandwani Date: Sat, 29 Aug 2026 10:32:27 +0000 Subject: [PATCH 2/3] fix(storage): resolve PR feedback and CI failures [Generated-by: AI] --- .../v2/samples/storage_control_folder_samples.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc b/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc index f22e4cc13ec28..d84c2acc84d1d 100644 --- a/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc +++ b/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc @@ -142,7 +142,9 @@ void DeleteFolderRecursive( std::string const& bucket_name, std::string const& folder_id) { auto const name = std::string{"projects/_/buckets/"} + bucket_name + "/folders/" + folder_id; - auto status = client.DeleteFolderRecursive(name).get(); + google::cloud::StatusOr< + google::storage::control::v2::DeleteFolderRecursiveMetadata> + status = client.DeleteFolderRecursive(name).get(); if (!status.ok()) throw std::move(status).status(); std::cout << "Deleted folder recursively: " << folder_id << "\n"; From b13e3b9d8088727bc407faa09812e2ad6ce561ff Mon Sep 17 00:00:00 2001 From: Nidhi Nandwani Date: Sat, 29 Aug 2026 11:03:12 +0000 Subject: [PATCH 3/3] fix(storage): resolve CI build failures [Generated-by: AI] --- .../v2/samples/storage_control_folder_samples.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc b/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc index d84c2acc84d1d..f41b0c60a5e89 100644 --- a/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc +++ b/google/cloud/storagecontrol/v2/samples/storage_control_folder_samples.cc @@ -30,7 +30,7 @@ void RemoveStaleFolders( google::cloud::storagecontrol_v2::StorageControlClient client, std::string const& bucket_name, std::string const& prefix, std::chrono::system_clock::time_point created_time_limit) { - std::regex re(prefix + R"re(-[a-z]{32})re"); + std::regex re(prefix + R"re(-(recursive-)?[a-z]{16,32})re"); auto const parent = std::string{"projects/_/buckets/"} + bucket_name; for (auto folder : client.ListFolders(parent)) { if (!folder) throw std::move(folder).status(); @@ -38,7 +38,7 @@ void RemoveStaleFolders( auto const create_time = google::cloud::internal::ToChronoTimePoint(folder->create_time()); if (create_time > created_time_limit) continue; - (void)client.DeleteFolder(folder->name()); + (void)client.DeleteFolderRecursive(folder->name()).get(); } }