@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
package/Cargo.toml
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
name = "repokit"
|
|
3
|
-
version = "4.0.6"
|
|
4
|
-
edition = "2024"
|
|
5
|
-
|
|
6
|
-
[[bin]]
|
|
7
|
-
name = "repokit"
|
|
8
|
-
path = "internals/main.rs"
|
|
9
|
-
|
|
10
|
-
[dependencies]
|
|
11
|
-
jsonschema = { version = "0.46.2", default-features = false }
|
|
12
|
-
serde = { version = "1.0", features = ["derive"] }
|
|
13
|
-
serde_json = "1.0"
|
|
14
|
-
colored = "3"
|
|
15
|
-
normalize-path = "0.2.1"
|
|
16
|
-
alphanumeric-sort = "1.5.6"
|
|
17
|
-
ignore = "0.4.25"
|
|
18
|
-
regex = { version = "1.12.3", features = ["std", "unicode"] }
|
|
19
|
-
shellexpand = "3.1.2"
|
|
20
|
-
schemars = "1.2.1"
|
|
21
|
-
terminal-spinners = "0.3.2"
|
|
22
|
-
futures = "0.3.32"
|
|
23
|
-
tokio = { version = "1.52.1", features = ["full"] }
|
package/installation/install.sh
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
CURRENT_VERSION="4.0.6"
|
|
2
|
-
CWD=$(pwd)
|
|
3
|
-
|
|
4
|
-
REPLACEMENT="/node_modules"
|
|
5
|
-
FALLBACK_ROOT="${CWD%${REPLACEMENT}*}"
|
|
6
|
-
|
|
7
|
-
GIT_ROOT=$(git rev-parse --show-toplevel)
|
|
8
|
-
REPO_ROOT=${GIT_ROOT:-$FALLBACK_ROOT}
|
|
9
|
-
|
|
10
|
-
if [[ "$CWD" != *"$REPLACEMENT"* ]]; then
|
|
11
|
-
exit 0;
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
cd $REPO_ROOT
|
|
16
|
-
|
|
17
|
-
command_exists() {
|
|
18
|
-
command -v "$1" > /dev/null 2>&1
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if command_exists rustc && command_exists cargo; then
|
|
22
|
-
echo "Rust is installed."
|
|
23
|
-
else
|
|
24
|
-
echo "Installing rust"
|
|
25
|
-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
|
26
|
-
fi
|
|
27
|
-
|
|
28
|
-
echo "Installing Repokit CLI"
|
|
29
|
-
|
|
30
|
-
ROOT_COMMIT=$(git rev-list --parents HEAD | tail -1) || ROOT_COMMIT=""
|
|
31
|
-
|
|
32
|
-
cd
|
|
33
|
-
|
|
34
|
-
OLD_CACHE_FILE=".repokit";
|
|
35
|
-
CACHE_DIRECTORY=".repokit_cache";
|
|
36
|
-
VERSION_FILE=".version"
|
|
37
|
-
SETTINGS_FILE=".settings"
|
|
38
|
-
REPO_CACHE_DIRECTORY="$CACHE_DIRECTORY/$ROOT_COMMIT"
|
|
39
|
-
|
|
40
|
-
OLD_SCHEMA_CACHED_THEME=""
|
|
41
|
-
OLD_SCHEMA_CACHED_VERSION="$CURRENT_VERSION"
|
|
42
|
-
|
|
43
|
-
if [ -f "$OLD_CACHE_FILE" ]; then
|
|
44
|
-
{
|
|
45
|
-
read -r OLD_SCHEMA_CACHED_VERSION
|
|
46
|
-
read -r OLD_SCHEMA_CACHED_THEME
|
|
47
|
-
} < "$OLD_CACHE_FILE"
|
|
48
|
-
if [ -n "$ROOT_COMMIT" ] && [ -f "$REPO_CACHE_DIRECTORY/$SETTINGS_FILE" ]; then
|
|
49
|
-
OLD_SCHEMA_CACHED_THEME=""
|
|
50
|
-
fi
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
if [ ! -d "$CACHE_DIRECTORY" ]; then
|
|
54
|
-
mkdir "$CACHE_DIRECTORY"
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
cd "$CACHE_DIRECTORY"
|
|
58
|
-
|
|
59
|
-
if [ -n "$ROOT_COMMIT" ]; then
|
|
60
|
-
if [ ! -d "$ROOT_COMMIT" ]; then
|
|
61
|
-
mkdir "$ROOT_COMMIT"
|
|
62
|
-
fi
|
|
63
|
-
cd $ROOT_COMMIT;
|
|
64
|
-
if [ ! -f "$SETTINGS_FILE" ]; then
|
|
65
|
-
touch "$SETTINGS_FILE"
|
|
66
|
-
fi
|
|
67
|
-
if [ -n "$OLD_SCHEMA_CACHED_THEME" ]; then
|
|
68
|
-
echo "$OLD_SCHEMA_CACHED_THEME\n" > "$SETTINGS_FILE"
|
|
69
|
-
fi
|
|
70
|
-
cd "../"
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
if [ -f $VERSION_FILE ]; then
|
|
74
|
-
read -r CACHED_VERSION < "$VERSION_FILE"
|
|
75
|
-
if [ "$CACHED_VERSION" == "$CURRENT_VERSION" ] && [ "$CACHED_VERSION" == "$OLD_SCHEMA_CACHED_VERSION" ]; then
|
|
76
|
-
exit 0;
|
|
77
|
-
fi
|
|
78
|
-
else
|
|
79
|
-
touch "$VERSION_FILE"
|
|
80
|
-
fi
|
|
81
|
-
|
|
82
|
-
echo "$CURRENT_VERSION\n" > "$VERSION_FILE"
|
|
83
|
-
|
|
84
|
-
cd ../
|
|
85
|
-
|
|
86
|
-
if [ -f "$OLD_CACHE_FILE" ]; then
|
|
87
|
-
TEMP_FILE=".repokit_tmp";
|
|
88
|
-
printf "$CURRENT_VERSION\n" > "$TEMP_FILE"
|
|
89
|
-
tail +2 "$OLD_CACHE_FILE" >> "$TEMP_FILE"
|
|
90
|
-
mv "$TEMP_FILE" "$OLD_CACHE_FILE"
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
cd $CWD
|
|
94
|
-
|
|
95
|
-
echo "Compiling from $CWD"
|
|
96
|
-
|
|
97
|
-
. "$HOME/.cargo/env"
|
|
98
|
-
RUSTFLAGS="-Awarnings" cargo build --release
|
|
99
|
-
cargo install --path .
|
package/internals/argv/argv.rs
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
use std::{collections::HashMap, env};
|
|
2
|
-
|
|
3
|
-
use crate::logger::logger::Logger;
|
|
4
|
-
|
|
5
|
-
#[derive(Clone)]
|
|
6
|
-
pub enum ArgvType {
|
|
7
|
-
String,
|
|
8
|
-
Boolean,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
#[derive(Clone)]
|
|
12
|
-
pub struct ArgvOption {
|
|
13
|
-
pub value_type: ArgvType,
|
|
14
|
-
pub short: Option<&'static str>,
|
|
15
|
-
pub name: &'static str,
|
|
16
|
-
pub multiple: Option<bool>,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
pub struct Argv {
|
|
20
|
-
pub values: HashMap<String, Vec<String>>,
|
|
21
|
-
pub positionals: Vec<String>,
|
|
22
|
-
lookup_table: HashMap<String, ArgvOption>,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
impl Argv {
|
|
26
|
-
pub fn new<const N: usize>(schema: [ArgvOption; N], args: Option<Vec<String>>) -> Argv {
|
|
27
|
-
let mut argv = Argv {
|
|
28
|
-
values: HashMap::new(),
|
|
29
|
-
positionals: Vec::new(),
|
|
30
|
-
lookup_table: Argv::build_option_table(&schema),
|
|
31
|
-
};
|
|
32
|
-
argv.parse(args);
|
|
33
|
-
argv
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
pub fn has(&self, key: &str) -> bool {
|
|
37
|
-
let fallback_bucket = Vec::new();
|
|
38
|
-
let values = self.values.get(key).unwrap_or(&fallback_bucket);
|
|
39
|
-
!values.is_empty()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
pub fn get_first(&self, key: &str) -> String {
|
|
43
|
-
let fallback_bucket = Vec::new();
|
|
44
|
-
let values = self.values.get(key).unwrap_or(&fallback_bucket);
|
|
45
|
-
if values.is_empty() {
|
|
46
|
-
return "".to_string();
|
|
47
|
-
}
|
|
48
|
-
values[0].clone()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
pub fn get_all(&mut self, key: &str) -> &mut Vec<String> {
|
|
52
|
-
self.values.entry(key.to_string()).or_default()
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
fn parse(&mut self, argv: Option<Vec<String>>) {
|
|
56
|
-
let args = argv.unwrap_or(env::args().collect());
|
|
57
|
-
let mut pointer = 0;
|
|
58
|
-
let length = args.len();
|
|
59
|
-
while pointer < length {
|
|
60
|
-
let arg = &args[pointer];
|
|
61
|
-
if self.lookup_table.contains_key(arg) {
|
|
62
|
-
let schema = self.lookup_table.get(arg).expect("arg exists");
|
|
63
|
-
let values = self.values.entry(schema.name.to_string()).or_default();
|
|
64
|
-
match schema.value_type {
|
|
65
|
-
ArgvType::Boolean => {
|
|
66
|
-
values.push("1".to_string());
|
|
67
|
-
pointer += 1;
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
ArgvType::String => {
|
|
71
|
-
let mut current = pointer + 1;
|
|
72
|
-
while current < length {
|
|
73
|
-
let value = &args[current];
|
|
74
|
-
if self.lookup_table.contains_key(value) {
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
let values_for_argument = values.len();
|
|
78
|
-
if values_for_argument == 0 || schema.multiple.is_some_and(|v| v) {
|
|
79
|
-
values.push(value.to_string());
|
|
80
|
-
current += 1;
|
|
81
|
-
} else {
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
self.positionals.push(arg.to_owned());
|
|
89
|
-
}
|
|
90
|
-
pointer += 1;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
fn build_option_table<const N: usize>(
|
|
95
|
-
options: &[ArgvOption; N],
|
|
96
|
-
) -> HashMap<String, ArgvOption> {
|
|
97
|
-
let mut table: HashMap<String, ArgvOption> = HashMap::new();
|
|
98
|
-
for option in options {
|
|
99
|
-
if option.name.len() < 2 {
|
|
100
|
-
Logger::exit_with_error("Option names must be at least 2 characters");
|
|
101
|
-
}
|
|
102
|
-
let first_char = option
|
|
103
|
-
.name
|
|
104
|
-
.chars()
|
|
105
|
-
.next()
|
|
106
|
-
.expect("already checked for emptiness")
|
|
107
|
-
.to_string();
|
|
108
|
-
let short_flag = option.short.unwrap_or(&first_char);
|
|
109
|
-
let flags = [format!("--{}", option.name), format!("-{}", short_flag)];
|
|
110
|
-
for flag in flags {
|
|
111
|
-
if table.contains_key(&flag) {
|
|
112
|
-
Logger::error(
|
|
113
|
-
format!(
|
|
114
|
-
"I encountered the flag {} more than once.",
|
|
115
|
-
Logger::with_theme(|theme| theme.highlight(&flag)),
|
|
116
|
-
)
|
|
117
|
-
.as_str(),
|
|
118
|
-
);
|
|
119
|
-
Logger::error(
|
|
120
|
-
format!(
|
|
121
|
-
"Short flags will default to the first letter of the option's name. If two options begin with the same letter, please specify the {} option for one of them.",
|
|
122
|
-
Logger::with_theme(|theme| theme.highlight("short")),
|
|
123
|
-
)
|
|
124
|
-
.as_str(),
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
table.insert(flag, option.clone());
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
table
|
|
131
|
-
}
|
|
132
|
-
}
|
package/internals/argv/mod.rs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
pub mod argv;
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
use std::{
|
|
2
|
-
collections::HashSet,
|
|
3
|
-
path::{Path, PathBuf},
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
use regex::Regex;
|
|
7
|
-
|
|
8
|
-
use crate::{
|
|
9
|
-
caches::file_cache::FileCache, context::git_scope::GitScope, executor::executor::Executor,
|
|
10
|
-
logger::logger::Logger, post_processing::post_processor::PostProcessor,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
#[derive(Clone)]
|
|
14
|
-
pub struct CrawlCache {
|
|
15
|
-
pub cache_directory: Option<PathBuf>,
|
|
16
|
-
pub changed_files: Option<Vec<String>>,
|
|
17
|
-
pub files_to_crawl: Option<Vec<String>>,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
impl CrawlCache {
|
|
21
|
-
pub fn new(cache_directory: &Option<PathBuf>) -> Self {
|
|
22
|
-
CrawlCache {
|
|
23
|
-
changed_files: None,
|
|
24
|
-
files_to_crawl: None,
|
|
25
|
-
cache_directory: cache_directory.clone(),
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
pub async fn initialize(&mut self, git_scope: &GitScope) {
|
|
30
|
-
let head_commit = git_scope
|
|
31
|
-
.head_commit_hash
|
|
32
|
-
.to_owned()
|
|
33
|
-
.unwrap_or("".to_string());
|
|
34
|
-
if let Some((mut lines, path)) = self.read() {
|
|
35
|
-
let commit_hash = self.unwrap_line(lines.nth(0), "non_existent_hash");
|
|
36
|
-
if commit_hash != head_commit {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
let lines = self.line_buffer_to_vec(lines);
|
|
40
|
-
if lines.is_empty() {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
let (git_ignore_changed, mut changed_files) = self.get_changed_files(&git_scope.root);
|
|
44
|
-
if git_ignore_changed {
|
|
45
|
-
CrawlCache::clear_cache_file(path.to_owned(), false);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
for line in &lines {
|
|
49
|
-
if changed_files.contains(line) {
|
|
50
|
-
changed_files.remove(line);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if !changed_files.is_empty() {
|
|
54
|
-
self.changed_files = Some(changed_files.into_iter().collect());
|
|
55
|
-
}
|
|
56
|
-
self.files_to_crawl = Some(lines);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
pub fn crawl_cache_enabled(&self) -> bool {
|
|
61
|
-
self.files_to_crawl.is_some()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
pub fn cache_crawl_results(&self, results: String) {
|
|
65
|
-
self.write(&results, |_| {
|
|
66
|
-
self.on_crawl_cache_storage_error();
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
fn on_crawl_cache_storage_error(&self) {
|
|
71
|
-
if let Some(storage_path) = self.storage_path() {
|
|
72
|
-
PostProcessor::get().register_task(move || {
|
|
73
|
-
Logger::info(
|
|
74
|
-
"I attempted to cache the results of a file crawl, but couldn't write to disk",
|
|
75
|
-
);
|
|
76
|
-
CrawlCache::log_cache_write_error();
|
|
77
|
-
Logger::info(
|
|
78
|
-
"To avoid issues with stale caches I'm going to delete what's currently on disk",
|
|
79
|
-
);
|
|
80
|
-
CrawlCache::clear_cache_file(storage_path.clone(), true);
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
fn get_changed_files(&self, git_root: &str) -> (bool, HashSet<String>) {
|
|
86
|
-
let mut contains_git_ignore = false;
|
|
87
|
-
let file_path_matcher = Regex::new(r#"^.*\s(.*\.ts)$"#).unwrap();
|
|
88
|
-
let stdout = Executor::exec("git status --porcelain -uall", |cmd| cmd);
|
|
89
|
-
let git_root_path = Path::new(git_root);
|
|
90
|
-
let files: HashSet<String> = stdout
|
|
91
|
-
.split("\n")
|
|
92
|
-
.filter_map(|file| {
|
|
93
|
-
if !contains_git_ignore && file.ends_with(".gitignore") {
|
|
94
|
-
contains_git_ignore = true;
|
|
95
|
-
return None;
|
|
96
|
-
}
|
|
97
|
-
let matches: Vec<&str> = file_path_matcher
|
|
98
|
-
.captures_iter(file)
|
|
99
|
-
.filter_map(|entry| {
|
|
100
|
-
if let Some(match_result) = entry.get(1) {
|
|
101
|
-
return Some(match_result.as_str());
|
|
102
|
-
}
|
|
103
|
-
None
|
|
104
|
-
})
|
|
105
|
-
.collect();
|
|
106
|
-
if let Some(file_path) = matches.first()
|
|
107
|
-
&& git_root_path.join(file_path).exists()
|
|
108
|
-
{
|
|
109
|
-
return Some(file_path.to_string());
|
|
110
|
-
}
|
|
111
|
-
None
|
|
112
|
-
})
|
|
113
|
-
.collect();
|
|
114
|
-
(contains_git_ignore, files)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
impl FileCache for CrawlCache {
|
|
119
|
-
fn cache_file(&self) -> &str {
|
|
120
|
-
".crawl_cache"
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
fn cache_directory(&self) -> &Option<PathBuf> {
|
|
124
|
-
&self.cache_directory
|
|
125
|
-
}
|
|
126
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
use std::{
|
|
2
|
-
fs::{File, write},
|
|
3
|
-
io::{BufRead, BufReader, Error, Lines},
|
|
4
|
-
path::PathBuf,
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
use normalize_path::NormalizePath;
|
|
8
|
-
|
|
9
|
-
use crate::{logger::logger::Logger, post_processing::post_processor::PostProcessor};
|
|
10
|
-
|
|
11
|
-
pub trait FileCache {
|
|
12
|
-
fn cache_file(&self) -> &str;
|
|
13
|
-
|
|
14
|
-
fn cache_directory(&self) -> &Option<PathBuf>;
|
|
15
|
-
|
|
16
|
-
fn storage_path(&self) -> Option<PathBuf> {
|
|
17
|
-
if let Some(storage_path) = self.perspective_path()
|
|
18
|
-
&& storage_path.exists()
|
|
19
|
-
{
|
|
20
|
-
return Some(storage_path);
|
|
21
|
-
}
|
|
22
|
-
None
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
fn perspective_path(&self) -> Option<PathBuf> {
|
|
26
|
-
if let Some(cache_dir) = &self.cache_directory() {
|
|
27
|
-
return Some(cache_dir.join(self.cache_file()).normalize());
|
|
28
|
-
}
|
|
29
|
-
None
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async fn create_cache_file_if_not_exists(&self) -> Option<PathBuf> {
|
|
33
|
-
if let Some(storage_path) = self.perspective_path()
|
|
34
|
-
&& !&storage_path.exists()
|
|
35
|
-
&& write(&storage_path, "").is_ok()
|
|
36
|
-
{
|
|
37
|
-
return Some(storage_path);
|
|
38
|
-
}
|
|
39
|
-
None
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
fn read(&self) -> Option<(Lines<BufReader<File>>, PathBuf)> {
|
|
43
|
-
if let Some(path) = self.storage_path()
|
|
44
|
-
&& let Ok(file) = File::open(&path)
|
|
45
|
-
{
|
|
46
|
-
return Some((BufReader::new(file).lines(), path));
|
|
47
|
-
}
|
|
48
|
-
None
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
fn write(&self, content: &str, on_error: impl Fn(Error)) {
|
|
52
|
-
if let Some(path) = self.storage_path()
|
|
53
|
-
&& let Err(error) = write(path, content)
|
|
54
|
-
{
|
|
55
|
-
on_error(error);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
fn line_buffer_to_vec(&self, lines: Lines<BufReader<File>>) -> Vec<String> {
|
|
60
|
-
lines.filter_map(Result::ok).collect()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
fn insert_as_first_line(&self, lines: Lines<BufReader<File>>, value: String) -> Vec<String> {
|
|
64
|
-
let mut lines: Vec<String> = self.line_buffer_to_vec(lines);
|
|
65
|
-
if !lines.is_empty() {
|
|
66
|
-
lines[0] = value;
|
|
67
|
-
} else {
|
|
68
|
-
lines.push(value);
|
|
69
|
-
}
|
|
70
|
-
lines
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
fn unwrap_line(&self, line_result: Option<Result<String, Error>>, fallback: &str) -> String {
|
|
74
|
-
line_result
|
|
75
|
-
.and_then(|r| r.ok())
|
|
76
|
-
.unwrap_or(fallback.to_string())
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
fn clear_cache_file(path: PathBuf, notify: bool) {
|
|
80
|
-
// This is post-processed so it doesn't block the command the user is executing
|
|
81
|
-
PostProcessor::get().register_task(move || {
|
|
82
|
-
if write(&path, "").is_err() {
|
|
83
|
-
Logger::error("I was unable to remove a cache on disk");
|
|
84
|
-
Logger::error("To correct this, please run");
|
|
85
|
-
Logger::log_file_path(format!("rm {}", path.to_string_lossy()).as_str())
|
|
86
|
-
} else if notify {
|
|
87
|
-
Logger::info("Cache deleted!");
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
fn log_cache_write_error() {
|
|
93
|
-
Logger::info("This is typically a permission-related issue on the operating system");
|
|
94
|
-
Logger::info(
|
|
95
|
-
format!(
|
|
96
|
-
"If you believe this to be a bug within {}",
|
|
97
|
-
Logger::with_theme(|theme| theme.highlight("Repokit"))
|
|
98
|
-
)
|
|
99
|
-
.as_str(),
|
|
100
|
-
);
|
|
101
|
-
Logger::info("Please file an issue here");
|
|
102
|
-
Logger::log_issue_link();
|
|
103
|
-
}
|
|
104
|
-
}
|
package/internals/caches/mod.rs
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
use std::{env::home_dir, path::PathBuf, sync::LazyLock};
|
|
2
|
-
|
|
3
|
-
use crate::caches::{file_cache::FileCache, version_cache::VERSION_REGEX};
|
|
4
|
-
|
|
5
|
-
static OLD_CACHE_FILE: &str = ".repokit";
|
|
6
|
-
|
|
7
|
-
static OLD_CACHE_FILE_PATH: LazyLock<Option<PathBuf>> = LazyLock::new(home_dir);
|
|
8
|
-
|
|
9
|
-
pub struct OldCache;
|
|
10
|
-
|
|
11
|
-
impl FileCache for OldCache {
|
|
12
|
-
fn cache_file(&self) -> &str {
|
|
13
|
-
OLD_CACHE_FILE
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
fn cache_directory(&self) -> &Option<PathBuf> {
|
|
17
|
-
&OLD_CACHE_FILE_PATH
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
impl OldCache {
|
|
22
|
-
pub fn new() -> Self {
|
|
23
|
-
OldCache {}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pub fn get_version(&self) -> Option<String> {
|
|
27
|
-
if let Some((mut lines, _)) = self.read() {
|
|
28
|
-
let version = self.unwrap_line(lines.nth(0), "");
|
|
29
|
-
if VERSION_REGEX.is_match(&version) {
|
|
30
|
-
return Some(version);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
None
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
use std::env::args;
|
|
2
|
-
|
|
3
|
-
use terminal_spinners::{BOUNCING_BALL, SpinnerBuilder};
|
|
4
|
-
|
|
5
|
-
use crate::{
|
|
6
|
-
context::file_system::FileSystem, executor::executor::Executor, logger::logger::Logger,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
pub struct RepoKitVersionResolver;
|
|
10
|
-
|
|
11
|
-
impl RepoKitVersionResolver {
|
|
12
|
-
pub fn hop_to_installed_version(files: &FileSystem) {
|
|
13
|
-
if files.install_script_path.is_absolute() && files.install_script_path.exists() {
|
|
14
|
-
if let Some(errors) = RepoKitVersionResolver::run_post_install(files) {
|
|
15
|
-
println!("{errors}");
|
|
16
|
-
Logger::error("My installer failed");
|
|
17
|
-
RepoKitVersionResolver::on_error();
|
|
18
|
-
} else {
|
|
19
|
-
RepoKitVersionResolver::re_run_command();
|
|
20
|
-
}
|
|
21
|
-
} else {
|
|
22
|
-
Logger::error("I couldn't find my installer");
|
|
23
|
-
RepoKitVersionResolver::on_error();
|
|
24
|
-
}
|
|
25
|
-
panic!();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
fn run_post_install(files: &FileSystem) -> Option<String> {
|
|
29
|
-
let handle = SpinnerBuilder::new()
|
|
30
|
-
.spinner(&BOUNCING_BALL)
|
|
31
|
-
.text(" Installing")
|
|
32
|
-
.start();
|
|
33
|
-
let result =
|
|
34
|
-
Executor::exec_with_errors(format!("./{}", files.install_script_location), |cmd| {
|
|
35
|
-
cmd.current_dir(&files.package_directory)
|
|
36
|
-
});
|
|
37
|
-
handle.done();
|
|
38
|
-
result
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
fn re_run_command() {
|
|
42
|
-
let args: Vec<String> = args().collect();
|
|
43
|
-
Executor::with_stdio(args.join(" "), |cmd| cmd);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
fn on_error() {
|
|
47
|
-
Logger::info("Please file a bug here");
|
|
48
|
-
Logger::log_issue_link();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
use std::path::PathBuf;
|
|
2
|
-
|
|
3
|
-
use crate::{
|
|
4
|
-
caches::file_cache::FileCache, logger::logger::Logger,
|
|
5
|
-
post_processing::post_processor::PostProcessor,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
#[derive(Clone)]
|
|
9
|
-
pub struct SettingsCache {
|
|
10
|
-
pub cache_directory: Option<PathBuf>,
|
|
11
|
-
pub theme_preference: String,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
impl SettingsCache {
|
|
15
|
-
pub fn new(cache_directory: &Option<PathBuf>) -> Self {
|
|
16
|
-
SettingsCache {
|
|
17
|
-
cache_directory: cache_directory.clone(),
|
|
18
|
-
theme_preference: Logger::with_registry(|registry| registry.default_theme.to_owned()),
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub async fn initialize(&mut self) {
|
|
23
|
-
if let Some((mut lines, _)) = self.read()
|
|
24
|
-
&& let Some(result) = lines.nth(0)
|
|
25
|
-
&& let Ok(theme) = result
|
|
26
|
-
{
|
|
27
|
-
self.theme_preference = theme;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
pub fn store_theme_preference(&self, theme: &str) {
|
|
32
|
-
self.write(format!("{theme}\n").as_str(), |_| {
|
|
33
|
-
self.on_theme_storage_error(theme);
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
fn on_theme_storage_error(&self, theme: &str) {
|
|
38
|
-
if let Some(storage_path) = self.storage_path() {
|
|
39
|
-
let theme_clone = theme.to_string();
|
|
40
|
-
PostProcessor::get().register_task(move || {
|
|
41
|
-
Logger::info("I failed to write your theme preference to the file system");
|
|
42
|
-
Logger::info(
|
|
43
|
-
format!(
|
|
44
|
-
"This usually indicates a bug within {}",
|
|
45
|
-
Logger::with_theme(|theme| theme.highlight("Repokit"))
|
|
46
|
-
)
|
|
47
|
-
.as_str(),
|
|
48
|
-
);
|
|
49
|
-
Logger::info("Please file an issue here");
|
|
50
|
-
Logger::log_issue_link();
|
|
51
|
-
Logger::info("To repair this manually you can run");
|
|
52
|
-
Logger::log_file_path(
|
|
53
|
-
format!(
|
|
54
|
-
"printf \"{}\n\" > {}",
|
|
55
|
-
theme_clone,
|
|
56
|
-
storage_path.to_string_lossy(),
|
|
57
|
-
)
|
|
58
|
-
.as_str(),
|
|
59
|
-
);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
impl FileCache for SettingsCache {
|
|
66
|
-
fn cache_file(&self) -> &str {
|
|
67
|
-
".settings"
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
fn cache_directory(&self) -> &Option<PathBuf> {
|
|
71
|
-
&self.cache_directory
|
|
72
|
-
}
|
|
73
|
-
}
|