@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.
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 -19
  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
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"] }
@@ -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 .
@@ -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
- }
@@ -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
- }
@@ -1,6 +0,0 @@
1
- pub mod crawl_cache;
2
- pub mod file_cache;
3
- pub mod old_cache;
4
- pub mod repokit_version_resolver;
5
- pub mod settings_cache;
6
- pub mod version_cache;
@@ -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
- }