1
1
import { Command } from "@cliffy/command" ;
2
- import VTConfig from "~/vt/VTConfig.ts" ;
2
+ import VTConfig , { globalConfig } from "~/vt/VTConfig.ts" ;
3
3
import { findVtRoot } from "~/vt/vt/utils.ts" ;
4
4
import { doWithSpinner } from "~/cmd/utils.ts" ;
5
5
import { getNestedProperty , setNestedProperty } from "~/utils.ts" ;
@@ -10,6 +10,11 @@ import { printYaml } from "~/cmd/styles.ts";
10
10
import { fromError } from "zod-validation-error" ;
11
11
import z from "zod" ;
12
12
import { colors } from "@cliffy/ansi/colors" ;
13
+ import { DEFAULT_WRAP_AMOUNT , GLOBAL_VT_CONFIG_PATH } from "~/consts.ts" ;
14
+ import { join } from "@std/path" ;
15
+ import wrap from "word-wrap" ;
16
+ import { openEditorAt } from "~/cmd/lib/utils/openEditorAt.ts" ;
17
+ import { Select } from "@cliffy/prompt" ;
13
18
14
19
function showConfigOptions ( ) {
15
20
// deno-lint-ignore no-explicit-any
@@ -37,6 +42,32 @@ function showConfigOptions() {
37
42
printYaml ( stringifyYaml ( jsonSchema [ "properties" ] ) ) ;
38
43
}
39
44
45
+ export const configWhereCmd = new Command ( )
46
+ . name ( "where" )
47
+ . description ( "Show the config file locations" )
48
+ . action ( async ( ) => {
49
+ // Find project root, if in a Val Town project
50
+ let vtRoot : string | undefined = undefined ;
51
+ try {
52
+ vtRoot = await findVtRoot ( Deno . cwd ( ) ) ;
53
+ } catch ( _ ) {
54
+ // ignore not found
55
+ }
56
+
57
+ // Local config is always in <root>/.vt/config.yaml
58
+ const localConfigPath = vtRoot
59
+ ? join ( vtRoot , ".vt" , "config.yaml" )
60
+ : undefined ;
61
+
62
+ // Just print the resolved paths, always global first, then local if it exists
63
+ if ( GLOBAL_VT_CONFIG_PATH ) {
64
+ console . log ( GLOBAL_VT_CONFIG_PATH ) ;
65
+ }
66
+ if ( localConfigPath ) {
67
+ console . log ( localConfigPath ) ;
68
+ }
69
+ } ) ;
70
+
40
71
export const configSetCmd = new Command ( )
41
72
. description ( "Set a configuration value" )
42
73
. option ( "--local" , "Set in the local configuration (val-specific)" )
@@ -60,11 +91,11 @@ export const configSetCmd = new Command()
60
91
61
92
const config = await vtConfig . loadConfig ( ) ;
62
93
const updatedConfig = setNestedProperty ( config , key , value ) ;
63
- const oldProperty = getNestedProperty ( config , key ) as
94
+ const oldProperty = getNestedProperty ( config , key , null ) as
64
95
| string
65
- | undefined ;
96
+ | null ;
66
97
67
- if ( oldProperty && oldProperty === value ) {
98
+ if ( oldProperty !== null && oldProperty . toString ( ) === value ) {
68
99
throw new Error (
69
100
`Property ${ colors . bold ( key ) } is already set to ${
70
101
colors . bold ( oldProperty )
@@ -98,7 +129,9 @@ export const configSetCmd = new Command()
98
129
if ( e instanceof z . ZodError ) {
99
130
throw new Error (
100
131
"Invalid input provided! \n" +
101
- colors . red ( fromError ( e ) . toString ( ) ) ,
132
+ wrap ( colors . red ( fromError ( e ) . toString ( ) ) , {
133
+ width : DEFAULT_WRAP_AMOUNT ,
134
+ } ) ,
102
135
) ;
103
136
} else throw e ;
104
137
}
@@ -110,6 +143,8 @@ export const configGetCmd = new Command()
110
143
. description ( "Get a configuration value" )
111
144
. arguments ( "[key]" )
112
145
. alias ( "show" )
146
+ . example ( "Display current configuration" , "vt config get" )
147
+ . example ( "Display the API key" , "vt config get apiKey" )
113
148
. action ( async ( _ : unknown , key ?: string ) => {
114
149
await doWithSpinner ( "Retreiving configuration..." , async ( spinner ) => {
115
150
// Check if we're in a Val Town Val directory
@@ -140,6 +175,41 @@ export const configGetCmd = new Command()
140
175
} ) ;
141
176
} ) ;
142
177
178
+ export const configIgnoreCmd = new Command ( )
179
+ . name ( "ignore" )
180
+ . description ( "Edit or display the global vtignore file" )
181
+ . option ( "--no-editor" , "Do not open the editor, just display the file path" )
182
+ . action ( async ( { editor } : { editor ?: boolean } ) => {
183
+ const { globalIgnoreFiles } = await globalConfig . loadConfig ( ) ;
184
+
185
+ if ( ! globalIgnoreFiles || globalIgnoreFiles . length === 0 ) {
186
+ console . log ( "No global ignore files found" ) ;
187
+ Deno . exit ( 1 ) ;
188
+ }
189
+
190
+ let globalIgnorePath : string ;
191
+
192
+ if ( globalIgnoreFiles . length === 1 ) {
193
+ globalIgnorePath = globalIgnoreFiles [ 0 ] ;
194
+ } else {
195
+ // Use Select prompt if multiple files are available
196
+ globalIgnorePath = await Select . prompt ( {
197
+ message : "Select a vtignore file to edit or display" ,
198
+ options : globalIgnoreFiles . map ( ( file ) => ( { name : file , value : file } ) ) ,
199
+ } ) ;
200
+ }
201
+
202
+ if ( ! editor ) console . log ( globalIgnorePath ) ;
203
+ else {
204
+ const editor = Deno . env . get ( "EDITOR" ) ;
205
+ if ( editor ) {
206
+ await openEditorAt ( globalIgnorePath ) ;
207
+ } else {
208
+ console . log ( globalIgnorePath ) ;
209
+ }
210
+ }
211
+ } ) ;
212
+
143
213
export const configOptionsCmd = new Command ( )
144
214
. name ( "options" )
145
215
. description ( "List all available configuration options" )
@@ -152,4 +222,6 @@ export const configCmd = new Command()
152
222
. description ( "Manage vt configuration" )
153
223
. command ( "set" , configSetCmd )
154
224
. command ( "get" , configGetCmd )
225
+ . command ( "ignore" , configIgnoreCmd )
226
+ . command ( "where" , configWhereCmd )
155
227
. command ( "options" , configOptionsCmd ) ;
0 commit comments