Skip to content

Commit 165efbe

Browse files
authored
feat: new library to refactor common example code (#3630)
1 parent 8197df7 commit 165efbe

File tree

9 files changed

+454
-80
lines changed

9 files changed

+454
-80
lines changed

google/cloud/bigtable/examples/bigtable_examples_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@ namespace cloud {
2828
namespace bigtable {
2929
namespace examples {
3030

31+
// TODO(#3624) - refactor this class to -common
3132
class Usage : public std::runtime_error {
3233
public:
3334
explicit Usage(std::string const& msg) : std::runtime_error(msg) {}
3435
};
3536

37+
// TODO(#3624) - refactor these types to -common
3638
using CommandType = std::function<void(std::vector<std::string> const& argv)>;
3739
using Commands = std::map<std::string, CommandType>;
3840

41+
// TODO(#3624) - refactor this class to -common
3942
class Example {
4043
public:
4144
explicit Example(std::map<std::string, CommandType> commands);

google/cloud/storage/examples/BUILD

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,56 @@ package(default_visibility = ["//visibility:public"])
1616

1717
licenses(["notice"]) # Apache 2.0
1818

19-
cc_binary(
20-
name = "storage_bucket_samples",
21-
srcs = ["storage_bucket_samples.cc"],
22-
deps = ["//google/cloud/storage:storage_client"],
23-
)
19+
load(":storage_examples_common.bzl", "storage_examples_common_hdrs", "storage_examples_common_srcs")
2420

25-
cc_binary(
26-
name = "storage_bucket_acl_samples",
27-
srcs = ["storage_bucket_acl_samples.cc"],
28-
deps = ["//google/cloud/storage:storage_client"],
21+
cc_library(
22+
name = "storage_examples_common",
23+
srcs = storage_examples_common_srcs,
24+
hdrs = storage_examples_common_hdrs,
25+
deps = [
26+
"//google/cloud/storage:storage_client",
27+
"@com_github_googleapis_google_cloud_cpp_common//google/cloud:google_cloud_cpp_common",
28+
],
2929
)
3030

31-
cc_binary(
32-
name = "storage_bucket_iam_samples",
33-
srcs = ["storage_bucket_iam_samples.cc"],
34-
deps = ["//google/cloud/storage:storage_client"],
35-
)
31+
load(":storage_examples_unit_tests.bzl", "storage_examples_unit_tests")
3632

37-
cc_binary(
38-
name = "storage_default_object_acl_samples",
39-
srcs = ["storage_default_object_acl_samples.cc"],
40-
deps = ["//google/cloud/storage:storage_client"],
41-
)
33+
[cc_test(
34+
name = test.replace("/", "_").replace(".cc", ""),
35+
srcs = [test],
36+
deps = [
37+
":storage_examples_common",
38+
"//google/cloud/storage:storage_client",
39+
"@com_github_googleapis_google_cloud_cpp_common//google/cloud:google_cloud_cpp_common",
40+
"@com_github_googleapis_google_cloud_cpp_common//google/cloud/testing_util:google_cloud_cpp_testing",
41+
"@com_google_googletest//:gtest",
42+
],
43+
) for test in storage_examples_unit_tests]
4244

43-
cc_binary(
44-
name = "storage_object_samples",
45-
srcs = ["storage_object_samples.cc"],
46-
deps = ["//google/cloud/storage:storage_client"],
47-
)
45+
load(":storage_examples.bzl", "storage_examples")
4846

49-
cc_binary(
50-
name = "storage_object_acl_samples",
51-
srcs = ["storage_object_acl_samples.cc"],
52-
deps = ["//google/cloud/storage:storage_client"],
53-
)
47+
# TODO(#3523) - add auto-runnable examples to this list until all
48+
# examples are auto-runnable and then cleanup this code.
49+
auto_runnable_storage_examples = []
5450

55-
cc_binary(
56-
name = "storage_notification_samples",
57-
srcs = ["storage_notification_samples.cc"],
58-
deps = ["//google/cloud/storage:storage_client"],
59-
)
51+
auto_runnable_tags = [
52+
"storage-integration-tests",
53+
"integration-tests",
54+
]
6055

61-
cc_binary(
62-
name = "storage_quickstart",
63-
srcs = ["storage_quickstart.cc"],
64-
deps = ["//google/cloud/storage:storage_client"],
65-
)
56+
integration_test_tags = [
57+
"integration-tests",
58+
]
6659

67-
cc_binary(
68-
name = "storage_service_account_samples",
69-
srcs = ["storage_service_account_samples.cc"],
70-
deps = ["//google/cloud/storage:storage_client"],
71-
)
60+
[cc_test(
61+
name = test.replace("/", "_").replace(".cc", ""),
62+
srcs = [test],
63+
tags = auto_runnable_tags if test in auto_runnable_storage_examples else integration_test_tags,
64+
deps = [
65+
":storage_examples_common",
66+
"//google/cloud/storage:storage_client",
67+
"@com_github_googleapis_google_cloud_cpp_common//google/cloud:google_cloud_cpp_common",
68+
"@com_github_googleapis_google_cloud_cpp_common//google/cloud/testing_util:google_cloud_cpp_testing",
69+
"@com_google_googletest//:gtest",
70+
],
71+
) for test in storage_examples]

google/cloud/storage/examples/CMakeLists.txt

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,73 @@
1414
# limitations under the License.
1515
# ~~~
1616

17-
# While it is tempting create these targets using a function or a loop, we want
18-
# to keep this particular file as simple as possible, as it is intended to be
19-
# part of the examples.
17+
add_library(storage_examples_common storage_examples_common.cc
18+
storage_examples_common.h)
19+
target_link_libraries(storage_examples_common storage_client
20+
google_cloud_cpp_common)
21+
22+
set(storage_examples
23+
# cmake-format: sort
24+
storage_bucket_acl_samples.cc
25+
storage_bucket_iam_samples.cc
26+
storage_bucket_samples.cc
27+
storage_default_object_acl_samples.cc
28+
storage_notification_samples.cc
29+
storage_object_acl_samples.cc
30+
storage_object_samples.cc
31+
storage_quickstart.cc
32+
storage_service_account_samples.cc)
2033

21-
add_executable(storage_bucket_samples storage_bucket_samples.cc)
22-
target_link_libraries(storage_bucket_samples storage_client
23-
storage_common_options)
34+
set(storage_examples_unit_tests # cmake-format: sort
35+
storage_examples_common_test.cc)
2436

25-
add_executable(storage_bucket_acl_samples storage_bucket_acl_samples.cc)
26-
target_link_libraries(storage_bucket_acl_samples storage_client
27-
storage_common_options)
37+
include(CreateBazelConfig)
38+
export_list_to_bazel("storage_examples.bzl" "storage_examples")
39+
export_list_to_bazel("storage_examples_unit_tests.bzl"
40+
"storage_examples_unit_tests")
41+
create_bazel_config(storage_examples_common)
2842

29-
add_executable(storage_bucket_iam_samples storage_bucket_iam_samples.cc)
30-
target_link_libraries(storage_bucket_iam_samples storage_client
31-
storage_common_options)
43+
# While it is tempting create these targets using a function or a loop, we want
44+
# to keep this particular file as simple as possible, as it is intended to be
45+
# part of the examples.
3246

3347
if (BUILD_TESTING)
48+
find_package(google_cloud_cpp_testing CONFIG REQUIRED)
49+
3450
add_executable(storage_client_mock_samples storage_client_mock_samples.cc)
3551
target_link_libraries(
3652
storage_client_mock_samples storage_client storage_common_options
3753
GTest::gmock_main GTest::gmock GTest::gtest)
38-
endif ()
39-
40-
add_executable(storage_default_object_acl_samples
41-
storage_default_object_acl_samples.cc)
42-
target_link_libraries(storage_default_object_acl_samples storage_client
43-
storage_common_options)
44-
45-
add_executable(storage_object_samples storage_object_samples.cc)
46-
target_link_libraries(storage_object_samples storage_client
47-
storage_common_options)
4854

49-
add_executable(storage_object_acl_samples storage_object_acl_samples.cc)
50-
target_link_libraries(storage_object_acl_samples storage_client
51-
storage_common_options)
52-
53-
add_executable(storage_notification_samples storage_notification_samples.cc)
54-
target_link_libraries(storage_notification_samples storage_client
55-
storage_common_options)
55+
foreach (fname ${storage_examples_unit_tests})
56+
string(REPLACE "/" "_" target ${fname})
57+
string(REPLACE ".cc" "" target ${target})
58+
add_executable(${target} ${fname})
59+
target_link_libraries(
60+
${target}
61+
PRIVATE storage_examples_common
62+
storage_client
63+
google_cloud_cpp_testing
64+
google_cloud_cpp_common
65+
GTest::gmock_main
66+
GTest::gmock
67+
GTest::gtest
68+
storage_common_options)
69+
add_test(NAME ${target} COMMAND ${target})
70+
endforeach ()
71+
endif ()
5672

57-
add_executable(storage_quickstart storage_quickstart.cc)
58-
target_link_libraries(storage_quickstart storage_client storage_common_options
59-
google_cloud_cpp_common_options)
73+
foreach (fname ${storage_examples})
74+
string(REPLACE "/" "_" target ${fname})
75+
string(REPLACE ".cc" "" target ${target})
76+
add_executable(${target} ${fname})
77+
target_link_libraries(
78+
${target} PRIVATE storage_examples_common storage_client
79+
google_cloud_cpp_common storage_common_options)
80+
add_test(NAME ${target} COMMAND ${target})
81+
set_tests_properties(${target} PROPERTIES LABELS "integration-tests")
82+
endforeach ()
6083

61-
add_executable(storage_service_account_samples
62-
storage_service_account_samples.cc)
63-
target_link_libraries(storage_service_account_samples storage_client
64-
storage_common_options)
84+
# TODO(#3524) - add here the examples driven by CTest and/or Bazel foreach
85+
# (target ) set_tests_properties( ${target} PROPERTIES LABELS "integration-
86+
# tests;storage-integration-tests") endforeach ()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed
16+
17+
"""Automatically generated unit tests list - DO NOT EDIT."""
18+
19+
storage_examples = [
20+
"storage_bucket_acl_samples.cc",
21+
"storage_bucket_iam_samples.cc",
22+
"storage_bucket_samples.cc",
23+
"storage_default_object_acl_samples.cc",
24+
"storage_notification_samples.cc",
25+
"storage_object_acl_samples.cc",
26+
"storage_object_samples.cc",
27+
"storage_quickstart.cc",
28+
"storage_service_account_samples.cc",
29+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# DO NOT EDIT -- GENERATED BY CMake -- Change the CMakeLists.txt file if needed
16+
17+
"""Automatically generated source lists for storage_examples_common - DO NOT EDIT."""
18+
19+
storage_examples_common_hdrs = [
20+
"storage_examples_common.h",
21+
]
22+
23+
storage_examples_common_srcs = [
24+
"storage_examples_common.cc",
25+
]
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/storage/examples/storage_examples_common.h"
16+
#include "google/cloud/internal/getenv.h"
17+
18+
namespace google {
19+
namespace cloud {
20+
namespace storage {
21+
namespace examples {
22+
23+
Example::Example(std::map<std::string, CommandType> commands)
24+
: commands_(std::move(commands)) {
25+
// Force each command to generate its Usage string, so we can provide a good
26+
// usage string for the whole program.
27+
for (auto const& kv : commands_) {
28+
if (kv.first == "auto") continue;
29+
try {
30+
kv.second({});
31+
} catch (Usage const& u) {
32+
full_usage_ += " ";
33+
full_usage_ += u.what();
34+
full_usage_ += "\n";
35+
}
36+
}
37+
}
38+
39+
int Example::Run(int argc, char const* const argv[]) try {
40+
bool auto_run =
41+
google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_AUTO_RUN_EXAMPLES")
42+
.value_or("") == "yes";
43+
if (argc == 1 && auto_run) {
44+
auto entry = commands_.find("auto");
45+
if (entry == commands_.end()) {
46+
PrintUsage(argv[0], "Requested auto run but there is no 'auto' command");
47+
return 1;
48+
}
49+
entry->second({});
50+
return 0;
51+
}
52+
53+
if (argc < 2) {
54+
PrintUsage(argv[0], "Missing command");
55+
return 1;
56+
}
57+
58+
std::string const command_name = argv[1];
59+
auto command = commands_.find(command_name);
60+
if (commands_.end() == command) {
61+
PrintUsage(argv[0], "Unknown command: " + command_name);
62+
return 1;
63+
}
64+
65+
command->second({argv + 2, argv + argc});
66+
67+
return 0;
68+
} catch (Usage const& u) {
69+
PrintUsage(argv[0], u.what());
70+
return 1;
71+
} catch (std::exception const& ex) {
72+
std::cerr << "Standard C++ exception raised: " << ex.what() << "\n";
73+
return 1;
74+
}
75+
76+
void Example::PrintUsage(std::string const& cmd, std::string const& msg) {
77+
auto last_slash = cmd.find_last_of('/');
78+
auto program = cmd.substr(last_slash + 1);
79+
std::cerr << msg << "\nUsage: " << program << " <command> [arguments]\n\n"
80+
<< "Commands:\n"
81+
<< full_usage_ << "\n";
82+
}
83+
84+
} // namespace examples
85+
} // namespace storage
86+
} // namespace cloud
87+
} // namespace google

0 commit comments

Comments
 (0)