@repokit/core 3.0.2 → 3.0.3

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 (43) hide show
  1. package/Cargo.lock +1056 -2
  2. package/Cargo.toml +4 -1
  3. package/dist/CommandParser.mjs +3 -3
  4. package/externals/CommandParser.ts +3 -3
  5. package/installation/install.sh +1 -1
  6. package/internals/configuration/configuration.rs +3 -2
  7. package/internals/configuration/mod.rs +2 -0
  8. package/internals/configuration/recovery.rs +42 -0
  9. package/internals/{internal_commands → configuration}/typescript_command.rs +20 -22
  10. package/internals/executables/internal_executable_definition.rs +1 -1
  11. package/internals/executables/mod.rs +1 -2
  12. package/internals/executor/executor.rs +13 -0
  13. package/internals/internal_commands/help.rs +5 -2
  14. package/internals/internal_commands/internal_registry.rs +6 -4
  15. package/internals/internal_commands/list_commands.rs +2 -2
  16. package/internals/internal_commands/list_owners.rs +2 -2
  17. package/internals/internal_commands/list_themes.rs +1 -1
  18. package/internals/internal_commands/list_version.rs +60 -0
  19. package/internals/internal_commands/locate_command.rs +5 -4
  20. package/internals/internal_commands/mod.rs +1 -1
  21. package/internals/internal_commands/onboarder.rs +1 -1
  22. package/internals/internal_commands/register_command.rs +3 -3
  23. package/internals/internal_commands/search_commands.rs +2 -2
  24. package/internals/internal_commands/upgrade_repokit.rs +37 -34
  25. package/internals/internal_filesystem/file_builder.rs +4 -0
  26. package/internals/internal_filesystem/internal_filesystem.rs +101 -9
  27. package/internals/logger/logger.rs +26 -14
  28. package/internals/main.rs +6 -3
  29. package/internals/post_processing/mod.rs +1 -0
  30. package/internals/post_processing/post_processor.rs +37 -0
  31. package/internals/repokit/command_definition.rs +11 -0
  32. package/internals/repokit/mod.rs +5 -1
  33. package/internals/repokit/repokit.rs +10 -14
  34. package/internals/repokit/repokit_command.rs +96 -0
  35. package/internals/repokit/repokit_config.rs +75 -0
  36. package/internals/repokit/repokit_construct_validator.rs +14 -0
  37. package/internals/repokit/runtime_compiler.rs +61 -0
  38. package/internals/themes/theme_inputs.rs +3 -2
  39. package/internals/validations/command_validations.rs +4 -5
  40. package/package.json +1 -1
  41. package/internals/executables/external_executable.rs +0 -4
  42. package/internals/repokit/interfaces.rs +0 -48
  43. /package/internals/executables/{intenal_executable.rs → internal_executable.rs} +0 -0
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "repokit"
3
- version = "3.0.2"
3
+ version = "3.0.3"
4
4
  edition = "2024"
5
5
 
6
6
  [[bin]]
@@ -8,6 +8,7 @@ name = "repokit"
8
8
  path = "internals/main.rs"
9
9
 
10
10
  [dependencies]
11
+ jsonschema = { version = "0.45.0", default-features = false }
11
12
  serde = { version = "1.0", features = ["derive"] }
12
13
  serde_json = "1.0"
13
14
  colored = "3"
@@ -17,3 +18,5 @@ tokio = "1.50.0"
17
18
  ignore = "0.4.25"
18
19
  regex = { version = "1.12.3", features = ["std", "unicode"] }
19
20
  shellexpand = "3.1.2"
