Skip to content

Commit caa5db9

Browse files
authored
feat: add gradle and npm workspaces examples (#92)
1 parent e149bbf commit caa5db9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+11147
-0
lines changed

gradle/.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Ignore Gradle project-specific cache directory
2+
.gradle
3+
4+
# Ignore Gradle build output directory
5+
build
6+
7+
.nx/installation
8+
.nx/cache
9+
.nx/workspace-data

gradle/.nx/nxw.js

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"use strict";
2+
// This file should be committed to your repository! It wraps Nx and ensures
3+
// that your local installation matches nx.json.
4+
// See: https://nx.dev/recipes/installation/install-non-javascript for more info.
5+
6+
7+
8+
9+
Object.defineProperty(exports, "__esModule", { value: true });
10+
const fs = require('fs');
11+
const path = require('path');
12+
const cp = require('child_process');
13+
const installationPath = path.join(__dirname, 'installation', 'package.json');
14+
function matchesCurrentNxInstall(currentInstallation, nxJsonInstallation) {
15+
if (!currentInstallation.devDependencies ||
16+
!Object.keys(currentInstallation.devDependencies).length) {
17+
return false;
18+
}
19+
try {
20+
if (currentInstallation.devDependencies['nx'] !==
21+
nxJsonInstallation.version ||
22+
require(path.join(path.dirname(installationPath), 'node_modules', 'nx', 'package.json')).version !== nxJsonInstallation.version) {
23+
return false;
24+
}
25+
for (const [plugin, desiredVersion] of Object.entries(nxJsonInstallation.plugins || {})) {
26+
if (currentInstallation.devDependencies[plugin] !== desiredVersion) {
27+
return false;
28+
}
29+
}
30+
return true;
31+
}
32+
catch {
33+
return false;
34+
}
35+
}
36+
function ensureDir(p) {
37+
if (!fs.existsSync(p)) {
38+
fs.mkdirSync(p, { recursive: true });
39+
}
40+
}
41+
function getCurrentInstallation() {
42+
try {
43+
return require(installationPath);
44+
}
45+
catch {
46+
return {
47+
name: 'nx-installation',
48+
version: '0.0.0',
49+
devDependencies: {},
50+
};
51+
}
52+
}
53+
function performInstallation(currentInstallation, nxJson) {
54+
fs.writeFileSync(installationPath, JSON.stringify({
55+
name: 'nx-installation',
56+
devDependencies: {
57+
nx: nxJson.installation.version,
58+
...nxJson.installation.plugins,
59+
},
60+
}));
61+
try {
62+
cp.execSync('npm i', {
63+
cwd: path.dirname(installationPath),
64+
stdio: 'inherit',
65+
});
66+
}
67+
catch (e) {
68+
// revert possible changes to the current installation
69+
fs.writeFileSync(installationPath, JSON.stringify(currentInstallation));
70+
// rethrow
71+
throw e;
72+
}
73+
}
74+
function ensureUpToDateInstallation() {
75+
const nxJsonPath = path.join(__dirname, '..', 'nx.json');
76+
let nxJson;
77+
try {
78+
nxJson = require(nxJsonPath);
79+
if (!nxJson.installation) {
80+
console.error('[NX]: The "installation" entry in the "nx.json" file is required when running the nx wrapper. See https://nx.dev/recipes/installation/install-non-javascript');
81+
process.exit(1);
82+
}
83+
}
84+
catch {
85+
console.error('[NX]: The "nx.json" file is required when running the nx wrapper. See https://nx.dev/recipes/installation/install-non-javascript');
86+
process.exit(1);
87+
}
88+
try {
89+
ensureDir(path.join(__dirname, 'installation'));
90+
const currentInstallation = getCurrentInstallation();
91+
if (!matchesCurrentNxInstall(currentInstallation, nxJson.installation)) {
92+
performInstallation(currentInstallation, nxJson);
93+
}
94+
}
95+
catch (e) {
96+
const messageLines = [
97+
'[NX]: Nx wrapper failed to synchronize installation.',
98+
];
99+
if (e instanceof Error) {
100+
messageLines.push('');
101+
messageLines.push(e.message);
102+
messageLines.push(e.stack);
103+
}
104+
else {
105+
messageLines.push(e.toString());
106+
}
107+
console.error(messageLines.join('\n'));
108+
process.exit(1);
109+
}
110+
}
111+
if (!process.env.NX_WRAPPER_SKIP_INSTALL) {
112+
ensureUpToDateInstallation();
113+
}
114+
115+
require('./installation/node_modules/nx/bin/nx');

gradle/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Gradle Multi Module Example Repo
2+
3+
This repository is a completed version of the [Spring framework](https://spring.io/)'s guide for [Multi-Module Projects](https://spring.io/guides/gs/multi-module). It is intended for use as a starting point to show how to [add Nx to a Gradle repository](https://nx.dev/getting-started/tutorials/gradle-tutorial).
4+
5+
The repository contains 2 projects:
6+
7+
- The main `application` project which contains the Spring `DemoApplication`
8+
- A `library` project which contains a Service used in the `DemoApplication`
9+
10+
You can see the above 2 projects by running `./gradlew projects`
11+
12+
```text {% command="./gradlew projects" %}
13+
> Task :projects
14+
15+
------------------------------------------------------------
16+
Root project 'gradle-tutorial'
17+
------------------------------------------------------------
18+
19+
Root project 'gradle-tutorial'
20+
+--- Project ':application'
21+
\--- Project ':library'
22+
23+
```
24+
25+
## Add Nx
26+
27+
To see how Nx can improve the developer experience in a Gradle repository, follow the [Gradle tutorial](https://nx.dev/getting-started/tutorials/gradle-tutorial) on nx.dev.

gradle/application/build.gradle

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
plugins {
2+
id 'org.springframework.boot' version '3.2.2'
3+
id 'io.spring.dependency-management' version '1.1.4'
4+
id 'java'
5+
}
6+
7+
group = 'com.example'
8+
version = '0.0.1-SNAPSHOT'
9+
10+
java {
11+
sourceCompatibility = '17'
12+
}
13+
14+
repositories {
15+
mavenCentral()
16+
}
17+
18+
dependencies {
19+
implementation 'org.springframework.boot:spring-boot-starter-actuator'
20+
implementation 'org.springframework.boot:spring-boot-starter-web'
21+
implementation project(':library')
22+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
23+
}
24+
25+
allprojects {
26+
apply {
27+
plugin("project-report")
28+
}
29+
}
30+
tasks.register("projectReportAll") {
31+
// All project reports of subprojects
32+
allprojects.forEach {
33+
dependsOn(it.tasks.getAt("projectReport"))
34+
}
35+
36+
// All projectReportAll of included builds
37+
gradle.includedBuilds.forEach {
38+
dependsOn(it.task(":projectReportAll"))
39+
}
40+
}

gradle/application/settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rootProject.name = 'application'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.example.multimodule.application;
2+
3+
import com.example.multimodule.service.MyService;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.web.bind.annotation.GetMapping;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
@SpringBootApplication(scanBasePackages = "com.example.multimodule")
10+
@RestController
11+
public class DemoApplication {
12+
13+
private final MyService myService;
14+
15+
public DemoApplication(MyService myService) {
16+
this.myService = myService;
17+
}
18+
19+
@GetMapping("/")
20+
public String home() {
21+
return myService.message();
22+
}
23+
24+
public static void main(String[] args) {
25+
SpringApplication.run(DemoApplication.class, args);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
service.message=Hello, World
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.example.multimodule.application;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
10+
import com.example.multimodule.service.MyService;
11+
12+
@SpringBootTest
13+
public class DemoApplicationTest {
14+
15+
@Autowired
16+
private MyService myService;
17+
18+
@Test
19+
public void contextLoads() {
20+
assertThat(myService.message()).isNotNull();
21+
}
22+
23+
}

gradle/build.gradle

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
allprojects {
3+
apply {
4+
plugin("project-report")
5+
}
6+
}
7+
tasks.register("projectReportAll") {
8+
// All project reports of subprojects
9+
allprojects.forEach {
10+
dependsOn(it.tasks.getAt("projectReport"))
11+
}
12+
13+
// All projectReportAll of included builds
14+
gradle.includedBuilds.forEach {
15+
dependsOn(it.task(":projectReportAll"))
16+
}
17+
}
42.4 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)