@repokit/core 4.0.6 → 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.
- 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,142 +0,0 @@
|
|
|
1
|
-
use std::{
|
|
2
|
-
fs::File,
|
|
3
|
-
io::{BufRead, BufReader},
|
|
4
|
-
path::PathBuf,
|
|
5
|
-
sync::LazyLock,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
use futures::{executor::block_on, join};
|
|
9
|
-
use regex::Regex;
|
|
10
|
-
|
|
11
|
-
use crate::{
|
|
12
|
-
caches::{
|
|
13
|
-
file_cache::FileCache, old_cache::OldCache,
|
|
14
|
-
repokit_version_resolver::RepoKitVersionResolver,
|
|
15
|
-
},
|
|
16
|
-
context::file_system::FileSystem,
|
|
17
|
-
logger::logger::Logger,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
#[derive(Clone)]
|
|
21
|
-
pub struct VersionCache {
|
|
22
|
-
pub runtime_version: String,
|
|
23
|
-
pub installed_version: String,
|
|
24
|
-
pub old_cache_path_version: String,
|
|
25
|
-
pub cache_directory: Option<PathBuf>,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub static VERSION_REGEX: LazyLock<Regex> =
|
|
29
|
-
LazyLock::new(|| Regex::new(r#"\d*\.\d*.\d*"#).unwrap());
|
|
30
|
-
|
|
31
|
-
impl VersionCache {
|
|
32
|
-
pub fn new(cache_directory: &Option<PathBuf>) -> Self {
|
|
33
|
-
VersionCache {
|
|
34
|
-
runtime_version: "".to_string(),
|
|
35
|
-
installed_version: "".to_string(),
|
|
36
|
-
old_cache_path_version: "".to_string(),
|
|
37
|
-
cache_directory: cache_directory.clone(),
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub fn refresh_installed_version(&self, files: &FileSystem) -> Option<String> {
|
|
42
|
-
let installed_version = block_on(self.installed_repokit_version(files));
|
|
43
|
-
if let Some(version) = &installed_version
|
|
44
|
-
&& *version != self.installed_version
|
|
45
|
-
{
|
|
46
|
-
return Some(version.to_string());
|
|
47
|
-
}
|
|
48
|
-
None
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
pub async fn initialize(&mut self, files: &FileSystem) {
|
|
52
|
-
let (runtime_result, install_result, old_cache_path_version) = join!(
|
|
53
|
-
self.runtime_version(),
|
|
54
|
-
self.installed_repokit_version(files),
|
|
55
|
-
self.get_old_cache_path_version(),
|
|
56
|
-
);
|
|
57
|
-
if let Some(installed_version) = install_result {
|
|
58
|
-
self.installed_version = installed_version;
|
|
59
|
-
}
|
|
60
|
-
if let Some(runtime_version) = runtime_result {
|
|
61
|
-
self.runtime_version = runtime_version;
|
|
62
|
-
}
|
|
63
|
-
if let Some(old_cache_version) = old_cache_path_version {
|
|
64
|
-
self.old_cache_path_version = old_cache_version;
|
|
65
|
-
}
|
|
66
|
-
if (self.installed_version != self.runtime_version)
|
|
67
|
-
|| (self.installed_version != self.old_cache_path_version
|
|
68
|
-
&& !self.old_cache_path_version.is_empty())
|
|
69
|
-
&& VERSION_REGEX.is_match(&self.installed_version)
|
|
70
|
-
{
|
|
71
|
-
self.hop_to_installed_version(files);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
fn hop_to_installed_version(&self, files: &FileSystem) {
|
|
76
|
-
Logger::info(
|
|
77
|
-
format!(
|
|
78
|
-
"Switching to version {}",
|
|
79
|
-
Logger::with_theme(|theme| theme.highlight(&self.installed_version))
|
|
80
|
-
)
|
|
81
|
-
.as_str(),
|
|
82
|
-
);
|
|
83
|
-
RepoKitVersionResolver::hop_to_installed_version(files);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async fn runtime_version(&self) -> Option<String> {
|
|
87
|
-
if let Some((mut lines, _)) = self.read() {
|
|
88
|
-
let last_known_version = self.unwrap_line(lines.nth(0), "");
|
|
89
|
-
if VERSION_REGEX.is_match(&last_known_version) {
|
|
90
|
-
return Some(last_known_version);
|
|
91
|
-
}
|
|
92
|
-
return None;
|
|
93
|
-
}
|
|
94
|
-
None
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async fn installed_repokit_version(&self, files: &FileSystem) -> Option<String> {
|
|
98
|
-
let package_path = FileSystem::join_with(&files.package_directory, "package.json");
|
|
99
|
-
if !package_path.exists() || !package_path.is_file() {
|
|
100
|
-
return None;
|
|
101
|
-
}
|
|
102
|
-
let file = File::open(package_path);
|
|
103
|
-
if file.is_err() {
|
|
104
|
-
return None;
|
|
105
|
-
}
|
|
106
|
-
let lines = BufReader::new(file.unwrap()).lines();
|
|
107
|
-
let version_matcher = Regex::new(r#""([^"]*)""#).unwrap();
|
|
108
|
-
for line in lines.map_while(Result::ok) {
|
|
109
|
-
if line.contains("\"version\": ") {
|
|
110
|
-
let captures: Vec<String> = version_matcher
|
|
111
|
-
.captures_iter(&line)
|
|
112
|
-
.filter_map(|item| {
|
|
113
|
-
item.get(1)
|
|
114
|
-
.map(|match_text| match_text.as_str().to_string())
|
|
115
|
-
})
|
|
116
|
-
.collect();
|
|
117
|
-
if let Some(version) = captures.get(1)
|
|
118
|
-
&& VERSION_REGEX.is_match(version)
|
|
119
|
-
{
|
|
120
|
-
return Some(version.to_string());
|
|
121
|
-
}
|
|
122
|
-
return None;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
None
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async fn get_old_cache_path_version(&self) -> Option<String> {
|
|
129
|
-
let old_cache = OldCache::new();
|
|
130
|
-
old_cache.get_version()
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
impl FileCache for VersionCache {
|
|
135
|
-
fn cache_file(&self) -> &str {
|
|
136
|
-
"../.version"
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
fn cache_directory(&self) -> &Option<PathBuf> {
|
|
140
|
-
&self.cache_directory
|
|
141
|
-
}
|
|
142
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
use futures::{executor::block_on, join};
|
|
2
|
-
use std::{
|
|
3
|
-
env::home_dir,
|
|
4
|
-
fs::create_dir_all,
|
|
5
|
-
path::PathBuf,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
use crate::{
|
|
9
|
-
caches::{
|
|
10
|
-
crawl_cache::CrawlCache, file_cache::FileCache,
|
|
11
|
-
settings_cache::SettingsCache, version_cache::VersionCache,
|
|
12
|
-
},
|
|
13
|
-
context::{file_system::FileSystem, git_scope::GitScope},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
#[derive(Clone)]
|
|
17
|
-
pub struct CacheScope {
|
|
18
|
-
pub crawl_cache: CrawlCache,
|
|
19
|
-
pub version_cache: VersionCache,
|
|
20
|
-
pub settings_cache: SettingsCache,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static CACHE_DIRECTORY: &str = ".repokit_cache";
|
|
24
|
-
|
|
25
|
-
impl CacheScope {
|
|
26
|
-
pub fn new(git_scope: &GitScope, file_system: &FileSystem) -> CacheScope {
|
|
27
|
-
let home = home_dir();
|
|
28
|
-
let cache_directory =
|
|
29
|
-
CacheScope::resolve_cache_directory(&home, &git_scope.root_commit_hash);
|
|
30
|
-
let mut instance = CacheScope {
|
|
31
|
-
crawl_cache: CrawlCache::new(&cache_directory),
|
|
32
|
-
version_cache: VersionCache::new(&cache_directory),
|
|
33
|
-
settings_cache: SettingsCache::new(&cache_directory),
|
|
34
|
-
};
|
|
35
|
-
block_on(instance.initialize_all(git_scope, file_system));
|
|
36
|
-
instance
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async fn initialize_all(&mut self, git_scope: &GitScope, file_system: &FileSystem) {
|
|
40
|
-
self.create_cache_files().await;
|
|
41
|
-
join!(
|
|
42
|
-
self.version_cache.initialize(file_system),
|
|
43
|
-
self.settings_cache.initialize(),
|
|
44
|
-
self.crawl_cache.initialize(git_scope),
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async fn create_cache_files(&self) {
|
|
49
|
-
join!(
|
|
50
|
-
self.version_cache.create_cache_file_if_not_exists(),
|
|
51
|
-
self.settings_cache.create_cache_file_if_not_exists(),
|
|
52
|
-
self.crawl_cache.create_cache_file_if_not_exists(),
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fn resolve_cache_directory(
|
|
57
|
-
home_path: &Option<PathBuf>,
|
|
58
|
-
root_commit: &Option<String>,
|
|
59
|
-
) -> Option<PathBuf> {
|
|
60
|
-
if let Some(home) = home_path
|
|
61
|
-
&& let Some(commit_hash) = root_commit
|
|
62
|
-
{
|
|
63
|
-
let cache_dir = home.join(CACHE_DIRECTORY).join(commit_hash);
|
|
64
|
-
if !cache_dir.exists() && create_dir_all(&cache_dir).is_err() {
|
|
65
|
-
return None;
|
|
66
|
-
}
|
|
67
|
-
return Some(cache_dir);
|
|
68
|
-
}
|
|
69
|
-
None
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
use normalize_path::NormalizePath;
|
|
2
|
-
|
|
3
|
-
use std::{
|
|
4
|
-
fs::File,
|
|
5
|
-
path::{Path, PathBuf},
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
use crate::{internal_filesystem::file_builder::FileBuilder, logger::logger::Logger};
|
|
9
|
-
|
|
10
|
-
#[derive(Clone)]
|
|
11
|
-
pub struct FileSystem {
|
|
12
|
-
pub git_root: String,
|
|
13
|
-
pub git_root_path: PathBuf,
|
|
14
|
-
pub package_directory: PathBuf,
|
|
15
|
-
pub commands_directory: PathBuf,
|
|
16
|
-
pub templates_directory: PathBuf,
|
|
17
|
-
pub install_script_path: PathBuf,
|
|
18
|
-
pub install_script_location: &'static str,
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static INSTALL_SCRIPT_LOCATION: &str = "installation/install.sh";
|
|
22
|
-
static INSTALLED_PACKAGE_PATH: &str = "node_modules/@repokit/core";
|
|
23
|
-
static TYPESCRIPT_COMMANDS: &str = "dist/commands";
|
|
24
|
-
static TYPESCRIPT_TEMPLATES: &str = "externals/templates";
|
|
25
|
-
|
|
26
|
-
impl FileSystem {
|
|
27
|
-
pub fn new(git_root: &str) -> FileSystem {
|
|
28
|
-
let git_root_path = Path::new(&git_root).normalize();
|
|
29
|
-
let package_directory = FileSystem::join_with(&git_root_path, INSTALLED_PACKAGE_PATH);
|
|
30
|
-
FileSystem {
|
|
31
|
-
git_root_path,
|
|
32
|
-
git_root: git_root.to_owned(),
|
|
33
|
-
install_script_path: FileSystem::join_with(&package_directory, INSTALL_SCRIPT_LOCATION),
|
|
34
|
-
commands_directory: FileSystem::join_with(&package_directory, TYPESCRIPT_COMMANDS),
|
|
35
|
-
templates_directory: FileSystem::join_with(&package_directory, TYPESCRIPT_TEMPLATES),
|
|
36
|
-
package_directory,
|
|
37
|
-
install_script_location: INSTALL_SCRIPT_LOCATION,
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub fn join_with(root: &PathBuf, segment: &str) -> PathBuf {
|
|
42
|
-
root.join(segment).normalize()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
pub fn resolve_command(&self, command_name: &str) -> String {
|
|
46
|
-
FileSystem::path_buf_to_str(&FileSystem::join_with(
|
|
47
|
-
&self.commands_directory,
|
|
48
|
-
format!("{command_name}.mjs").as_str(),
|
|
49
|
-
))
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
pub fn resolve_template(&self, file_name: &str) -> File {
|
|
53
|
-
FileBuilder::open(
|
|
54
|
-
FileSystem::join_with(&self.templates_directory, file_name),
|
|
55
|
-
|_| {
|
|
56
|
-
Logger::error(format!("Unable to locate internal {file_name}").as_str());
|
|
57
|
-
Logger::error("Please file a bug here");
|
|
58
|
-
Logger::log_issue_link();
|
|
59
|
-
},
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
pub fn path_buf_to_str(path: &PathBuf) -> String {
|
|
64
|
-
path.to_string_lossy().to_string()
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
use std::path::Path;
|
|
2
|
-
|
|
3
|
-
use futures::{executor::block_on, join};
|
|
4
|
-
|
|
5
|
-
use crate::{executor::executor::Executor, logger::logger::Logger};
|
|
6
|
-
|
|
7
|
-
#[derive(Clone)]
|
|
8
|
-
pub struct GitScope {
|
|
9
|
-
pub root: String,
|
|
10
|
-
pub root_commit_hash: Option<String>,
|
|
11
|
-
pub head_commit_hash: Option<String>,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
impl GitScope {
|
|
15
|
-
pub fn new() -> GitScope {
|
|
16
|
-
let mut instance = GitScope {
|
|
17
|
-
root: "".to_string(),
|
|
18
|
-
root_commit_hash: None,
|
|
19
|
-
head_commit_hash: None,
|
|
20
|
-
};
|
|
21
|
-
block_on(instance.resolve());
|
|
22
|
-
instance
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async fn resolve(&mut self) {
|
|
26
|
-
let (root, root_commit, head_commit) = join!(
|
|
27
|
-
GitScope::find_root(),
|
|
28
|
-
GitScope::get_root_commit(),
|
|
29
|
-
GitScope::get_head_commit()
|
|
30
|
-
);
|
|
31
|
-
self.root = root;
|
|
32
|
-
self.root_commit_hash = root_commit;
|
|
33
|
-
self.head_commit_hash = head_commit;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async fn find_root() -> String {
|
|
37
|
-
if let Some(root) = Executor::exec_with_stdout("git rev-parse --show-toplevel", |cmd| cmd)
|
|
38
|
-
&& !root.is_empty()
|
|
39
|
-
&& Path::new(&root).exists()
|
|
40
|
-
{
|
|
41
|
-
return root;
|
|
42
|
-
}
|
|
43
|
-
Logger::info("Please initialize your repository by running");
|
|
44
|
-
Logger::log_file_path("git init");
|
|
45
|
-
panic!();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async fn get_head_commit() -> Option<String> {
|
|
49
|
-
Executor::exec_with_stdout("git rev-parse HEAD", |cmd| cmd)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async fn get_root_commit() -> Option<String> {
|
|
53
|
-
Executor::exec_with_stdout("git rev-list --parents HEAD | tail -1", |cmd| cmd)
|
|
54
|
-
}
|
|
55
|
-
}
|
package/internals/context/mod.rs
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
use std::{collections::HashMap, path::Path};
|
|
2
|
-
|
|
3
|
-
use normalize_path::NormalizePath;
|
|
4
|
-
|
|
5
|
-
use crate::{
|
|
6
|
-
caches::version_cache::VERSION_REGEX, executor::executor::Executor, logger::logger::Logger,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
#[derive(Clone)]
|
|
10
|
-
pub struct NodeScope {
|
|
11
|
-
pub install_command: String,
|
|
12
|
-
pub command_executor: String,
|
|
13
|
-
pub package_manager: String,
|
|
14
|
-
pub resolved_typescript_version: Option<u32>,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
impl NodeScope {
|
|
18
|
-
pub fn new(git_root: &str) -> NodeScope {
|
|
19
|
-
let package_manager = NodeScope::get_package_manager(git_root).to_string();
|
|
20
|
-
NodeScope {
|
|
21
|
-
resolved_typescript_version: None,
|
|
22
|
-
command_executor: NodeScope::get_node_executor(&package_manager).to_string(),
|
|
23
|
-
install_command: NodeScope::get_install_command(&package_manager).to_string(),
|
|
24
|
-
package_manager,
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub fn type_check_file(&mut self, file_path: &str) {
|
|
29
|
-
let command = self.get_typecheck_command(file_path);
|
|
30
|
-
Executor::with_stdio(command, |cmd| cmd);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
pub fn get_typecheck_command(&mut self, file_path: &str) -> String {
|
|
34
|
-
let typescript_version = self.get_typescript_version();
|
|
35
|
-
let ignore_config = if typescript_version >= 6 {
|
|
36
|
-
" --ignoreConfig".to_string()
|
|
37
|
-
} else {
|
|
38
|
-
"".to_string()
|
|
39
|
-
};
|
|
40
|
-
let tsc_command = format!(
|
|
41
|
-
"{} tsc {} --noEmit{}",
|
|
42
|
-
self.command_executor, file_path, ignore_config
|
|
43
|
-
);
|
|
44
|
-
tsc_command
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
pub fn prompt_to_fix_errors(config_path: &str) {
|
|
48
|
-
Logger::info(
|
|
49
|
-
"Please fix the above type-errors and rerun your command"
|
|
50
|
-
.to_string()
|
|
51
|
-
.as_str(),
|
|
52
|
-
);
|
|
53
|
-
Logger::log_file_path(config_path);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
fn get_typescript_version(&mut self) -> u32 {
|
|
57
|
-
if let Some(resolved_version) = self.resolved_typescript_version {
|
|
58
|
-
return resolved_version;
|
|
59
|
-
}
|
|
60
|
-
let stdout = Executor::exec(format!("{} tsc --version", self.command_executor), |cmd| {
|
|
61
|
-
cmd
|
|
62
|
-
});
|
|
63
|
-
let lines: Vec<&str> = stdout
|
|
64
|
-
.split("\n")
|
|
65
|
-
.filter_map(|s| {
|
|
66
|
-
let trimmed = s.trim();
|
|
67
|
-
if trimmed.is_empty() {
|
|
68
|
-
return None;
|
|
69
|
-
}
|
|
70
|
-
Some(trimmed)
|
|
71
|
-
})
|
|
72
|
-
.collect();
|
|
73
|
-
let fallback_version = "5.0.0";
|
|
74
|
-
let version = lines.last().unwrap_or(&fallback_version);
|
|
75
|
-
let captures: Vec<String> = VERSION_REGEX
|
|
76
|
-
.captures_iter(version)
|
|
77
|
-
.filter_map(|item| {
|
|
78
|
-
item.get(0)
|
|
79
|
-
.map(|match_text| match_text.as_str().to_string())
|
|
80
|
-
})
|
|
81
|
-
.collect();
|
|
82
|
-
let fallback_version_str = fallback_version.to_string();
|
|
83
|
-
let semver = captures.first().unwrap_or(&fallback_version_str);
|
|
84
|
-
let major = semver
|
|
85
|
-
.chars()
|
|
86
|
-
.next()
|
|
87
|
-
.unwrap_or('5')
|
|
88
|
-
.to_digit(10)
|
|
89
|
-
.unwrap_or(5);
|
|
90
|
-
self.resolved_typescript_version = Some(major);
|
|
91
|
-
major
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
fn get_install_command(package_manager: &str) -> &str {
|
|
95
|
-
let npm_install = "npm i -D";
|
|
96
|
-
let manager_map = HashMap::from([
|
|
97
|
-
("npm", npm_install),
|
|
98
|
-
("yarn", "yarn add -D"),
|
|
99
|
-
("pnpm", "pnpm i -D"),
|
|
100
|
-
("bun", "bun add -D"),
|
|
101
|
-
]);
|
|
102
|
-
manager_map.get(package_manager).unwrap_or(&npm_install)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
fn get_node_executor(package_manager: &str) -> &str {
|
|
106
|
-
let npx = "npx";
|
|
107
|
-
let manager_map = HashMap::from([
|
|
108
|
-
("npm", "npx"),
|
|
109
|
-
("yarn", "yarn run -T"),
|
|
110
|
-
("pnpm", "pnpm"),
|
|
111
|
-
("bun", "bunx"),
|
|
112
|
-
]);
|
|
113
|
-
manager_map.get(package_manager).unwrap_or(&npx)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
fn get_package_manager(root: &str) -> &str {
|
|
117
|
-
let manager_map = HashMap::from([
|
|
118
|
-
("npm", ["package-lock.json"].to_vec()),
|
|
119
|
-
("yarn", ["yarn.lock"].to_vec()),
|
|
120
|
-
("pnpm", ["pnpm-lock.yaml"].to_vec()),
|
|
121
|
-
("bun", ["bun.lockb", "bun.lock"].to_vec()),
|
|
122
|
-
]);
|
|
123
|
-
for (manager, lock_files) in manager_map {
|
|
124
|
-
for lock_file in lock_files {
|
|
125
|
-
let path = Path::new(root).join(lock_file).normalize();
|
|
126
|
-
if path.exists() && path.is_file() {
|
|
127
|
-
return manager;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
"npm"
|
|
132
|
-
}
|
|
133
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
use core::panic;
|
|
2
|
-
use std::{
|
|
3
|
-
path::{Path, PathBuf},
|
|
4
|
-
sync::{LazyLock, MutexGuard},
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
use regex::Regex;
|
|
8
|
-
use serde_json::{Value, from_str};
|
|
9
|
-
|
|
10
|
-
use crate::{
|
|
11
|
-
context::{file_system::FileSystem, node_scope::NodeScope},
|
|
12
|
-
executor::executor::Executor,
|
|
13
|
-
logger::logger::Logger,
|
|
14
|
-
repokit::{
|
|
15
|
-
repokit_command::RepoKitCommand, repokit_config::RepoKitConfig,
|
|
16
|
-
repokit_runtime::RepoKitRuntime,
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
static BRIDGE_PARSING_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
|
21
|
-
Regex::new(r#"=============== REPOKIT PARSE FLAG ===============(.*)=============== REPOKIT PARSE FLAG ==============="#).unwrap()
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
pub struct TypeScriptBridge;
|
|
25
|
-
|
|
26
|
-
impl TypeScriptBridge {
|
|
27
|
-
pub fn parse_configuration(files: &FileSystem, node: &mut NodeScope) -> RepoKitConfig {
|
|
28
|
-
let executable = files.resolve_command("parse_configuration");
|
|
29
|
-
let stdout = TypeScriptBridge::execute_with_node(
|
|
30
|
-
&files.git_root_path,
|
|
31
|
-
format!("{executable} --root {}", &files.git_root).as_str(),
|
|
32
|
-
);
|
|
33
|
-
if stdout.is_empty() {
|
|
34
|
-
RepoKitConfig::create(files);
|
|
35
|
-
}
|
|
36
|
-
if let Some(parsed_config) = TypeScriptBridge::unwrap_stdout(&stdout) {
|
|
37
|
-
let parse_result: Result<Value, serde_json::Error> = from_str(parsed_config);
|
|
38
|
-
if let Ok(config) = parse_result {
|
|
39
|
-
return RepoKitConfig::from_input(&files.git_root, node, config);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
Logger::parse_error("configuration", &stdout);
|
|
43
|
-
panic!();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
pub fn parse_commands(path_list: &MutexGuard<Vec<String>>) -> Vec<RepoKitCommand> {
|
|
47
|
-
let paths = path_list.join(",");
|
|
48
|
-
let stdout = RepoKitRuntime::with_runtime(|runtime| {
|
|
49
|
-
let executable = runtime.files.resolve_command("parse_commands");
|
|
50
|
-
TypeScriptBridge::execute_with_node(
|
|
51
|
-
&runtime.files.git_root_path,
|
|
52
|
-
format!(
|
|
53
|
-
"{executable} --paths {paths} --root {}",
|
|
54
|
-
runtime.files.git_root
|
|
55
|
-
)
|
|
56
|
-
.as_str(),
|
|
57
|
-
)
|
|
58
|
-
});
|
|
59
|
-
if let Some(parsed_commands) = TypeScriptBridge::unwrap_stdout(&stdout) {
|
|
60
|
-
let parse_result: Result<Vec<Value>, serde_json::Error> =
|
|
61
|
-
serde_json::from_str(parsed_commands);
|
|
62
|
-
if let Ok(commands) = parse_result {
|
|
63
|
-
return RepoKitCommand::from_input(commands);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
Logger::parse_error("commands", &stdout);
|
|
67
|
-
panic!();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
fn execute_with_node(root: &PathBuf, args: &str) -> String {
|
|
71
|
-
Executor::exec(format!("node {args}"), |cmd| {
|
|
72
|
-
cmd.current_dir(Path::new(root))
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
fn unwrap_stdout(stdout: &str) -> Option<&str> {
|
|
77
|
-
if let Some(capture) = BRIDGE_PARSING_REGEX.captures(stdout)
|
|
78
|
-
&& let Some(result) = capture.get(1)
|
|
79
|
-
{
|
|
80
|
-
return Some(result.as_str());
|
|
81
|
-
}
|
|
82
|
-
None
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
use std::collections::HashMap;
|
|
2
|
-
|
|
3
|
-
use crate::{
|
|
4
|
-
executables::internal_executable_definition::InternalExecutableDefinition,
|
|
5
|
-
internal_commands::help::Help,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
pub trait InternalExecutable {
|
|
9
|
-
fn run(&self, args: Vec<String>, internals: &HashMap<String, Box<dyn InternalExecutable>>);
|
|
10
|
-
fn get_definition(&self) -> &InternalExecutableDefinition;
|
|
11
|
-
|
|
12
|
-
fn help(&self) {
|
|
13
|
-
Help::log_internal_command(self.get_definition());
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
use std::collections::HashMap;
|
|
2
|
-
|
|
3
|
-
#[derive(Clone)]
|
|
4
|
-
pub struct InternalExecutableDefinition {
|
|
5
|
-
pub name: String,
|
|
6
|
-
pub description: String,
|
|
7
|
-
pub args: Option<HashMap<String, String>>,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
pub struct InternalExecutableDefinitionInput<'a, const N: usize> {
|
|
11
|
-
pub name: &'a str,
|
|
12
|
-
pub description: &'a str,
|
|
13
|
-
pub args: [(&'a str, &'a str); N],
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
impl InternalExecutableDefinition {
|
|
17
|
-
pub fn define<const N: usize>(
|
|
18
|
-
definition: InternalExecutableDefinitionInput<N>,
|
|
19
|
-
) -> InternalExecutableDefinition {
|
|
20
|
-
let InternalExecutableDefinitionInput {
|
|
21
|
-
name,
|
|
22
|
-
description,
|
|
23
|
-
args,
|
|
24
|
-
} = definition;
|
|
25
|
-
InternalExecutableDefinition {
|
|
26
|
-
name: String::from(name),
|
|
27
|
-
description: String::from(description),
|
|
28
|
-
args: InternalExecutableDefinition::args(args),
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
pub fn args<const N: usize>(tuples: [(&str, &str); N]) -> Option<HashMap<String, String>> {
|
|
33
|
-
if tuples.is_empty() {
|
|
34
|
-
return None;
|
|
35
|
-
}
|
|
36
|
-
Some(HashMap::from(tuples.map(|(key, value)| {
|
|
37
|
-
(String::from(key), String::from(value))
|
|
38
|
-
})))
|
|
39
|
-
}
|
|
40
|
-
}
|