Skip to content

Commit

Permalink
fix(core): read v2 workspace format in converted nx generators
Browse files Browse the repository at this point in the history
closes #6452
  • Loading branch information
AgentEnder authored and vsavkin committed Sep 15, 2021
1 parent f929a47 commit 8f9da7c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 40 deletions.
39 changes: 37 additions & 2 deletions packages/devkit/src/utils/invoke-nx-generator.ts
Expand Up @@ -4,10 +4,13 @@ import type {
Tree,
TreeWriteOptions,
} from '@nrwl/tao/src/shared/tree';
import type {
import {
Generator,
GeneratorCallback,
toNewFormat,
toOldFormatOrNull,
} from '@nrwl/tao/src/shared/workspace';
import { parseJson, serializeJson } from '@nrwl/tao/src/utils/json';
import { join, relative } from 'path';

class RunCallbackTask {
Expand Down Expand Up @@ -79,6 +82,8 @@ const actionToFileChangeMap = {
};

class DevkitTreeFromAngularDevkitTree implements Tree {
private configFileName: string;

constructor(private tree, private _root: string) {}

get root(): string {
Expand Down Expand Up @@ -144,9 +149,16 @@ class DevkitTreeFromAngularDevkitTree implements Tree {
read(filePath: string): Buffer;
read(filePath: string, encoding: BufferEncoding): string;
read(filePath: string, encoding?: BufferEncoding) {
return encoding
const rawResult = encoding
? this.tree.read(filePath).toString(encoding)
: this.tree.read(filePath);
if (isWorkspaceJsonChange(filePath)) {
const formatted = toNewFormat(
parseJson(Buffer.isBuffer(rawResult) ? rawResult.toString() : rawResult)
);
return encoding ? serializeJson(formatted) : serializeJson(formatted);
}
return rawResult;
}

rename(from: string, to: string): void {
Expand All @@ -162,6 +174,20 @@ class DevkitTreeFromAngularDevkitTree implements Tree {
this.warnUnsupportedFilePermissionsChange(filePath, options.mode);
}

if (isWorkspaceJsonChange(filePath)) {
const w = parseJson(content.toString());
for (const [project, configuration] of Object.entries(w.projects)) {
if (typeof configuration === 'string') {
w.projects[project] = parseJson(
this.tree.read(`${configuration}/project.json`)
);
w.projects[project].configFilePath = `${configuration}/project.json`;
}
}
const formatted = toOldFormatOrNull(w);
content = serializeJson(formatted ? formatted : w);
}

if (this.tree.exists(filePath)) {
this.tree.overwrite(filePath, content);
} else {
Expand All @@ -183,3 +209,12 @@ class DevkitTreeFromAngularDevkitTree implements Tree {
);
}
}

function isWorkspaceJsonChange(path) {
return (
path === 'workspace.json' ||
path === '/workspace.json' ||
path === 'angular.json' ||
path === '/angular.json'
);
}
79 changes: 44 additions & 35 deletions packages/tao/src/commands/ngcli-adapter.ts
Expand Up @@ -279,11 +279,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
.toPromise();
}

protected context(path: string): Observable<{
isWorkspaceConfig: boolean;
actualConfigFileName: any;
isNewFormat: boolean;
}> {
protected context(path: string): Observable<ChangeContext> {
if (isWorkspaceConfigPath(path)) {
return super.exists('/angular.json' as any).pipe(
switchMap((isAngularJson) => {
Expand Down Expand Up @@ -319,60 +315,67 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
}
}

private writeWorkspaceConfiguration(context, content): Observable<void> {
private writeWorkspaceConfiguration(
context: ChangeContext,
content
): Observable<void> {
const config = parseJson(Buffer.from(content).toString());
if (context.isNewFormat) {
try {
const w = parseJson(Buffer.from(content).toString());
const formatted = toNewFormatOrNull(w);
if (formatted) {
return this.writeWorkspaceConfigFiles(
context.actualConfigFileName,
formatted
);
return this.writeWorkspaceConfigFiles(context, formatted);
} else {
return this.writeWorkspaceConfigFiles(
context.actualConfigFileName,
config
);
return this.writeWorkspaceConfigFiles(context, config);
}
} catch (e) {
return this.writeWorkspaceConfigFiles(
context.actualConfigFileName,
config
);
return this.writeWorkspaceConfigFiles(context, config);
}
} else {
return this.writeWorkspaceConfigFiles(
context.actualConfigFileName,
config
);
return this.writeWorkspaceConfigFiles(context, config);
}
}

private writeWorkspaceConfigFiles(workspaceFileName, config) {
private writeWorkspaceConfigFiles(
{ actualConfigFileName: workspaceFileName, isNewFormat }: ChangeContext,
config
) {
// copy to avoid removing inlined config files.
let writeObservable: Observable<void>;
const configToWrite = {
...config,
projects: { ...config.projects },
};

Object.entries(configToWrite.projects as Record<string, any>).forEach(
([project, projectConfig]) => {
if (projectConfig.configFilePath) {
// project was read from a project.json file
const configPath = projectConfig.configFilePath;
const fileConfigObject = { ...projectConfig };
delete fileConfigObject.configFilePath; // remove the configFilePath before writing
super.write(configPath, Buffer.from(serializeJson(fileConfigObject))); // write back to the project.json file
configToWrite.projects[project] = normalize(dirname(configPath)); // update the config object to point to the written file.
const projects: [string, any][] = Object.entries(configToWrite.projects);
for (const [project, projectConfig] of projects) {
if (projectConfig.configFilePath) {
if (!isNewFormat) {
throw new Error(
'Attempted to write standalone project configuration into a v1 workspace'
);
}
// project was read from a project.json file
const configPath = projectConfig.configFilePath;
const fileConfigObject = { ...projectConfig };
delete fileConfigObject.configFilePath; // remove the configFilePath before writing
const projectJsonWrite = super.write(
configPath,
Buffer.from(serializeJson(fileConfigObject))
); // write back to the project.json file
writeObservable = writeObservable
? concat(writeObservable, projectJsonWrite)
: projectJsonWrite;
configToWrite.projects[project] = normalize(dirname(configPath)); // update the config object to point to the written file.
}
);
return super.write(
}
const workspaceJsonWrite = super.write(
workspaceFileName,
Buffer.from(serializeJson(configToWrite))
);
return writeObservable
? concat(writeObservable, workspaceJsonWrite)
: workspaceJsonWrite;
}

protected resolveInlineProjectConfigurations(config: {
Expand Down Expand Up @@ -419,6 +422,12 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
}
}

type ChangeContext = {
isWorkspaceConfig: boolean;
actualConfigFileName: any;
isNewFormat: boolean;
};

/**
* This host contains the workaround needed to run Angular migrations
*/
Expand Down
13 changes: 10 additions & 3 deletions packages/tao/src/shared/workspace.ts
Expand Up @@ -572,9 +572,12 @@ export function toOldFormatOrNull(w: any) {

export function resolveOldFormatWithInlineProjects(
w: any,
root: string = appRootPath
root: string = appRootPath,
includeConfigFilePath = false
) {
return toOldFormatOrNull(inlineProjectConfigurations(w, root));
const inlined = inlineProjectConfigurations(w, root, includeConfigFilePath);
const formatted = toOldFormatOrNull(inlined);
return formatted ? formatted : inlined;
}

export function resolveNewFormatWithInlineProjects(
Expand All @@ -586,13 +589,17 @@ export function resolveNewFormatWithInlineProjects(

export function inlineProjectConfigurations(
w: any,
root: string = appRootPath
root: string = appRootPath,
includeConfigFilePath = false
) {
Object.entries(w.projects || {}).forEach(
([project, config]: [string, any]) => {
if (typeof config === 'string') {
const configFilePath = path.join(root, config, 'project.json');
const fileConfig = readJsonFile(configFilePath);
if (includeConfigFilePath) {
fileConfig.configFilePath = configFilePath;
}
w.projects[project] = fileConfig;
}
}
Expand Down

0 comments on commit 8f9da7c

Please sign in to comment.