@repokit/core 4.0.6 → 5.0.1
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.
- package/README.md +17 -4
- package/dist/types.d.mts +1 -1
- package/externals/TSCompiler.ts +1 -2
- package/externals/types.ts +1 -1
- package/package.json +29 -19
- package/Cargo.lock +0 -1609
- package/Cargo.toml +0 -23
- package/installation/install.sh +0 -99
- package/internals/argv/argv.rs +0 -132
- package/internals/argv/mod.rs +0 -1
- package/internals/caches/crawl_cache.rs +0 -126
- package/internals/caches/file_cache.rs +0 -104
- package/internals/caches/mod.rs +0 -6
- package/internals/caches/old_cache.rs +0 -35
- package/internals/caches/repokit_version_resolver.rs +0 -50
- package/internals/caches/settings_cache.rs +0 -73
- package/internals/caches/version_cache.rs +0 -142
- package/internals/context/cache_scope.rs +0 -71
- package/internals/context/file_system.rs +0 -66
- package/internals/context/git_scope.rs +0 -55
- package/internals/context/mod.rs +0 -5
- package/internals/context/node_scope.rs +0 -133
- package/internals/context/typescript_bridge.rs +0 -84
- package/internals/executables/internal_executable.rs +0 -15
- package/internals/executables/internal_executable_definition.rs +0 -40
- package/internals/executables/mod.rs +0 -2
- package/internals/executor/executor.rs +0 -88
- package/internals/executor/mod.rs +0 -1
- package/internals/file_walker/file_walker.rs +0 -69
- package/internals/file_walker/mod.rs +0 -2
- package/internals/file_walker/walker.rs +0 -114
- package/internals/internal_commands/help.rs +0 -174
- package/internals/internal_commands/internal_registry.rs +0 -34
- package/internals/internal_commands/list_commands.rs +0 -97
- package/internals/internal_commands/list_owners.rs +0 -61
- package/internals/internal_commands/list_themes.rs +0 -114
- package/internals/internal_commands/list_version.rs +0 -59
- package/internals/internal_commands/locate_command.rs +0 -77
- package/internals/internal_commands/mod.rs +0 -11
- package/internals/internal_commands/onboarder.rs +0 -60
- package/internals/internal_commands/register_command.rs +0 -99
- package/internals/internal_commands/search_commands.rs +0 -201
- package/internals/internal_commands/upgrade_repokit.rs +0 -71
- package/internals/internal_filesystem/file_builder.rs +0 -56
- package/internals/internal_filesystem/mod.rs +0 -1
- package/internals/logger/logger.rs +0 -163
- package/internals/logger/mod.rs +0 -1
- package/internals/main.rs +0 -23
- package/internals/post_processing/mod.rs +0 -1
- package/internals/post_processing/post_processor.rs +0 -37
- package/internals/repokit/command_definition.rs +0 -11
- package/internals/repokit/mod.rs +0 -6
- package/internals/repokit/repokit.rs +0 -146
- package/internals/repokit/repokit_command.rs +0 -101
- package/internals/repokit/repokit_config.rs +0 -101
- package/internals/repokit/repokit_construct_validator.rs +0 -11
- package/internals/repokit/repokit_runtime.rs +0 -43
- package/internals/themes/built_in_themes/mod.rs +0 -3
- package/internals/themes/built_in_themes/money.rs +0 -41
- package/internals/themes/built_in_themes/seeing_red.rs +0 -41
- package/internals/themes/built_in_themes/the_blues.rs +0 -41
- package/internals/themes/mod.rs +0 -5
- package/internals/themes/theme.rs +0 -108
- package/internals/themes/theme_colors.rs +0 -32
- package/internals/themes/theme_inputs.rs +0 -35
- package/internals/themes/theme_registry.rs +0 -123
- package/internals/validations/command_validations.rs +0 -127
- 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,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(®istered_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
|
-
}
|