21
+ schemars = "1.2.1"
22
+ terminal-spinners = "0.3.2"
@@ -9,12 +9,12 @@ var CommandParser = class extends TSCompiler {
9
9
  static async parse() {
10
10
  const { paths, root } = this.parsePaths();
11
11
  if (!root || !existsSync(root) || !(await stat(root)).isDirectory()) return console.log(JSON.stringify([]));
12
- const commands = paths.split(",").filter(Boolean).map((path) => this.parseCommand(join(root, path)));
12
+ const commands = paths.split(",").filter(Boolean).map((path) => this.parseCommand(root, path));
13
13
  console.log(JSON.stringify(commands.flat()));
14
14
  }
15
- static parseCommand(path) {
15
+ static parseCommand(root, path) {
16
16
  const commands = [];
17
- const declaredExports = super.compile(path);
17
+ const declaredExports = super.compile(join(root, path));
18
18
  for (const key in declaredExports) if (declaredExports[key] instanceof RepoKitCommand) commands.push({
19
19
  ...declaredExports[key],
20
20
  location: path
@@ -14,13 +14,13 @@ export class CommandParser extends TSCompiler {
14
14
  return console.log(JSON.stringify([]));
15
15
  }
16
16
  const pathList = paths.split(",").filter(Boolean);
17
- const commands = pathList.map(path => this.parseCommand(join(root, path)));
17
+ const commands = pathList.map(path => this.parseCommand(root, path));
18
18
  console.log(JSON.stringify(commands.flat()));
19
19
  }
20
20
 
21
- private static parseCommand(path: string) {
21
+ private static parseCommand(root: string, path: string) {
22
22
  const commands: ILocatedCommand[] = [];
23
- const declaredExports = super.compile(path);
23
+ const declaredExports = super.compile(join(root, path));
24
24
  for (const key in declaredExports) {
25
25
  if (declaredExports[key] instanceof RepoKitCommand) {
26
26
  commands.push({ ...declaredExports[key], location: path });
@@ -1,4 +1,4 @@
1
- CURRENT_VERSION="3.0.2"
1
+ CURRENT_VERSION="3.0.3"
2
2
  CWD=$(pwd)
3
3
 
4
4
  REPLACEMENT="/node_modules"
@@ -1,8 +1,9 @@
1
- use std::{path::Path, process::exit};
1
+ use std::path::Path;
2
2
 
3
3
  use crate::{
4
4
  internal_filesystem::{file_builder::FileBuilder, internal_filesystem::InternalFileSystem},
5
5
  logger::logger::Logger,
6
+ post_processing::post_processor::PostProcessor,
6
7
  };
7
8
 
8
9
  pub struct Configuration;
@@ -34,7 +35,7 @@ impl Configuration {
34
35
  .as_str(),
35
36
  );
36
37
  Logger::log_file_path(file_path.as_str());
37
- exit(0);
38
+ PostProcessor::get().flush();
38
39
  }
39
40
 
40
41
  fn welcome() {
@@ -1 +1,3 @@
1
1
  pub mod configuration;
2
+ pub mod recovery;
3
+ pub mod typescript_command;
@@ -0,0 +1,42 @@
1
+ use crate::{
2
+ executor::executor::Executor, internal_filesystem::internal_filesystem::InternalFileSystem,
3
+ logger::logger::Logger,
4
+ };
5
+
6
+ pub struct Recovery {
7
+ root: String,
8
+ }
9
+
10
+ impl Recovery {
11
+ pub fn new(root: &str) -> Recovery {
12
+ Recovery {
13
+ root: root.to_owned(),
14
+ }
15
+ }
16
+
17
+ pub fn run(&mut self, file_path: &str) {
18
+ let command = self.get_typecheck_command(file_path);
19
+ Executor::with_stdio(command, |cmd| cmd);
20
+ }
21
+
22
+ pub fn get_typecheck_command(&self, file_path: &str) -> String {
23
+ let executor = InternalFileSystem::get_node_executor(&self.root);
24
+ let typescript_version = InternalFileSystem::get_typescript_version(executor);
25
+ let ignore_config = if typescript_version >= 6 {
26
+ " --ignoreConfig".to_string()
27
+ } else {
28
+ "".to_string()
29
+ };
30
+ let tsc_command = format!("{} tsc {} --noEmit{}", executor, file_path, ignore_config);
31
+ tsc_command
32
+ }
33
+
34
+ pub fn prompt_to_fix_errors(&self, config_path: &str) {
35
+ Logger::info(
36
+ "Please fix the above type-errors and rerun your command"
37
+ .to_string()
38
+ .as_str(),
39
+ );
40
+ Logger::log_file_path(config_path);
41
+ }
42
+ }
@@ -1,13 +1,16 @@
1
1
  use std::{path::Path, process::exit, sync::MutexGuard};
2
2
 
3
- use serde_json::from_str;
3
+ use serde_json::{Value, from_str};
4
4
 
5
5
  use crate::{
6
6
  configuration::configuration::Configuration,
7
7
  executor::executor::Executor,
8
8
  internal_filesystem::internal_filesystem::InternalFileSystem,
9
- logger::logger::Logger,
10
- repokit::interfaces::{RepoKitCommand, RepoKitConfig},
9
+ post_processing::post_processor::PostProcessor,
10
+ repokit::{
11
+ repokit_command::RepoKitCommand, repokit_config::RepoKitConfig,
12
+ repokit_construct_validator::RepoKitConstructValidator,
13
+ },
11
14
  };
12
15
 
13
16
  pub struct TypescriptCommand {
@@ -17,7 +20,7 @@ pub struct TypescriptCommand {
17
20
  impl TypescriptCommand {
18
21
  pub fn new(root: &str) -> TypescriptCommand {
19
22
  TypescriptCommand {
20
- root: root.to_string(),
23
+ root: root.to_owned(),
21
24
  }
22
25
  }
23
26
 
@@ -27,8 +30,15 @@ impl TypescriptCommand {
27
30
  if stdout.is_empty() {
28
31
  Configuration::create(&self.root);
29
32
  }
30
- let config: RepoKitConfig = from_str(stdout.as_str()).unwrap();
31
- config
33
+ let result: Result<Value, serde_json::Error> = from_str(stdout.as_str());
34
+ match result {
35
+ Ok(config) => RepoKitConfig::from_input(&self.root, config),
36
+ Err(_) => {
37
+ RepoKitConfig::on_parsing_error(&self.root, Value::Null);
38
+ PostProcessor::get().flush();
39
+ exit(0)
40
+ }
41
+ }
32
42
  }
33
43
 
34
44
  pub fn parse_commands(&self, path_list: &MutexGuard<Vec<String>>) -> Vec<RepoKitCommand> {
@@ -36,24 +46,12 @@ impl TypescriptCommand {
36
46
  let executable = InternalFileSystem::new(&self.root).resolve_command("parse_commands");
37
47
  let stdout =
38
48
  self.execute(format!("{executable} --paths {paths} --root {}", self.root).as_str());
39
- let result: Result<Vec<RepoKitCommand>, serde_json::Error> = serde_json::from_str(&stdout);
49
+ let result: Result<Vec<Value>, serde_json::Error> = serde_json::from_str(&stdout);
40
50
  match result {
41
- Ok(mut commands) => {
42
- for command in commands.iter_mut() {
43
- let relative_location = &command.location;
44
- command.location = Path::join(Path::new(&self.root), relative_location)
45
- .to_str()
46
- .expect("str")
47
- .to_string()
48
- }
49
- commands
50
- }
51
+ Ok(commands) => RepoKitCommand::from_input(&self.root, commands),
51
52
  Err(_) => {
52
- Logger::info("There was an error parsing one of your commands");
53
- Logger::info(
54
- "You can validate a command file's syntactical correctness by running",
55
- );
56
- Logger::log_file_path("tsc --noEmit");
53
+ RepoKitCommand::on_parsing_error(&self.root, Value::Null);
54
+ PostProcessor::get().flush();
57
55
  exit(0);
58
56
  }
59
57
  }
@@ -1,6 +1,6 @@
1
1
  use std::collections::HashMap;
2
2
 
3
- use crate::repokit::interfaces::RepoKitConfig;
3
+ use crate::repokit::repokit_config::RepoKitConfig;
4
4
 
5
5
  #[derive(Clone)]
6
6
  pub struct RepoKitScope {
@@ -1,3 +1,2 @@
1
- pub mod external_executable;
2
- pub mod intenal_executable;
1
+ pub mod internal_executable;
3
2
  pub mod internal_executable_definition;
@@ -18,6 +18,19 @@ impl Executor {
18
18
  Executor::unwrap(&output.stderr)
19
19
  }
20
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
+
21
34
  pub fn with_stdio<T: AsRef<OsStr>>(
22
35
  command: T,
23
36
  composer: impl Fn(&mut Command) -> &mut Command,
@@ -4,11 +4,14 @@ use alphanumeric_sort::{sort_slice_by_str_key, sort_str_slice};
4
4
 
5
5
  use crate::{
6
6
  executables::{
7
- intenal_executable::InternalExecutable,
7
+ internal_executable::InternalExecutable,
8
8
  internal_executable_definition::InternalExecutableDefinition,
9
9
  },
10
10
  logger::logger::Logger,
11
- repokit::interfaces::{CommandDefinition, RepoKitCommand, RootCommand},
11
+ repokit::{
12
+ command_definition::CommandDefinition, repokit_command::RepoKitCommand,
13
+ repokit_config::RootCommand,
14
+ },
12
15
  };
13
16
 
14
17
  pub struct Help;
@@ -2,12 +2,13 @@ use std::collections::HashMap;
2
2
 
3
3
  use crate::{
4
4
  executables::{
5
- intenal_executable::InternalExecutable, internal_executable_definition::RepoKitScope,
5
+ internal_executable::InternalExecutable, internal_executable_definition::RepoKitScope,
6
6
  },
7
7
  internal_commands::{
8
8
  list_commands::ListCommands, list_owners::ListOwners, list_themes::ListThemes,
9
- locate_command::LocateCommand, onboarder::Onboarder, register_command::RegisterCommand,
10
- search_commands::SearchCommands, upgrade_repokit::UpgradeRepoKit,
9
+ list_version::ListVersion, locate_command::LocateCommand, onboarder::Onboarder,
10
+ register_command::RegisterCommand, search_commands::SearchCommands,
11
+ upgrade_repokit::UpgradeRepoKit,
11
12
  },
12
13
  };
13
14
 
@@ -23,7 +24,7 @@ impl InternalRegistry {
23
24
  }
24
25
 
25
26
  pub fn get_all(&self) -> HashMap<String, Box<dyn InternalExecutable>> {
26
- let internals: [Box<dyn InternalExecutable>; 8] = [
27
+ let internals: [Box<dyn InternalExecutable>; 9] = [
27
28
  Box::new(Onboarder::new(&self.scope)),
28
29
  Box::new(ListCommands::new(&self.scope)),
29
30
  Box::new(SearchCommands::new(&self.scope)),
@@ -32,6 +33,7 @@ impl InternalRegistry {
32
33
  Box::new(RegisterCommand::new(&self.scope)),
33
34
  Box::new(UpgradeRepoKit::new(&self.scope)),
34
35
  Box::new(ListThemes::new(&self.scope)),
36
+ Box::new(ListVersion::new(&self.scope)),
35
37
  ];
36
38
  HashMap::from(internals.map(|x| (x.get_definition().name.to_string(), x)))
37
39
  }
@@ -2,14 +2,14 @@ use std::collections::HashMap;
2
2
 
3
3
  use crate::{
4
4
  executables::{
5
- intenal_executable::InternalExecutable,
5
+ internal_executable::InternalExecutable,
6
6
  internal_executable_definition::{
7
7
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
8
8
  },
9
9
  },
10
10
  internal_commands::help::Help,
11
11
  logger::logger::Logger,
12
- repokit::interfaces::RepoKitCommand,
12
+ repokit::repokit_command::RepoKitCommand,
13
13
  validations::command_validations::CommandValidations,
14
14
  };
15
15
 
@@ -4,14 +4,14 @@ use alphanumeric_sort::sort_str_slice;
4
4
 
5
5
  use crate::{
6
6
  executables::{
7
- intenal_executable::InternalExecutable,
7
+ internal_executable::InternalExecutable,
8
8
  internal_executable_definition::{
9
9
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
10
10
  },
11
11
  },
12
12
  internal_commands::help::Help,
13
13
  logger::logger::Logger,
14
- repokit::interfaces::RepoKitCommand,
14
+ repokit::repokit_command::RepoKitCommand,
15
15
  validations::command_validations::CommandValidations,
16
16
  };
17
17
 
@@ -6,7 +6,7 @@ use colored::Colorize;
6
6
  use crate::{
7
7
  argv::argv::{Argv, ArgvOption, ArgvType},
8
8
  executables::{
9
- intenal_executable::InternalExecutable,
9
+ internal_executable::InternalExecutable,
10
10
  internal_executable_definition::{
11
11
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
12
12
  },
@@ -0,0 +1,60 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::{
4
+ executables::{
5
+ internal_executable::InternalExecutable,
6
+ internal_executable_definition::{
7
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
8
+ },
9
+ },
10
+ executor::executor::Executor,
11
+ internal_commands::help::Help,
12
+ internal_filesystem::internal_filesystem::InternalFileSystem,
13
+ logger::logger::Logger,
14
+ };
15
+
16
+ pub struct ListVersion {
17
+ pub scope: RepoKitScope,
18
+ pub definition: InternalExecutableDefinition,
19
+ }
20
+
21
+ impl ListVersion {
22
+ pub fn new(scope: &RepoKitScope) -> ListVersion {
23
+ ListVersion {
24
+ scope: scope.clone(),
25
+ definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
26
+ name: "version",
27
+ description: "Lists the version of repokit running in this repository",
28
+ args: [],
29
+ }),
30
+ }
31
+ }
32
+
33
+ fn log_version(&self, version: &str) {
34
+ Logger::info(format!("{}", Logger::with_theme(|theme| theme.highlight(version))).as_str());
35
+ }
36
+ }
37
+
38
+ impl InternalExecutable for ListVersion {
39
+ fn run(&self, _: Vec<String>, _: &HashMap<String, Box<dyn InternalExecutable>>) {
40
+ Logger::info("Fetching the installed version of repokit");
41
+ if let Some(local_version) =
42
+ InternalFileSystem::new(&self.scope.root).installed_repokit_version()
43
+ {
44
+ return self.log_version(&local_version);
45
+ }
46
+ Logger::info("Falling back to the runtime version");
47
+ if let Some(runtime_version) = InternalFileSystem::runtime_repokit_version() {
48
+ return self.log_version(&runtime_version);
49
+ }
50
+ Executor::with_stdio("npm list @repokit/core", |cmd| cmd);
51
+ }
52
+
53
+ fn help(&self) {
54
+ Help::log_internal_command(&self.definition);
55
+ }
56
+
57
+ fn get_definition(&self) -> &InternalExecutableDefinition {
58
+ &self.definition
59
+ }
60
+ }
@@ -1,14 +1,15 @@
1
- use std::{collections::HashMap, process::exit};
1
+ use std::collections::HashMap;
2
2
 
3
3
  use crate::{
4
4
  executables::{
5
- intenal_executable::InternalExecutable,
5
+ internal_executable::InternalExecutable,
6
6
  internal_executable_definition::{
7
7
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
8
8
  },
9
9
  },
10
10
  internal_commands::help::Help,
11
11
  logger::logger::Logger,
12
+ post_processing::post_processor::PostProcessor,
12
13
  validations::command_validations::CommandValidations,
13
14
  };
14
15
 
@@ -35,7 +36,7 @@ impl LocateCommand {
35
36
  for (_, command) in all {
36
37
  if command.name == query {
37
38
  Logger::log_file_path(&command.location);
38
- exit(0);
39
+ PostProcessor::get().flush();
39
40
  }
40
41
  }
41
42
  }
@@ -43,7 +44,7 @@ impl LocateCommand {
43
44
  fn search_root(&self, command: &str) {
44
45
  if self.scope.configuration.commands.contains_key(command) {
45
46
  Logger::log_file_path(format!("{}/repokit.ts", &self.scope.root).as_str());
46
- exit(0);
47
+ PostProcessor::get().flush();
47
48
  }
48
49
  }
49
50
  }
@@ -3,9 +3,9 @@ pub mod internal_registry;
3
3
  pub mod list_commands;
4
4
  pub mod list_owners;
5
5
  pub mod list_themes;
6
+ pub mod list_version;
6
7
  pub mod locate_command;
7
8
  pub mod onboarder;
8
9
  pub mod register_command;
9
10
  pub mod search_commands;
10
- pub mod typescript_command;
11
11
  pub mod upgrade_repokit;
@@ -2,7 +2,7 @@ use std::collections::HashMap;
2
2
 
3
3
  use crate::{
4
4
  executables::{
5
- intenal_executable::InternalExecutable,
5
+ internal_executable::InternalExecutable,
6
6
  internal_executable_definition::{
7
7
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
8
8
  },
@@ -2,12 +2,11 @@ use normalize_path::NormalizePath;
2
2
  use std::{
3
3
  collections::HashMap,
4
4
  path::{Path, PathBuf},
5
- process,
6
5
  };
7
6
 
8
7
  use crate::{
9
8
  executables::{
10
- intenal_executable::InternalExecutable,
9
+ internal_executable::InternalExecutable,
11
10
  internal_executable_definition::{
12
11
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
13
12
  },
@@ -15,6 +14,7 @@ use crate::{
15
14
  internal_commands::help::Help,
16
15
  internal_filesystem::{file_builder::FileBuilder, internal_filesystem::InternalFileSystem},
17
16
  logger::logger::Logger,
17
+ post_processing::post_processor::PostProcessor,
18
18
  };
19
19
 
20
20
  pub struct RegisterCommand {
@@ -72,7 +72,7 @@ impl RegisterCommand {
72
72
  "You can append additional commands to the existing {} instance or export another one",
73
73
  Logger::with_theme(|theme| theme.highlight("RepoKitCommand"))
74
74
  ).as_str());
75
- process::exit(0);
75
+ PostProcessor::get().flush();
76
76
  }
77
77
  command_path.clone()
78
78
  }
@@ -3,14 +3,14 @@ use std::collections::HashMap;
3
3
 
4
4
  use crate::{
5
5
  executables::{
6
- intenal_executable::InternalExecutable,
6
+ internal_executable::InternalExecutable,
7
7
  internal_executable_definition::{
8
8
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
9
9
  },
10
10
  },
11
11
  internal_commands::help::Help,
12
12
  logger::logger::Logger,
13
- repokit::interfaces::{CommandDefinition, RepoKitCommand},
13
+ repokit::{command_definition::CommandDefinition, repokit_command::RepoKitCommand},
14
14
  validations::command_validations::CommandValidations,
15
15
  };
16
16
 
@@ -1,15 +1,17 @@
1
- use normalize_path::NormalizePath;
2
- use std::{collections::HashMap, path::Path, process::exit};
1
+ use std::collections::HashMap;
2
+
3
+ use terminal_spinners::{BOUNCING_BALL, SpinnerBuilder};
3
4
 
4
5
  use crate::{
5
6
  executables::{
6
- intenal_executable::InternalExecutable,
7
+ internal_executable::InternalExecutable,
7
8
  internal_executable_definition::{
8
9
  InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
9
10
  },
10
11
  },
11
12
  executor::executor::Executor,
12
13
  internal_commands::help::Help,
14
+ internal_filesystem::internal_filesystem::InternalFileSystem,
13
15
  logger::logger::Logger,
14
16
  };
15
17
 
@@ -30,43 +32,44 @@ impl UpgradeRepoKit {
30
32
  }
31
33
  }
32
34
 
33
- fn get_package_manager(&self) -> &str {
34
- let manager_map = HashMap::from([
35
- ("npm", ("package-lock.json", "npm i -D")),
36
- ("yarn", ("yarn.lock", "yarn add -D")),
37
- ("pnpm", ("pnpm-lock.yaml", "pnpm i -D")),
38
- ("bun", ("bun.lockb", "bun add -d")),
39
- ]);
40
- for (manager, (lock_file, command_prefix)) in manager_map {
41
- let path = Path::new(&self.scope.root).join(lock_file).normalize();
42
- if path.exists() && path.is_file() {
43
- Logger::info(
44
- format!(
45
- "Detected {} installation",
46
- Logger::with_theme(|theme| theme.highlight(manager))
47
- )
48
- .as_str(),
49
- );
50
- return command_prefix;
51
- }
52
- }
53
- Logger::info("A node package manager was not detected");
54
- Logger::info(
55
- "To upgrade repokit install the latest version using the package manager of your choosing",
35
+ pub fn static_execute(root: &str) {
36
+ Logger::info("Upgrading installation");
37
+ let handle = SpinnerBuilder::new()
38
+ .spinner(&BOUNCING_BALL)
39
+ .text(" Installing")
40
+ .start();
41
+ let command_prefix = InternalFileSystem::get_install_command(root);
42
+ Executor::exec(
43
+ format!("{} @repokit/core@latest", command_prefix).as_str(),
44
+ |cmd| cmd.current_dir(root),
56
45
  );
57
- exit(0);
46
+ handle.done();
58
47
  }
59
48
  }
60
49
 
61
50
  impl InternalExecutable for UpgradeRepoKit {
62
51
  fn run(&self, _: Vec<String>, _: &HashMap<String, Box<dyn InternalExecutable>>) {
63
- Logger::info("Upgrading installation");
64
- let command_prefix = self.get_package_manager();
65
- Executor::exec(
66
- format!("{} @repokit/core@latest", command_prefix).as_str(),
67
- |cmd| cmd.current_dir(&self.scope.root),
68
- );
69
- Logger::info("Upgrade complete!");
52
+ let internal_fs = InternalFileSystem::new(&self.scope.root);
53
+ let fallback = "unknown";
54
+ let runtime_version = internal_fs
55
+ .installed_repokit_version()
56
+ .unwrap_or(fallback.to_string());
57
+ UpgradeRepoKit::static_execute(&self.scope.root);
58
+ let installed_version = internal_fs
59
+ .installed_repokit_version()
60
+ .unwrap_or(fallback.to_string());
61
+ if runtime_version != installed_version {
62
+ Logger::info("Upgrade Complete!");
63
+ Logger::info(
64
+ format!(
65
+ "The currently installed version is {}",
66
+ Logger::with_theme(|theme| theme.highlight(&installed_version))
67
+ )
68
+ .as_str(),
69
+ );
70
+ } else {
71
+ Logger::info("The latest version is already installed");
72
+ }
70
73
  }
71
74
 
72
75
  fn help(&self) {
@@ -1,3 +1,4 @@
1
+ use crate::post_processing::post_processor::PostProcessor;
1
2
  use std::{
2
3
  fs::{File, create_dir_all},
3
4
  io::{Error, copy},
@@ -14,6 +15,7 @@ impl FileBuilder {
14
15
  Ok(file) => file,
15
16
  Err(error) => {
16
17
  on_error(error);
18
+ PostProcessor::get().flush();
17
19
  exit(0);
18
20
  }
19
21
  }
@@ -25,6 +27,7 @@ impl FileBuilder {
25
27
  Ok(file) => file,
26
28
  Err(error) => {
27
29
  on_error(error);
30
+ PostProcessor::get().flush();
28
31
  exit(0);
29
32
  }
30
33
  }
@@ -50,6 +53,7 @@ impl FileBuilder {
50
53
  Ok(result) => result,
51
54
  Err(error) => {
52
55
  on_error(error);
56
+ PostProcessor::get().flush();
53
57
  exit(0);
54
58
  }
55
59
  }