@repokit/core 1.1.0 → 1.3.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.
@@ -1,10 +1,13 @@
1
1
  import type { ICommand, IRepoKitConfig } from "./types";
2
+ import type { RepoKitCommand } from "./RepoKitCommand";
2
3
 
3
4
  export class RepoKitConfig implements Required<IRepoKitConfig> {
4
5
  project: string;
6
+ thirdParty: RepoKitCommand[];
5
7
  commands: Record<string, ICommand>;
6
- constructor({ project, commands = {} }: IRepoKitConfig) {
8
+ constructor({ project, commands = {}, thirdParty = [] }: IRepoKitConfig) {
7
9
  this.project = project;
8
10
  this.commands = commands;
11
+ this.thirdParty = thirdParty;
9
12
  }
10
13
  }
@@ -1,5 +1,8 @@
1
+ import type { RepoKitCommand } from "./RepoKitCommand";
2
+
1
3
  export interface IRepoKitConfig {
2
4
  project: string;
5
+ thirdParty?: RepoKitCommand[];
3
6
  commands?: Record<string, ICommand>;
4
7
  }
5
8
 
@@ -6,7 +6,7 @@ REPO_ROOT=$(git rev-parse --show-toplevel)
6
6
  cd $REPO_ROOT
7
7
 
8
8
  command_exists() {
9
- command -v "$1"
9
+ command -v "$1" > /dev/null 2>&1
10
10
  }
11
11
 
12
12
  if command_exists rustc && command_exists cargo; then
@@ -12,7 +12,8 @@ impl Configuration {
12
12
  return;
13
13
  }
14
14
  Configuration::welcome();
15
- let template_path = InternalFileSystem::resolve_template("configuration_template.ts");
15
+ let template_path =
16
+ InternalFileSystem::new(root).resolve_template("configuration_template.ts");
16
17
  let mut source = File::open(template_path).expect("Template");
17
18
  let mut target = File::create(path_buf).expect("creating");
18
19
  io::copy(&mut source, &mut target).expect("writing");
@@ -1,5 +1,13 @@
1
1
  use std::collections::HashMap;
2
2
 
3
+ use crate::repokit::interfaces::RepoKitConfig;
4
+
5
+ #[derive(Clone)]
6
+ pub struct RepoKitScope {
7
+ pub root: String,
8
+ pub configuration: RepoKitConfig,
9
+ }
10
+
3
11
  #[derive(Clone)]
4
12
  pub struct InternalExecutableDefinition {
5
13
  pub name: String,
@@ -14,7 +22,7 @@ pub struct InternalExecutableDefinitionInput<'a, const N: usize> {
14
22
  }
15
23
 
16
24
  impl InternalExecutableDefinition {
17
- pub fn define<'a, const N: usize>(
25
+ pub fn define<const N: usize>(
18
26
  definition: InternalExecutableDefinitionInput<N>,
19
27
  ) -> InternalExecutableDefinition {
20
28
  let InternalExecutableDefinitionInput {
@@ -17,8 +17,10 @@ pub struct ExternalCommands {
17
17
  }
18
18
 
19
19
  impl ExternalCommands {
20
- pub fn new(root: String) -> ExternalCommands {
21
- ExternalCommands { root }
20
+ pub fn new(root: &str) -> ExternalCommands {
21
+ ExternalCommands {
22
+ root: root.to_string(),
23
+ }
22
24
  }
23
25
 
24
26
  pub async fn find_all(&self) -> Vec<RepoKitCommand> {
@@ -64,7 +66,7 @@ impl ExternalCommands {
64
66
  }
65
67
  }
66
68
  pool.pool.shutdown_background();
67
- TypescriptCommand::new(self.root.clone()).parse_commands(paths)
69
+ TypescriptCommand::new(&self.root).parse_commands(paths)
68
70
  }
69
71
 
70
72
  fn read(path: &Path) -> bool {
@@ -1,58 +1,36 @@
1
1
  use std::collections::HashMap;
2
2
 
3
3
  use crate::{
4
- executables::intenal_executable::InternalExecutable,
4
+ executables::{
5
+ intenal_executable::InternalExecutable, internal_executable_definition::RepoKitScope,
6
+ },
5
7
  internal_commands::{
6
8
  list_commands::ListCommands, list_owners::ListOwners, locate_command::LocateCommand,
7
9
  onboarder::Onboarder, register_command::RegisterCommand, search_commands::SearchCommands,
8
10
  upgrade_repokit::UpgradeRepoKit,
9
11
  },
10
- repokit::interfaces::RepoKitConfig,
11
12
  };
12
13
 
13
14
  pub struct InternalRegistry {
14
- root: String,
15
- configuration: RepoKitConfig,
15
+ scope: RepoKitScope,
16
16
  }
17
17
 
18
18
  impl InternalRegistry {
19
- pub fn new(root: String, configuration: RepoKitConfig) -> InternalRegistry {
19
+ pub fn new(scope: &RepoKitScope) -> InternalRegistry {
20
20
  InternalRegistry {
21
- root,
22
- configuration,
21
+ scope: scope.clone(),
23
22
  }
24
23
  }
25
24
 
26
25
  pub fn get_all(&self) -> HashMap<String, Box<dyn InternalExecutable>> {
27
26
  let internals: [Box<dyn InternalExecutable>; 7] = [
28
- Box::new(Onboarder::new(
29
- self.root.clone(),
30
- self.configuration.clone(),
31
- )),
32
- Box::new(ListCommands::new(
33
- self.root.clone(),
34
- self.configuration.clone(),
35
- )),
36
- Box::new(SearchCommands::new(
37
- self.root.clone(),
38
- self.configuration.clone(),
39
- )),
40
- Box::new(ListOwners::new(
41
- self.root.clone(),
42
- self.configuration.clone(),
43
- )),
44
- Box::new(LocateCommand::new(
45
- self.root.clone(),
46
- self.configuration.clone(),
47
- )),
48
- Box::new(RegisterCommand::new(
49
- self.root.clone(),
50
- self.configuration.clone(),
51
- )),
52
- Box::new(UpgradeRepoKit::new(
53
- self.root.clone(),
54
- self.configuration.clone(),
55
- )),
27
+ Box::new(Onboarder::new(&self.scope)),
28
+ Box::new(ListCommands::new(&self.scope)),
29
+ Box::new(SearchCommands::new(&self.scope)),
30
+ Box::new(ListOwners::new(&self.scope)),
31
+ Box::new(LocateCommand::new(&self.scope)),
32
+ Box::new(RegisterCommand::new(&self.scope)),
33
+ Box::new(UpgradeRepoKit::new(&self.scope)),
56
34
  ];
57
35
  HashMap::from(internals.map(|x| (x.get_definition().name.to_string(), x)))
58
36
  }
@@ -4,28 +4,26 @@ use crate::{
4
4
  executables::{
5
5
  intenal_executable::InternalExecutable,
6
6
  internal_executable_definition::{
7
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
7
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
8
8
  },
9
9
  },
10
10
  internal_commands::help::Help,
11
11
  logger::logger::Logger,
12
- repokit::interfaces::{RepoKitCommand, RepoKitConfig},
12
+ repokit::interfaces::RepoKitCommand,
13
13
  validations::command_validations::CommandValidations,
14
14
  };
15
15
 
16
16
  pub struct ListCommands {
17
- pub root: String,
18
- pub configuration: RepoKitConfig,
17
+ pub scope: RepoKitScope,
19
18
  pub definition: InternalExecutableDefinition,
20
19
  }
21
20
 
22
21
  static SCOPES: [&str; 4] = ["internal", "registered", "root", "<owner>"];
23
22
 
24
23
  impl ListCommands {
25
- pub fn new(root: String, configuration: RepoKitConfig) -> ListCommands {
24
+ pub fn new(scope: &RepoKitScope) -> ListCommands {
26
25
  ListCommands {
27
- root,
28
- configuration,
26
+ scope: scope.clone(),
29
27
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
30
28
  name: "list",
31
29
  description: "List commands based on their scope of definition",
@@ -42,7 +40,7 @@ impl ListCommands {
42
40
  }
43
41
 
44
42
  fn collect_registered_commands(&self) -> HashMap<String, RepoKitCommand> {
45
- let validators = CommandValidations::new(self.root.clone(), self.configuration.clone());
43
+ let validators = CommandValidations::new(&self.scope);
46
44
  validators.collect_and_validate_externals()
47
45
  }
48
46
 
@@ -68,7 +66,7 @@ impl InternalExecutable for ListCommands {
68
66
  return Help::log_internal_commands(internals);
69
67
  }
70
68
  if scope == SCOPES[2] {
71
- return Help::log_root_commands(&self.configuration.commands);
69
+ return Help::log_root_commands(&self.scope.configuration.commands);
72
70
  }
73
71
  let registered_commands = self.collect_registered_commands();
74
72
  if scope == SCOPES[1] {
@@ -6,26 +6,24 @@ use crate::{
6
6
  executables::{
7
7
  intenal_executable::InternalExecutable,
8
8
  internal_executable_definition::{
9
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
9
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
10
10
  },
11
11
  },
12
12
  internal_commands::help::Help,
13
13
  logger::logger::Logger,
14
- repokit::interfaces::{RepoKitCommand, RepoKitConfig},
14
+ repokit::interfaces::RepoKitCommand,
15
15
  validations::command_validations::CommandValidations,
16
16
  };
17
17
 
18
18
  pub struct ListOwners {
19
- pub root: String,
20
- pub configuration: RepoKitConfig,
19
+ pub scope: RepoKitScope,
21
20
  pub definition: InternalExecutableDefinition,
22
21
  }
23
22
 
24
23
  impl ListOwners {
25
- pub fn new(root: String, configuration: RepoKitConfig) -> ListOwners {
24
+ pub fn new(scope: &RepoKitScope) -> ListOwners {
26
25
  ListOwners {
27
- root,
28
- configuration,
26
+ scope: scope.clone(),
29
27
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
30
28
  name: "owners",
31
29
  description: "Lists all registered command owners",
@@ -35,7 +33,7 @@ impl ListOwners {
35
33
  }
36
34
 
37
35
  fn collect_registered_commands(&self) -> HashMap<String, RepoKitCommand> {
38
- let validators = CommandValidations::new(self.root.clone(), self.configuration.clone());
36
+ let validators = CommandValidations::new(&self.scope);
39
37
  validators.collect_and_validate_externals()
40
38
  }
41
39
  }
@@ -1,30 +1,26 @@
1
- use ::futures::executor;
2
1
  use std::{collections::HashMap, process::exit};
3
2
 
4
3
  use crate::{
5
4
  executables::{
6
5
  intenal_executable::InternalExecutable,
7
6
  internal_executable_definition::{
8
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
7
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
9
8
  },
10
9
  },
11
- external_commands::external_commands::ExternalCommands,
12
10
  internal_commands::help::Help,
13
11
  logger::logger::Logger,
14
- repokit::interfaces::RepoKitConfig,
12
+ validations::command_validations::CommandValidations,
15
13
  };
16
14
 
17
15
  pub struct LocateCommand {
18
- pub root: String,
19
- pub configuration: RepoKitConfig,
16
+ pub scope: RepoKitScope,
20
17
  pub definition: InternalExecutableDefinition,
21
18
  }
22
19
 
23
20
  impl LocateCommand {
24
- pub fn new(root: String, configuration: RepoKitConfig) -> LocateCommand {
21
+ pub fn new(scope: &RepoKitScope) -> LocateCommand {
25
22
  LocateCommand {
26
- root,
27
- configuration,
23
+ scope: scope.clone(),
28
24
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
29
25
  name: "locate",
30
26
  description: "Locates command definitions",
@@ -34,9 +30,9 @@ impl LocateCommand {
34
30
  }
35
31
 
36
32
  fn search_externals(&self, query: &str) {
37
- let finder = ExternalCommands::new(self.root.clone());
38
- let commands = executor::block_on(finder.find_all());
39
- for command in commands {
33
+ let finder = CommandValidations::new(&self.scope);
34
+ let all = finder.collect_and_validate_externals();
35
+ for (_, command) in all {
40
36
  if command.name == query {
41
37
  Logger::log_file_path(&command.location);
42
38
  exit(0);
@@ -45,8 +41,8 @@ impl LocateCommand {
45
41
  }
46
42
 
47
43
  fn search_root(&self, command: &str) {
48
- if self.configuration.commands.contains_key(command) {
49
- Logger::log_file_path(format!("{}/repokit.ts", &self.root).as_str());
44
+ if self.scope.configuration.commands.contains_key(command) {
45
+ Logger::log_file_path(format!("{}/repokit.ts", &self.scope.root).as_str());
50
46
  exit(0);
51
47
  }
52
48
  }
@@ -4,25 +4,22 @@ use crate::{
4
4
  executables::{
5
5
  intenal_executable::InternalExecutable,
6
6
  internal_executable_definition::{
7
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
7
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
8
8
  },
9
9
  },
10
10
  internal_commands::help::Help,
11
11
  logger::logger::Logger,
12
- repokit::interfaces::RepoKitConfig,
13
12
  };
14
13
 
15
14
  pub struct Onboarder {
16
- pub root: String,
17
- pub configuration: RepoKitConfig,
15
+ pub scope: RepoKitScope,
18
16
  pub definition: InternalExecutableDefinition,
19
17
  }
20
18
 
21
19
  impl Onboarder {
22
- pub fn new(root: String, configuration: RepoKitConfig) -> Onboarder {
20
+ pub fn new(scope: &RepoKitScope) -> Onboarder {
23
21
  Onboarder {
24
- root,
25
- configuration,
22
+ scope: scope.clone(),
26
23
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
27
24
  name: "onboard",
28
25
  description: "Onboarding instructions for first time users",
@@ -11,26 +11,23 @@ use crate::{
11
11
  executables::{
12
12
  intenal_executable::InternalExecutable,
13
13
  internal_executable_definition::{
14
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
14
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
15
15
  },
16
16
  },
17
17
  internal_commands::help::Help,
18
18
  internal_filesystem::internal_filesystem::InternalFileSystem,
19
19
  logger::logger::Logger,
20
- repokit::interfaces::RepoKitConfig,
21
20
  };
22
21
 
23
22
  pub struct RegisterCommand {
24
- pub root: String,
25
- pub configuration: RepoKitConfig,
23
+ pub scope: RepoKitScope,
26
24
  pub definition: InternalExecutableDefinition,
27
25
  }
28
26
 
29
27
  impl RegisterCommand {
30
- pub fn new(root: String, configuration: RepoKitConfig) -> RegisterCommand {
28
+ pub fn new(scope: &RepoKitScope) -> RegisterCommand {
31
29
  RegisterCommand {
32
- root,
33
- configuration,
30
+ scope: scope.clone(),
34
31
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
35
32
  name: "register",
36
33
  description: "Creates new Repokit commands",
@@ -50,7 +47,7 @@ impl RegisterCommand {
50
47
  if path_arg.is_empty() {
51
48
  RegisterCommand::exit_on_missing_path();
52
49
  }
53
- let path = Path::new(&self.root).join(&path_arg).normalize();
50
+ let path = Path::new(&self.scope.root).join(&path_arg).normalize();
54
51
  if !path.exists() {
55
52
  Logger::info(
56
53
  format!(
@@ -93,7 +90,8 @@ impl InternalExecutable for RegisterCommand {
93
90
  fn run(&self, args: Vec<String>, _: &HashMap<String, Box<dyn InternalExecutable>>) {
94
91
  Logger::info("Registering a new command");
95
92
  let command_path = self.validate_path(args);
96
- let template_path = InternalFileSystem::resolve_template("command_template.ts");
93
+ let template_path =
94
+ InternalFileSystem::new(&self.scope.root).resolve_template("command_template.ts");
97
95
  let mut source = File::open(template_path).expect("Template");
98
96
  let mut target = File::create(&command_path).expect("creating");
99
97
  io::copy(&mut source, &mut target).expect("writing");
@@ -5,26 +5,24 @@ use crate::{
5
5
  executables::{
6
6
  intenal_executable::InternalExecutable,
7
7
  internal_executable_definition::{
8
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
8
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
9
9
  },
10
10
  },
11
11
  internal_commands::help::Help,
12
12
  logger::logger::Logger,
13
- repokit::interfaces::{CommandDefinition, RepoKitCommand, RepoKitConfig},
13
+ repokit::interfaces::{CommandDefinition, RepoKitCommand},
14
14
  validations::command_validations::CommandValidations,
15
15
  };
16
16
 
17
17
  pub struct SearchCommands {
18
- pub root: String,
19
- pub configuration: RepoKitConfig,
18
+ pub scope: RepoKitScope,
20
19
  pub definition: InternalExecutableDefinition,
21
20
  }
22
21
 
23
22
  impl SearchCommands {
24
- pub fn new(root: String, configuration: RepoKitConfig) -> SearchCommands {
23
+ pub fn new(scope: &RepoKitScope) -> SearchCommands {
25
24
  SearchCommands {
26
- root,
27
- configuration,
25
+ scope: scope.clone(),
28
26
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
29
27
  name: "search",
30
28
  description: "Retrieve commands that match any search query",
@@ -46,8 +44,7 @@ impl SearchCommands {
46
44
  }
47
45
  if let Some(args) = &config.args {
48
46
  for (arg, description) in args {
49
- if arg.to_lowercase().contains(query)
50
- || description.to_lowercase().contains(query)
47
+ if arg.to_lowercase().contains(query) || description.to_lowercase().contains(query)
51
48
  {
52
49
  return true;
53
50
  }
@@ -66,7 +63,7 @@ impl SearchCommands {
66
63
  }
67
64
  if command
68
65
  .location
69
- .replace(self.root.as_str(), "")
66
+ .replace(self.scope.root.as_str(), "")
70
67
  .to_lowercase()
71
68
  .contains(query)
72
69
  {
@@ -158,12 +155,11 @@ impl InternalExecutable for SearchCommands {
158
155
  Logger::exit_with_error("Please specify a search string to query with");
159
156
  }
160
157
  let query = args.join(" ").to_lowercase();
161
- let externals = CommandValidations::new(self.root.clone(), self.configuration.clone())
162
- .collect_and_validate_externals();
158
+ let externals = CommandValidations::new(&self.scope).collect_and_validate_externals();
163
159
  let mut root_results: HashMap<String, CommandDefinition> = HashMap::new();
164
160
  let mut internal_results: HashMap<String, &Box<dyn InternalExecutable>> = HashMap::new();
165
161
  let mut external_results: HashMap<String, RepoKitCommand> = HashMap::new();
166
- for (command, script) in &self.configuration.commands {
162
+ for (command, script) in &self.scope.configuration.commands {
167
163
  if self.search_command(&query, script) {
168
164
  root_results.insert(command.clone(), script.clone());
169
165
  }
@@ -14,24 +14,26 @@ pub struct TypescriptCommand {
14
14
  }
15
15
 
16
16
  impl TypescriptCommand {
17
- pub fn new(root: String) -> TypescriptCommand {
18
- TypescriptCommand { root }
17
+ pub fn new(root: &str) -> TypescriptCommand {
18
+ TypescriptCommand {
19
+ root: root.to_string(),
20
+ }
19
21
  }
20
22
 
21
23
  pub fn parse_configuration(&self) -> RepoKitConfig {
22
- let executable = InternalFileSystem::resolve_command("parse_configuration.ts");
24
+ let executable =
25
+ InternalFileSystem::new(&self.root).resolve_command("parse_configuration.ts");
23
26
  let stdout = self.execute(format!("{executable} --root {}", &self.root).as_str());
24
27
  if stdout.is_empty() {
25
28
  Configuration::create(&self.root);
26
29
  }
27
- let RepoKitConfig { project, commands } =
28
- from_str(stdout.as_str()).expect("Error parsing stdout");
29
- RepoKitConfig { project, commands }
30
+ let config: RepoKitConfig = from_str(stdout.as_str()).unwrap();
31
+ config
30
32
  }
31
33
 
32
34
  pub fn parse_commands(&self, path_list: Vec<String>) -> Vec<RepoKitCommand> {
33
35
  let paths = path_list.join(",");
34
- let executable = InternalFileSystem::resolve_command("parse_commands.ts");
36
+ let executable = InternalFileSystem::new(&self.root).resolve_command("parse_commands.ts");
35
37
  let stdout =
36
38
  self.execute(format!("{executable} --paths {paths} --root {}", self.root).as_str());
37
39
  let commands: Vec<RepoKitCommand> = serde_json::from_str(&stdout).expect("parse");
@@ -5,26 +5,23 @@ use crate::{
5
5
  executables::{
6
6
  intenal_executable::InternalExecutable,
7
7
  internal_executable_definition::{
8
- InternalExecutableDefinition, InternalExecutableDefinitionInput,
8
+ InternalExecutableDefinition, InternalExecutableDefinitionInput, RepoKitScope,
9
9
  },
10
10
  },
11
11
  executor::executor::Executor,
12
12
  internal_commands::help::Help,
13
13
  logger::logger::Logger,
14
- repokit::interfaces::RepoKitConfig,
15
14
  };
16
15
 
17
16
  pub struct UpgradeRepoKit {
18
- pub root: String,
19
- pub configuration: RepoKitConfig,
17
+ pub scope: RepoKitScope,
20
18
  pub definition: InternalExecutableDefinition,
21
19
  }
22
20
 
23
21
  impl UpgradeRepoKit {
24
- pub fn new(root: String, configuration: RepoKitConfig) -> UpgradeRepoKit {
22
+ pub fn new(scope: &RepoKitScope) -> UpgradeRepoKit {
25
23
  UpgradeRepoKit {
26
- root,
27
- configuration,
24
+ scope: scope.clone(),
28
25
  definition: InternalExecutableDefinition::define(InternalExecutableDefinitionInput {
29
26
  name: "upgrade",
30
27
  description: "Upgrades your installation of repokit to the latest stable version",
@@ -41,7 +38,7 @@ impl UpgradeRepoKit {
41
38
  ("bun", ("bun.lockb", "bun add -d")),
42
39
  ]);
43
40
  for (manager, (lock_file, command_prefix)) in manager_map {
44
- let path = Path::new(&self.root).join(lock_file).normalize();
41
+ let path = Path::new(&self.scope.root).join(lock_file).normalize();
45
42
  if path.exists() && path.is_file() {
46
43
  Logger::info(
47
44
  format!("Detected {} installation", Logger::blue_bright(manager)).as_str(),
@@ -63,7 +60,7 @@ impl InternalExecutable for UpgradeRepoKit {
63
60
  let command_prefix = self.get_package_manager();
64
61
  Executor::exec(
65
62
  format!("{} @repokit/core@latest", command_prefix).as_str(),
66
- |cmd| cmd.current_dir(&self.root),
63
+ |cmd| cmd.current_dir(&self.scope.root),
67
64
  );
68
65
  Logger::info("Upgrade complete!");
69
66
  }
@@ -1,36 +1,47 @@
1
1
  use normalize_path::NormalizePath;
2
2
  use std::path::{Path, PathBuf};
3
3
 
4
- pub struct InternalFileSystem;
4
+ pub struct InternalFileSystem {
5
+ root: String,
6
+ }
5
7
 
6
8
  impl InternalFileSystem {
7
- pub fn absolute(segment: &str) -> PathBuf {
8
- let origin = env!("CARGO_MANIFEST_DIR");
9
- let path = Path::new(origin);
9
+ pub fn new(root: &str) -> InternalFileSystem {
10
+ InternalFileSystem {
11
+ root: root.to_string(),
12
+ }
13
+ }
14
+
15
+ pub fn absolute(&self, segment: &str) -> PathBuf {
16
+ let path = Path::new(&self.root);
10
17
  path.join(segment).normalize()
11
18
  }
12
19
 
13
- pub fn resolve_command(file_name: &str) -> String {
14
- InternalFileSystem::path_buf_to_str(
15
- InternalFileSystem::commands_directory().join(file_name),
16
- )
20
+ pub fn resolve_command(&self, file_name: &str) -> String {
21
+ self.path_buf_to_str(self.commands_directory().join(file_name))
22
+ }
23
+
24
+ pub fn resolve_template(&self, file_name: &str) -> String {
25
+ self.path_buf_to_str(self.templates_directory().join(file_name))
26
+ }
27
+
28
+ fn commands_directory(&self) -> PathBuf {
29
+ self.absolute(format!("{}/commands", self.package_directory()).as_str())
17
30
  }
18
31
 
19
- pub fn resolve_template(file_name: &str) -> String {
20
- InternalFileSystem::path_buf_to_str(
21
- InternalFileSystem::templates_directory().join(file_name),
22
- )
32
+ fn templates_directory(&self) -> PathBuf {
33
+ self.absolute(format!("{}/templates", self.package_directory()).as_str())
23
34
  }
24
35
 
25
- fn commands_directory() -> PathBuf {
26
- InternalFileSystem::absolute("./externals/commands")
36
+ fn package_directory(&self) -> String {
37
+ format!("./node_modules/{}/externals", self.package_name())
27
38
  }
28
39
 
29
- fn templates_directory() -> PathBuf {
30
- InternalFileSystem::absolute("./externals/templates")
40
+ fn package_name(&self) -> String {
41
+ "@repokit/core".to_string()
31
42
  }
32
43
 
33
- fn path_buf_to_str(buffer: PathBuf) -> String {
44
+ fn path_buf_to_str(&self, buffer: PathBuf) -> String {
34
45
  buffer
35
46
  .into_os_string()
36
47
  .into_string()
package/internals/main.rs CHANGED
@@ -15,7 +15,7 @@ mod validations;
15
15
 
16
16
  fn main() {
17
17
  let root = Executor::exec("git rev-parse --show-toplevel", |cmd| cmd);
18
- let config = TypescriptCommand::new(root.clone()).parse_configuration();
18
+ let config = TypescriptCommand::new(&root).parse_configuration();
19
19
  let kit = RepoKit::new(root, config);
20
20
  kit.invoke();
21
21
  }
@@ -31,13 +31,19 @@ impl RootCommand {
31
31
  #[derive(Debug, Deserialize, Clone)]
32
32
  pub struct RepoKitConfig {
33
33
  pub project: String,
34
+ pub thirdParty: Vec<RepoKitCommand>,
34
35
  pub commands: HashMap<String, CommandDefinition>,
35
36
  }
36
37
 
38
+ fn registered_as_plugin() -> String {
39
+ "This command is registered in your devkit.ts file".to_string()
40
+ }
41
+
37
42
  #[derive(Debug, Deserialize, Clone)]
38
43
  pub struct RepoKitCommand {
39
44
  pub name: String,
40
45
  pub owner: String,
46
+ #[serde(default = "registered_as_plugin")]
41
47
  pub location: String,
42
48
  pub description: String,
43
49
  pub commands: HashMap<String, CommandDefinition>,
@@ -6,7 +6,9 @@ use std::{
6
6
  };
7
7
 
8
8
  use crate::{
9
- executables::intenal_executable::InternalExecutable,
9
+ executables::{
10
+ intenal_executable::InternalExecutable, internal_executable_definition::RepoKitScope,
11
+ },
10
12
  executor::executor::Executor,
11
13
  internal_commands::help::Help,
12
14
  logger::logger::Logger,
@@ -15,16 +17,17 @@ use crate::{
15
17
  };
16
18
 
17
19
  pub struct RepoKit {
18
- pub root: String,
19
- pub configuration: RepoKitConfig,
20
+ pub scope: RepoKitScope,
20
21
  }
21
22
 
22
23
  impl RepoKit {
23
24
  pub fn new(root: String, configuration: RepoKitConfig) -> RepoKit {
24
25
  Logger::set_name(&configuration.project);
25
26
  RepoKit {
26
- root,
27
- configuration,
27
+ scope: RepoKitScope {
28
+ root,
29
+ configuration,
30
+ },
28
31
  }
29
32
  }
30
33
 
@@ -36,11 +39,16 @@ impl RepoKit {
36
39
  let interface = internals.get(&command).expect("exists");
37
40
  return interface.run(args, &internals);
38
41
  }
39
- if self.configuration.commands.contains_key(&command) {
40
- let root_script = self.configuration.commands.get(&command).expect("exists");
42
+ if self.scope.configuration.commands.contains_key(&command) {
43
+ let root_script = self
44
+ .scope
45
+ .configuration
46
+ .commands
47
+ .get(&command)
48
+ .expect("exists");
41
49
  return Executor::with_stdio(
42
50
  format!("{} {}", root_script.command, &args.join(" ")),
43
- |cmd| cmd.current_dir(Path::new(&self.root)),
51
+ |cmd| cmd.current_dir(Path::new(&self.scope.root)),
44
52
  );
45
53
  }
46
54
  let externals = validator.collect_and_validate_externals();
@@ -70,7 +78,7 @@ impl RepoKit {
70
78
  let argv: Vec<String> = args().collect();
71
79
  if argv.len() < 2 {
72
80
  let (internals, externals) = self.collect_and_validate();
73
- Help::list_all(&self.configuration.commands, &internals, &externals);
81
+ Help::list_all(&self.scope.configuration.commands, &internals, &externals);
74
82
  process::exit(0);
75
83
  }
76
84
  let command = &argv[1];
@@ -99,7 +107,7 @@ impl RepoKit {
99
107
  internals: &HashMap<String, Box<dyn InternalExecutable>>,
100
108
  externals: &HashMap<String, RepoKitCommand>,
101
109
  ) {
102
- Help::list_all(&self.configuration.commands, internals, externals);
110
+ Help::list_all(&self.scope.configuration.commands, internals, externals);
103
111
  Logger::info(
104
112
  format!(
105
113
  "I'm not aware of a command named {}",
@@ -3,47 +3,43 @@ use std::collections::HashMap;
3
3
  use futures::executor;
4
4
 
5
5
  use crate::{
6
- repokit::{
7
- repokit::RepoKit,
8
- interfaces::{RepoKitCommand, RepoKitConfig},
6
+ executables::{
7
+ intenal_executable::InternalExecutable, internal_executable_definition::RepoKitScope,
9
8
  },
10
- executables::intenal_executable::InternalExecutable,
11
9
  external_commands::external_commands::ExternalCommands,
12
10
  internal_commands::internal_registry::InternalRegistry,
13
11
  logger::logger::Logger,
12
+ repokit::{interfaces::RepoKitCommand, repokit::RepoKit},
14
13
  };
15
14
 
16
15
  pub struct CommandValidations {
17
- root: String,
18
- configuration: RepoKitConfig,
16
+ scope: RepoKitScope,
19
17
  }
20
18
 
21
19
  impl CommandValidations {
22
- pub fn new(root: String, configuration: RepoKitConfig) -> CommandValidations {
20
+ pub fn new(scope: &RepoKitScope) -> CommandValidations {
23
21
  CommandValidations {
24
- root,
25
- configuration,
22
+ scope: scope.clone(),
26
23
  }
27
24
  }
28
25
 
29
26
  pub fn from(kit: &RepoKit) -> CommandValidations {
30
27
  CommandValidations {
31
- root: kit.root.clone(),
32
- configuration: kit.configuration.clone(),
28
+ scope: kit.scope.clone(),
33
29
  }
34
30
  }
35
31
 
36
32
  pub fn collect_and_validate_internals(&self) -> HashMap<String, Box<dyn InternalExecutable>> {
37
- let internals =
38
- InternalRegistry::new(self.root.clone(), self.configuration.clone()).get_all();
33
+ let internals = InternalRegistry::new(&self.scope).get_all();
39
34
  self.detect_collisions_between_internals_and_root_commands(&internals);
40
35
  internals
41
36
  }
42
37
 
43
38
  pub fn collect_and_validate_externals(&self) -> HashMap<String, RepoKitCommand> {
44
- let finder = ExternalCommands::new(self.root.clone());
39
+ let finder = ExternalCommands::new(&self.scope.root);
45
40
  let externals = executor::block_on(finder.find_all());
46
- self.detect_collisions_between_root_commands_and_externals(&externals)
41
+ let all = [&externals[..], &self.scope.configuration.thirdParty[..]].concat();
42
+ self.detect_collisions_between_root_commands_and_externals(&all)
47
43
  }
48
44
 
49
45
  pub fn detect_collisions_between_internals_and_externals(
@@ -71,7 +67,7 @@ impl CommandValidations {
71
67
  internals: &HashMap<String, Box<dyn InternalExecutable>>,
72
68
  ) {
73
69
  for name in internals.keys() {
74
- if self.configuration.commands.contains_key(name) {
70
+ if self.scope.configuration.commands.contains_key(name) {
75
71
  Logger::info(
76
72
  format!(
77
73
  "I encountered a command named {} in your {} file that conflicts with one of my internals",
@@ -96,7 +92,12 @@ impl CommandValidations {
96
92
  self.on_external_duplicate_collision(command, &original.location);
97
93
  }
98
94
  map.insert(command.name.clone(), command.clone());
99
- if self.configuration.commands.contains_key(&command.name) {
95
+ if self
96
+ .scope
97
+ .configuration
98
+ .commands
99
+ .contains_key(&command.name)
100
+ {
100
101
  self.on_external_root_collision(command);
101
102
  }
102
103
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repokit/core",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "A knowledgebase for your repository - wrapped in a CLI",
5
5
  "keywords": [
6
6
  "cli",
@@ -22,12 +22,14 @@
22
22
  "scripts": {
23
23
  "build:all": "yarn lint:ts && yarn lint:rust && yarn install:rust",
24
24
  "build:rust": "cargo build --release",
25
+ "grant:exec": "chmod -R +x ./installation",
25
26
  "install:rust": "yarn build:rust && cargo install --path .",
26
27
  "lint:rust": "cargo clippy --fix --allow-dirty",
27
28
  "lint:ts": "yarn oxlint --type-aware --type-check --report-unused-disable-directives --fix && yarn oxfmt",
28
- "postinstall": "chmod +x ./install.sh && ./install.sh",
29
- "repokit": "yarn install:repokit && repokit",
30
- "run:dev": "cargo run --package repokit --bin repokit"
29
+ "postinstall": "yarn grant:exec && ./installation/install.sh",
30
+ "repokit": "yarn install:rust && repokit",
31
+ "run:dev": "yarn symlink && cargo run --package repokit --bin repokit",
32
+ "symlink": "yarn grant:exec && ./installation/symlink.sh"
31
33
  },
32
34
  "dependencies": {
33
35
  "@figliolia/event-emitter": "^1.1.6",