@repokit/core 4.0.5 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +17 -4
  2. package/dist/types.d.mts +1 -1
  3. package/externals/TSCompiler.ts +1 -2
  4. package/externals/types.ts +1 -1
  5. package/package.json +29 -20
  6. package/Cargo.lock +0 -1609
  7. package/Cargo.toml +0 -23
  8. package/installation/install.sh +0 -99
  9. package/internals/argv/argv.rs +0 -132
  10. package/internals/argv/mod.rs +0 -1
  11. package/internals/caches/crawl_cache.rs +0 -126
  12. package/internals/caches/file_cache.rs +0 -104
  13. package/internals/caches/mod.rs +0 -6
  14. package/internals/caches/old_cache.rs +0 -35
  15. package/internals/caches/repokit_version_resolver.rs +0 -50
  16. package/internals/caches/settings_cache.rs +0 -73
  17. package/internals/caches/version_cache.rs +0 -142
  18. package/internals/context/cache_scope.rs +0 -71
  19. package/internals/context/file_system.rs +0 -66
  20. package/internals/context/git_scope.rs +0 -55
  21. package/internals/context/mod.rs +0 -5
  22. package/internals/context/node_scope.rs +0 -133
  23. package/internals/context/typescript_bridge.rs +0 -84
  24. package/internals/executables/internal_executable.rs +0 -15
  25. package/internals/executables/internal_executable_definition.rs +0 -40
  26. package/internals/executables/mod.rs +0 -2
  27. package/internals/executor/executor.rs +0 -88
  28. package/internals/executor/mod.rs +0 -1
  29. package/internals/file_walker/file_walker.rs +0 -69
  30. package/internals/file_walker/mod.rs +0 -2
  31. package/internals/file_walker/walker.rs +0 -114
  32. package/internals/internal_commands/help.rs +0 -174
  33. package/internals/internal_commands/internal_registry.rs +0 -34
  34. package/internals/internal_commands/list_commands.rs +0 -97
  35. package/internals/internal_commands/list_owners.rs +0 -61
  36. package/internals/internal_commands/list_themes.rs +0 -114
  37. package/internals/internal_commands/list_version.rs +0 -59
  38. package/internals/internal_commands/locate_command.rs +0 -77
  39. package/internals/internal_commands/mod.rs +0 -11
  40. package/internals/internal_commands/onboarder.rs +0 -60
  41. package/internals/internal_commands/register_command.rs +0 -99
  42. package/internals/internal_commands/search_commands.rs +0 -201
  43. package/internals/internal_commands/upgrade_repokit.rs +0 -71
  44. package/internals/internal_filesystem/file_builder.rs +0 -56
  45. package/internals/internal_filesystem/mod.rs +0 -1
  46. package/internals/logger/logger.rs +0 -163
  47. package/internals/logger/mod.rs +0 -1
  48. package/internals/main.rs +0 -23
  49. package/internals/post_processing/mod.rs +0 -1
  50. package/internals/post_processing/post_processor.rs +0 -37
  51. package/internals/repokit/command_definition.rs +0 -11
  52. package/internals/repokit/mod.rs +0 -6
  53. package/internals/repokit/repokit.rs +0 -146
  54. package/internals/repokit/repokit_command.rs +0 -101
  55. package/internals/repokit/repokit_config.rs +0 -101
  56. package/internals/repokit/repokit_construct_validator.rs +0 -11
  57. package/internals/repokit/repokit_runtime.rs +0 -43
  58. package/internals/themes/built_in_themes/mod.rs +0 -3
  59. package/internals/themes/built_in_themes/money.rs +0 -41
  60. package/internals/themes/built_in_themes/seeing_red.rs +0 -41
  61. package/internals/themes/built_in_themes/the_blues.rs +0 -41
  62. package/internals/themes/mod.rs +0 -5
  63. package/internals/themes/theme.rs +0 -108
  64. package/internals/themes/theme_colors.rs +0 -32
  65. package/internals/themes/theme_inputs.rs +0 -35
  66. package/internals/themes/theme_registry.rs +0 -123
  67. package/internals/validations/command_validations.rs +0 -127
  68. package/internals/validations/mod.rs +0 -1
