feat(core): add gradle plugin (#21055)
This commit is contained in:
parent
e687aad0e4
commit
42ad573405
@ -69,6 +69,50 @@ commands:
|
|||||||
- ~/.pnpm-store
|
- ~/.pnpm-store
|
||||||
- ~/.cache/Cypress
|
- ~/.cache/Cypress
|
||||||
- node_modules
|
- node_modules
|
||||||
|
install-sdkman:
|
||||||
|
description: Install SDKMAN
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
name: Restore SDKMAN executable and binaries from cache
|
||||||
|
keys:
|
||||||
|
- sdkman-cli-{{ arch }}-v2
|
||||||
|
- run:
|
||||||
|
name: Installing SDKMAN
|
||||||
|
command: |
|
||||||
|
if [ ! -d ~/.sdkman ]
|
||||||
|
then
|
||||||
|
curl -s "https://get.sdkman.io?rcupdate=false" | bash
|
||||||
|
sed -i -e 's/sdkman_auto_answer=false/sdkman_auto_answer=true/g' ~/.sdkman/etc/config
|
||||||
|
fi
|
||||||
|
echo -e '\nsource "/home/circleci/.sdkman/bin/sdkman-init.sh"' >> $BASH_ENV
|
||||||
|
source $BASH_ENV
|
||||||
|
sdk version
|
||||||
|
- save_cache:
|
||||||
|
name: Save SDKMAN executable and binaries to cache
|
||||||
|
key: sdkman-cli-{{ arch }}-v2
|
||||||
|
paths:
|
||||||
|
- ~/.sdkman
|
||||||
|
install-gradle:
|
||||||
|
description: Install gradle
|
||||||
|
parameters:
|
||||||
|
gradle-version:
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
name: Restore Gradle binary from cache
|
||||||
|
keys:
|
||||||
|
- gradle-cli-{{ arch }}-v1
|
||||||
|
- run:
|
||||||
|
name: Installing Gradle
|
||||||
|
command: |
|
||||||
|
sdk install gradle << parameters.gradle-version >>
|
||||||
|
gradle --version
|
||||||
|
- save_cache:
|
||||||
|
name: Save Gradle binary to cache
|
||||||
|
key: gradle-cli-{{ arch }}-v1
|
||||||
|
paths:
|
||||||
|
- ~/.sdkman/candidates/gradle/
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# JOBS
|
# JOBS
|
||||||
# -------------------------
|
# -------------------------
|
||||||
@ -96,6 +140,9 @@ jobs:
|
|||||||
sudo apt-get install -y ca-certificates lsof
|
sudo apt-get install -y ca-certificates lsof
|
||||||
- browser-tools/install-chrome
|
- browser-tools/install-chrome
|
||||||
- browser-tools/install-chromedriver
|
- browser-tools/install-chromedriver
|
||||||
|
- install-sdkman
|
||||||
|
- install-gradle:
|
||||||
|
gradle-version: '8.5'
|
||||||
- run-pnpm-install:
|
- run-pnpm-install:
|
||||||
os: linux
|
os: linux
|
||||||
- run:
|
- run:
|
||||||
|
|||||||
4
.github/workflows/e2e-matrix.yml
vendored
4
.github/workflows/e2e-matrix.yml
vendored
@ -165,6 +165,8 @@ jobs:
|
|||||||
codeowners: 'S04SJ6HHP0X'
|
codeowners: 'S04SJ6HHP0X'
|
||||||
- project: e2e-expo
|
- project: e2e-expo
|
||||||
codeowners: 'S04TNCNJG5N'
|
codeowners: 'S04TNCNJG5N'
|
||||||
|
- project: e2e-gradle
|
||||||
|
codeowners: 'S04TNCNJG5N'
|
||||||
- project: e2e-jest
|
- project: e2e-jest
|
||||||
codeowners: 'S04T16BTJJY'
|
codeowners: 'S04T16BTJJY'
|
||||||
- project: e2e-js
|
- project: e2e-js
|
||||||
@ -242,6 +244,8 @@ jobs:
|
|||||||
project: e2e-esbuild
|
project: e2e-esbuild
|
||||||
- node_version: 18
|
- node_version: 18
|
||||||
project: e2e-expo
|
project: e2e-expo
|
||||||
|
- node_version: 18
|
||||||
|
project: e2e-gradle
|
||||||
- node_version: 18
|
- node_version: 18
|
||||||
project: e2e-jest
|
project: e2e-jest
|
||||||
- node_version: 18
|
- node_version: 18
|
||||||
|
|||||||
@ -20,6 +20,8 @@ launch-templates:
|
|||||||
node_modules
|
node_modules
|
||||||
~/.cache/Cypress
|
~/.cache/Cypress
|
||||||
~/.pnpm-store
|
~/.pnpm-store
|
||||||
|
~/.sdkman
|
||||||
|
~/.sdkman/candidates/gradle
|
||||||
BASE_BRANCH: 'master'
|
BASE_BRANCH: 'master'
|
||||||
- name: Install e2e deps
|
- name: Install e2e deps
|
||||||
script: |
|
script: |
|
||||||
@ -49,3 +51,21 @@ launch-templates:
|
|||||||
|
|
||||||
- name: Load Cargo Env
|
- name: Load Cargo Env
|
||||||
script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV
|
script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV
|
||||||
|
|
||||||
|
- name: Install zip and unzip
|
||||||
|
script: sudo apt-get -yqq install zip unzip
|
||||||
|
|
||||||
|
- name: Install SDKMAN and gradle
|
||||||
|
script: |
|
||||||
|
if [ ! -d $HOME/.sdkman ]
|
||||||
|
then
|
||||||
|
curl -s "https://get.sdkman.io" | bash
|
||||||
|
source "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||||
|
fi
|
||||||
|
sdk version
|
||||||
|
if [ ! -d $HOME/.sdkman/candidates/gradle/8.5 ]
|
||||||
|
then
|
||||||
|
sdk install gradle 8.5
|
||||||
|
fi
|
||||||
|
gradle --version
|
||||||
|
echo "PATH=$HOME/.sdkman/candidates/gradle/8.5/bin:$PATH" >> $NX_CLOUD_ENV
|
||||||
|
|||||||
@ -144,6 +144,10 @@ rust-toolchain @nrwl/nx-native-reviewers
|
|||||||
/packages/devkit/public-api.ts @FrozenPandaz @vsavkin
|
/packages/devkit/public-api.ts @FrozenPandaz @vsavkin
|
||||||
/packages/devkit/nx.ts @FrozenPandaz @vsavkin
|
/packages/devkit/nx.ts @FrozenPandaz @vsavkin
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
/packages/gradle/** @FrozenPandaz @xiongemi
|
||||||
|
/e2e/gradle/** @FrozenPandaz @xiongemi
|
||||||
|
|
||||||
# Nx-Plugin
|
# Nx-Plugin
|
||||||
/docs/generated/packages/plugin/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
/docs/generated/packages/plugin/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||||
/docs/shared/packages/plugin/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
/docs/shared/packages/plugin/** @nrwl/nx-devkit-reviewers @nrwl/nx-docs-reviewers
|
||||||
|
|||||||
14
e2e/gradle/jest.config.ts
Normal file
14
e2e/gradle/jest.config.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
export default {
|
||||||
|
transform: {
|
||||||
|
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
|
||||||
|
maxWorkers: 1,
|
||||||
|
globals: {},
|
||||||
|
globalSetup: '../utils/global-setup.ts',
|
||||||
|
globalTeardown: '../utils/global-teardown.ts',
|
||||||
|
displayName: 'e2e-gradle',
|
||||||
|
testTimeout: 600000,
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
};
|
||||||
10
e2e/gradle/project.json
Normal file
10
e2e/gradle/project.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "e2e-gradle",
|
||||||
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"sourceRoot": "e2e/gradle",
|
||||||
|
"projectType": "application",
|
||||||
|
"targets": {
|
||||||
|
"e2e": {}
|
||||||
|
},
|
||||||
|
"implicitDependencies": ["eslint"]
|
||||||
|
}
|
||||||
87
e2e/gradle/src/gradle.test.ts
Normal file
87
e2e/gradle/src/gradle.test.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import {
|
||||||
|
checkFilesExist,
|
||||||
|
cleanupProject,
|
||||||
|
createFile,
|
||||||
|
e2eConsoleLogger,
|
||||||
|
newProject,
|
||||||
|
runCLI,
|
||||||
|
runCommand,
|
||||||
|
uniq,
|
||||||
|
updateFile,
|
||||||
|
updateJson,
|
||||||
|
} from '@nx/e2e/utils';
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
|
||||||
|
describe('Gradle', () => {
|
||||||
|
let gradleProjectName = uniq('my-gradle-project');
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
newProject();
|
||||||
|
createGradleProject(gradleProjectName);
|
||||||
|
});
|
||||||
|
afterAll(() => cleanupProject());
|
||||||
|
|
||||||
|
it('should build', () => {
|
||||||
|
const projects = runCLI(`show projects`);
|
||||||
|
expect(projects).toContain('app');
|
||||||
|
expect(projects).toContain('list');
|
||||||
|
expect(projects).toContain('utilities');
|
||||||
|
expect(projects).toContain(gradleProjectName);
|
||||||
|
|
||||||
|
const buildOutput = runCLI('build app', { verbose: true });
|
||||||
|
// app depends on list and utilities
|
||||||
|
expect(buildOutput).toContain('nx run list:build');
|
||||||
|
expect(buildOutput).toContain('nx run utilities:build');
|
||||||
|
|
||||||
|
checkFilesExist(
|
||||||
|
`app/build/libs/app.jar`,
|
||||||
|
`list/build/libs/list.jar`,
|
||||||
|
`utilities/build/libs/utilities.jar`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should track dependencies for new app', () => {
|
||||||
|
createFile(
|
||||||
|
'app2/build.gradle.kts',
|
||||||
|
`
|
||||||
|
plugins {
|
||||||
|
id("gradleProject.kotlin-application-conventions")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":app"))
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
updateFile(`settings.gradle.kts`, (content) => {
|
||||||
|
content += `\r\ninclude("app2")`;
|
||||||
|
return content;
|
||||||
|
});
|
||||||
|
const buildOutput = runCLI('build app2', { verbose: true });
|
||||||
|
// app2 depends on app
|
||||||
|
expect(buildOutput).toContain('nx run app:build');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function createGradleProject(projectName: string) {
|
||||||
|
e2eConsoleLogger(`Using java version: ${execSync('java --version')}`);
|
||||||
|
e2eConsoleLogger(`Using gradle version: ${execSync('gradle --version')}`);
|
||||||
|
e2eConsoleLogger(execSync(`gradle help --task :init`).toString());
|
||||||
|
e2eConsoleLogger(
|
||||||
|
runCommand(
|
||||||
|
`gradle init --type kotlin-application --dsl kotlin --project-name ${projectName} --package gradleProject --no-incubating --split-project`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
updateJson('nx.json', (nxJson) => {
|
||||||
|
nxJson.plugins = ['@nx/gradle'];
|
||||||
|
return nxJson;
|
||||||
|
});
|
||||||
|
createFile(
|
||||||
|
'build.gradle.kts',
|
||||||
|
`allprojects {
|
||||||
|
apply {
|
||||||
|
plugin("project-report")
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
}
|
||||||
13
e2e/gradle/tsconfig.json
Normal file
13
e2e/gradle/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": ["node", "jest"]
|
||||||
|
},
|
||||||
|
"include": [],
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
20
e2e/gradle/tsconfig.spec.json
Normal file
20
e2e/gradle/tsconfig.spec.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.test.ts",
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.spec.tsx",
|
||||||
|
"**/*.test.tsx",
|
||||||
|
"**/*.spec.js",
|
||||||
|
"**/*.test.js",
|
||||||
|
"**/*.spec.jsx",
|
||||||
|
"**/*.test.jsx",
|
||||||
|
"**/*.d.ts",
|
||||||
|
"jest.config.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -43,6 +43,7 @@ const nxPackages = [
|
|||||||
`@nx/eslint-plugin`,
|
`@nx/eslint-plugin`,
|
||||||
`@nx/express`,
|
`@nx/express`,
|
||||||
`@nx/esbuild`,
|
`@nx/esbuild`,
|
||||||
|
`@nx/gradle`,
|
||||||
`@nx/jest`,
|
`@nx/jest`,
|
||||||
`@nx/js`,
|
`@nx/js`,
|
||||||
`@nx/eslint`,
|
`@nx/eslint`,
|
||||||
|
|||||||
9
nx-dev/nx-dev/public/images/icons/gradle.svg
Normal file
9
nx-dev/nx-dev/public/images/icons/gradle.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
aria-label="Gradle" role="img"
|
||||||
|
viewBox="0 0 512 512">
|
||||||
|
<rect
|
||||||
|
width="512" height="512"
|
||||||
|
rx="15%"
|
||||||
|
fill="#ffffff"/>
|
||||||
|
<path d="M427 132.7a61 61 0 00-85-1a6 6 0 000 9l7 8a6 6 0 008 1a35 35 0 0146 53c-48 48-113 -87 -259 -17a20 20 0 00-9 28l25 43a20 20 0 0027 7l1 0l0 0l11-6a257 257 0 0035-26a6 6 0 018 0v0a6 6 0 010 9a263 263 0 01-37 28h0l-11 6a31 31 0 01-15 4a32 32 0 01-28-16L126 219C81 259 53 314 68.13 392.26a6 6 0 006 4.74H100.6a6 6 0 005.93-5.3a40 40 0 0178.62 0a6 6 0 005.72 5.08h26.2a6 6 0 005.7-5.1a40 40 0 0178.6 0a6 6 0 005.7 5h26a6 6 0 005.8-5.72c1-37 10 -79 38.7 -100c98-73 72 -136 49.4 -158.3zm-100 110l-19-9v0a12 12 0 1119 9z" fill="#02303a"/></svg>
|
||||||
|
After Width: | Height: | Size: 734 B |
@ -8,6 +8,7 @@ export const iconsMap: Record<string, string> = {
|
|||||||
'eslint-plugin': '/images/icons/eslint.svg',
|
'eslint-plugin': '/images/icons/eslint.svg',
|
||||||
expo: '/images/icons/expo.svg',
|
expo: '/images/icons/expo.svg',
|
||||||
express: '/images/icons/express.svg',
|
express: '/images/icons/express.svg',
|
||||||
|
gradle: '/images/icons/gradle.svg',
|
||||||
jest: '/images/icons/jest.svg',
|
jest: '/images/icons/jest.svg',
|
||||||
js: '/images/icons/javascript.svg',
|
js: '/images/icons/javascript.svg',
|
||||||
eslint: '/images/icons/eslint.svg',
|
eslint: '/images/icons/eslint.svg',
|
||||||
|
|||||||
37
packages/gradle/.eslintrc.json
Normal file
37
packages/gradle/.eslintrc.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"extends": ["../../.eslintrc.json"],
|
||||||
|
"ignorePatterns": ["!**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.json"],
|
||||||
|
"parser": "jsonc-eslint-parser",
|
||||||
|
"rules": {
|
||||||
|
"@nx/dependency-checks": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoredDependencies": ["nx"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["./package.json"],
|
||||||
|
"parser": "jsonc-eslint-parser",
|
||||||
|
"rules": {
|
||||||
|
"@nx/nx-plugin-checks": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
packages/gradle/README.md
Normal file
18
packages/gradle/README.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<p style="text-align: center;">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
|
||||||
|
<img alt="Nx - Smart Monorepos · Fast CI" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
||||||
|
</picture>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{links}}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
# Nx: Smart Monorepos · Fast CI
|
||||||
|
|
||||||
|
Nx is a build system with built-in tooling and advanced CI capabilities. It helps you maintain and scale monorepos, both locally and on CI.
|
||||||
|
|
||||||
|
This package is a [Gradle plugin for Nx](https://nx.dev/gradle/overview).
|
||||||
|
|
||||||
|
{{content}}
|
||||||
1
packages/gradle/index.ts
Normal file
1
packages/gradle/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './plugin';
|
||||||
10
packages/gradle/jest.config.ts
Normal file
10
packages/gradle/jest.config.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
export default {
|
||||||
|
transform: {
|
||||||
|
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'],
|
||||||
|
globals: {},
|
||||||
|
displayName: 'gradle',
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
};
|
||||||
4
packages/gradle/migrations.json
Normal file
4
packages/gradle/migrations.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"generators": {},
|
||||||
|
"packageJsonUpdates": {}
|
||||||
|
}
|
||||||
34
packages/gradle/package.json
Normal file
34
packages/gradle/package.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "@nx/gradle",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"private": true,
|
||||||
|
"description": "The Nx Plugin for gradle",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/nrwl/nx.git",
|
||||||
|
"directory": "packages/gradle"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"Monorepo",
|
||||||
|
"Java",
|
||||||
|
"Gradle",
|
||||||
|
"CLI"
|
||||||
|
],
|
||||||
|
"main": "./index",
|
||||||
|
"typings": "./index.d.ts",
|
||||||
|
"author": "Victor Savkin",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/nrwl/nx/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://nx.dev",
|
||||||
|
"nx-migrate": {
|
||||||
|
"migrations": "./migrations.json"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nx/devkit": "file:../devkit"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
2
packages/gradle/plugin.ts
Normal file
2
packages/gradle/plugin.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { createDependencies } from './src/plugin/dependencies';
|
||||||
|
export { createNodes } from './src/plugin/nodes';
|
||||||
73
packages/gradle/project.json
Normal file
73
packages/gradle/project.json
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"name": "gradle",
|
||||||
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||||
|
"sourceRoot": "packages/gradle/src",
|
||||||
|
"projectType": "library",
|
||||||
|
"targets": {
|
||||||
|
"nx-release-publish": {
|
||||||
|
"dependsOn": ["^nx-release-publish"],
|
||||||
|
"executor": "@nx/js:release-publish",
|
||||||
|
"options": {
|
||||||
|
"packageRoot": "build/packages/gradle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"build-base": {
|
||||||
|
"executor": "@nx/js:tsc",
|
||||||
|
"options": {
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"input": "packages/gradle",
|
||||||
|
"glob": "**/@(files|files-angular)/**",
|
||||||
|
"output": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "packages/gradle",
|
||||||
|
"glob": "**/files/**/.gitkeep",
|
||||||
|
"output": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "packages/gradle",
|
||||||
|
"glob": "**/*.json",
|
||||||
|
"ignore": ["**/tsconfig*.json", "project.json", ".eslintrc.json"],
|
||||||
|
"output": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "packages/gradle",
|
||||||
|
"glob": "**/*.js",
|
||||||
|
"ignore": ["**/jest.config.js"],
|
||||||
|
"output": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "packages/gradle",
|
||||||
|
"glob": "**/*.d.ts",
|
||||||
|
"output": "/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"glob": "LICENSE",
|
||||||
|
"output": "/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"executor": "nx:run-commands",
|
||||||
|
"outputs": ["{workspaceRoot}/build/packages/gradle"],
|
||||||
|
"options": {
|
||||||
|
"command": "node ./scripts/copy-readme.js gradle"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nx/eslint:lint",
|
||||||
|
"outputs": ["{options.outputFile}"]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"executor": "@nx/jest:jest",
|
||||||
|
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "packages/gradle/jest.config.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
124
packages/gradle/src/plugin/dependencies.ts
Normal file
124
packages/gradle/src/plugin/dependencies.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import {
|
||||||
|
CreateDependencies,
|
||||||
|
CreateDependenciesContext,
|
||||||
|
DependencyType,
|
||||||
|
FileMap,
|
||||||
|
RawProjectGraphDependency,
|
||||||
|
validateDependency,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import { basename } from 'node:path';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getGradleReport,
|
||||||
|
invalidateGradleReportCache,
|
||||||
|
} from '../utils/get-gradle-report';
|
||||||
|
import { calculatedTargets, writeTargetsToCache } from './nodes';
|
||||||
|
|
||||||
|
export const createDependencies: CreateDependencies = async (
|
||||||
|
_,
|
||||||
|
context: CreateDependenciesContext
|
||||||
|
) => {
|
||||||
|
const gradleFiles: string[] = findGradleFiles(context.filesToProcess);
|
||||||
|
if (gradleFiles.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let dependencies: RawProjectGraphDependency[] = [];
|
||||||
|
const gradleDependenciesStart = performance.mark('gradleDependencies:start');
|
||||||
|
const {
|
||||||
|
gradleFileToGradleProjectMap,
|
||||||
|
gradleProjectToProjectName,
|
||||||
|
buildFileToDepsMap,
|
||||||
|
} = getGradleReport();
|
||||||
|
|
||||||
|
for (const gradleFile of gradleFiles) {
|
||||||
|
const gradleProject = gradleFileToGradleProjectMap.get(gradleFile);
|
||||||
|
const projectName = gradleProjectToProjectName.get(gradleProject);
|
||||||
|
const depsFile = buildFileToDepsMap.get(gradleFile);
|
||||||
|
|
||||||
|
if (projectName && depsFile) {
|
||||||
|
dependencies = dependencies.concat(
|
||||||
|
processGradleDependencies(
|
||||||
|
depsFile,
|
||||||
|
gradleProjectToProjectName,
|
||||||
|
projectName,
|
||||||
|
gradleFile,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const gradleDependenciesEnd = performance.mark('gradleDependencies:end');
|
||||||
|
performance.measure(
|
||||||
|
'gradleDependencies',
|
||||||
|
gradleDependenciesStart.name,
|
||||||
|
gradleDependenciesEnd.name
|
||||||
|
);
|
||||||
|
|
||||||
|
writeTargetsToCache(calculatedTargets);
|
||||||
|
if (dependencies.length) {
|
||||||
|
invalidateGradleReportCache();
|
||||||
|
}
|
||||||
|
return dependencies;
|
||||||
|
};
|
||||||
|
|
||||||
|
const gradleConfigFileNames = new Set(['build.gradle', 'build.gradle.kts']);
|
||||||
|
|
||||||
|
function findGradleFiles(fileMap: FileMap): string[] {
|
||||||
|
const gradleFiles: string[] = [];
|
||||||
|
|
||||||
|
for (const [_, files] of Object.entries(fileMap.projectFileMap)) {
|
||||||
|
for (const file of files) {
|
||||||
|
if (gradleConfigFileNames.has(basename(file.file))) {
|
||||||
|
gradleFiles.push(file.file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gradleFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
function processGradleDependencies(
|
||||||
|
depsFile: string,
|
||||||
|
gradleProjectToProjectName: Map<string, string>,
|
||||||
|
sourceProjectName: string,
|
||||||
|
gradleFile: string,
|
||||||
|
context: CreateDependenciesContext
|
||||||
|
) {
|
||||||
|
const dependencies: RawProjectGraphDependency[] = [];
|
||||||
|
const lines = readFileSync(depsFile).toString().split('\n');
|
||||||
|
let inDeps = false;
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith('implementationDependenciesMetadata')) {
|
||||||
|
inDeps = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inDeps) {
|
||||||
|
if (line === '') {
|
||||||
|
inDeps = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const [indents, dep] = line.split('--- ');
|
||||||
|
if ((indents === '\\' || indents === '+') && dep.startsWith('project ')) {
|
||||||
|
const gradleProjectName = dep
|
||||||
|
.substring('project '.length)
|
||||||
|
.replace(/ \(n\)$/, '')
|
||||||
|
.trim();
|
||||||
|
const target = gradleProjectToProjectName.get(
|
||||||
|
gradleProjectName
|
||||||
|
) as string;
|
||||||
|
const dependency: RawProjectGraphDependency = {
|
||||||
|
source: sourceProjectName,
|
||||||
|
target,
|
||||||
|
type: DependencyType.static,
|
||||||
|
sourceFile: gradleFile,
|
||||||
|
};
|
||||||
|
validateDependency(dependency, context);
|
||||||
|
dependencies.push(dependency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
182
packages/gradle/src/plugin/nodes.ts
Normal file
182
packages/gradle/src/plugin/nodes.ts
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
import {
|
||||||
|
CreateNodes,
|
||||||
|
CreateNodesContext,
|
||||||
|
TargetConfiguration,
|
||||||
|
readJsonFile,
|
||||||
|
writeJsonFile,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { calculateHashForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
|
||||||
|
import { existsSync } from 'node:fs';
|
||||||
|
import { dirname, join } from 'node:path';
|
||||||
|
import { projectGraphCacheDirectory } from 'nx/src/utils/cache-directory';
|
||||||
|
|
||||||
|
import { getGradleBinaryPath } from '../utils/exec-gradle';
|
||||||
|
import { getGradleReport } from '../utils/get-gradle-report';
|
||||||
|
|
||||||
|
const nonCacheableGradleTaskTypes = new Set(['Application']);
|
||||||
|
const dependsOnMap = {
|
||||||
|
build: ['^build', 'classes'],
|
||||||
|
test: ['classes'],
|
||||||
|
classes: ['^classes'],
|
||||||
|
};
|
||||||
|
|
||||||
|
interface GradleTask {
|
||||||
|
type: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GradlePluginOptions {
|
||||||
|
testTargetName?: string;
|
||||||
|
classesTargetName?: string;
|
||||||
|
buildTargetName?: string;
|
||||||
|
[taskTargetName: string]: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachePath = join(projectGraphCacheDirectory, 'gradle.hash');
|
||||||
|
const targetsCache = existsSync(cachePath) ? readTargetsCache() : {};
|
||||||
|
|
||||||
|
export const calculatedTargets: Record<
|
||||||
|
string,
|
||||||
|
{ name: string; targets: Record<string, TargetConfiguration> }
|
||||||
|
> = {};
|
||||||
|
|
||||||
|
function readTargetsCache(): Record<
|
||||||
|
string,
|
||||||
|
{ name: string; targets: Record<string, TargetConfiguration> }
|
||||||
|
> {
|
||||||
|
return readJsonFile(cachePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writeTargetsToCache(
|
||||||
|
targets: Record<
|
||||||
|
string,
|
||||||
|
{ name: string; targets: Record<string, TargetConfiguration> }
|
||||||
|
>
|
||||||
|
) {
|
||||||
|
writeJsonFile(cachePath, targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createNodes: CreateNodes<GradlePluginOptions> = [
|
||||||
|
'**/build.{gradle.kts,gradle}',
|
||||||
|
(
|
||||||
|
gradleFilePath,
|
||||||
|
options: GradlePluginOptions | undefined,
|
||||||
|
context: CreateNodesContext
|
||||||
|
) => {
|
||||||
|
const projectRoot = dirname(gradleFilePath);
|
||||||
|
|
||||||
|
const hash = calculateHashForCreateNodes(
|
||||||
|
projectRoot,
|
||||||
|
options ?? {},
|
||||||
|
context
|
||||||
|
);
|
||||||
|
if (targetsCache[hash]) {
|
||||||
|
calculatedTargets[hash] = targetsCache[hash];
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[projectRoot]: targetsCache[hash],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
tasksMap,
|
||||||
|
gradleProjectToTasksTypeMap,
|
||||||
|
gradleFileToOutputDirsMap,
|
||||||
|
gradleFileToGradleProjectMap,
|
||||||
|
gradleProjectToProjectName,
|
||||||
|
} = getGradleReport();
|
||||||
|
|
||||||
|
const gradleProject = gradleFileToGradleProjectMap.get(
|
||||||
|
gradleFilePath
|
||||||
|
) as string;
|
||||||
|
const projectName = gradleProjectToProjectName.get(gradleProject);
|
||||||
|
if (!projectName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const availableTaskNames = tasksMap.get(gradleFilePath) as string[];
|
||||||
|
const tasksTypeMap = gradleProjectToTasksTypeMap.get(
|
||||||
|
gradleProject
|
||||||
|
) as Map<string, string>;
|
||||||
|
const tasks: GradleTask[] = availableTaskNames.map((taskName) => {
|
||||||
|
return {
|
||||||
|
type: tasksTypeMap.get(taskName) ?? 'Unknown',
|
||||||
|
name: taskName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const outputDirs = gradleFileToOutputDirsMap.get(gradleFilePath) as Map<
|
||||||
|
string,
|
||||||
|
string
|
||||||
|
>;
|
||||||
|
|
||||||
|
const targets = createGradleTargets(
|
||||||
|
tasks,
|
||||||
|
projectRoot,
|
||||||
|
options,
|
||||||
|
context,
|
||||||
|
outputDirs
|
||||||
|
);
|
||||||
|
calculatedTargets[hash] = {
|
||||||
|
name: projectName,
|
||||||
|
targets,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects: {
|
||||||
|
[projectRoot]: {
|
||||||
|
root: projectRoot,
|
||||||
|
name: projectName,
|
||||||
|
targets,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createGradleTargets(
|
||||||
|
tasks: GradleTask[],
|
||||||
|
projectRoot: string,
|
||||||
|
options: GradlePluginOptions | undefined,
|
||||||
|
context: CreateNodesContext,
|
||||||
|
outputDirs: Map<string, string>
|
||||||
|
): Record<string, TargetConfiguration> {
|
||||||
|
const inputsMap = createInputsMap(context);
|
||||||
|
|
||||||
|
const targets: Record<string, TargetConfiguration> = {};
|
||||||
|
for (const task of tasks) {
|
||||||
|
const targetName = options?.[`${task.name}TargetName`] ?? task.name;
|
||||||
|
|
||||||
|
const outputs = outputDirs.get(task.name);
|
||||||
|
targets[targetName] = {
|
||||||
|
command: `${getGradleBinaryPath()} ${task.name}`,
|
||||||
|
options: {
|
||||||
|
cwd: projectRoot,
|
||||||
|
},
|
||||||
|
cache: !nonCacheableGradleTaskTypes.has(task.type),
|
||||||
|
inputs: inputsMap[task.name],
|
||||||
|
outputs: outputs ? [outputs] : undefined,
|
||||||
|
dependsOn: dependsOnMap[task.name],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createInputsMap(
|
||||||
|
context: CreateNodesContext
|
||||||
|
): Record<string, TargetConfiguration['inputs']> {
|
||||||
|
const namedInputs = context.nxJsonConfiguration.namedInputs;
|
||||||
|
return {
|
||||||
|
build: namedInputs?.production
|
||||||
|
? ['production', '^production']
|
||||||
|
: ['default', '^default'],
|
||||||
|
test: ['default', namedInputs?.production ? '^production' : '^default'],
|
||||||
|
classes: ['default', '^default'],
|
||||||
|
};
|
||||||
|
}
|
||||||
63
packages/gradle/src/utils/exec-gradle.ts
Normal file
63
packages/gradle/src/utils/exec-gradle.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { workspaceRoot } from '@nx/devkit';
|
||||||
|
import { ExecFileOptions } from 'child_process';
|
||||||
|
import {
|
||||||
|
ExecFileSyncOptionsWithBufferEncoding,
|
||||||
|
execFile,
|
||||||
|
execFileSync,
|
||||||
|
} from 'node:child_process';
|
||||||
|
import { existsSync } from 'node:fs';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
|
||||||
|
export function execGradle(
|
||||||
|
args: string[],
|
||||||
|
execOptions: ExecFileSyncOptionsWithBufferEncoding
|
||||||
|
) {
|
||||||
|
const gradleBinaryPath = getGradleBinaryPath();
|
||||||
|
|
||||||
|
return execFileSync(gradleBinaryPath, args, execOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGradleBinaryPath() {
|
||||||
|
const gradleFile = process.platform.startsWith('win')
|
||||||
|
? 'gradlew.bat'
|
||||||
|
: 'gradlew';
|
||||||
|
const gradleBinaryPath = join(workspaceRoot, gradleFile);
|
||||||
|
if (!existsSync(gradleBinaryPath)) {
|
||||||
|
throw new Error('Gradle is not setup. Run "gradle init"');
|
||||||
|
}
|
||||||
|
|
||||||
|
return gradleBinaryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function execGradleAsync(
|
||||||
|
args: ReadonlyArray<string>,
|
||||||
|
execOptions: ExecFileOptions
|
||||||
|
) {
|
||||||
|
const gradleBinaryPath = getGradleBinaryPath();
|
||||||
|
if (!existsSync(gradleBinaryPath)) {
|
||||||
|
throw new Error('Gradle is not setup. Run "gradle init"');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise<Buffer>((res, rej) => {
|
||||||
|
const cp = execFile(gradleBinaryPath, args, execOptions);
|
||||||
|
|
||||||
|
let stdout = Buffer.from('');
|
||||||
|
cp.stdout?.on('data', (data) => {
|
||||||
|
stdout += data;
|
||||||
|
});
|
||||||
|
|
||||||
|
cp.on('exit', (code) => {
|
||||||
|
if (code === 0) {
|
||||||
|
res(stdout);
|
||||||
|
} else {
|
||||||
|
rej(
|
||||||
|
new Error(
|
||||||
|
`Executing Gradle with ${args.join(
|
||||||
|
' '
|
||||||
|
)} failed with code: ${code}. \nLogs: ${stdout}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
185
packages/gradle/src/utils/get-gradle-report.ts
Normal file
185
packages/gradle/src/utils/get-gradle-report.ts
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import { dirname, join, relative } from 'node:path';
|
||||||
|
|
||||||
|
import { workspaceRoot } from '@nx/devkit';
|
||||||
|
import { hashWithWorkspaceContext } from 'nx/src/utils/workspace-context';
|
||||||
|
|
||||||
|
import { execGradle } from './exec-gradle';
|
||||||
|
|
||||||
|
interface GradleReport {
|
||||||
|
gradleFileToGradleProjectMap: Map<string, string>;
|
||||||
|
buildFileToDepsMap: Map<string, string>;
|
||||||
|
gradleFileToOutputDirsMap: Map<string, Map<string, string>>;
|
||||||
|
gradleProjectToTasksTypeMap: Map<string, Map<string, string>>;
|
||||||
|
tasksMap: Map<string, string[]>;
|
||||||
|
gradleProjectToProjectName: Map<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let gradleReportCache: GradleReport;
|
||||||
|
|
||||||
|
export function invalidateGradleReportCache() {
|
||||||
|
gradleReportCache = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGradleReport(): GradleReport {
|
||||||
|
if (gradleReportCache) {
|
||||||
|
return gradleReportCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gradleProjectReportStart = performance.mark(
|
||||||
|
'gradleProjectReport:start'
|
||||||
|
);
|
||||||
|
const projectReportLines = execGradle(['projectReport'], {
|
||||||
|
cwd: workspaceRoot,
|
||||||
|
})
|
||||||
|
.toString()
|
||||||
|
.split('\n');
|
||||||
|
const gradleProjectReportEnd = performance.mark('gradleProjectReport:end');
|
||||||
|
performance.measure(
|
||||||
|
'gradleProjectReport',
|
||||||
|
gradleProjectReportStart.name,
|
||||||
|
gradleProjectReportEnd.name
|
||||||
|
);
|
||||||
|
gradleReportCache = processProjectReports(projectReportLines);
|
||||||
|
return gradleReportCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
function processProjectReports(projectReportLines: string[]): GradleReport {
|
||||||
|
/**
|
||||||
|
* Map of Gradle File path to Gradle Project Name
|
||||||
|
*/
|
||||||
|
const gradleFileToGradleProjectMap = new Map<string, string>();
|
||||||
|
/**
|
||||||
|
* Map of Gradle Project Name to Gradle File
|
||||||
|
*/
|
||||||
|
const gradleProjectToGradleFileMap = new Map<string, string>();
|
||||||
|
const dependenciesMap = new Map<string, string>();
|
||||||
|
/**
|
||||||
|
* Map of Gradle Build File to available tasks
|
||||||
|
*/
|
||||||
|
const tasksMap = new Map<string, string[]>();
|
||||||
|
/**
|
||||||
|
* Map of Gradle Build File to tasks type map
|
||||||
|
*/
|
||||||
|
const gradleProjectToTasksTypeMap = new Map<string, Map<string, string>>();
|
||||||
|
const gradleProjectToProjectName = new Map<string, string>();
|
||||||
|
/**
|
||||||
|
* Map of buildFile to dependencies report path
|
||||||
|
*/
|
||||||
|
const buildFileToDepsMap = new Map<string, string>();
|
||||||
|
/**
|
||||||
|
* Map fo possible output files of each gradle file
|
||||||
|
* e.g. {build.gradle.kts: { projectReportDir: '' testReportDir: '' }}
|
||||||
|
*/
|
||||||
|
const gradleFileToOutputDirsMap = new Map<string, Map<string, string>>();
|
||||||
|
|
||||||
|
projectReportLines.forEach((line, index) => {
|
||||||
|
if (line.startsWith('> Task ')) {
|
||||||
|
const nextLine = projectReportLines[index + 1];
|
||||||
|
if (line.endsWith(':dependencyReport')) {
|
||||||
|
const gradleProject = line.substring(
|
||||||
|
'> Task '.length,
|
||||||
|
line.length - ':dependencyReport'.length
|
||||||
|
);
|
||||||
|
const [_, file] = nextLine.split('file://');
|
||||||
|
dependenciesMap.set(gradleProject, file);
|
||||||
|
}
|
||||||
|
if (line.endsWith('propertyReport')) {
|
||||||
|
const gradleProject = line.substring(
|
||||||
|
'> Task '.length,
|
||||||
|
line.length - ':propertyReport'.length
|
||||||
|
);
|
||||||
|
const [_, file] = nextLine.split('file://');
|
||||||
|
const propertyReportLines = readFileSync(file).toString().split('\n');
|
||||||
|
|
||||||
|
let projectName: string,
|
||||||
|
absBuildFilePath: string,
|
||||||
|
absBuildDirPath: string;
|
||||||
|
const tasks: string[] = [];
|
||||||
|
const outputDirMap = new Map<string, string>();
|
||||||
|
for (const line of propertyReportLines) {
|
||||||
|
if (line.startsWith('name: ')) {
|
||||||
|
projectName = line.substring('name: '.length);
|
||||||
|
}
|
||||||
|
if (line.startsWith('buildFile: ')) {
|
||||||
|
absBuildFilePath = line.substring('buildFile: '.length);
|
||||||
|
}
|
||||||
|
if (line.startsWith('buildDir: ')) {
|
||||||
|
absBuildDirPath = line.substring('buildDir: '.length);
|
||||||
|
}
|
||||||
|
if (line.includes(': task ')) {
|
||||||
|
const taskSegments = line.split(': task ');
|
||||||
|
tasks.push(taskSegments[0]);
|
||||||
|
}
|
||||||
|
if (line.includes('Dir: ')) {
|
||||||
|
const [dirName, dirPath] = line.split(': ');
|
||||||
|
const taskName = dirName.replace('Dir', '');
|
||||||
|
outputDirMap.set(
|
||||||
|
taskName,
|
||||||
|
`{workspaceRoot}/${relative(workspaceRoot, dirPath)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!projectName || !absBuildFilePath || !absBuildDirPath) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const buildFile = relative(workspaceRoot, absBuildFilePath);
|
||||||
|
const buildDir = relative(workspaceRoot, absBuildDirPath);
|
||||||
|
buildFileToDepsMap.set(
|
||||||
|
buildFile,
|
||||||
|
dependenciesMap.get(gradleProject) as string
|
||||||
|
);
|
||||||
|
|
||||||
|
outputDirMap.set('build', `{workspaceRoot}/${buildDir}`);
|
||||||
|
outputDirMap.set(
|
||||||
|
'classes',
|
||||||
|
`{workspaceRoot}/${join(buildDir, 'classes')}`
|
||||||
|
);
|
||||||
|
|
||||||
|
gradleFileToOutputDirsMap.set(buildFile, outputDirMap);
|
||||||
|
gradleFileToGradleProjectMap.set(buildFile, gradleProject);
|
||||||
|
gradleProjectToGradleFileMap.set(gradleProject, buildFile);
|
||||||
|
gradleProjectToProjectName.set(gradleProject, projectName);
|
||||||
|
tasksMap.set(buildFile, tasks);
|
||||||
|
}
|
||||||
|
if (line.endsWith('taskReport')) {
|
||||||
|
const gradleProject = line.substring(
|
||||||
|
'> Task '.length,
|
||||||
|
line.length - ':taskReport'.length
|
||||||
|
);
|
||||||
|
const [_, file] = nextLine.split('file://');
|
||||||
|
const taskTypeMap = new Map<string, string>();
|
||||||
|
const tasksFileLines = readFileSync(file).toString().split('\n');
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
while (i < tasksFileLines.length) {
|
||||||
|
const line = tasksFileLines[i];
|
||||||
|
|
||||||
|
if (line.endsWith('tasks')) {
|
||||||
|
const dashes = new Array(line.length + 1).join('-');
|
||||||
|
if (tasksFileLines[i + 1] === dashes) {
|
||||||
|
const type = line.substring(0, line.length - ' tasks'.length);
|
||||||
|
i++;
|
||||||
|
while (tasksFileLines[++i] !== '') {
|
||||||
|
const [taskName] = tasksFileLines[i].split(' - ');
|
||||||
|
taskTypeMap.set(taskName, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
gradleProjectToTasksTypeMap.set(gradleProject, taskTypeMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
gradleFileToGradleProjectMap,
|
||||||
|
buildFileToDepsMap,
|
||||||
|
gradleFileToOutputDirsMap,
|
||||||
|
gradleProjectToTasksTypeMap,
|
||||||
|
tasksMap,
|
||||||
|
gradleProjectToProjectName,
|
||||||
|
};
|
||||||
|
}
|
||||||
14
packages/gradle/tsconfig.json
Normal file
14
packages/gradle/tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {},
|
||||||
|
"files": [],
|
||||||
|
"include": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.lib.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
10
packages/gradle/tsconfig.lib.json
Normal file
10
packages/gradle/tsconfig.lib.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"declaration": true,
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"include": ["**/*.ts"],
|
||||||
|
"exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
|
||||||
|
}
|
||||||
9
packages/gradle/tsconfig.spec.json
Normal file
9
packages/gradle/tsconfig.spec.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
|
||||||
|
}
|
||||||
@ -35,6 +35,8 @@
|
|||||||
"@nx/expo": ["packages/expo"],
|
"@nx/expo": ["packages/expo"],
|
||||||
"@nx/expo/*": ["packages/expo/*"],
|
"@nx/expo/*": ["packages/expo/*"],
|
||||||
"@nx/express": ["packages/express"],
|
"@nx/express": ["packages/express"],
|
||||||
|
"@nx/gradle": ["packages/gradle/src/index.ts"],
|
||||||
|
"@nx/gradle/*": ["packages/gradle/*"],
|
||||||
"@nx/graph/project-details": ["graph/project-details/src/index.ts"],
|
"@nx/graph/project-details": ["graph/project-details/src/index.ts"],
|
||||||
"@nx/graph/shared": ["graph/shared/src/index.ts"],
|
"@nx/graph/shared": ["graph/shared/src/index.ts"],
|
||||||
"@nx/graph/ui-code-block": ["graph/ui-code-block/src/index.ts"],
|
"@nx/graph/ui-code-block": ["graph/ui-code-block/src/index.ts"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user