Skip to content

Commit

Permalink
feat(node): Add output path to setup docker
Browse files Browse the repository at this point in the history
This helps when we are generating the docker file for inferred and non inferred projects
  • Loading branch information
ndcunningham committed Jun 4, 2024
1 parent d2d06cd commit 567ac46
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 84 deletions.
4 changes: 4 additions & 0 deletions docs/generated/packages/node/generators/setup-docker.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
"description": "The name of the build target",
"type": "string",
"default": "build"
},
"outputPath": {
"description": "The output path for the node application",
"type": "string"
}
},
"presets": []
Expand Down
5 changes: 5 additions & 0 deletions packages/node/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-com
export interface NormalizedSchema extends Schema {
appProjectRoot: string;
parsedTags: string[];
outputPath: string;
}

function getWebpackBuildConfig(
Expand Down Expand Up @@ -562,6 +563,10 @@ async function normalizeOptions(
unitTestRunner: options.unitTestRunner ?? 'jest',
rootProject: options.rootProject ?? false,
port: options.port ?? 3000,
outputPath: joinPathFragments(
'dist',
options.rootProject ? options.name : appProjectRoot
),
};
}

Expand Down
1 change: 1 addition & 0 deletions packages/node/src/generators/setup-docker/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface SetUpDockerOptions {
targetName?: string;
buildTarget?: string;
skipFormat?: boolean;
outputPath: string;
}
4 changes: 4 additions & 0 deletions packages/node/src/generators/setup-docker/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
"description": "The name of the build target",
"type": "string",
"default": "build"
},
"outputPath": {
"description": "The output path for the node application",
"type": "string"
}
}
}
42 changes: 2 additions & 40 deletions packages/node/src/generators/setup-docker/setup-docker.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import 'nx/src/internal-testing-utils/mock-project-graph';

import {
ProjectConfiguration,
readProjectConfiguration,
Tree,
} from '@nx/devkit';
import { readProjectConfiguration, Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { applicationGenerator } from '../application/application';

describe('setupDockerGenerator', () => {
let tree: Tree;
Expand All @@ -18,15 +13,6 @@ describe('setupDockerGenerator', () => {
describe('integrated', () => {
it('should create docker assets when --docker is passed', async () => {
const projectName = 'integreated-api';
// Since we mock the project graph, we need to mock the project configuration as well
mockReadCachedProjectConfiguration({
name: projectName,
root: projectName,
});

const { applicationGenerator } = await import(
'../application/application'
);

await applicationGenerator(tree, {
name: projectName,
Expand Down Expand Up @@ -56,11 +42,7 @@ describe('setupDockerGenerator', () => {
describe('standalone', () => {
it('should create docker assets when --docker is passed', async () => {
const projectName = 'standalone-api';
mockReadCachedProjectConfiguration({ name: projectName, root: '' });

const { applicationGenerator } = await import(
'../application/application'
);
await applicationGenerator(tree, {
name: projectName,
framework: 'fastify',
Expand All @@ -86,23 +68,3 @@ describe('setupDockerGenerator', () => {
});
});
});

const mockReadCachedProjectConfiguration = (
projectConfig: ProjectConfiguration
) => {
jest.mock('nx/src/project-graph/project-graph', () => {
return {
...jest.requireActual('nx/src/project-graph/project-graph'),
readCachedProjectConfiguration: jest.fn(() => {
return {
root: projectConfig.root,
targets: {
build: {
outputs: [`dist/${projectConfig.name}`],
},
},
};
}),
};
});
};
52 changes: 8 additions & 44 deletions packages/node/src/generators/setup-docker/setup-docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
generateFiles,
GeneratorCallback,
joinPathFragments,
logger,
ProjectConfiguration,
readNxJson,
readProjectConfiguration,
runTasksInSerial,
Expand All @@ -14,8 +12,6 @@ import {

import { SetUpDockerOptions } from './schema';
import { join } from 'path';
import { interpolate } from 'nx/src/tasks-runner/utils';
import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph';

function normalizeOptions(
tree: Tree,
Expand All @@ -30,47 +26,15 @@ function normalizeOptions(
}

function addDocker(tree: Tree, options: SetUpDockerOptions) {
// Inferred targets are only available in the project graph
const projectConfig = readCachedProjectConfiguration(options.project);

if (
!projectConfig ||
!projectConfig.targets ||
!projectConfig.targets[options.buildTarget]
) {
return;
}

// Returns an string like {workspaceRoot}/dist/apps/{projectName}
// Non crystalized projects would return {options.outputPath}
const tokenizedOutputPath =
projectConfig.targets[`${options.buildTarget}`]?.outputs?.[0];
const maybeBuildOptions =
projectConfig.targets[`${options.buildTarget}`]?.options;

if (tree.exists(joinPathFragments(projectConfig.root, 'DockerFile'))) {
logger.info(
`Skipping setup since a Dockerfile already exists inside ${projectConfig.root}`
);
} else if (!tokenizedOutputPath) {
logger.error(
`Skipping setup since the output path for the build target ${options.buildTarget} is not defined.`
);
} else {
const outputPath = interpolate(tokenizedOutputPath, {
projectName: projectConfig.name,
projectRoot: projectConfig.root,
workspaceRoot: '',
options: maybeBuildOptions || '',
});

generateFiles(tree, join(__dirname, './files'), projectConfig.root, {
tmpl: '',
app: projectConfig.sourceRoot,
buildLocation: outputPath,
project: options.project,
});
const projectConfig = readProjectConfiguration(tree, options.project);
if (!projectConfig) {
throw new Error(`Cannot find project configuration for ${options.project}`);
}
generateFiles(tree, join(__dirname, './files'), projectConfig.root, {
tmpl: '',
buildLocation: options.outputPath,
project: options.project,
});
}

export function updateProjectConfig(tree: Tree, options: SetUpDockerOptions) {
Expand Down

0 comments on commit 567ac46

Please sign in to comment.