@@ -1,88 +0,0 @@
1
- use std::ffi::OsStr;
2
- use std::process::Command;
3
- use std::str;
4
-
5
- pub struct Executor {}
6
-
7
- impl Executor {
8
- pub fn exec<T: AsRef<OsStr>>(
9
- command: T,
10
- composer: impl Fn(&mut Command) -> &mut Command,
11
- ) -> String {
12
- let output = composer(&mut Executor::spawn(command))
13
- .output()
14
- .expect("command failed to execute");
15
- if output.status.success() {
16
- return Executor::unwrap(&output.stdout);
17
- }
18
- Executor::unwrap(&output.stderr)
19
- }
20
-
21
- pub fn exec_with_errors<T: AsRef<OsStr>>(
22
- command: T,
23
- composer: impl Fn(&mut Command) -> &mut Command,
24
- ) -> Option<String> {
25
- let output = composer(&mut Executor::spawn(command))
26
- .output()
27
- .expect("command failed to execute");
28
- if output.status.success() {
29
- return None;
30
- }
31
- Some(Executor::unwrap(&output.stderr))
32
- }
33
-
34
- pub fn exec_with_stdout<T: AsRef<OsStr>>(
35
- command: T,
36
- composer: impl Fn(&mut Command) -> &mut Command,
37
- ) -> Option<String> {
38
- let output = composer(&mut Executor::spawn(command))
39
- .output()
40
- .expect("command failed to execute");
41
- if output.status.success() {
42
- return Some(Executor::unwrap(&output.stdout));
43
- }
44
- None
45
- }
46
-
47
- pub fn with_stdio<T: AsRef<OsStr>>(
48
- command: T,
49
- composer: impl Fn(&mut Command) -> &mut Command,
50
- ) {
51
- let mut child = composer(&mut Executor::spawn(command))
52
- .spawn()
53
- .expect("Failed to execute");
54
- child.wait().expect("failed to wait on child process");
55
- }
56
-
57
- pub fn spawn<T: AsRef<OsStr>>(program: T) -> Command {
58
- let mut command = Executor::platform_command();
59
- command.arg(program);
60
- command
61
- }
62
-
63
- fn platform_command() -> Command {
64
- if cfg!(target_os = "windows") {
65
- return Executor::windows_command();
66
- }
67
- Executor::unix_command()
68
- }
69
-
70
- fn windows_command() -> Command {
71
- let mut child_process = Command::new("cmd");
72
- child_process.arg("/C");
73
- child_process
74
- }
75
-
76
- fn unix_command() -> Command {
77
- let mut child_process = Command::new("sh");
78
- child_process.arg("-c");
79
- child_process
80
- }
81
-
82
- fn unwrap(io: &[u8]) -> String {
83
- str::from_utf8(io)
84
- .expect("Invalid output")
85
- .trim()
86
- .to_string()
87
- }
88
- }
@@ -1 +0,0 @@
1
- pub mod executor;
@@ -1,69 +0,0 @@
1
- use std::sync::{Arc, Mutex, MutexGuard};
2
-
3
- use ignore::WalkBuilder;
4
-
5
- use crate::{
6
- file_walker::walker::{TSFileVisitor, TSFileVisitorBuilder},
7
- repokit::repokit_runtime::RepoKitRuntime,
8
- };
9
-
10
- pub struct FileWalker {
11
- pub command_paths: Arc<Mutex<Vec<String>>>,
12
- }
13
-
14
- impl FileWalker {
15
- pub fn new() -> Self {
16
- let instance = FileWalker {
17
- command_paths: Arc::new(Mutex::new(Vec::new())),
18
- };
19
- instance.resolve();
20
- instance
21
- }
22
-
23
- pub fn get(&self) -> MutexGuard<'_, Vec<String>> {
24
- self.command_paths.lock().unwrap()
25
- }
26
-
27
- fn resolve(&self) {
28
- if RepoKitRuntime::with_runtime(|runtime| runtime.caches.crawl_cache.crawl_cache_enabled())
29
- {
30
- self.from_cache();
31
- } else {
32
- self.crawl_file_system();
33
- }
34
- }
35
-
36
- fn crawl_file_system(&self) {
37
- RepoKitRuntime::with_runtime(|runtime| {
38
- let mut visitor = TSFileVisitorBuilder::new(&runtime.git.root, &self.command_paths);
39
- WalkBuilder::new(&runtime.files.git_root_path)
40
- .build_parallel()
41
- .visit(&mut visitor);
42
- if let Some(head_commit) = &runtime.git.head_commit_hash {
43
- let files = self.command_paths.lock().unwrap();
44
- runtime
45
- .caches
46
- .crawl_cache
47
- .cache_crawl_results([head_commit.to_owned(), files.join("\n")].join("\n"));
48
- }
49
- });
50
- }
51
-
52
- fn from_cache(&self) {
53
- RepoKitRuntime::with_runtime(|runtime| {
54
- let mut paths_to_search = self.command_paths.lock().unwrap();
55
- if let Some(files_to_crawl) = &runtime.caches.crawl_cache.files_to_crawl {
56
- for file in files_to_crawl {
57
- paths_to_search.push(file.to_owned());
58
- }
59
- }
60
- if let Some(changed_files) = &runtime.caches.crawl_cache.changed_files {
61
- let mut paths_to_import =
62
- TSFileVisitor::traverse_list(&runtime.git.root, changed_files.to_owned());
63
- if !paths_to_import.is_empty() {
64
- paths_to_search.append(&mut paths_to_import);
65
- }
66
- }
67
- });
68
- }
69
- }
@@ -1,2 +0,0 @@
1
- pub mod file_walker;
2
- pub mod walker;
@@ -1,114 +0,0 @@
1
- use std::{
2
- fs::File,
3
- io::{BufRead, BufReader},
4
- path::Path,
5
- sync::{Arc, LazyLock, Mutex},
6
- };
7
-
8
- use ignore::{DirEntry, Error, ParallelVisitor, ParallelVisitorBuilder, WalkState};
9
- use regex::Regex;
10
- use tokio::task::JoinSet;
11
-
12
- use crate::{internal_filesystem::file_builder::FileBuilder, logger::logger::Logger};
13
-
14
- pub struct TSFileVisitor {
15
- root: String,
16
- paths: Arc<Mutex<Vec<String>>>,
17
- }
18
-
19
- static REPOKIT_IMPORT_MATCHER: LazyLock<Regex> = LazyLock::new(|| {
20
- Regex::new(r#"(require\(|from[\s*]?)['"]@repokit/core["'][\)]?[;]?$"#).unwrap()
21
- });
22
-
23
- impl ParallelVisitor for TSFileVisitor {
24
- fn visit(&mut self, entry: Result<DirEntry, Error>) -> WalkState {
25
- let root_replacer = format!("{}/", self.root);
26
- if let Ok(file_entry) = entry
27
- && file_entry.file_type().is_some_and(|ft| ft.is_file())
28
- && file_entry.file_name().to_string_lossy().ends_with(".ts")
29
- && let Some(matched_path) = TSFileVisitor::on_file(file_entry.path())
30
- {
31
- let mut vector = self.paths.lock().unwrap();
32
- vector.push(matched_path.to_string_lossy().replace(&root_replacer, ""));
33
- }
34
-
35
- WalkState::Continue
36
- }
37
- }
38
-
39
- impl TSFileVisitor {
40
- #[tokio::main]
41
- pub async fn traverse_list(root: &str, path_list: Vec<String>) -> Vec<String> {
42
- let mut handles = JoinSet::new();
43
- let root_replacer = format!("{}/", root);
44
- for path in path_list {
45
- handles.spawn(async move {
46
- if let Some(result) = TSFileVisitor::on_file(Path::new(&path)) {
47
- return Some(result.to_owned());
48
- }
49
- None
50
- });
51
- }
52
- handles
53
- .join_all()
54
- .await
55
- .iter()
56
- .filter_map(|result| {
57
- result
58
- .as_ref()
59
- .map(|path| path.to_string_lossy().replace(&root_replacer, ""))
60
- })
61
- .collect()
62
- }
63
-
64
- pub fn on_file(path: &Path) -> Option<&Path> {
65
- let mut open_comment = false;
66
- let file: File = FileBuilder::open(path, |_| Logger::open_file_error());
67
- let reader: BufReader<File> = BufReader::new(file);
68
- for line_result in reader.lines() {
69
- let unwrapped = line_result.unwrap();
70
- let line = unwrapped.trim();
71
- if !open_comment && line.starts_with("/*") {
72
- open_comment = true;
73
- continue;
74
- }
75
- if open_comment {
76
- if line.ends_with("*/") {
77
- open_comment = false;
78
- }
79
- continue;
80
- }
81
- if REPOKIT_IMPORT_MATCHER.is_match(line) {
82
- return Some(path);
83
- }
84
- if !line.is_empty()
85
- && !line.starts_with("import ")
86
- && !line.contains("require(")
87
- && !(line.starts_with("//") || line.starts_with("/*"))
88
- {
89
- break;
90
- }
91
- }
92
- None
93
- }
94
- }
95
-
96
- pub struct TSFileVisitorBuilder<'a> {
97
- pub root: &'a str,
98
- pub paths: &'a Arc<Mutex<Vec<String>>>,
99
- }
100
-
101
- impl<'a> TSFileVisitorBuilder<'a> {
102
- pub fn new(root: &'a str, paths: &'a Arc<Mutex<Vec<String>>>) -> TSFileVisitorBuilder<'a> {
103
- TSFileVisitorBuilder { paths, root }
104
- }
105
- }
106
-
107
- impl<'s> ParallelVisitorBuilder<'s> for TSFileVisitorBuilder<'s> {
108
- fn build(&mut self) -> Box<dyn ParallelVisitor + 's> {
109
- Box::new(TSFileVisitor {
110
- root: self.root.to_string(),
111
- paths: self.paths.clone(),
112
- })
113
- }
114
- }
@@ -1,174 +0,0 @@
1
- use std::collections::HashMap;
2
-
3
- use alphanumeric_sort::{sort_slice_by_str_key, sort_str_slice};
4
-
5
- use crate::{
6
- executables::{
7
- internal_executable::InternalExecutable,
8
- internal_executable_definition::InternalExecutableDefinition,
9
- },
10
- logger::logger::Logger,
11
- repokit::{
12
- command_definition::CommandDefinition, repokit_command::RepoKitCommand,
13
- repokit_config::RootCommand, repokit_runtime::RepoKitRuntime,
14
- },
15
- };
16
-
17
- pub struct Help;
18
-
19
- impl Help {
20
- pub fn list_all(
21
- internals: &HashMap<String, Box<dyn InternalExecutable>>,
22
- externals: &HashMap<String, RepoKitCommand>,
23
- ) {
24
- Help::log_internal_commands(internals);
25
- RepoKitRuntime::with_runtime(|runtime| {
26
- Help::log_root_commands(&runtime.configuration.commands);
27
- });
28
- Help::log_external_commands(externals);
29
- }
30
-
31
- pub fn log_internal_command(command: &InternalExecutableDefinition) {
32
- Logger::with_theme(|theme| {
33
- println!(
34
- "{}{} {}",
35
- Logger::indent(Some(3)),
36
- theme.command(&command.name),
37
- theme.description(&command.description),
38
- );
39
- });
40
- Help::log_args(&command.args, None);
41
- }
42
-
43
- pub fn log_root_command(command: &RootCommand) {
44
- Logger::with_theme(|theme| {
45
- println!(
46
- "{}{} {}",
47
- Logger::indent(Some(3)),
48
- theme.command(&command.name),
49
- theme.description(&command.description),
50
- );
51
- });
52
- Help::log_args(&command.args, None)
53
- }
54
-
55
- pub fn log_external_command(command: &RepoKitCommand) {
56
- Logger::with_theme(|theme| {
57
- println!(
58
- "{}{} {}",
59
- Logger::indent(Some(3)),
60
- theme.command(&command.name),
61
- theme.description(&command.description),
62
- );
63
- });
64
- println!();
65
- Help::log_external_subcommands(&command.commands, 6);
66
- if !command.owner.is_empty() {
67
- Logger::with_theme(|theme| {
68
- println!(
69
- "\n{}{}{}",
70
- Logger::indent(Some(9)),
71
- theme.description("Owned by: "),
72
- Logger::cyan(&command.owner),
73
- );
74
- });
75
- }
76
- }
77
-
78
- pub fn log_external_subcommands(map: &HashMap<String, CommandDefinition>, indentation: i32) {
79
- for (name, command) in map {
80
- Logger::with_theme(|theme| {
81
- println!(
82
- "{}{}: {}",
83
- Logger::indent(Some(indentation)),
84
- theme.sub_command(name),
85
- theme.description(&command.description),
86
- );
87
- });
88
- Help::log_args(&command.args, Some(indentation + 3));
89
- }
90
- }
91
-
92
- pub fn log_internal_commands(internals: &HashMap<String, Box<dyn InternalExecutable>>) {
93
- if internals.is_empty() {
94
- return;
95
- }
96
- let sorted_internals = Help::sort_internal(internals);
97
- Logger::space_around("Internal Commands:");
98
- for internal in sorted_internals {
99
- Help::log_internal_command(internal.get_definition());
100
- println!();
101
- }
102
- }
103
-
104
- pub fn log_root_commands(root_commands: &HashMap<String, CommandDefinition>) {
105
- if root_commands.is_empty() {
106
- return;
107
- }
108
- Logger::info("Project Level Commands:");
109
- Logger::with_surrounding_space(|| {
110
- let sorted_commands = Help::sort_root_commands(root_commands);
111
- for command in sorted_commands {
112
- Help::log_root_command(&command);
113
- }
114
- });
115
- }
116
-
117
- pub fn log_external_commands(externals: &HashMap<String, RepoKitCommand>) {
118
- if externals.is_empty() {
119
- return;
120
- }
121
- let sorted_externals = Help::sort_external(externals);
122
- Logger::info("Registered Commands:");
123
- println!();
124
- for external in sorted_externals {
125
- Help::log_external_command(external);
126
- println!();
127
- }
128
- }
129
-
130
- fn log_args(map: &Option<HashMap<String, String>>, indentation: Option<i32>) {
131
- Logger::with_theme(|theme| {
132
- if let Some(args) = map {
133
- for (name, description) in args {
134
- println!(
135
- "{}{} {}",
136
- Logger::indent(Some(indentation.unwrap_or(6))),
137
- theme.arg(name),
138
- theme.description(description)
139
- );
140
- }
141
- }
142
- });
143
- }
144
-
145
- fn sort_internal(
146
- commands: &HashMap<String, Box<dyn InternalExecutable>>,
147
- ) -> Vec<&Box<dyn InternalExecutable>> {
148
- let mut vector: Vec<&Box<dyn InternalExecutable>> = commands.values().collect();
149
- sort_slice_by_str_key(&mut vector, |x| &x.get_definition().name);
150
- vector
151
- }
152
-
153
- fn sort_external(commands: &HashMap<String, RepoKitCommand>) -> Vec<&RepoKitCommand> {
154
- let mut vector: Vec<&RepoKitCommand> = (commands).values().collect();
155
- sort_slice_by_str_key(&mut vector, |x| &x.name);
156
- vector
157
- }
158
-
159
- fn sort_root_commands(commands: &HashMap<String, CommandDefinition>) -> Vec<RootCommand> {
160
- let mut vector: Vec<&String> = (commands).keys().collect();
161
- sort_str_slice(&mut vector);
162
- vector
163
- .iter()
164
- .map(|&name| {
165
- RootCommand::from(
166
- name,
167
- commands
168
- .get(name)
169
- .expect("iteration is over known keys only"),
170
- )
171
- })
172
- .collect()
173
- }
174
- }
@@ -1,34 +0,0 @@
1
- use std::collections::HashMap;
2
-
3
- use crate::{
4
- executables::internal_executable::InternalExecutable,
5
- internal_commands::{
6
- list_commands::ListCommands, list_owners::ListOwners, list_themes::ListThemes,
7
- list_version::ListVersion, locate_command::LocateCommand, onboarder::Onboarder,
8
- register_command::RegisterCommand, search_commands::SearchCommands,
9
- upgrade_repokit::UpgradeRepoKit,
10
- },
11
- };
12
-
13
- pub struct InternalCommandRegistry;
14
-
15
- impl InternalCommandRegistry {
16
- pub fn new() -> InternalCommandRegistry {
17
- InternalCommandRegistry {}
18
- }
19
-
20
- pub fn get_all(&self) -> HashMap<String, Box<dyn InternalExecutable>> {
21
- let internals: [Box<dyn InternalExecutable>; 9] = [
22
- Box::new(Onboarder::new()),
23
- Box::new(ListCommands::new()),
24
- Box::new(SearchCommands::new()),
25
- Box::new(ListOwners::new()),
26
- Box::new(LocateCommand::new()),
27
- Box::new(RegisterCommand::new()),
28
- Box::new(UpgradeRepoKit::new()),
29
- Box::new(ListThemes::new()),
30
- Box::new(ListVersion::new()),
31
- ];
32
- HashMap::from(internals.map(|x| (x.get_definition().name.to_string(), x)))
33
- }
34
- }
@@ -1,97 +0,0 @@
1
- use std::collections::HashMap;
2
-
3
- use crate::{
4
- executables::{
5
- internal_executable::InternalExecutable,
6
- internal_executable_definition::{
7
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
8
- },
9
- },
10
- internal_commands::help::Help,
11
- logger::logger::Logger,
12
- repokit::{repokit_command::RepoKitCommand, repokit_runtime::RepoKitRuntime},
13
- validations::command_validations::CommandValidations,
14
- };
15
-
16
- pub struct ListCommands {
17
- pub definition: InternalExecutableDefinition,
18
- }
19
-
20
- static SCOPES: [&str; 4] = ["internal", "registered", "root", "<owner>"];
21
-
22
- impl ListCommands {
23
- pub fn new() -> ListCommands {
24
- ListCommands {
25
- definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
26
- name: "list",
27
- description: "List commands based on their scope of definition",
28
- args: [(
29
- "<scope>",
30
- format!(
31
- "The scope of the commands you wish to list. Specify one of {}",
32
- Logger::with_theme(|theme| theme.highlight(SCOPES.join(" | ").as_str()))
33
- )
34
- .as_str(),
35
- )],
36
- }),
37
- }
38
- }
39
-
40
- fn exit_on_invalid_scope(&self) {
41
- Logger::exit_with_info(
42
- format!(
43
- "Please specify a scope to list the commands of. Select one of {}",
44
- Logger::with_theme(|theme| theme.highlight(SCOPES.join(" | ").as_str()))
45
- )
46
- .as_str(),
47
- );
48
- }
49
- }
50
-
51
- impl InternalExecutable for ListCommands {
52
- fn run(&self, args: Vec<String>, internals: &HashMap<String, Box<dyn InternalExecutable>>) {
53
- if args.is_empty() {
54
- return self.exit_on_invalid_scope();
55
- }
56
- let query = args[0].as_str();
57
- let scope = &query.to_lowercase();
58
- if scope == SCOPES[0] {
59
- return Help::log_internal_commands(internals);
60
- }
61
- if scope == SCOPES[2] {
62
- return RepoKitRuntime::with_runtime(|runtime| {
63
- Help::log_root_commands(&runtime.configuration.commands)
64
- });
65
- }
66
- let registered_commands = CommandValidations::collect_and_validate_externals();
67
- if scope == SCOPES[1] {
68
- return Help::log_external_commands(&registered_commands);
69
- }
70
- let full_query = args.join(" ");
71
- let full_scope = &full_query.to_lowercase();
72
- Logger::info("Searching registered commands");
73
- let matches: HashMap<String, RepoKitCommand> = registered_commands
74
- .iter()
75
- .filter_map(|(name, x)| {
76
- if x.owner.to_lowercase().contains(full_scope) {
77
- return Some((name.clone(), x.clone()));
78
- }
79
- None
80
- })
81
- .collect();
82
- if matches.is_empty() {
83
- Logger::exit_with_info(
84
- format!(
85
- "I could not find any commands matching {}",
86
- Logger::with_theme(|theme| theme.highlight(&full_query))
87
- )
88
- .as_str(),
89
- );
90
- }
91
- Help::log_external_commands(&matches);
92
- }
93
-
94
- fn get_definition(&self) -> &InternalExecutableDefinition {
95
- &self.definition
96
- }
97
- }
@@ -1,61 +0,0 @@
1
- use std::collections::{HashMap, HashSet};
2
-
3
- use alphanumeric_sort::sort_str_slice;
4
-
5
- use crate::{
6
- executables::{
7
- internal_executable::InternalExecutable,
8
- internal_executable_definition::{
9
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
10
- },
11
- },
12
- logger::logger::Logger,
13
- validations::command_validations::CommandValidations,
14
- };
15
-
16
- pub struct ListOwners {
17
- pub definition: InternalExecutableDefinition,
18
- }
19
-
20
- impl ListOwners {
21
- pub fn new() -> ListOwners {
22
- ListOwners {
23
- definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
24
- name: "owners",
25
- description: "Lists all registered command owners",
26
- args: [],
27
- }),
28
- }
29
- }
30
- }
31
-
32
- impl InternalExecutable for ListOwners {
33
- fn run(&self, _: Vec<String>, _: &HashMap<String, Box<dyn InternalExecutable>>) {
34
- let registered_commands = CommandValidations::collect_and_validate_externals();
35
- Logger::info("Listing all command owners");
36
- let mut owners: HashSet<String> = HashSet::new();
37
- for (_, command) in registered_commands {
38
- if !command.owner.is_empty() {
39
- owners.insert(command.owner);
40
- }
41
- }
42
- if owners.is_empty() {
43
- return Logger::exit_with_info("No owners found");
44
- }
45
- let mut list: Vec<String> = owners.into_iter().collect();
46
- Logger::with_surrounding_space(|| {
47
- sort_str_slice(&mut list);
48
- for (index, owner) in list.iter().enumerate() {
49
- println!(
50
- "{}{}",
51
- Logger::indent(None),
52
- Logger::cyan(format!("{}. {}", index + 1, &owner).as_str()),
53
- );
54
- }
55
- });
56
- }
57
-
58
- fn get_definition(&self) -> &InternalExecutableDefinition {
59
- &self.definition
60
- }
61
- }