Skip to content

Commit 472825c

Browse files
vaadin-botcaalador
andauthored
fix: when using pnpm write overrides under pnpm (#21760) (#21815)
* fix: when using pnpm write overrides under pnpm For pnpm usage write the overrides section under the pnpm object instead of the root of the package.json Fixes #21724 Fixes #21682 * add all component versions to overrides. Will use $NAME for existing dependencies and devDpendencies. For other components in vaadin-versions and vaadin-core-versions version value will be added to overrides. * Keep existing overrides content from othe system if any Keep the existing overrides when moving from npm to pnpm and vice versa Refactor test to use Jackson Co-authored-by: caalador <mikael.grankvist@vaadin.com>
1 parent 1858ba8 commit 472825c

File tree

5 files changed

+410
-177
lines changed

5 files changed

+410
-177
lines changed

flow-plugins/flow-plugin-base/src/main/java/com/vaadin/flow/plugin/base/CleanFrontendUtil.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class CleanFrontendUtil {
3838
public static final String DEPENDENCIES = "dependencies";
3939
public static final String DEV_DEPENDENCIES = "devDependencies";
4040
public static final String OVERRIDES = "overrides";
41+
public static final String PNPM = "pnpm";
4142

4243
/**
4344
* Exception thrown when cleaning the frontend fails.
@@ -207,6 +208,9 @@ private static void cleanupPackage(PluginAdapterBase adapter,
207208
ObjectNode devDependencies = (ObjectNode) packageJson
208209
.get(DEV_DEPENDENCIES);
209210
ObjectNode overridesSection = (ObjectNode) packageJson.get(OVERRIDES);
211+
ObjectNode pnpmOverridesSection = packageJson.has(PNPM)
212+
? (ObjectNode) packageJson.get(PNPM).get(OVERRIDES)
213+
: null;
210214

211215
if (packageJson.has(VAADIN)) {
212216
ObjectNode vaadin = (ObjectNode) packageJson.get(VAADIN);
@@ -219,6 +223,7 @@ private static void cleanupPackage(PluginAdapterBase adapter,
219223
cleanObject(dependencies, vaadinDependencies);
220224
cleanObject(devDependencies, vaadinDevDependencies);
221225
cleanObject(overridesSection, vaadinDependencies, false);
226+
cleanObject(pnpmOverridesSection, vaadinDependencies, false);
222227

223228
packageJson.remove(VAADIN);
224229
}

flow-server/src/main/java/com/vaadin/flow/server/frontend/NodeUpdater.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public abstract class NodeUpdater implements FallibleCommand {
7777
static final String HASH_KEY = "hash";
7878
static final String DEV_DEPENDENCIES = "devDependencies";
7979
static final String OVERRIDES = "overrides";
80+
static final String PNPM = "pnpm";
8081

8182
private static final String DEP_LICENSE_KEY = "license";
8283
private static final String DEP_LICENSE_DEFAULT = "UNLICENSED";

flow-server/src/main/java/com/vaadin/flow/server/frontend/TaskUpdatePackages.java

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
import com.vaadin.flow.server.frontend.scanner.ClassFinder;
4646
import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner;
4747

48+
import static com.vaadin.flow.server.frontend.VersionsJsonConverter.JS_VERSION;
49+
import static com.vaadin.flow.server.frontend.VersionsJsonConverter.NPM_NAME;
50+
import static com.vaadin.flow.server.frontend.VersionsJsonConverter.NPM_VERSION;
51+
import static com.vaadin.flow.server.frontend.VersionsJsonConverter.VAADIN_CORE_NPM_PACKAGE;
52+
4853
/**
4954
* Updates <code>package.json</code> by visiting {@link NpmPackage} annotations
5055
* found in the classpath. It also visits classes annotated with
@@ -114,6 +119,7 @@ boolean lockVersionForNpm(ObjectNode packageJson) throws IOException {
114119

115120
ObjectNode overridesSection = getOverridesSection(packageJson);
116121
final JsonNode dependencies = packageJson.get(DEPENDENCIES);
122+
ObjectNode fullPlatformDependencies = getFullPlatformDependencies();
117123
for (String dependency : JacksonUtils.getKeys(versionsJson)) {
118124
if (!overridesSection.has(dependency)
119125
&& shouldLockDependencyVersion(dependency, dependencies,
@@ -133,9 +139,108 @@ && shouldLockDependencyVersion(dependency, dependencies,
133139
}
134140
}
135141

142+
/*
143+
* Remove platform dependencies for all existing dependencies and
144+
* devDependencies
145+
*/
146+
for (String dependency : JacksonUtils.getKeys(dependencies)) {
147+
fullPlatformDependencies.remove(dependency);
148+
}
149+
for (String dependency : JacksonUtils.getKeys(devDependencies)) {
150+
fullPlatformDependencies.remove(dependency);
151+
}
152+
153+
// After removing any existing dependencies and devDependencies add all
154+
// platform versions to overrides block
155+
for (String dependency : JacksonUtils
156+
.getKeys(fullPlatformDependencies)) {
157+
try {
158+
FrontendVersion frontendVersion = new FrontendVersion(
159+
fullPlatformDependencies.get(dependency).textValue());
160+
if ("SNAPSHOT".equals(frontendVersion.getBuildIdentifier())) {
161+
continue;
162+
}
163+
overridesSection.set(dependency, JacksonUtils
164+
.createNode(frontendVersion.getFullVersion()));
165+
versionLockingUpdated = true;
166+
} catch (NumberFormatException nfe) {
167+
continue;
168+
}
169+
}
170+
136171
return versionLockingUpdated;
137172
}
138173

174+
/**
175+
* Collect all platform npm dependencies from vaadin-core-versions.json and
176+
* vaadin-versions.json to use in overrides so that any component versions
177+
* get locked even when they are transitive.
178+
*
179+
* @return json containing all npm keys and versions
180+
* @throws IOException
181+
* thrown for exception reading stream
182+
*/
183+
private ObjectNode getFullPlatformDependencies() throws IOException {
184+
ObjectNode platformDependencies = JacksonUtils.createObjectNode();
185+
URL coreVersionsResource = finder
186+
.getResource(Constants.VAADIN_CORE_VERSIONS_JSON);
187+
if (coreVersionsResource == null) {
188+
return platformDependencies;
189+
}
190+
191+
try (InputStream content = coreVersionsResource.openStream()) {
192+
collectDependencies(
193+
JacksonUtils.readTree(
194+
IOUtils.toString(content, StandardCharsets.UTF_8)),
195+
platformDependencies);
196+
}
197+
198+
URL vaadinVersionsResource = finder
199+
.getResource(Constants.VAADIN_VERSIONS_JSON);
200+
if (vaadinVersionsResource == null) {
201+
// vaadin is not on the classpath, only vaadin-core is present.
202+
return platformDependencies;
203+
}
204+
205+
try (InputStream content = vaadinVersionsResource.openStream()) {
206+
collectDependencies(
207+
JacksonUtils.readTree(
208+
IOUtils.toString(content, StandardCharsets.UTF_8)),
209+
platformDependencies);
210+
}
211+
212+
return platformDependencies;
213+
}
214+
215+
private void collectDependencies(JsonNode obj, ObjectNode collection) {
216+
for (String key : JacksonUtils.getKeys(obj)) {
217+
JsonNode value = obj.get(key);
218+
if (!(value instanceof ObjectNode)) {
219+
continue;
220+
}
221+
if (value.has(NPM_NAME)) {
222+
String npmName = value.get(NPM_NAME).textValue();
223+
if (Objects.equals(npmName, VAADIN_CORE_NPM_PACKAGE)) {
224+
return;
225+
}
226+
String version;
227+
if (value.has(NPM_VERSION)) {
228+
version = value.get(NPM_VERSION).textValue();
229+
} else if (value.has(JS_VERSION)) {
230+
version = value.get(JS_VERSION).textValue();
231+
} else {
232+
log().debug(
233+
"dependency '{}' has no 'npmVersion'/'jsVersion'.",
234+
npmName);
235+
continue;
236+
}
237+
collection.put(npmName, version);
238+
} else {
239+
collectDependencies(value, collection);
240+
}
241+
}
242+
}
243+
139244
private boolean shouldLockDependencyVersion(String dependency,
140245
JsonNode projectDependencies, JsonNode versionsJson) {
141246
String platformDefinedVersion = versionsJson.get(dependency)
@@ -166,9 +271,37 @@ private boolean isInternalPseudoDependency(String dependencyVersion) {
166271

167272
private ObjectNode getOverridesSection(ObjectNode packageJson) {
168273
ObjectNode overridesSection = (ObjectNode) packageJson.get(OVERRIDES);
274+
ObjectNode oldOverrides = null;
275+
if (options.isEnablePnpm()) {
276+
if (overridesSection != null) {
277+
oldOverrides = overridesSection;
278+
// remove npm overrides when moving to pnpm
279+
packageJson.remove(OVERRIDES);
280+
}
281+
JsonNode pnpm = packageJson.get(PNPM);
282+
if (pnpm == null) {
283+
overridesSection = null;
284+
} else {
285+
overridesSection = (ObjectNode) pnpm.get(OVERRIDES);
286+
}
287+
} else if (packageJson.has(PNPM)) {
288+
oldOverrides = overridesSection;
289+
// remove pnpm overrides for npm
290+
((ObjectNode) packageJson.get(PNPM)).remove(OVERRIDES);
291+
}
169292
if (overridesSection == null) {
170-
overridesSection = JacksonUtils.createObjectNode();
171-
packageJson.set(OVERRIDES, overridesSection);
293+
overridesSection = oldOverrides == null
294+
? JacksonUtils.createObjectNode()
295+
: oldOverrides;
296+
if (options.isEnablePnpm()) {
297+
ObjectNode pnpmNode = packageJson.has(PNPM)
298+
? (ObjectNode) packageJson.get(PNPM)
299+
: JacksonUtils.createObjectNode();
300+
packageJson.set(PNPM, pnpmNode);
301+
pnpmNode.set(OVERRIDES, overridesSection);
302+
} else {
303+
packageJson.set(OVERRIDES, overridesSection);
304+
}
172305
}
173306
return overridesSection;
174307
}

flow-server/src/main/java/com/vaadin/flow/server/frontend/VersionsJsonConverter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class VersionsJsonConverter {
4343

4444
static final String VAADIN_CORE_NPM_PACKAGE = "@vaadin/vaadin-core";
4545
static final String VAADIN_BUNDLES = "@vaadin/bundles";
46-
private static final String JS_VERSION = "jsVersion";
47-
private static final String NPM_NAME = "npmName";
48-
private static final String NPM_VERSION = "npmVersion";
46+
static final String JS_VERSION = "jsVersion";
47+
static final String NPM_NAME = "npmName";
48+
static final String NPM_VERSION = "npmVersion";
4949

5050
/**
5151
* Key for exclusions array.

0 commit comments

Comments
 (0)