yarnpkg / berry

📦🐈 Active development trunk for Yarn ⚒
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.47k stars 1.12k forks source link

[Bug?]: Problem with applying patch if there is "No newline at end of file" #6612

Open adam-sajko opened 6 days ago

adam-sajko commented 6 days ago

Self-service

Describe the bug

Here is the strange situation I had. I created and applied the patch, but it looks like if my changes are at the end of the file and there is \ No newline at end of file fragment in the patch (which is generated by the patch) then the patch doesn't apply the last line.

Context

I made a patch for @tamagui/web for v0.117.0:

The issue was because there was no "}" and the end of node_modules/@tamagui/web/dist/cjs/helpers/getSplitStyles.cjs. This file btw. was generated by the tamagui build process when I was preparing the files for the patch, so I didn't make any manual changes in this file, and the patch, so we can exclude any human mistake.

To reproduce

diff --git a/dist/cjs/helpers/getSplitStyles.cjs b/dist/cjs/helpers/getSplitStyles.cjs
index 3d1d071174774fa0240839b51ab2b4abfcb70752..5665b22cb954456651974df1e604be83bf6bd842 100644
--- a/dist/cjs/helpers/getSplitStyles.cjs
+++ b/dist/cjs/helpers/getSplitStyles.cjs
@@ -104,6 +104,7 @@ const getSplitStyles = (props, staticConfig, theme, themeName, componentState, s
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -554,7 +555,11 @@ current`, {
       style && (style.$$css ? Object.assign(styleState.classNames, style) : (styleState.style ||= {}, Object.assign(styleState.style, normalizeStyle(style))));
     }
   }
-  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`;
+  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`, process.env.NODE_ENV === "development" && (styleState.style = {
+    ...filterTokens(props),
+    ...filterTokens(styleState.originalVariantStyles),
+    ...styleState.style
+  });
   const result = {
     space,
     hasMedia,
@@ -723,3 +728,6 @@ function applyDefaultStyle(pkey, styleState) {
   const defaultValues = animatableDefaults[pkey];
   defaultValues != null && !(pkey in styleState.usedKeys) && (!styleState.style || !(pkey in styleState.style)) && mergeStyle(styleState, pkey, defaultValues);
 }
+function filterTokens(tokens) {
+  return Object.entries(tokens).reduce((acc, [key, value]) => (typeof value == "string" && value.startsWith("$") && (acc[`${key}Token`] = value), acc), {});
+}
\ No newline at end of file
diff --git a/dist/cjs/helpers/getSplitStyles.js b/dist/cjs/helpers/getSplitStyles.js
index e6d26c2ccae44ee63fb2a64adb0707154b8c6f01..81a53c0b98fd97bd4429a77c006a3af567c5dbd1 100644
--- a/dist/cjs/helpers/getSplitStyles.js
+++ b/dist/cjs/helpers/getSplitStyles.js
@@ -57,6 +57,7 @@ const getSplitStyles = (props, staticConfig, theme, themeName, componentState, s
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -508,7 +509,11 @@ current`, {
         style && (style.$$css ? Object.assign(styleState.classNames, style) : (styleState.style ||= {}, Object.assign(styleState.style, normalizeStyle(style))));
       }
     }
