77 */
88
99import { json , workspaces } from '@angular-devkit/core' ;
10- import { existsSync , promises as fs , writeFileSync } from 'fs' ;
10+ import { existsSync , promises as fs } from 'fs' ;
1111import * as os from 'os' ;
1212import * as path from 'path' ;
1313import { PackageManager } from '../../lib/config/workspace-schema' ;
@@ -51,6 +51,7 @@ export const workspaceSchemaPath = path.join(__dirname, '../../lib/config/schema
5151
5252const configNames = [ 'angular.json' , '.angular.json' ] ;
5353const globalFileName = '.angular-config.json' ;
54+ const defaultGlobalFilePath = path . join ( os . homedir ( ) , globalFileName ) ;
5455
5556function xdgConfigHome ( home : string , configFile ?: string ) : string {
5657 // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
@@ -106,9 +107,8 @@ function globalFilePath(): string | null {
106107 return xdgConfigOld ;
107108 }
108109
109- const p = path . join ( home , globalFileName ) ;
110- if ( existsSync ( p ) ) {
111- return p ;
110+ if ( existsSync ( defaultGlobalFilePath ) ) {
111+ return defaultGlobalFilePath ;
112112 }
113113
114114 return null ;
@@ -147,7 +147,12 @@ export class AngularWorkspace {
147147 }
148148
149149 save ( ) : Promise < void > {
150- return workspaces . writeWorkspace ( this . workspace , createWorkspaceHost ( ) , this . filePath ) ;
150+ return workspaces . writeWorkspace (
151+ this . workspace ,
152+ createWorkspaceHost ( ) ,
153+ this . filePath ,
154+ workspaces . WorkspaceFormat . JSON ,
155+ ) ;
151156 }
152157
153158 static async load ( workspaceFilePath : string ) : Promise < AngularWorkspace > {
@@ -162,22 +167,38 @@ export class AngularWorkspace {
162167}
163168
164169const cachedWorkspaces = new Map < string , AngularWorkspace | undefined > ( ) ;
170+
171+ export async function getWorkspace ( level : 'global' ) : Promise < AngularWorkspace > ;
172+ export async function getWorkspace ( level : 'local' ) : Promise < AngularWorkspace | undefined > ;
165173export async function getWorkspace (
166- level : 'local' | 'global' = 'local' ,
174+ level : 'local' | 'global' ,
175+ ) : Promise < AngularWorkspace | undefined > ;
176+
177+ export async function getWorkspace (
178+ level : 'local' | 'global' ,
167179) : Promise < AngularWorkspace | undefined > {
168180 if ( cachedWorkspaces . has ( level ) ) {
169181 return cachedWorkspaces . get ( level ) ;
170182 }
171183
172- let configPath = level === 'local' ? projectFilePath ( ) : globalFilePath ( ) ;
184+ const configPath = level === 'local' ? projectFilePath ( ) : globalFilePath ( ) ;
173185 if ( ! configPath ) {
174- if ( level === 'local' ) {
175- cachedWorkspaces . set ( level , undefined ) ;
186+ if ( level === 'global' ) {
187+ // Unlike a local config, a global config is not mandatory.
188+ // So we create an empty one in memory and keep it as such until it has been modified and saved.
189+ const globalWorkspace = new AngularWorkspace (
190+ { extensions : { } , projects : new workspaces . ProjectDefinitionCollection ( ) } ,
191+ defaultGlobalFilePath ,
192+ ) ;
193+
194+ cachedWorkspaces . set ( level , globalWorkspace ) ;
176195
177- return undefined ;
196+ return globalWorkspace ;
178197 }
179198
180- configPath = createGlobalSettings ( ) ;
199+ cachedWorkspaces . set ( level , undefined ) ;
200+
201+ return undefined ;
181202 }
182203
183204 try {
@@ -193,26 +214,24 @@ export async function getWorkspace(
193214 }
194215}
195216
196- export function createGlobalSettings ( ) : string {
197- const home = os . homedir ( ) ;
198- if ( ! home ) {
199- throw new Error ( 'No home directory found.' ) ;
200- }
201-
202- const globalPath = path . join ( home , globalFileName ) ;
203- writeFileSync ( globalPath , JSON . stringify ( { version : 1 } ) ) ;
204-
205- return globalPath ;
206- }
207-
208- export function getWorkspaceRaw (
217+ /**
218+ * This method will load the workspace configuration in raw JSON format.
219+ * When `level` is `global` and file doesn't exists, it will be created.
220+ *
221+ * NB: This method is intended to be used only for `ng config`.
222+ */
223+ export async function getWorkspaceRaw (
209224 level : 'local' | 'global' = 'local' ,
210- ) : [ JSONFile | null , string | null ] {
225+ ) : Promise < [ JSONFile | null , string | null ] > {
211226 let configPath = level === 'local' ? projectFilePath ( ) : globalFilePath ( ) ;
212227
213228 if ( ! configPath ) {
214229 if ( level === 'global' ) {
215- configPath = createGlobalSettings ( ) ;
230+ configPath = defaultGlobalFilePath ;
231+ // Config doesn't exist, force create it.
232+
233+ const globalWorkspace = await getWorkspace ( 'global' ) ;
234+ await globalWorkspace . save ( ) ;
216235 } else {
217236 return [ null , null ] ;
218237 }
0 commit comments