@repokit/core 2.0.6 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +3 -3
- package/Cargo.toml +2 -2
- package/README.md +45 -0
- package/dist/RepoKitConfig.d.mts +4 -1
- package/dist/RepoKitConfig.mjs +3 -1
- package/dist/RepoKitTheme.d.mts +47 -0
- package/dist/RepoKitTheme.mjs +45 -0
- package/dist/TSCompiler.mjs +1 -5
- package/dist/Themes.d.mts +8 -0
- package/dist/Themes.mjs +31 -0
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +3 -1
- package/dist/types.d.mts +5 -1
- package/externals/RepoKitConfig.ts +10 -2
- package/externals/RepoKitTheme.ts +52 -0
- package/externals/TSCompiler.ts +1 -6
- package/externals/Themes.ts +31 -0
- package/externals/index.ts +2 -0
- package/externals/types.ts +7 -0
- package/installation/install.sh +1 -1
- package/internals/configuration/configuration.rs +2 -2
- package/internals/internal_commands/help.rs +51 -39
- package/internals/internal_commands/list_commands.rs +3 -3
- package/internals/internal_commands/locate_command.rs +8 -2
- package/internals/internal_commands/onboarder.rs +10 -4
- package/internals/internal_commands/register_command.rs +3 -3
- package/internals/internal_commands/search_commands.rs +3 -3
- package/internals/internal_commands/upgrade_repokit.rs +5 -1
- package/internals/internal_filesystem/internal_filesystem.rs +2 -2
- package/internals/logger/logger.rs +27 -54
- package/internals/main.rs +1 -0
- package/internals/repokit/interfaces.rs +3 -0
- package/internals/repokit/repokit.rs +8 -5
- package/internals/themes/mod.rs +2 -0
- package/internals/themes/theme.rs +130 -0
- package/internals/themes/theme_registry.rs +29 -0
- package/internals/validations/command_validations.rs +8 -8
- package/media/seeing-red.webp +0 -0
- package/package.json +4 -4
package/Cargo.lock
CHANGED
|
@@ -169,7 +169,7 @@ checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
|
|
|
169
169
|
|
|
170
170
|
[[package]]
|
|
171
171
|
name = "repokit"
|
|
172
|
-
version = "2.0
|
|
172
|
+
version = "2.1.0"
|
|
173
173
|
dependencies = [
|
|
174
174
|
"alphanumeric-sort",
|
|
175
175
|
"colored",
|
|
@@ -246,9 +246,9 @@ dependencies = [
|
|
|
246
246
|
|
|
247
247
|
[[package]]
|
|
248
248
|
name = "tokio"
|
|
249
|
-
version = "1.
|
|
249
|
+
version = "1.50.0"
|
|
250
250
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
251
|
-
checksum = "
|
|
251
|
+
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
|
|
252
252
|
dependencies = [
|
|
253
253
|
"pin-project-lite",
|
|
254
254
|
]
|
package/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "repokit"
|
|
3
|
-
version = "2.0
|
|
3
|
+
version = "2.1.0"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
|
|
6
6
|
[[bin]]
|
|
@@ -13,6 +13,6 @@ serde_json = "1.0"
|
|
|
13
13
|
colored = "3"
|
|
14
14
|
normalize-path = "0.2.1"
|
|
15
15
|
alphanumeric-sort = "1.5.5"
|
|
16
|
-
tokio = "1.
|
|
16
|
+
tokio = "1.50.0"
|
|
17
17
|
ignore = "0.4.25"
|
|
18
18
|
regex = { version = "1.12.3", features = ["std", "unicode"] }
|
package/README.md
CHANGED
|
@@ -228,6 +228,51 @@ The commands you register onto the repokit toolchain will always be invoked usin
|
|
|
228
228
|
|
|
229
229
|
If your command needs to reason about the file system, keep this in mind.
|
|
230
230
|
|
|
231
|
+
### Themes
|
|
232
|
+
|
|
233
|
+
The Repokit CLI can be customized to support themes that better match your team's visual preferences.
|
|
234
|
+
|
|
235
|
+
Repokit comes with 4 pre-built themes that you can use in your `RepoKitConfig`.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import {
|
|
239
|
+
RepoKitConfig,
|
|
240
|
+
SeeingRed, // A red theme
|
|
241
|
+
TheBlues, // A blue theme
|
|
242
|
+
Green, // A green theme
|
|
243
|
+
} from "@repokit/core";
|
|
244
|
+
|
|
245
|
+
export const Kit = new RepoKitConfig({
|
|
246
|
+
project: "My Project",
|
|
247
|
+
theme: SeeingRed, // Specify a theme here
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
By omitting the `theme` property `RepoKit` will use its default visuals.
|
|
252
|
+
|
|
253
|
+
In addition to built-in themes, you can create your own using the `RepoKitTheme`
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import { RepoKitConfig, RepoKitTheme } from "@repokit/core";
|
|
257
|
+
|
|
258
|
+
export const Kit = new RepoKitConfig({
|
|
259
|
+
project: "My Project",
|
|
260
|
+
theme: new RepoKitTheme({
|
|
261
|
+
prefixColor: "rgb(220, 36, 91)",
|
|
262
|
+
commandColor: "rgb(220, 36, 36)",
|
|
263
|
+
subcommandColor: "rgb(220, 131, 36)",
|
|
264
|
+
argColor: "rgb(220, 205, 36)",
|
|
265
|
+
descriptionColor: "rgb(179, 100, 151)",
|
|
266
|
+
errorPrefixColor: "rgb(220, 36, 39)",
|
|
267
|
+
highlightColor: "rgb(237, 175, 41)",
|
|
268
|
+
}),
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
All properties on the `RepoKitTheme` are optional overrides for `RepoKit`'s default styling. A color can be any CSS-valid `rgb()` string.
|
|
273
|
+
|
|
274
|
+
<img src="media/seeing-red.webp" width="100%" alt="seeing red theme" />
|
|
275
|
+
|
|
231
276
|
## Motivation
|
|
232
277
|
|
|
233
278
|
I worked in a codebase at Google that used just about every programming language in existence. Each team had their own methodology for exposing commands, scripts, and API's for their team's day-to-day development needs.
|
package/dist/RepoKitConfig.d.mts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { RepoKitTheme } from "./RepoKitTheme.mjs";
|
|
1
2
|
import { ICommand, IRepoKitConfig } from "./types.mjs";
|
|
2
3
|
import { RepoKitCommand } from "./RepoKitCommand.mjs";
|
|
3
4
|
|
|
4
5
|
//#region externals/RepoKitConfig.d.ts
|
|
5
|
-
declare class RepoKitConfig
|
|
6
|
+
declare class RepoKitConfig {
|
|
6
7
|
project: string;
|
|
8
|
+
theme?: RepoKitTheme;
|
|
7
9
|
thirdParty: RepoKitCommand[];
|
|
8
10
|
commands: Record<string, ICommand>;
|
|
9
11
|
constructor({
|
|
12
|
+
theme,
|
|
10
13
|
project,
|
|
11
14
|
commands,
|
|
12
15
|
thirdParty
|
package/dist/RepoKitConfig.mjs
CHANGED
|
@@ -2,9 +2,11 @@ import { RepoKitCommand } from "./RepoKitCommand.mjs";
|
|
|
2
2
|
//#region externals/RepoKitConfig.ts
|
|
3
3
|
var RepoKitConfig = class {
|
|
4
4
|
project;
|
|
5
|
+
theme;
|
|
5
6
|
thirdParty;
|
|
6
7
|
commands;
|
|
7
|
-
constructor({ project, commands = {}, thirdParty = [] }) {
|
|
8
|
+
constructor({ theme, project, commands = {}, thirdParty = [] }) {
|
|
9
|
+
this.theme = theme;
|
|
8
10
|
this.project = project;
|
|
9
11
|
this.commands = commands;
|
|
10
12
|
this.thirdParty = thirdParty.map((command) => new RepoKitCommand(command));
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { RGBString } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region externals/RepoKitTheme.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Repokit Theme
|
|
6
|
+
*
|
|
7
|
+
* A repokit theme allows you to customize the color
|
|
8
|
+
* usage of the CLI by adding a `RepoKitTheme` instance
|
|
9
|
+
* to your `RepoKitConfig`
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { RepoKitConfig, RepoKitTheme } from "@repokit/core";
|
|
13
|
+
*
|
|
14
|
+
* export const RepoKit = new RepoKitConfig({
|
|
15
|
+
* project: "Repokit",
|
|
16
|
+
* theme: new RepoKitTheme({
|
|
17
|
+
* prefixColor: "rgb(220, 36, 91)",
|
|
18
|
+
* commandColor: "rgb(220, 36, 36)",
|
|
19
|
+
* subcommandColor: "rgb(220, 131, 36)",
|
|
20
|
+
* argColor: "rgb(220, 205, 36)",
|
|
21
|
+
* descriptionColor: "rgb(95, 28, 71)",
|
|
22
|
+
* errorPrefixColor: "rgb(220, 36, 39)",
|
|
23
|
+
* hightlightColor: "rgb(8, 98, 255)",
|
|
24
|
+
* }),
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare class RepoKitTheme {
|
|
29
|
+
prefixColor?: RGBString;
|
|
30
|
+
commandColor?: RGBString;
|
|
31
|
+
subcommandColor?: RGBString;
|
|
32
|
+
argColor?: RGBString;
|
|
33
|
+
descriptionColor?: RGBString;
|
|
34
|
+
errorPrefixColor?: RGBString;
|
|
35
|
+
highlightColor?: RGBString;
|
|
36
|
+
constructor({
|
|
37
|
+
prefixColor,
|
|
38
|
+
commandColor,
|
|
39
|
+
subcommandColor,
|
|
40
|
+
argColor,
|
|
41
|
+
descriptionColor,
|
|
42
|
+
errorPrefixColor,
|
|
43
|
+
highlightColor
|
|
44
|
+
}: RepoKitTheme);
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { RepoKitTheme };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region externals/RepoKitTheme.ts
|
|
2
|
+
/**
|
|
3
|
+
* Repokit Theme
|
|
4
|
+
*
|
|
5
|
+
* A repokit theme allows you to customize the color
|
|
6
|
+
* usage of the CLI by adding a `RepoKitTheme` instance
|
|
7
|
+
* to your `RepoKitConfig`
|
|
8
|
+
*
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { RepoKitConfig, RepoKitTheme } from "@repokit/core";
|
|
11
|
+
*
|
|
12
|
+
* export const RepoKit = new RepoKitConfig({
|
|
13
|
+
* project: "Repokit",
|
|
14
|
+
* theme: new RepoKitTheme({
|
|
15
|
+
* prefixColor: "rgb(220, 36, 91)",
|
|
16
|
+
* commandColor: "rgb(220, 36, 36)",
|
|
17
|
+
* subcommandColor: "rgb(220, 131, 36)",
|
|
18
|
+
* argColor: "rgb(220, 205, 36)",
|
|
19
|
+
* descriptionColor: "rgb(95, 28, 71)",
|
|
20
|
+
* errorPrefixColor: "rgb(220, 36, 39)",
|
|
21
|
+
* hightlightColor: "rgb(8, 98, 255)",
|
|
22
|
+
* }),
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
var RepoKitTheme = class {
|
|
27
|
+
prefixColor;
|
|
28
|
+
commandColor;
|
|
29
|
+
subcommandColor;
|
|
30
|
+
argColor;
|
|
31
|
+
descriptionColor;
|
|
32
|
+
errorPrefixColor;
|
|
33
|
+
highlightColor;
|
|
34
|
+
constructor({ prefixColor, commandColor, subcommandColor, argColor, descriptionColor, errorPrefixColor, highlightColor }) {
|
|
35
|
+
this.prefixColor = prefixColor;
|
|
36
|
+
this.commandColor = commandColor;
|
|
37
|
+
this.subcommandColor = subcommandColor;
|
|
38
|
+
this.argColor = argColor;
|
|
39
|
+
this.descriptionColor = descriptionColor;
|
|
40
|
+
this.errorPrefixColor = errorPrefixColor;
|
|
41
|
+
this.highlightColor = highlightColor;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { RepoKitTheme };
|
package/dist/TSCompiler.mjs
CHANGED
|
@@ -16,14 +16,10 @@ var TSCompiler = class {
|
|
|
16
16
|
static compile(path) {
|
|
17
17
|
const compiler = register(this.compilerOptions);
|
|
18
18
|
compiler.enabled(true);
|
|
19
|
-
const result =
|
|
19
|
+
const result = __require(path);
|
|
20
20
|
compiler.enabled(false);
|
|
21
21
|
return result;
|
|
22
22
|
}
|
|
23
|
-
static import(filePath) {
|
|
24
|
-
const _module = __require(filePath);
|
|
25
|
-
return _module?.__esModule ? _module : { default: _module };
|
|
26
|
-
}
|
|
27
23
|
};
|
|
28
24
|
//#endregion
|
|
29
25
|
export { TSCompiler };
|
package/dist/Themes.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RepoKitTheme } from "./RepoKitTheme.mjs";
|
|
2
|
+
//#region externals/Themes.ts
|
|
3
|
+
const SeeingRed = new RepoKitTheme({
|
|
4
|
+
prefixColor: "rgb(220, 36, 91)",
|
|
5
|
+
commandColor: "rgb(220, 36, 36)",
|
|
6
|
+
subcommandColor: "rgb(220, 131, 36)",
|
|
7
|
+
argColor: "rgb(220, 205, 36)",
|
|
8
|
+
descriptionColor: "rgb(179, 100, 151)",
|
|
9
|
+
errorPrefixColor: "rgb(220, 36, 39)",
|
|
10
|
+
highlightColor: "rgb(237, 175, 41)"
|
|
11
|
+
});
|
|
12
|
+
const TheBlues = new RepoKitTheme({
|
|
13
|
+
prefixColor: "rgb(33, 111, 255)",
|
|
14
|
+
commandColor: "rgb(52, 96, 255)",
|
|
15
|
+
subcommandColor: "rgb(0, 157, 255)",
|
|
16
|
+
argColor: "rgb(40, 175, 253)",
|
|
17
|
+
descriptionColor: "rgb(100, 165, 179)",
|
|
18
|
+
errorPrefixColor: "rgb(220, 36, 100)",
|
|
19
|
+
highlightColor: "rgb(69, 219, 229)"
|
|
20
|
+
});
|
|
21
|
+
const Green = new RepoKitTheme({
|
|
22
|
+
prefixColor: "rgb(26, 227, 133)",
|
|
23
|
+
commandColor: "rgb(82, 234, 74)",
|
|
24
|
+
subcommandColor: "rgb(51, 241, 162)",
|
|
25
|
+
argColor: "rgb(124, 244, 102)",
|
|
26
|
+
descriptionColor: "rgb(126, 168, 140)",
|
|
27
|
+
errorPrefixColor: "rgb(220, 36, 100)",
|
|
28
|
+
highlightColor: "rgb(25, 206, 91)"
|
|
29
|
+
});
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Green, SeeingRed, TheBlues };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RepoKitTheme } from "./RepoKitTheme.mjs";
|
|
2
|
+
import { AsyncTask, ICommand, ILocatedCommand, IRepoKitCommand, IRepoKitConfig, RGBString } from "./types.mjs";
|
|
2
3
|
import { RepoKitCommand } from "./RepoKitCommand.mjs";
|
|
3
4
|
import { RepoKitConfig } from "./RepoKitConfig.mjs";
|
|
4
|
-
|
|
5
|
+
import { Green, SeeingRed, TheBlues } from "./Themes.mjs";
|
|
6
|
+
export { AsyncTask, Green, ICommand, ILocatedCommand, IRepoKitCommand, IRepoKitConfig, RGBString, RepoKitCommand, RepoKitConfig, RepoKitTheme, SeeingRed, TheBlues };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { RepoKitCommand } from "./RepoKitCommand.mjs";
|
|
2
2
|
import { RepoKitConfig } from "./RepoKitConfig.mjs";
|
|
3
|
-
|
|
3
|
+
import { RepoKitTheme } from "./RepoKitTheme.mjs";
|
|
4
|
+
import { Green, SeeingRed, TheBlues } from "./Themes.mjs";
|
|
5
|
+
export { Green, RepoKitCommand, RepoKitConfig, RepoKitTheme, SeeingRed, TheBlues };
|
package/dist/types.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RepoKitTheme } from "./RepoKitTheme.mjs";
|
|
1
2
|
import { RepoKitCommand } from "./RepoKitCommand.mjs";
|
|
2
3
|
|
|
3
4
|
//#region externals/types.d.ts
|
|
@@ -5,6 +6,7 @@ interface IRepoKitConfig {
|
|
|
5
6
|
project: string;
|
|
6
7
|
thirdParty?: RepoKitCommand[];
|
|
7
8
|
commands?: Record<string, ICommand>;
|
|
9
|
+
theme?: RepoKitTheme;
|
|
8
10
|
}
|
|
9
11
|
interface IRepoKitCommand {
|
|
10
12
|
name: string;
|
|
@@ -21,5 +23,7 @@ interface ILocatedCommand extends IRepoKitCommand {
|
|
|
21
23
|
location: string;
|
|
22
24
|
}
|
|
23
25
|
type AsyncTask<T> = () => Promise<T>;
|
|
26
|
+
type OptionalSpace = " " | "";
|
|
27
|
+
type RGBString = `rgb(${number},${OptionalSpace}${number},${OptionalSpace}${number})`;
|
|
24
28
|
//#endregion
|
|
25
|
-
export { AsyncTask, ICommand, ILocatedCommand, IRepoKitCommand, IRepoKitConfig };
|
|
29
|
+
export { AsyncTask, ICommand, ILocatedCommand, IRepoKitCommand, IRepoKitConfig, RGBString };
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { RepoKitCommand } from "./RepoKitCommand";
|
|
2
|
+
import type { RepoKitTheme } from "./RepoKitTheme";
|
|
2
3
|
import type { ICommand, IRepoKitConfig } from "./types";
|
|
3
4
|
/* eslint-disable typescript-eslint(no-misused-spread */
|
|
4
5
|
|
|
5
|
-
export class RepoKitConfig
|
|
6
|
+
export class RepoKitConfig {
|
|
6
7
|
project: string;
|
|
8
|
+
theme?: RepoKitTheme;
|
|
7
9
|
thirdParty: RepoKitCommand[];
|
|
8
10
|
commands: Record<string, ICommand>;
|
|
9
|
-
constructor({
|
|
11
|
+
constructor({
|
|
12
|
+
theme,
|
|
13
|
+
project,
|
|
14
|
+
commands = {},
|
|
15
|
+
thirdParty = [],
|
|
16
|
+
}: IRepoKitConfig) {
|
|
17
|
+
this.theme = theme;
|
|
10
18
|
this.project = project;
|
|
11
19
|
this.commands = commands;
|
|
12
20
|
this.thirdParty = thirdParty.map(command => new RepoKitCommand(command));
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { RGBString } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Repokit Theme
|
|
5
|
+
*
|
|
6
|
+
* A repokit theme allows you to customize the color
|
|
7
|
+
* usage of the CLI by adding a `RepoKitTheme` instance
|
|
8
|
+
* to your `RepoKitConfig`
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { RepoKitConfig, RepoKitTheme } from "@repokit/core";
|
|
12
|
+
*
|
|
13
|
+
* export const RepoKit = new RepoKitConfig({
|
|
14
|
+
* project: "Repokit",
|
|
15
|
+
* theme: new RepoKitTheme({
|
|
16
|
+
* prefixColor: "rgb(220, 36, 91)",
|
|
17
|
+
* commandColor: "rgb(220, 36, 36)",
|
|
18
|
+
* subcommandColor: "rgb(220, 131, 36)",
|
|
19
|
+
* argColor: "rgb(220, 205, 36)",
|
|
20
|
+
* descriptionColor: "rgb(95, 28, 71)",
|
|
21
|
+
* errorPrefixColor: "rgb(220, 36, 39)",
|
|
22
|
+
* hightlightColor: "rgb(8, 98, 255)",
|
|
23
|
+
* }),
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class RepoKitTheme {
|
|
28
|
+
prefixColor?: RGBString;
|
|
29
|
+
commandColor?: RGBString;
|
|
30
|
+
subcommandColor?: RGBString;
|
|
31
|
+
argColor?: RGBString;
|
|
32
|
+
descriptionColor?: RGBString;
|
|
33
|
+
errorPrefixColor?: RGBString;
|
|
34
|
+
highlightColor?: RGBString;
|
|
35
|
+
constructor({
|
|
36
|
+
prefixColor,
|
|
37
|
+
commandColor,
|
|
38
|
+
subcommandColor,
|
|
39
|
+
argColor,
|
|
40
|
+
descriptionColor,
|
|
41
|
+
errorPrefixColor,
|
|
42
|
+
highlightColor,
|
|
43
|
+
}: RepoKitTheme) {
|
|
44
|
+
this.prefixColor = prefixColor;
|
|
45
|
+
this.commandColor = commandColor;
|
|
46
|
+
this.subcommandColor = subcommandColor;
|
|
47
|
+
this.argColor = argColor;
|
|
48
|
+
this.descriptionColor = descriptionColor;
|
|
49
|
+
this.errorPrefixColor = errorPrefixColor;
|
|
50
|
+
this.highlightColor = highlightColor;
|
|
51
|
+
}
|
|
52
|
+
}
|
package/externals/TSCompiler.ts
CHANGED
|
@@ -19,13 +19,8 @@ export class TSCompiler {
|
|
|
19
19
|
public static compile<T extends Record<string, unknown>>(path: string) {
|
|
20
20
|
const compiler = register(this.compilerOptions);
|
|
21
21
|
compiler.enabled(true);
|
|
22
|
-
const result =
|
|
22
|
+
const result = require(path) as T;
|
|
23
23
|
compiler.enabled(false);
|
|
24
24
|
return result;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
private static import(filePath: string) {
|
|
28
|
-
const _module = require(filePath);
|
|
29
|
-
return _module?.__esModule ? _module : { default: _module };
|
|
30
|
-
}
|
|
31
26
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RepoKitTheme } from "./RepoKitTheme";
|
|
2
|
+
|
|
3
|
+
export const SeeingRed = new RepoKitTheme({
|
|
4
|
+
prefixColor: "rgb(220, 36, 91)",
|
|
5
|
+
commandColor: "rgb(220, 36, 36)",
|
|
6
|
+
subcommandColor: "rgb(220, 131, 36)",
|
|
7
|
+
argColor: "rgb(220, 205, 36)",
|
|
8
|
+
descriptionColor: "rgb(179, 100, 151)",
|
|
9
|
+
errorPrefixColor: "rgb(220, 36, 39)",
|
|
10
|
+
highlightColor: "rgb(237, 175, 41)",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const TheBlues = new RepoKitTheme({
|
|
14
|
+
prefixColor: "rgb(33, 111, 255)",
|
|
15
|
+
commandColor: "rgb(52, 96, 255)",
|
|
16
|
+
subcommandColor: "rgb(0, 157, 255)",
|
|
17
|
+
argColor: "rgb(40, 175, 253)",
|
|
18
|
+
descriptionColor: "rgb(100, 165, 179)",
|
|
19
|
+
errorPrefixColor: "rgb(220, 36, 100)",
|
|
20
|
+
highlightColor: "rgb(69, 219, 229)",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const Green = new RepoKitTheme({
|
|
24
|
+
prefixColor: "rgb(26, 227, 133)",
|
|
25
|
+
commandColor: "rgb(82, 234, 74)",
|
|
26
|
+
subcommandColor: "rgb(51, 241, 162)",
|
|
27
|
+
argColor: "rgb(124, 244, 102)",
|
|
28
|
+
descriptionColor: "rgb(126, 168, 140)",
|
|
29
|
+
errorPrefixColor: "rgb(220, 36, 100)",
|
|
30
|
+
highlightColor: "rgb(25, 206, 91)",
|
|
31
|
+
});
|
package/externals/index.ts
CHANGED
package/externals/types.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { RepoKitCommand } from "./RepoKitCommand";
|
|
2
|
+
import type { RepoKitTheme } from "./RepoKitTheme";
|
|
2
3
|
|
|
3
4
|
export interface IRepoKitConfig {
|
|
4
5
|
project: string;
|
|
5
6
|
thirdParty?: RepoKitCommand[];
|
|
6
7
|
commands?: Record<string, ICommand>;
|
|
8
|
+
theme?: RepoKitTheme;
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
export interface IRepoKitCommand {
|
|
@@ -24,3 +26,8 @@ export interface ILocatedCommand extends IRepoKitCommand {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export type AsyncTask<T> = () => Promise<T>;
|
|
29
|
+
|
|
30
|
+
type OptionalSpace = " " | "";
|
|
31
|
+
|
|
32
|
+
export type RGBString =
|
|
33
|
+
`rgb(${number},${OptionalSpace}${number},${OptionalSpace}${number})`;
|
package/installation/install.sh
CHANGED
|
@@ -15,7 +15,7 @@ impl Configuration {
|
|
|
15
15
|
Logger::info(
|
|
16
16
|
format!(
|
|
17
17
|
"I found a Repokit configuration without an exported {} instance",
|
|
18
|
-
Logger::
|
|
18
|
+
Logger::with_theme(|theme| theme.highlight("RepokitConfig"))
|
|
19
19
|
)
|
|
20
20
|
.as_str(),
|
|
21
21
|
);
|
|
@@ -29,7 +29,7 @@ impl Configuration {
|
|
|
29
29
|
Logger::info(
|
|
30
30
|
format!(
|
|
31
31
|
"Please fill out this file with your desired settings. Then run {}",
|
|
32
|
-
Logger::
|
|
32
|
+
Logger::with_theme(|theme| theme.highlight("repokit onboard"))
|
|
33
33
|
)
|
|
34
34
|
.as_str(),
|
|
35
35
|
);
|
|
@@ -25,52 +25,62 @@ impl Help {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
pub fn log_internal_command(command: &InternalExecutableDefinition) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
Logger::with_theme(|theme| {
|
|
29
|
+
println!(
|
|
30
|
+
"{}{} {}",
|
|
31
|
+
Logger::indent(Some(3)),
|
|
32
|
+
theme.command(&command.name),
|
|
33
|
+
theme.description(&command.description),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
34
36
|
Help::log_args(&command.args, None);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
pub fn log_root_command(command: &RootCommand) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
Logger::with_theme(|theme| {
|
|
41
|
+
println!(
|
|
42
|
+
"{}{} {}",
|
|
43
|
+
Logger::indent(Some(3)),
|
|
44
|
+
theme.command(&command.name),
|
|
45
|
+
theme.description(&command.description),
|
|
46
|
+
);
|
|
47
|
+
});
|
|
44
48
|
Help::log_args(&command.args, None)
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
pub fn log_external_command(command: &RepoKitCommand) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
Logger::with_theme(|theme| {
|
|
53
|
+
println!(
|
|
54
|
+
"{}{} {}",
|
|
55
|
+
Logger::indent(Some(3)),
|
|
56
|
+
theme.command(&command.name),
|
|
57
|
+
theme.description(&command.description),
|
|
58
|
+
);
|
|
59
|
+
});
|
|
54
60
|
println!();
|
|
55
61
|
Help::log_external_subcommands(&command.commands, 6);
|
|
56
62
|
if !command.owner.is_empty() {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
Logger::with_theme(|theme| {
|
|
64
|
+
println!(
|
|
65
|
+
"\n{}{}{}",
|
|
66
|
+
Logger::indent(Some(9)),
|
|
67
|
+
theme.description("Owned by: "),
|
|
68
|
+
Logger::cyan(&command.owner),
|
|
69
|
+
);
|
|
70
|
+
});
|
|
63
71
|
}
|
|
64
72
|
}
|
|
65
73
|
|
|
66
74
|
pub fn log_external_subcommands(map: &HashMap<String, CommandDefinition>, indentation: i32) {
|
|
67
75
|
for (name, command) in map {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
Logger::with_theme(|theme| {
|
|
77
|
+
println!(
|
|
78
|
+
"{}{}: {}",
|
|
79
|
+
Logger::indent(Some(indentation)),
|
|
80
|
+
theme.sub_command(name),
|
|
81
|
+
theme.description(&command.description),
|
|
82
|
+
);
|
|
83
|
+
});
|
|
74
84
|
Help::log_args(&command.args, Some(indentation + 3));
|
|
75
85
|
}
|
|
76
86
|
}
|
|
@@ -114,16 +124,18 @@ impl Help {
|
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
fn log_args(map: &Option<HashMap<String, String>>, indentation: Option<i32>) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
Logger::with_theme(|theme| {
|
|
128
|
+
if let Some(args) = map {
|
|
129
|
+
for (name, description) in args {
|
|
130
|
+
println!(
|
|
131
|
+
"{}{} {}",
|
|
132
|
+
Logger::indent(Some(indentation.unwrap_or(6))),
|
|
133
|
+
theme.arg(name),
|
|
134
|
+
theme.description(description)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
125
137
|
}
|
|
126
|
-
}
|
|
138
|
+
});
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
fn sort_internal(
|
|
@@ -31,7 +31,7 @@ impl ListCommands {
|
|
|
31
31
|
"<scope>",
|
|
32
32
|
format!(
|
|
33
33
|
"The scope of the commands you wish to list. Specify one of {}",
|
|
34
|
-
Logger::
|
|
34
|
+
Logger::with_theme(|theme| theme.highlight(SCOPES.join(" | ").as_str()))
|
|
35
35
|
)
|
|
36
36
|
.as_str(),
|
|
37
37
|
)],
|
|
@@ -48,7 +48,7 @@ impl ListCommands {
|
|
|
48
48
|
Logger::exit_with_info(
|
|
49
49
|
format!(
|
|
50
50
|
"Please specify a scope to list the commands of. Select one of {}",
|
|
51
|
-
Logger::
|
|
51
|
+
Logger::with_theme(|theme| theme.highlight(SCOPES.join(" | ").as_str()))
|
|
52
52
|
)
|
|
53
53
|
.as_str(),
|
|
54
54
|
);
|
|
@@ -88,7 +88,7 @@ impl InternalExecutable for ListCommands {
|
|
|
88
88
|
Logger::exit_with_info(
|
|
89
89
|
format!(
|
|
90
90
|
"I could not find any commands matching {}",
|
|
91
|
-
Logger::
|
|
91
|
+
Logger::with_theme(|theme| theme.highlight(&full_query))
|
|
92
92
|
)
|
|
93
93
|
.as_str(),
|
|
94
94
|
);
|
|
@@ -54,13 +54,19 @@ impl InternalExecutable for LocateCommand {
|
|
|
54
54
|
Logger::exit_with_info("Please specify a command to locate");
|
|
55
55
|
}
|
|
56
56
|
let command = &args[0];
|
|
57
|
-
Logger::info(
|
|
57
|
+
Logger::info(
|
|
58
|
+
format!(
|
|
59
|
+
"Locating a command named {}",
|
|
60
|
+
Logger::with_theme(|theme| theme.highlight(command))
|
|
61
|
+
)
|
|
62
|
+
.as_str(),
|
|
63
|
+
);
|
|
58
64
|
self.search_externals(command);
|
|
59
65
|
self.search_root(command);
|
|
60
66
|
Logger::exit_with_error(
|
|
61
67
|
format!(
|
|
62
68
|
"I could not find a command named {}",
|
|
63
|
-
Logger::
|
|
69
|
+
Logger::with_theme(|theme| theme.highlight(command))
|
|
64
70
|
)
|
|
65
71
|
.as_str(),
|
|
66
72
|
);
|
|
@@ -31,12 +31,18 @@ impl Onboarder {
|
|
|
31
31
|
|
|
32
32
|
impl InternalExecutable for Onboarder {
|
|
33
33
|
fn run(&self, _: Vec<String>, _: &HashMap<String, Box<dyn InternalExecutable>>) {
|
|
34
|
-
Logger::info(
|
|
34
|
+
Logger::info(
|
|
35
|
+
format!(
|
|
36
|
+
"Welcome to {}",
|
|
37
|
+
Logger::with_theme(|theme| theme.highlight("Repokit"))
|
|
38
|
+
)
|
|
39
|
+
.as_str(),
|
|
40
|
+
);
|
|
35
41
|
Logger::info(
|
|
36
42
|
"Repokit is a tool designed to self-document and publish developer facing workflows in a single CLI",
|
|
37
43
|
);
|
|
38
44
|
Logger::info(
|
|
39
|
-
format!("As you develop new features in your codebase, you can publish commands, API's, and tools to the {} CLI by running", Logger::
|
|
45
|
+
format!("As you develop new features in your codebase, you can publish commands, API's, and tools to the {} CLI by running", Logger::with_theme(|theme|theme.highlight("Repokit"))).as_str()
|
|
40
46
|
);
|
|
41
47
|
Logger::log_file_path("repokit register ./path/to/your-feature");
|
|
42
48
|
Logger::info(
|
|
@@ -45,12 +51,12 @@ impl InternalExecutable for Onboarder {
|
|
|
45
51
|
Logger::info(
|
|
46
52
|
format!(
|
|
47
53
|
"The {} CLI will automatically detect these files and add them to its toolchain",
|
|
48
|
-
Logger::
|
|
54
|
+
Logger::with_theme(|theme| theme.highlight("Repokit"))
|
|
49
55
|
)
|
|
50
56
|
.as_str(),
|
|
51
57
|
);
|
|
52
58
|
Logger::info(
|
|
53
|
-
format!("As your codebase grows, your {} CLI will continue to track all of the published workflows created by your team", Logger::
|
|
59
|
+
format!("As your codebase grows, your {} CLI will continue to track all of the published workflows created by your team", Logger::with_theme(|theme|theme.highlight("Repokit"))).as_str()
|
|
54
60
|
);
|
|
55
61
|
Logger::space_around("It's your living source of knowledge and documentation");
|
|
56
62
|
}
|
|
@@ -50,7 +50,7 @@ impl RegisterCommand {
|
|
|
50
50
|
Logger::info(
|
|
51
51
|
format!(
|
|
52
52
|
"Creating the path {} in your file system",
|
|
53
|
-
Logger::
|
|
53
|
+
Logger::with_theme(|theme| theme.highlight(path_arg.as_str()))
|
|
54
54
|
)
|
|
55
55
|
.as_str(),
|
|
56
56
|
);
|
|
@@ -64,13 +64,13 @@ impl RegisterCommand {
|
|
|
64
64
|
Logger::error(
|
|
65
65
|
format!(
|
|
66
66
|
"A {} file already exists in this directory",
|
|
67
|
-
Logger::
|
|
67
|
+
Logger::with_theme(|theme| theme.highlight("Commands.ts"))
|
|
68
68
|
)
|
|
69
69
|
.as_str(),
|
|
70
70
|
);
|
|
71
71
|
Logger::info(format!(
|
|
72
72
|
"You can append additional commands to the existing {} instance or export another one",
|
|
73
|
-
Logger::
|
|
73
|
+
Logger::with_theme(|theme| theme.highlight("RepoKitCommand"))
|
|
74
74
|
).as_str());
|
|
75
75
|
process::exit(0);
|
|
76
76
|
}
|
|
@@ -98,7 +98,7 @@ impl SearchCommands {
|
|
|
98
98
|
Logger::info(
|
|
99
99
|
format!(
|
|
100
100
|
"Matched {} command{} in your repokit config",
|
|
101
|
-
Logger::
|
|
101
|
+
Logger::with_theme(|theme| theme.highlight(total.to_string().as_str())),
|
|
102
102
|
plural_appendage,
|
|
103
103
|
)
|
|
104
104
|
.as_str(),
|
|
@@ -124,7 +124,7 @@ impl SearchCommands {
|
|
|
124
124
|
Logger::info(
|
|
125
125
|
format!(
|
|
126
126
|
"Matched {} internal command{}",
|
|
127
|
-
Logger::
|
|
127
|
+
Logger::with_theme(|theme| theme.highlight(total.to_string().as_str())),
|
|
128
128
|
plural_appendage,
|
|
129
129
|
)
|
|
130
130
|
.as_str(),
|
|
@@ -140,7 +140,7 @@ impl SearchCommands {
|
|
|
140
140
|
Logger::info(
|
|
141
141
|
format!(
|
|
142
142
|
"Matched {} registered command{}",
|
|
143
|
-
Logger::
|
|
143
|
+
Logger::with_theme(|theme| theme.highlight(total.to_string().as_str())),
|
|
144
144
|
plural_appendage,
|
|
145
145
|
)
|
|
146
146
|
.as_str(),
|
|
@@ -41,7 +41,11 @@ impl UpgradeRepoKit {
|
|
|
41
41
|
let path = Path::new(&self.scope.root).join(lock_file).normalize();
|
|
42
42
|
if path.exists() && path.is_file() {
|
|
43
43
|
Logger::info(
|
|
44
|
-
format!(
|
|
44
|
+
format!(
|
|
45
|
+
"Detected {} installation",
|
|
46
|
+
Logger::with_theme(|theme| theme.highlight(manager))
|
|
47
|
+
)
|
|
48
|
+
.as_str(),
|
|
45
49
|
);
|
|
46
50
|
return command_prefix;
|
|
47
51
|
}
|
|
@@ -49,8 +49,8 @@ impl InternalFileSystem {
|
|
|
49
49
|
Logger::exit_with_info(
|
|
50
50
|
format!(
|
|
51
51
|
"To start using {}, please initialize your git repository by running {}",
|
|
52
|
-
Logger::
|
|
53
|
-
Logger::
|
|
52
|
+
Logger::with_theme(|theme| theme.highlight("Repokit")),
|
|
53
|
+
Logger::with_theme(|theme| theme.highlight("git init"))
|
|
54
54
|
)
|
|
55
55
|
.as_str(),
|
|
56
56
|
);
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
use std::process::exit;
|
|
2
2
|
use std::sync::LazyLock;
|
|
3
3
|
use std::sync::Mutex;
|
|
4
|
+
use std::sync::MutexGuard;
|
|
4
5
|
|
|
5
|
-
use colored::{ColoredString, Colorize
|
|
6
|
+
use colored::{ColoredString, Colorize};
|
|
7
|
+
|
|
8
|
+
use crate::themes::theme::Theme;
|
|
9
|
+
use crate::themes::theme_registry::ThemeRegistry;
|
|
6
10
|
|
|
7
11
|
static REGISTERED_NAME: LazyLock<Mutex<String>> =
|
|
8
12
|
LazyLock::new(|| Mutex::new("Repokit".to_string()));
|
|
9
13
|
|
|
14
|
+
static THEMES: LazyLock<Mutex<ThemeRegistry>> = LazyLock::new(|| Mutex::new(ThemeRegistry::new()));
|
|
15
|
+
|
|
10
16
|
pub struct Logger {}
|
|
11
17
|
|
|
12
18
|
impl Logger {
|
|
@@ -37,7 +43,11 @@ impl Logger {
|
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
pub fn log_file_path(path: &str) {
|
|
40
|
-
println!(
|
|
46
|
+
println!(
|
|
47
|
+
"\n{}{}\n",
|
|
48
|
+
Logger::indent(None),
|
|
49
|
+
Logger::with_theme(|theme| theme.highlight(path))
|
|
50
|
+
);
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
pub fn indent(times: Option<i32>) -> String {
|
|
@@ -45,54 +55,10 @@ impl Logger {
|
|
|
45
55
|
" ".repeat(indentation.try_into().unwrap())
|
|
46
56
|
}
|
|
47
57
|
|
|
48
|
-
pub fn blue(message: &str) -> ColoredString {
|
|
49
|
-
message.bright_blue()
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
pub fn blue_bright(message: &str) -> ColoredString {
|
|
53
|
-
message.bright_blue().bold()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
pub fn magenta_bright(message: &str) -> ColoredString {
|
|
57
|
-
message.bright_magenta().bold()
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
pub fn magenta(message: &str) -> ColoredString {
|
|
61
|
-
message.magenta()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
pub fn green(message: &str) -> ColoredString {
|
|
65
|
-
message.green()
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
pub fn green_bright(message: &str) -> ColoredString {
|
|
69
|
-
message.bright_green()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
58
|
pub fn cyan(message: &str) -> ColoredString {
|
|
73
59
|
message.cyan()
|
|
74
60
|
}
|
|
75
61
|
|
|
76
|
-
pub fn cyan_bright(message: &str) -> ColoredString {
|
|
77
|
-
message.bright_cyan().bold()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
pub fn gray(message: &str) -> ColoredString {
|
|
81
|
-
message.custom_color(CustomColor {
|
|
82
|
-
r: 128,
|
|
83
|
-
g: 128,
|
|
84
|
-
b: 128,
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
pub fn lime(message: &str) -> ColoredString {
|
|
89
|
-
message.custom_color(CustomColor {
|
|
90
|
-
r: 175,
|
|
91
|
-
g: 247,
|
|
92
|
-
b: 7,
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
|
|
96
62
|
pub fn file_create_error() {
|
|
97
63
|
Logger::file_error("create a file");
|
|
98
64
|
}
|
|
@@ -113,6 +79,15 @@ impl Logger {
|
|
|
113
79
|
Logger::log_file_path("https://github.com/alexfigliolia/repokit/issues");
|
|
114
80
|
}
|
|
115
81
|
|
|
82
|
+
pub fn with_theme<R>(func: impl Fn(&Theme) -> R) -> R {
|
|
83
|
+
Logger::with_registry(|registry| func(®istry.theme))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
pub fn with_registry<R>(func: impl Fn(MutexGuard<'_, ThemeRegistry>) -> R) -> R {
|
|
87
|
+
let registry = THEMES.lock().unwrap();
|
|
88
|
+
func(registry)
|
|
89
|
+
}
|
|
90
|
+
|
|
116
91
|
fn file_error(operation: &str) {
|
|
117
92
|
Logger::info(format!("I was unable to {operation} in your repository").as_str());
|
|
118
93
|
Logger::error("Please verify the permissions on your working directory or file a bug here");
|
|
@@ -120,15 +95,13 @@ impl Logger {
|
|
|
120
95
|
exit(0);
|
|
121
96
|
}
|
|
122
97
|
|
|
123
|
-
fn info_prefix() ->
|
|
124
|
-
format!("{}: ",
|
|
125
|
-
.bright_magenta()
|
|
126
|
-
.bold()
|
|
98
|
+
fn info_prefix() -> String {
|
|
99
|
+
Logger::with_theme(|theme| format!("{}: ", theme.prefix(®ISTERED_NAME.lock().unwrap())))
|
|
127
100
|
}
|
|
128
101
|
|
|
129
|
-
fn error_prefix() ->
|
|
130
|
-
|
|
131
|
-
.
|
|
132
|
-
|
|
102
|
+
fn error_prefix() -> String {
|
|
103
|
+
Logger::with_theme(|theme| {
|
|
104
|
+
format!("{}: ", theme.error_prefix(®ISTERED_NAME.lock().unwrap()))
|
|
105
|
+
})
|
|
133
106
|
}
|
|
134
107
|
}
|
package/internals/main.rs
CHANGED
|
@@ -2,6 +2,8 @@ use std::collections::HashMap;
|
|
|
2
2
|
|
|
3
3
|
use serde::Deserialize;
|
|
4
4
|
|
|
5
|
+
use crate::themes::theme::RepoKitTheme;
|
|
6
|
+
|
|
5
7
|
#[derive(Debug, Deserialize, Clone)]
|
|
6
8
|
pub struct CommandDefinition {
|
|
7
9
|
pub command: String,
|
|
@@ -33,6 +35,7 @@ pub struct RepoKitConfig {
|
|
|
33
35
|
pub project: String,
|
|
34
36
|
pub thirdParty: Vec<RepoKitCommand>,
|
|
35
37
|
pub commands: HashMap<String, CommandDefinition>,
|
|
38
|
+
pub theme: Option<RepoKitTheme>,
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
#[derive(Debug, Deserialize, Clone)]
|
|
@@ -23,6 +23,9 @@ pub struct RepoKit {
|
|
|
23
23
|
impl RepoKit {
|
|
24
24
|
pub fn new(root: String, configuration: RepoKitConfig) -> RepoKit {
|
|
25
25
|
Logger::set_name(&configuration.project);
|
|
26
|
+
if let Some(theme) = &configuration.theme {
|
|
27
|
+
Logger::with_registry(|mut registry| registry.register(theme))
|
|
28
|
+
}
|
|
26
29
|
RepoKit {
|
|
27
30
|
scope: RepoKitScope {
|
|
28
31
|
root,
|
|
@@ -113,7 +116,7 @@ impl RepoKit {
|
|
|
113
116
|
Logger::info(
|
|
114
117
|
format!(
|
|
115
118
|
"I'm not aware of a command named {}",
|
|
116
|
-
Logger::
|
|
119
|
+
Logger::with_theme(|theme| theme.highlight(command))
|
|
117
120
|
)
|
|
118
121
|
.as_str(),
|
|
119
122
|
);
|
|
@@ -123,15 +126,15 @@ impl RepoKit {
|
|
|
123
126
|
Logger::info(
|
|
124
127
|
format!(
|
|
125
128
|
"The command {} was not found on {}",
|
|
126
|
-
Logger::
|
|
127
|
-
Logger::
|
|
129
|
+
Logger::with_theme(|theme| theme.highlight(sub_command)),
|
|
130
|
+
Logger::with_theme(|theme| theme.highlight(&command.name))
|
|
128
131
|
)
|
|
129
132
|
.as_str(),
|
|
130
133
|
);
|
|
131
134
|
Logger::info(
|
|
132
135
|
format!(
|
|
133
136
|
"Here are the commands that belong to {}",
|
|
134
|
-
Logger::
|
|
137
|
+
Logger::with_theme(|theme| theme.highlight(&command.name))
|
|
135
138
|
)
|
|
136
139
|
.as_str(),
|
|
137
140
|
);
|
|
@@ -142,7 +145,7 @@ impl RepoKit {
|
|
|
142
145
|
Logger::info(
|
|
143
146
|
format!(
|
|
144
147
|
"Listing available commands for {}\n",
|
|
145
|
-
Logger::
|
|
148
|
+
Logger::with_theme(|theme| theme.command(&command.name))
|
|
146
149
|
)
|
|
147
150
|
.as_str(),
|
|
148
151
|
);
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
use colored::{Color, ColoredString, Colorize};
|
|
2
|
+
use serde::Deserialize;
|
|
3
|
+
|
|
4
|
+
pub struct Theme {
|
|
5
|
+
prefixColor: Color,
|
|
6
|
+
commandColor: Color,
|
|
7
|
+
subcommandColor: Color,
|
|
8
|
+
argColor: Color,
|
|
9
|
+
descriptionColor: Color,
|
|
10
|
+
errorPrefixColor: Color,
|
|
11
|
+
highlightColor: Color,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
impl Theme {
|
|
15
|
+
pub fn new(colors: ThemeInputColors) -> Theme {
|
|
16
|
+
Theme::from(colors)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub fn prefix(&self, msg: &str) -> ColoredString {
|
|
20
|
+
msg.color(self.prefixColor).bold()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn command(&self, msg: &str) -> ColoredString {
|
|
24
|
+
msg.color(self.commandColor)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pub fn sub_command(&self, msg: &str) -> ColoredString {
|
|
28
|
+
msg.color(self.subcommandColor)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pub fn arg(&self, msg: &str) -> ColoredString {
|
|
32
|
+
msg.color(self.argColor)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
pub fn description(&self, msg: &str) -> ColoredString {
|
|
36
|
+
msg.color(self.descriptionColor)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
pub fn error_prefix(&self, msg: &str) -> ColoredString {
|
|
40
|
+
msg.color(self.errorPrefixColor).bold()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
pub fn highlight(&self, msg: &str) -> ColoredString {
|
|
44
|
+
msg.color(self.highlightColor)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
pub fn from_configuration(theme: &RepoKitTheme) -> Theme {
|
|
48
|
+
let copy = theme.clone();
|
|
49
|
+
Theme::new(ThemeInputColors {
|
|
50
|
+
prefixColor: Theme::parse_rgb(copy.prefixColor),
|
|
51
|
+
commandColor: Theme::parse_rgb(copy.commandColor),
|
|
52
|
+
subcommandColor: Theme::parse_rgb(copy.subcommandColor),
|
|
53
|
+
argColor: Theme::parse_rgb(copy.argColor),
|
|
54
|
+
descriptionColor: Theme::parse_rgb(copy.descriptionColor),
|
|
55
|
+
errorPrefixColor: Theme::parse_rgb(copy.errorPrefixColor),
|
|
56
|
+
highlightColor: Theme::parse_rgb(copy.highlightColor),
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fn parse_rgb(rgb_str: Option<String>) -> Option<Color> {
|
|
61
|
+
match rgb_str {
|
|
62
|
+
Some(rgb) => {
|
|
63
|
+
let trimmed = rgb
|
|
64
|
+
.strip_prefix("rgb(")
|
|
65
|
+
.and_then(|s| s.strip_suffix(')'))
|
|
66
|
+
.map(|s| s.trim())?;
|
|
67
|
+
|
|
68
|
+
// 2. Split the remaining string by commas.
|
|
69
|
+
let parts: Vec<&str> = trimmed.split(',').collect();
|
|
70
|
+
|
|
71
|
+
if parts.len() == 3 {
|
|
72
|
+
// 3. Trim whitespace from each part and parse to a u8.
|
|
73
|
+
// `.parse()` returns a `Result`, so we use `.ok()` to convert to an `Option`,
|
|
74
|
+
// and the `?` operator to return early if any parse fails.
|
|
75
|
+
let r = parts[0].trim().parse::<u8>().ok()?;
|
|
76
|
+
let g = parts[1].trim().parse::<u8>().ok()?;
|
|
77
|
+
let b = parts[2].trim().parse::<u8>().ok()?;
|
|
78
|
+
|
|
79
|
+
Some(Color::TrueColor { r, g, b })
|
|
80
|
+
} else {
|
|
81
|
+
None
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
None => None,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
pub struct ThemeInputColors {
|
|
90
|
+
pub prefixColor: Option<Color>,
|
|
91
|
+
pub commandColor: Option<Color>,
|
|
92
|
+
pub subcommandColor: Option<Color>,
|
|
93
|
+
pub argColor: Option<Color>,
|
|
94
|
+
pub descriptionColor: Option<Color>,
|
|
95
|
+
pub errorPrefixColor: Option<Color>,
|
|
96
|
+
pub highlightColor: Option<Color>,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
impl From<ThemeInputColors> for Theme {
|
|
100
|
+
fn from(input: ThemeInputColors) -> Theme {
|
|
101
|
+
Theme {
|
|
102
|
+
prefixColor: input.prefixColor.unwrap_or(Color::BrightMagenta),
|
|
103
|
+
commandColor: input.commandColor.unwrap_or(Color::BrightBlue),
|
|
104
|
+
subcommandColor: input.subcommandColor.unwrap_or(Color::TrueColor {
|
|
105
|
+
r: 175,
|
|
106
|
+
g: 247,
|
|
107
|
+
b: 7,
|
|
108
|
+
}),
|
|
109
|
+
argColor: input.argColor.unwrap_or(Color::Green),
|
|
110
|
+
descriptionColor: input.descriptionColor.unwrap_or(Color::TrueColor {
|
|
111
|
+
r: 128,
|
|
112
|
+
g: 128,
|
|
113
|
+
b: 128,
|
|
114
|
+
}),
|
|
115
|
+
errorPrefixColor: input.errorPrefixColor.unwrap_or(Color::Red),
|
|
116
|
+
highlightColor: input.highlightColor.unwrap_or(Color::BrightBlue),
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
#[derive(Debug, Deserialize, Clone)]
|
|
122
|
+
pub struct RepoKitTheme {
|
|
123
|
+
pub prefixColor: Option<String>,
|
|
124
|
+
pub commandColor: Option<String>,
|
|
125
|
+
pub subcommandColor: Option<String>,
|
|
126
|
+
pub argColor: Option<String>,
|
|
127
|
+
pub descriptionColor: Option<String>,
|
|
128
|
+
pub errorPrefixColor: Option<String>,
|
|
129
|
+
pub highlightColor: Option<String>,
|
|
130
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
use crate::themes::theme::{RepoKitTheme, Theme, ThemeInputColors};
|
|
2
|
+
|
|
3
|
+
pub struct ThemeRegistry {
|
|
4
|
+
pub theme: Theme,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
impl ThemeRegistry {
|
|
8
|
+
pub fn new() -> ThemeRegistry {
|
|
9
|
+
ThemeRegistry {
|
|
10
|
+
theme: ThemeRegistry::default_theme(),
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub fn register(&mut self, theme: &RepoKitTheme) {
|
|
15
|
+
self.theme = Theme::from_configuration(theme);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fn default_theme() -> Theme {
|
|
19
|
+
Theme::new(ThemeInputColors {
|
|
20
|
+
prefixColor: None,
|
|
21
|
+
commandColor: None,
|
|
22
|
+
subcommandColor: None,
|
|
23
|
+
argColor: None,
|
|
24
|
+
descriptionColor: None,
|
|
25
|
+
errorPrefixColor: None,
|
|
26
|
+
highlightColor: None,
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -61,7 +61,7 @@ impl CommandValidations {
|
|
|
61
61
|
Logger::info(
|
|
62
62
|
format!(
|
|
63
63
|
"I encountered a command named {} that conflicts with one of my internals",
|
|
64
|
-
Logger::
|
|
64
|
+
Logger::with_theme(|theme| theme.highlight(name)),
|
|
65
65
|
)
|
|
66
66
|
.as_str(),
|
|
67
67
|
);
|
|
@@ -81,8 +81,8 @@ impl CommandValidations {
|
|
|
81
81
|
Logger::info(
|
|
82
82
|
format!(
|
|
83
83
|
"I encountered a command named {} in your {} file that conflicts with one of my internals",
|
|
84
|
-
Logger::
|
|
85
|
-
Logger::
|
|
84
|
+
Logger::with_theme(|theme|theme.highlight(name)),
|
|
85
|
+
Logger::with_theme(|theme|theme.highlight("repokit.ts")),
|
|
86
86
|
)
|
|
87
87
|
.as_str(),
|
|
88
88
|
);
|
|
@@ -117,8 +117,8 @@ impl CommandValidations {
|
|
|
117
117
|
fn on_external_root_collision(&self, command: &RepoKitCommand) {
|
|
118
118
|
Logger::info(format!(
|
|
119
119
|
"I encountered a package command named {} that conflicts with a command in your {} file",
|
|
120
|
-
Logger::
|
|
121
|
-
Logger::
|
|
120
|
+
Logger::with_theme(|theme|theme.highlight(&command.name)),
|
|
121
|
+
Logger::with_theme(|theme|theme.highlight("repokit.ts"))
|
|
122
122
|
)
|
|
123
123
|
.as_str(),
|
|
124
124
|
);
|
|
@@ -131,7 +131,7 @@ impl CommandValidations {
|
|
|
131
131
|
Logger::info(
|
|
132
132
|
format!(
|
|
133
133
|
"I encountered two packages with the name {}",
|
|
134
|
-
Logger::
|
|
134
|
+
Logger::with_theme(|theme| theme.highlight(&command.name)),
|
|
135
135
|
)
|
|
136
136
|
.as_str(),
|
|
137
137
|
);
|
|
@@ -139,12 +139,12 @@ impl CommandValidations {
|
|
|
139
139
|
println!(
|
|
140
140
|
"{}1. {}",
|
|
141
141
|
Logger::indent(None),
|
|
142
|
-
Logger::
|
|
142
|
+
Logger::with_theme(|theme| theme.highlight(collision_path))
|
|
143
143
|
);
|
|
144
144
|
println!(
|
|
145
145
|
"{}2. {}\n",
|
|
146
146
|
Logger::indent(None),
|
|
147
|
-
Logger::
|
|
147
|
+
Logger::with_theme(|theme| theme.highlight(&command.location))
|
|
148
148
|
);
|
|
149
149
|
Logger::exit_with_info("Please rename one of these");
|
|
150
150
|
}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repokit/core",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A knowledgebase for your repository - wrapped in a CLI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
"eslint-plugin-import": "^2.32.0",
|
|
63
63
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
64
64
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
65
|
-
"oxfmt": "^0.
|
|
65
|
+
"oxfmt": "^0.42.0",
|
|
66
66
|
"oxlint": "^1.42.0",
|
|
67
|
-
"oxlint-tsgolint": "^0.
|
|
67
|
+
"oxlint-tsgolint": "^0.18.1",
|
|
68
68
|
"tsdown": "^0.21.0",
|
|
69
69
|
"tsx": "^4.21.0",
|
|
70
|
-
"typescript": "^
|
|
70
|
+
"typescript": "^6.0.2"
|
|
71
71
|
}
|
|
72
72
|
}
|