-  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`;
+  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`, process.env.NODE_ENV === "development" && (styleState.style = {
+    ...filterTokens(props),
+    ...filterTokens(styleState.originalVariantStyles),
+    ...styleState.style
+  });
   const result = {
     space,
     hasMedia,
@@ -683,4 +688,7 @@ function applyDefaultStyle(pkey, styleState) {
   const defaultValues = animatableDefaults[pkey];
   defaultValues != null && !(pkey in styleState.usedKeys) && (!styleState.style || !(pkey in styleState.style)) && mergeStyle(styleState, pkey, defaultValues);
 }
+function filterTokens(tokens) {
+  return Object.entries(tokens).reduce((acc, [key, value]) => (typeof value == "string" && value.startsWith("$") && (acc[`${key}Token`] = value), acc), {});
+}
 //# sourceMappingURL=getSplitStyles.js.map
diff --git a/dist/cjs/helpers/getSplitStyles.native.js b/dist/cjs/helpers/getSplitStyles.native.js
index 5d2cfefdb88d42c8805325059e963cfa8f240a0d..2e580c90f8416e69c18d1d3ca3e46accaf0b9f8e 100644
--- a/dist/cjs/helpers/getSplitStyles.native.js
+++ b/dist/cjs/helpers/getSplitStyles.native.js
@@ -44,6 +44,7 @@ var getSplitStyles = function(props, staticConfig, theme, themeName, componentSt
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -460,7 +461,11 @@ current`, {
     }
     process.env.NODE_ENV === "development" && debug && debug !== "profile" && (0, import_log.log)(`Found fontFamily native: ${style1.fontFamily}`, faceInfo);
   }
-  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`;
+  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`, process.env.NODE_ENV === "development" && (styleState.style = {
+    ...filterTokens(props),
+    ...filterTokens(styleState.originalVariantStyles),
+    ...styleState.style
+  });
   var result = {
     space,
     hasMedia,
@@ -645,6 +650,12 @@ function applyDefaultStyle(pkey, styleState) {
   var defaultValues = animatableDefaults[pkey];
   defaultValues != null && !(pkey in styleState.usedKeys) && (!styleState.style || !(pkey in styleState.style)) && mergeStyle(styleState, pkey, defaultValues);
 }
+function filterTokens(tokens) {
+  return Object.entries(tokens).reduce(function(acc, param) {
+    var [key, value] = param;
+    return typeof value == "string" && value.startsWith("$") && (acc[`${key}Token`] = value), acc;
+  }, {});
+}
 // Annotate the CommonJS export names for ESM import in node:
 0 && (module.exports = {
   PROP_SPLIT,
diff --git a/dist/cjs/helpers/propMapper.cjs b/dist/cjs/helpers/propMapper.cjs
index 2086b0c81ac2a53834f30c46510240d83ea4be0a..a70ebf4a345f456e4b800aee60dfabee546732e8 100644
--- a/dist/cjs/helpers/propMapper.cjs
+++ b/dist/cjs/helpers/propMapper.cjs
@@ -93,6 +93,10 @@ const propMapper = (key, value, styleState) => {
         extras
       }), console.groupEnd());
     }
+    process.env.NODE_ENV === "development" && (0, import_isObj.isObj)(variantValue) && (styleState.originalVariantStyles = {
+      ...styleState.originalVariantStyles,
+      ...variantValue
+    });
     let fontFamilyResult;
     if ((0, import_isObj.isObj)(variantValue)) {
       const fontFamilyUpdate = variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily];
diff --git a/dist/cjs/helpers/propMapper.js b/dist/cjs/helpers/propMapper.js
index e4fdf3a7551914184198a5a6d6cb2dfc029ebaf6..f3061d2298ce234344b78ab8ea3223f56242bbda 100644
--- a/dist/cjs/helpers/propMapper.js
+++ b/dist/cjs/helpers/propMapper.js
@@ -70,6 +70,10 @@ const propMapper = (key, value, styleState) => {
     const fn = variantValue, extras = (0, import_getVariantExtras.getVariantExtras)(styleState);
     variantValue = fn(value, extras), process.env.NODE_ENV === "development" && debug === "verbose" && (console.groupCollapsed("   expanded functional variant", key), console.info({ fn, variantValue, extras }), console.groupEnd());
   }
+  process.env.NODE_ENV === "development" && (0, import_isObj.isObj)(variantValue) && (styleState.originalVariantStyles = {
+    ...styleState.originalVariantStyles,
+    ...variantValue
+  });
   let fontFamilyResult;
   if ((0, import_isObj.isObj)(variantValue)) {
     const fontFamilyUpdate = variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily];
diff --git a/dist/cjs/helpers/propMapper.native.js b/dist/cjs/helpers/propMapper.native.js
index 4cfa06902028000473624cec916fd9b43be849c1..ecf951210a61522caf8c3f11fbd3306de5f5ccd5 100644
--- a/dist/cjs/helpers/propMapper.native.js
+++ b/dist/cjs/helpers/propMapper.native.js
@@ -68,6 +68,10 @@ var import_constants = require("@tamagui/constants"), import_helpers = require("
       var fn = variantValue, extras = (0, import_getVariantExtras.getVariantExtras)(styleState);
       variantValue = fn(value, extras), process.env.NODE_ENV;
     }
+    process.env.NODE_ENV === "development" && (0, import_isObj.isObj)(variantValue) && (styleState.originalVariantStyles = {
+      ...styleState.originalVariantStyles,
+      ...variantValue
+    });
     var fontFamilyResult;
     if ((0, import_isObj.isObj)(variantValue)) {
       var fontFamilyUpdate = variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily];
diff --git a/dist/esm/helpers/getSplitStyles.js b/dist/esm/helpers/getSplitStyles.js
index 048050fbc74374f4bafc9250d4309b27feb25c2b..e931225738ca3593bf738eb56b67441ef19f094d 100644
--- a/dist/esm/helpers/getSplitStyles.js
+++ b/dist/esm/helpers/getSplitStyles.js
@@ -78,6 +78,7 @@ const getSplitStyles = (props, staticConfig, theme, themeName, componentState, s
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -529,7 +530,11 @@ current`, {
         style && (style.$$css ? Object.assign(styleState.classNames, style) : (styleState.style ||= {}, Object.assign(styleState.style, normalizeStyle(style))));
       }
     }
-  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`;
+  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`, process.env.NODE_ENV === "development" && (styleState.style = {
+    ...filterTokens(props),
+    ...filterTokens(styleState.originalVariantStyles),
+    ...styleState.style
+  });
   const result = {
     space,
     hasMedia,
@@ -704,6 +709,9 @@ function applyDefaultStyle(pkey, styleState) {
   const defaultValues = animatableDefaults[pkey];
   defaultValues != null && !(pkey in styleState.usedKeys) && (!styleState.style || !(pkey in styleState.style)) && mergeStyle(styleState, pkey, defaultValues);
 }
+function filterTokens(tokens) {
+  return Object.entries(tokens).reduce((acc, [key, value]) => (typeof value == "string" && value.startsWith("$") && (acc[`${key}Token`] = value), acc), {});
+}
 export {
   PROP_SPLIT,
   getSplitStyles,
diff --git a/dist/esm/helpers/getSplitStyles.mjs b/dist/esm/helpers/getSplitStyles.mjs
index 346d7ebb7f8ff97fd1301940b85b2b8e19bd7a12..464a20bfbedb2e751af1e21d84a6449a2d64bd76 100644
--- a/dist/esm/helpers/getSplitStyles.mjs
+++ b/dist/esm/helpers/getSplitStyles.mjs
@@ -65,6 +65,7 @@ const getSplitStyles = (props, staticConfig, theme, themeName, componentState, s
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -515,7 +516,11 @@ current`, {
       style && (style.$$css ? Object.assign(styleState.classNames, style) : (styleState.style ||= {}, Object.assign(styleState.style, normalizeStyle(style))));
     }
   }
-  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`;
+  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`, process.env.NODE_ENV === "development" && (styleState.style = {
+    ...filterTokens(props),
+    ...filterTokens(styleState.originalVariantStyles),
+    ...styleState.style
+  });
   const result = {
     space,
     hasMedia,
@@ -684,5 +689,8 @@ function applyDefaultStyle(pkey, styleState) {
   const defaultValues = animatableDefaults[pkey];
   defaultValues != null && !(pkey in styleState.usedKeys) && (!styleState.style || !(pkey in styleState.style)) && mergeStyle(styleState, pkey, defaultValues);
 }
+function filterTokens(tokens) {
+  return Object.entries(tokens).reduce((acc, [key, value]) => (typeof value == "string" && value.startsWith("$") && (acc[`${key}Token`] = value), acc), {});
+}
 export { PROP_SPLIT, getSplitStyles, getSubStyle, useSplitStyles };
 //# sourceMappingURL=getSplitStyles.mjs.map
diff --git a/dist/esm/helpers/getSplitStyles.native.js b/dist/esm/helpers/getSplitStyles.native.js
index 3b8d384c1a6d74b77ed20190af637187d89bc120..a99c3e70ec8c69859cd58359246ba34dd8d4052c 100644
--- a/dist/esm/helpers/getSplitStyles.native.js
+++ b/dist/esm/helpers/getSplitStyles.native.js
@@ -35,6 +35,7 @@ var getSplitStyles = function(props, staticConfig, theme, themeName, componentSt
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -451,7 +452,11 @@ current`, {
     }
     process.env.NODE_ENV === "development" && debug && debug !== "profile" && log(`Found fontFamily native: ${style1.fontFamily}`, faceInfo);
   }
-  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`;
+  process.env.NODE_ENV === "development" && debug === "profile" && time`split-styles-pre-result`, process.env.NODE_ENV === "development" && (styleState.style = {
+    ...filterTokens(props),
+    ...filterTokens(styleState.originalVariantStyles),
+    ...styleState.style
+  });
   var result = {
     space,
     hasMedia,
@@ -636,6 +641,12 @@ function applyDefaultStyle(pkey, styleState) {
   var defaultValues = animatableDefaults[pkey];
   defaultValues != null && !(pkey in styleState.usedKeys) && (!styleState.style || !(pkey in styleState.style)) && mergeStyle(styleState, pkey, defaultValues);
 }
+function filterTokens(tokens) {
+  return Object.entries(tokens).reduce(function(acc, param) {
+    var [key, value] = param;
+    return typeof value == "string" && value.startsWith("$") && (acc[`${key}Token`] = value), acc;
+  }, {});
+}
 export {
   PROP_SPLIT,
   getSplitStyles,
diff --git a/dist/esm/helpers/propMapper.js b/dist/esm/helpers/propMapper.js
index 9537d09e46b201acd7de1efad4ee8cf433821319..681a27af34db54df5a0cab6ff67826d83b5969a9 100644
--- a/dist/esm/helpers/propMapper.js
+++ b/dist/esm/helpers/propMapper.js
@@ -57,6 +57,10 @@ const propMapper = (key, value, styleState) => {
     const fn = variantValue, extras = getVariantExtras(styleState);
     variantValue = fn(value, extras), process.env.NODE_ENV === "development" && debug === "verbose" && (console.groupCollapsed("   expanded functional variant", key), console.info({ fn, variantValue, extras }), console.groupEnd());
   }
+  process.env.NODE_ENV === "development" && isObj(variantValue) && (styleState.originalVariantStyles = {
+    ...styleState.originalVariantStyles,
+    ...variantValue
+  });
   let fontFamilyResult;
   if (isObj(variantValue)) {
     const fontFamilyUpdate = variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily];
diff --git a/dist/esm/helpers/propMapper.mjs b/dist/esm/helpers/propMapper.mjs
index 31626fdf41e98241b92eaca17904257ea8e20710..e125978999e3e126ddf830fadd191cf24249d20d 100644
--- a/dist/esm/helpers/propMapper.mjs
+++ b/dist/esm/helpers/propMapper.mjs
@@ -65,6 +65,10 @@ const propMapper = (key, value, styleState) => {
         extras
       }), console.groupEnd());
     }
+    process.env.NODE_ENV === "development" && isObj(variantValue) && (styleState.originalVariantStyles = {
+      ...styleState.originalVariantStyles,
+      ...variantValue
+    });
     let fontFamilyResult;
     if (isObj(variantValue)) {
       const fontFamilyUpdate = variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily];
diff --git a/dist/esm/helpers/propMapper.native.js b/dist/esm/helpers/propMapper.native.js
index 23210673ab3b0937f4d8f8d4169047400a6977e3..5e9322dd2602bf87c97d58bbebc42236633c3aab 100644
--- a/dist/esm/helpers/propMapper.native.js
+++ b/dist/esm/helpers/propMapper.native.js
@@ -55,6 +55,10 @@ var propMapper = function(key, value, styleState) {
       var fn = variantValue, extras = getVariantExtras(styleState);
       variantValue = fn(value, extras), process.env.NODE_ENV;
     }
+    process.env.NODE_ENV === "development" && isObj(variantValue) && (styleState.originalVariantStyles = {
+      ...styleState.originalVariantStyles,
+      ...variantValue
+    });
     var fontFamilyResult;
     if (isObj(variantValue)) {
       var fontFamilyUpdate = variantValue.fontFamily || variantValue[conf.inverseShorthands.fontFamily];
diff --git a/src/helpers/getSplitStyles.tsx b/src/helpers/getSplitStyles.tsx
index 5497dc21cd515fc642a3ab62730fbb7ad6649799..d6445ebcf92f43563ce7883a94ecfcf6c370de1e 100644
--- a/src/helpers/getSplitStyles.tsx
+++ b/src/helpers/getSplitStyles.tsx
@@ -197,6 +197,7 @@ export const getSplitStyles: StyleSplitter = (
     componentState,
     staticConfig,
     style: null,
+    originalVariantStyles: {},
     theme,
     usedKeys,
     viewProps,
@@ -1321,6 +1322,15 @@ export const getSplitStyles: StyleSplitter = (
     time`split-styles-pre-result`
   }

+  if (process.env.NODE_ENV === 'development') {
+    // Merge original variant props with the resolved styles
+    styleState.style = {
+      ...filterTokens(props),
+      ...filterTokens(styleState.originalVariantStyles),
+      ...styleState.style,
+    }
+  }
+
   const result: GetStyleResult = {
     space,
     hasMedia,
@@ -1710,3 +1720,12 @@ function applyDefaultStyle(pkey: string, styleState: GetStyleState) {
     mergeStyle(styleState, pkey, defaultValues)
   }
 }
+
+function filterTokens(tokens: Record<string, any>) {
+  return Object.entries(tokens).reduce((acc, [key, value]) => {
+    if (typeof value === 'string' && value.startsWith('$')) {
+      acc[`${key}Token`] = value
+    }
+    return acc
+  }, {})
+}
diff --git a/src/helpers/propMapper.ts b/src/helpers/propMapper.ts
index c5e135a551eb34ee1ec7605993c12805b4f2c9c7..d3415ef0e022ff8872215c4af8bd88cc29af88df 100644
--- a/src/helpers/propMapper.ts
+++ b/src/helpers/propMapper.ts
@@ -150,6 +150,14 @@ const resolveVariants: StyleResolver = (
     }
   }

+  if (process.env.NODE_ENV === 'development' && isObj(variantValue)) {
+    // Store the original $-prefixed value for debugging
+    styleState.originalVariantStyles = {
+      ...styleState.originalVariantStyles,
+      ...variantValue,
+    }
+  }
+
   let fontFamilyResult: any

   if (isObj(variantValue)) {
diff --git a/src/types.tsx b/src/types.tsx
index e5e7945c2862cf4a9d805d02edc19aa2c9bf120a..937424b899b675ee80b74e01dc384ff881ca5dd7 100644
--- a/src/types.tsx
+++ b/src/types.tsx
@@ -2114,6 +2114,7 @@ export type PropMappedValue = [string, any][] | undefined

 export type GetStyleState = {
   style: TextStyle | null
+  originalVariantStyles: Record<string, any>
   usedKeys: Record<string, number>
   classNames: ClassNamesObject
   staticConfig: StaticConfig
diff --git a/types/types.d.ts b/types/types.d.ts
index 0439bca887b0764e80167053b2199da2511db006..d17f27d04a77bb9d4c0edfe3efa4effb4933d88b 100644
--- a/types/types.d.ts
+++ b/types/types.d.ts
@@ -1329,6 +1329,7 @@ export type TamaguiProviderProps = Partial<Omit<ThemeProviderProps, 'children'>>
 export type PropMappedValue = [string, any][] | undefined;
 export type GetStyleState = {
     style: TextStyle | null;
+    originalVariantStyles: Record<string, any>;
     usedKeys: Record<string, number>;
     classNames: ClassNamesObject;
     staticConfig: StaticConfig;

Everything works fine after removing this line \ No newline at end of file. Or if I added manually a new line in the file for the patch.

Environment

System:
  OS: macOS 15.1
  CPU: (12) arm64 Apple M3 Pro
Binaries:
  Node: 20.14.0 - /private/var/folders/fc/74t23kl53h944kcvmqyfblgm0000gn/T/xfs-902e9090/node
  Yarn: 4.1.1 - /private/var/folders/fc/74t23kl53h944kcvmqyfblgm0000gn/T/xfs-902e9090/yarn
  npm: 10.8.1 - ~/.nvm/versions/node/v20.14.0/bin/npm

Additional context

No response