Skip to content

Commit 3de8a0b

Browse files
laramielcopybara-github
authored andcommitted
Rework tscli command mechanism.
This separates the parsing/invoking of the commands into subclasses of cli::Command, achieving separation of parsing and actual method, which are moved to tscli/lib PiperOrigin-RevId: 750640308 Change-Id: I446bcb2eb00db604841f7be9d597191c9419ec13
1 parent d35cae9 commit 3de8a0b

33 files changed

+1720
-824
lines changed

tensorstore/tscli/BUILD

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,92 @@
1-
load("//bazel:tensorstore.bzl", "tensorstore_cc_binary", "tensorstore_cc_library", "tensorstore_cc_test")
1+
load(
2+
"//bazel:tensorstore.bzl",
3+
"tensorstore_cc_binary",
4+
"tensorstore_cc_library",
5+
)
26

37
package(default_visibility = ["//visibility:public"])
48

59
licenses(["notice"])
610

7-
tensorstore_cc_test(
8-
name = "args_test",
9-
srcs = ["args_test.cc"],
11+
tensorstore_cc_binary(
12+
name = "tscli",
13+
srcs = [
14+
"main.cc",
15+
],
1016
deps = [
11-
":tsclilib",
12-
"@com_google_googletest//:gtest_main",
17+
":command",
18+
":tscli_commands",
19+
"//tensorstore:context",
20+
"//tensorstore/internal/metrics:collect",
21+
"//tensorstore/internal/metrics:registry",
22+
"//tensorstore/util:json_absl_flag",
23+
"//tensorstore/util:span",
24+
"@com_google_absl//absl/base:log_severity",
25+
"@com_google_absl//absl/base:no_destructor",
26+
"@com_google_absl//absl/flags:flag",
27+
"@com_google_absl//absl/flags:parse",
28+
"@com_google_absl//absl/log:globals",
29+
"@com_google_absl//absl/log:initialize",
30+
"@com_google_absl//absl/status",
1331
],
1432
)
1533

1634
tensorstore_cc_library(
17-
name = "tsclilib",
35+
name = "tscli_commands",
1836
srcs = [
19-
"args.cc",
20-
"kvstore_copy.cc",
21-
"kvstore_list.cc",
22-
"ts_print_spec.cc",
23-
"ts_print_stats.cc",
24-
"ts_search.cc",
37+
"copy_command.cc",
38+
"list_command.cc",
39+
"print_spec_command.cc",
40+
"print_stats_command.cc",
41+
"search_command.cc",
2542
],
2643
hdrs = [
27-
"args.h",
28-
"cli.h",
44+
"copy_command.h",
45+
"list_command.h",
46+
"print_spec_command.h",
47+
"print_stats_command.h",
48+
"search_command.h",
2949
],
3050
deps = [
31-
"//tensorstore",
32-
"//tensorstore:array_storage_statistics",
51+
":command",
3352
"//tensorstore:box",
3453
"//tensorstore:context",
3554
"//tensorstore:json_serialization_options_base",
36-
"//tensorstore:open",
37-
"//tensorstore:open_mode",
3855
"//tensorstore:spec",
39-
"//tensorstore/index_space:dim_expression",
40-
"//tensorstore/internal:path",
4156
"//tensorstore/internal/json_binding",
4257
"//tensorstore/internal/json_binding:bindable",
4358
"//tensorstore/kvstore",
44-
"//tensorstore/kvstore:generation",
45-
"//tensorstore/kvstore:key_range",
46-
"//tensorstore/util:division",
47-
"//tensorstore/util:executor",
48-
"//tensorstore/util:future",
49-
"//tensorstore/util:iterate",
59+
"//tensorstore/tscli/lib:kvstore_copy",
60+
"//tensorstore/tscli/lib:kvstore_list",
61+
"//tensorstore/tscli/lib:ts_print_spec",
62+
"//tensorstore/tscli/lib:ts_print_stats",
63+
"//tensorstore/tscli/lib:ts_search",
5064
"//tensorstore/util:json_absl_flag",
51-
"//tensorstore/util:quote_string",
52-
"//tensorstore/util:result",
53-
"//tensorstore/util:span",
54-
"//tensorstore/util:status",
55-
"@com_github_nlohmann_json//:json",
56-
"@com_google_absl//absl/container:flat_hash_map",
57-
"@com_google_absl//absl/container:flat_hash_set",
58-
"@com_google_absl//absl/flags:parse",
59-
"@com_google_absl//absl/functional:function_ref",
60-
"@com_google_absl//absl/log",
6165
"@com_google_absl//absl/status",
6266
"@com_google_absl//absl/strings",
6367
"@com_google_absl//absl/strings:str_format",
64-
"@com_google_absl//absl/strings:string_view",
65-
"@com_google_absl//absl/synchronization",
66-
"@com_google_re2//:re2",
6768
],
6869
)
6970

70-
tensorstore_cc_binary(
71-
name = "tscli",
71+
tensorstore_cc_library(
72+
name = "command",
7273
srcs = [
73-
"main.cc",
74+
"command.cc",
75+
"command_parser.cc",
76+
],
77+
hdrs = [
78+
"command.h",
79+
"command_parser.h",
7480
],
7581
deps = [
76-
":tsclilib",
7782
"//tensorstore:context",
78-
"//tensorstore/driver:all_drivers",
79-
"//tensorstore/internal/metrics:collect",
80-
"//tensorstore/internal/metrics:registry",
81-
"//tensorstore/kvstore:all_drivers",
82-
"//tensorstore/util:json_absl_flag",
83-
"@com_google_absl//absl/base:log_severity",
84-
"@com_google_absl//absl/flags:flag",
85-
"@com_google_absl//absl/flags:parse",
86-
"@com_google_absl//absl/log:globals",
87-
"@com_google_absl//absl/log:initialize",
83+
"//tensorstore/util:span",
84+
"//tensorstore/util:status",
85+
"@com_google_absl//absl/container:flat_hash_map",
86+
"@com_google_absl//absl/container:flat_hash_set",
87+
"@com_google_absl//absl/log:absl_check",
8888
"@com_google_absl//absl/status",
89+
"@com_google_absl//absl/strings",
90+
"@com_google_absl//absl/strings:string_view",
8991
],
9092
)

tensorstore/tscli/args.h

Lines changed: 0 additions & 65 deletions
This file was deleted.

tensorstore/tscli/command.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2025 The TensorStore Authors
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 "tensorstore/tscli/command.h"
16+
17+
#include <string_view>
18+
19+
namespace tensorstore {
20+
namespace cli {
21+
22+
Command::Command(std::string_view name, std::string_view short_description)
23+
: parser_(name, short_description) {}
24+
25+
} // namespace cli
26+
} // namespace tensorstore

tensorstore/tscli/command.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2025 The TensorStore Authors
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+
#ifndef TENSORSTORE_TSCLI_COMMAND_H_
16+
#define TENSORSTORE_TSCLI_COMMAND_H_
17+
18+
#include <algorithm>
19+
#include <string_view>
20+
#include <vector>
21+
22+
#include "absl/status/status.h"
23+
#include "tensorstore/context.h"
24+
#include "tensorstore/tscli/command_parser.h"
25+
26+
namespace tensorstore {
27+
namespace cli {
28+
29+
// Command encapsulates the option parsing and execution logic for a
30+
// single command.
31+
class Command {
32+
public:
33+
// Constructs a command with the given `name` and `usage`. The name
34+
// is what the user types on the command line, and is later
35+
// available through the `name()` method. The `usage` text is free
36+
// form English text describing the command.
37+
Command(std::string_view name, std::string_view short_description);
38+
39+
Command(const Command&) = delete;
40+
Command& operator=(const Command&) = delete;
41+
virtual ~Command() = default;
42+
43+
// Name of the command.
44+
std::string_view name() const { return parser().name(); }
45+
46+
// Returns whether the command matches the name.
47+
bool MatchesCommand(std::string_view command) const {
48+
if (name() == command) return true;
49+
return std::find(aliases_.begin(), aliases_.end(), command) !=
50+
aliases_.end();
51+
}
52+
53+
// Executes the command, returning a `Status` indicating OK or the
54+
// nature of the failure. The `Command` will log any error
55+
// returned. Derived classes must implement this.
56+
//
57+
// TODO: Add RunOptions struct to allow for more flexibility in how the
58+
// command is run.
59+
virtual absl::Status Run(Context::Spec context_spec) = 0;
60+
61+
CommandParser& parser() { return parser_; }
62+
const CommandParser& parser() const { return parser_; }
63+
64+
protected:
65+
void AddAlias(std::string_view alias) { aliases_.push_back(alias); }
66+
67+
private:
68+
CommandParser parser_;
69+
std::vector<std::string_view> aliases_;
70+
};
71+
72+
} // namespace cli
73+
} // namespace tensorstore
74+
75+
#endif // TENSORSTORE_TSCLI_COMMAND_H_

0 commit comments

Comments
 (0)