@@ -4,8 +4,23 @@ import * as fs from "fs/promises";
44import * as os from "os" ;
55import * as path from "path" ;
66
7- const CONFIG_FILE_NAME = ".ziit.json" ;
8- const CONFIG_FILE_PATH = path . join ( os . homedir ( ) , CONFIG_FILE_NAME ) ;
7+ function getConfigDir ( ) : string {
8+ const xdgConfigHome = process . env . XDG_CONFIG_HOME ;
9+ if ( xdgConfigHome ) {
10+ return path . join ( xdgConfigHome , "ziit" ) ;
11+ }
12+ return path . join ( os . homedir ( ) , ".config" , "ziit" ) ;
13+ }
14+
15+ const CONFIG_DIR = getConfigDir ( ) ;
16+ const CONFIG_FILE_NAME = "config.json" ;
17+ const CONFIG_FILE_PATH = path . join ( CONFIG_DIR , CONFIG_FILE_NAME ) ;
18+
19+ const LEGACY_CONFIG_FILE_NAME = ".ziit.json" ;
20+ const LEGACY_CONFIG_FILE_PATH = path . join (
21+ os . homedir ( ) ,
22+ LEGACY_CONFIG_FILE_NAME ,
23+ ) ;
924const OLD_CONFIG_FILE_NAME = ".ziit.cfg" ;
1025const OLD_CONFIG_FILE_PATH = path . join ( os . homedir ( ) , OLD_CONFIG_FILE_NAME ) ;
1126
@@ -14,33 +29,98 @@ interface ZiitConfig {
1429 baseUrl ?: string ;
1530}
1631
17- async function migrateOldConfigIfNeeded ( ) {
32+ async function ensureConfigDir ( ) : Promise < void > {
1833 try {
19- await fs . access ( OLD_CONFIG_FILE_PATH ) ;
20- const content = await fs . readFile ( OLD_CONFIG_FILE_PATH , "utf-8" ) ;
21- let apiKey : string | undefined ;
22- let baseUrl : string | undefined ;
23- const lines = content . split ( / \r ? \n / ) ;
24- for ( const line of lines ) {
25- const trimmed = line . trim ( ) ;
26- if ( trimmed . startsWith ( "api_key" ) ) {
27- apiKey = trimmed . split ( "=" ) [ 1 ] ?. trim ( ) ;
34+ await fs . mkdir ( CONFIG_DIR , { recursive : true } ) ;
35+ } catch ( error : any ) {
36+ log ( `Error creating config directory: ${ error . message } ` ) ;
37+ }
38+ }
39+
40+ async function migrateLegacyConfigs ( ) : Promise < void > {
41+ try {
42+ await fs . access ( CONFIG_FILE_PATH ) ;
43+ log ( "New config file already exists, skipping migration" ) ;
44+ return ;
45+ } catch {
46+ log ( "New config file not found, checking for legacy configs to migrate" ) ;
47+ }
48+
49+ let migratedConfig : ZiitConfig = { } ;
50+ let migrationSource = "" ;
51+
52+ try {
53+ await fs . access ( LEGACY_CONFIG_FILE_PATH ) ;
54+ const content = await fs . readFile ( LEGACY_CONFIG_FILE_PATH , "utf-8" ) ;
55+ migratedConfig = JSON . parse ( content ) ;
56+ migrationSource = LEGACY_CONFIG_FILE_PATH ;
57+ log ( "Found legacy .ziit.json config file for migration" ) ;
58+ } catch {
59+ try {
60+ await fs . access ( OLD_CONFIG_FILE_PATH ) ;
61+ const content = await fs . readFile ( OLD_CONFIG_FILE_PATH , "utf-8" ) ;
62+ let apiKey : string | undefined ;
63+ let baseUrl : string | undefined ;
64+ const lines = content . split ( / \r ? \n / ) ;
65+ for ( const line of lines ) {
66+ const trimmed = line . trim ( ) ;
67+ if ( trimmed . startsWith ( "api_key" ) ) {
68+ apiKey = trimmed . split ( "=" ) [ 1 ] ?. trim ( ) ;
69+ }
70+ if ( trimmed . startsWith ( "base_url" ) ) {
71+ baseUrl = trimmed . split ( "=" ) [ 1 ] ?. trim ( ) . replace ( / \\ : / g, ":" ) ;
72+ }
2873 }
29- if ( trimmed . startsWith ( "base_url" ) ) {
30- baseUrl = trimmed . split ( "=" ) [ 1 ] ?. trim ( ) . replace ( / \\ : / g, ":" ) ;
74+ if ( apiKey ) migratedConfig . apiKey = apiKey ;
75+ if ( baseUrl ) migratedConfig . baseUrl = baseUrl ;
76+ migrationSource = OLD_CONFIG_FILE_PATH ;
77+ log ( "Found legacy .ziit.cfg config file for migration" ) ;
78+ } catch {
79+ return ;
80+ }
81+ }
82+
83+ if ( migrationSource ) {
84+ try {
85+ await ensureConfigDir ( ) ;
86+ await fs . writeFile (
87+ CONFIG_FILE_PATH ,
88+ JSON . stringify ( migratedConfig , null , 2 ) ,
89+ ) ;
90+
91+ try {
92+ if ( migrationSource === LEGACY_CONFIG_FILE_PATH ) {
93+ await fs . unlink ( LEGACY_CONFIG_FILE_PATH ) ;
94+ log (
95+ `Migrated config from ${ LEGACY_CONFIG_FILE_PATH } to ${ CONFIG_FILE_PATH } ` ,
96+ ) ;
97+ } else if ( migrationSource === OLD_CONFIG_FILE_PATH ) {
98+ await fs . unlink ( OLD_CONFIG_FILE_PATH ) ;
99+ log (
100+ `Migrated config from ${ OLD_CONFIG_FILE_PATH } to ${ CONFIG_FILE_PATH } ` ,
101+ ) ;
102+ }
103+ } catch ( cleanupError : any ) {
104+ log (
105+ `Warning: Could not remove old config file: ${ cleanupError . message } ` ,
106+ ) ;
31107 }
108+
109+ vscode . window . showInformationMessage (
110+ "Ziit configuration has been migrated to the new location. " +
111+ `New location: ${ CONFIG_FILE_PATH } ` ,
112+ ) ;
113+ } catch ( error : any ) {
114+ log ( `Error during migration: ${ error . message } ` ) ;
115+ vscode . window . showErrorMessage (
116+ `Failed to migrate Ziit configuration: ${ error . message } ` ,
117+ ) ;
32118 }
33- const jsonConfig : ZiitConfig = { } ;
34- if ( apiKey ) jsonConfig . apiKey = apiKey ;
35- if ( baseUrl ) jsonConfig . baseUrl = baseUrl ;
36- await fs . writeFile ( CONFIG_FILE_PATH , JSON . stringify ( jsonConfig , null , 2 ) ) ;
37- await fs . unlink ( OLD_CONFIG_FILE_PATH ) ;
38- log ( "Migrated old .ziit.cfg to .ziit.json" ) ;
39- } catch { }
119+ }
40120}
41121
42122async function readConfigFile ( ) : Promise < ZiitConfig > {
43- await migrateOldConfigIfNeeded ( ) ;
123+ await migrateLegacyConfigs ( ) ;
44124 try {
45125 const content = await fs . readFile ( CONFIG_FILE_PATH , "utf-8" ) ;
46126 return JSON . parse ( content ) ;
@@ -50,7 +130,7 @@ async function readConfigFile(): Promise<ZiitConfig> {
50130 } else {
51131 log ( `Error reading config file: ${ error . message } ` ) ;
52132 vscode . window . showErrorMessage (
53- `Error reading Ziit config file: ${ error . message } `
133+ `Error reading Ziit config file: ${ error . message } ` ,
54134 ) ;
55135 return { } ;
56136 }
@@ -59,18 +139,19 @@ async function readConfigFile(): Promise<ZiitConfig> {
59139
60140async function writeConfigFile ( config : ZiitConfig ) : Promise < void > {
61141 try {
142+ await ensureConfigDir ( ) ;
62143 await fs . writeFile ( CONFIG_FILE_PATH , JSON . stringify ( config , null , 2 ) ) ;
63- log ( " Config file updated (.ziit.json)" ) ;
144+ log ( ` Config file updated (${ CONFIG_FILE_PATH } )` ) ;
64145 } catch ( error : any ) {
65146 log ( `Error writing config file: ${ error . message } ` ) ;
66147 vscode . window . showErrorMessage (
67- `Failed to write Ziit config file: ${ error . message } `
148+ `Failed to write Ziit config file: ${ error . message } ` ,
68149 ) ;
69150 }
70151}
71152
72153async function getConfigValue < T > (
73- key : keyof ZiitConfig
154+ key : keyof ZiitConfig ,
74155) : Promise < T | undefined > {
75156 const vscodeConfig = vscode . workspace . getConfiguration ( "ziit" ) ;
76157
@@ -100,7 +181,7 @@ async function getConfigValue<T>(
100181
101182async function updateConfigValue < T > (
102183 key : keyof ZiitConfig ,
103- value : T
184+ value : T ,
104185) : Promise < void > {
105186 let currentConfig : ZiitConfig = { } ;
106187 try {
@@ -113,7 +194,9 @@ async function updateConfigValue<T>(
113194 const newConfig = { ...currentConfig , [ key ] : value } ;
114195 await writeConfigFile ( newConfig ) ;
115196 await vscode . workspace . getConfiguration ( "ziit" ) . update ( key , value , true ) ;
116- log ( `${ key } updated in config file (.ziit.json) and VS Code settings.` ) ;
197+ log (
198+ `${ key } updated in config file (${ CONFIG_FILE_PATH } ) and VS Code settings.` ,
199+ ) ;
117200}
118201
119202export async function setApiKey ( ) : Promise < void > {
@@ -155,13 +238,13 @@ export async function getBaseUrl(): Promise<string> {
155238
156239export async function initializeAndSyncConfig ( ) : Promise < void > {
157240 log (
158- " Initializing or syncing config file (.ziit.json ) with VS Code settings..."
241+ ` Initializing or syncing config file (${ CONFIG_FILE_PATH } ) with VS Code settings...` ,
159242 ) ;
160243 let fileConfig : ZiitConfig ;
161244 let fileNeedsCreation = false ;
162245 try {
163246 fileConfig = await readConfigFile ( ) ;
164- log ( " Config file found (.ziit.json)" ) ;
247+ log ( ` Config file found (${ CONFIG_FILE_PATH } )` ) ;
165248 } catch ( error : any ) {
166249 if ( error . code === "ENOENT" ) {
167250 log ( `Config file not found at ${ CONFIG_FILE_PATH } . Will create it.` ) ;
@@ -183,7 +266,7 @@ export async function initializeAndSyncConfig(): Promise<void> {
183266 }
184267 await writeConfigFile ( initialConfig ) ;
185268 fileConfig = initialConfig ;
186- log ( " Config file created and populated (.ziit.json)" ) ;
269+ log ( ` Config file created and populated (${ CONFIG_FILE_PATH } )` ) ;
187270 }
188271 let updated = false ;
189272 for ( const key of [ "apiKey" , "baseUrl" ] ) {
@@ -201,7 +284,7 @@ export async function initializeAndSyncConfig(): Promise<void> {
201284 if ( vscodeValue !== undefined && vscodeValue !== defaultValue ) {
202285 await vscodeConfig . update ( key , undefined , true ) ;
203286 log (
204- `Reset VS Code setting '${ key } ' to default as it's not in config file.`
287+ `Reset VS Code setting '${ key } ' to default as it's not in config file.` ,
205288 ) ;
206289 updated = true ;
207290 }
0 commit comments