Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/default_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ jobs:
run: >
pnpx nx run-many
-t lint,test
--configuration ci
--exclude
devextreme
devextreme-themebuilder
Expand Down
9 changes: 9 additions & 0 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
"{projectRoot}/**/*.ts",
"{projectRoot}/tsconfig.json",
{ "externalDependencies": [ "devextreme-internal-tools", "ts-node", "typescript"] }
],
"devextreme-sources": [
"{projectRoot}/js/**/*",
"{projectRoot}/ts/**/*"
],
"devextreme-build-config": [
"{projectRoot}/build/**/*",
"{projectRoot}/webpack.config.js",
"{projectRoot}/gulpfile.js"
]
},
"targetDefaults": {
Expand Down
81 changes: 81 additions & 0 deletions packages/devextreme/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,87 @@
"devextreme-scss"
],
"targets": {
"clean:artifacts": {
"executor": "devextreme-nx-infra-plugin:clean",
"options": {
"targetDirectory": "./artifacts",
"excludePatterns": [
"./artifacts/css",
"./artifacts/npm/devextreme/package.json",
"./artifacts/npm/devextreme-dist/package.json"
]
}
},
"clean:cldr-data": {
"executor": "devextreme-nx-infra-plugin:clean",
"options": {
"targetDirectory": "./js/__internal/core/localization/cldr-data"
}
},
"build:localization:generate": {
"executor": "devextreme-nx-infra-plugin:localization",
"options": {
"messagesDir": "./js/localization/messages",
"messageTemplate": "./build/gulp/localization-template.jst",
"messageOutputDir": "./artifacts/js/localization",
"generatedTemplate": "./build/gulp/generated_js.jst",
"cldrDataOutputDir": "./js/__internal/core/localization/cldr-data",
"defaultMessagesOutputDir": "./js/__internal/core/localization"
},
"inputs": [
"{projectRoot}/js/localization/messages/**/*.json",
"{projectRoot}/build/gulp/localization-template.jst",
"{projectRoot}/build/gulp/generated_js.jst"
],
"outputs": [
"{projectRoot}/artifacts/js/localization",
"{projectRoot}/js/__internal/core/localization/default_messages.ts",
"{projectRoot}/js/__internal/core/localization/cldr-data"
],
"cache": true
},
"build:localization:headers": {
"executor": "devextreme-nx-infra-plugin:add-license-headers",
"options": {
"targetDirectory": "./artifacts/js/localization",
"licenseTemplateFile": "./build/gulp/license-header.txt",
"eulaUrl": "https://js.devexpress.com/Licensing/",
"prependAfterLicense": "\"use strict\";\n\n",
"separatorBetweenBannerAndContent": "",
"includePatterns": ["**/*.js"]
},
"inputs": [
"{projectRoot}/artifacts/js/localization/**/*.js",
"{projectRoot}/build/gulp/license-header.txt"
],
"outputs": [
"{projectRoot}/artifacts/js/localization"
],
"cache": true
},
"build:localization": {
"executor": "nx:run-commands",
"options": {
"commands": [
"pnpm nx clean:cldr-data devextreme",
"pnpm nx build:localization:generate devextreme",
"pnpm nx build:localization:headers devextreme"
],
"parallel": false
},
"inputs": [
"{projectRoot}/js/localization/messages/**/*.json",
"{projectRoot}/build/gulp/localization-template.jst",
"{projectRoot}/build/gulp/generated_js.jst",
"{projectRoot}/build/gulp/license-header.txt"
],
"outputs": [
"{projectRoot}/artifacts/js/localization",
"{projectRoot}/js/__internal/core/localization/default_messages.ts",
"{projectRoot}/js/__internal/core/localization/cldr-data"
],
"cache": true
},
"build": {
"executor": "nx:run-script",
"options": {
Expand Down
5 changes: 5 additions & 0 deletions packages/nx-infra-plugin/executors.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
"implementation": "./src/executors/karma-multi-env/executor",
"schema": "./src/executors/karma-multi-env/schema.json",
"description": "Run Karma tests sequentially across multiple Angular environments (client, server, hydration)"
},
"localization": {
"implementation": "./src/executors/localization/executor",
"schema": "./src/executors/localization/schema.json",
"description": "Generate localization message files and TypeScript CLDR data modules"
}
}
}
2 changes: 2 additions & 0 deletions packages/nx-infra-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"fs-extra": "^11.2.0",
"glob": "11.1.0",
"normalize-path": "3.0.0",
"lodash": "^4.17.21",
"rimraf": "3.0.2"
},
"peerDependencies": {
Expand All @@ -34,6 +35,7 @@
"@types/jest": "29.5.14",
"@types/normalize-path": "3.0.2",
"@types/node": "18.19.130",
"@types/lodash": "^4.17.0",
"prettier": "catalog:tools",
"ts-jest": "29.1.3",
"typescript": "4.9.5"
Expand Down
5 changes: 5 additions & 0 deletions packages/nx-infra-plugin/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "{projectRoot}/jest.config.ts"
},
"configurations": {
"ci": {
"silent": true
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ describe('AddLicenseHeadersExecutor E2E', () => {
expect(indexContent).toContain('test-package');
expect(indexContent).toContain('Version: 1.0.0');
expect(indexContent).toContain('Developer Express Inc.');
expect(indexContent).toContain('MIT license');
const currentYear = new Date().getFullYear();
expect(indexContent).toContain(`2012 - ${currentYear}`);
expect(indexContent).toMatch(/Build date:/);

const utilsContent = await readFileText(path.join(npmDir, 'utils.js'));
expect(utilsContent).toMatch(/^\/\*!/);
Expand Down Expand Up @@ -107,6 +111,46 @@ describe('AddLicenseHeadersExecutor E2E', () => {

expect(newContent).toContain(originalContent.trim());
});

it('should support custom license template', async () => {
const projectDir = path.join(tempDir, 'packages', 'test-lib');
const buildDir = path.join(projectDir, 'build', 'gulp');
fs.mkdirSync(buildDir, { recursive: true });

await writeFileText(
path.join(buildDir, 'license-header.txt'),
`/*!
* DevExtreme (<%= file.relative %>)
* Version: <%= version %>
* Build date: <%= date %>
*
* Copyright (c) 2012 - <%= year %> Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: <%= eula %>
*/
`,
);

const options: AddLicenseHeadersExecutorSchema = {
targetDirectory: './npm',
packageJsonPath: './package.json',
licenseTemplateFile: './build/gulp/license-header.txt',
eulaUrl: 'https://js.devexpress.com/Licensing/',
prependAfterLicense: '"use strict";\n\n',
includePatterns: ['**/*.js'],
};

const result = await executor(options, context);
expect(result.success).toBe(true);

const npmDir = path.join(projectDir, 'npm');
const content = await readFileText(path.join(npmDir, 'index.js'));

expect(content).toMatch(/^\/\*!/);
expect(content).toContain('DevExtreme (index.js)');
expect(content).toContain('https://js.devexpress.com/Licensing/');
expect(content).toContain('"use strict";');
expect(content).toContain("return 'Hello'");
});
});

describe('Idempotence', () => {
Expand Down Expand Up @@ -159,65 +203,6 @@ describe('AddLicenseHeadersExecutor E2E', () => {
});
});

describe('Header content validation', () => {
it('should include package name in header', async () => {
const options: AddLicenseHeadersExecutorSchema = {
targetDirectory: './npm',
packageJsonPath: './package.json',
};

await executor(options, context);

const npmDir = path.join(tempDir, 'packages', 'test-lib', 'npm');
const content = await readFileText(path.join(npmDir, 'index.js'));

expect(content).toContain('test-package');
});

it('should include version in header', async () => {
const options: AddLicenseHeadersExecutorSchema = {
targetDirectory: './npm',
packageJsonPath: './package.json',
};

await executor(options, context);

const npmDir = path.join(tempDir, 'packages', 'test-lib', 'npm');
const content = await readFileText(path.join(npmDir, 'index.js'));

expect(content).toContain('Version: 1.0.0');
});

it('should include current year in header', async () => {
const options: AddLicenseHeadersExecutorSchema = {
targetDirectory: './npm',
packageJsonPath: './package.json',
};

await executor(options, context);

const npmDir = path.join(tempDir, 'packages', 'test-lib', 'npm');
const content = await readFileText(path.join(npmDir, 'index.js'));

const currentYear = new Date().getFullYear();
expect(content).toContain(`2012 - ${currentYear}`);
});

it('should include build date in header', async () => {
const options: AddLicenseHeadersExecutorSchema = {
targetDirectory: './npm',
packageJsonPath: './package.json',
};

await executor(options, context);

const npmDir = path.join(tempDir, 'packages', 'test-lib', 'npm');
const content = await readFileText(path.join(npmDir, 'index.js'));

expect(content).toMatch(/Build date:/);
});
});

describe('Error handling', () => {
it('should fail gracefully with missing package.json', async () => {
const options: AddLicenseHeadersExecutorSchema = {
Expand Down
Loading
Loading