Skip to content

Commit 0633d0d

Browse files
justin808claude
andcommitted
Replace left/right labels with meaningful file-based labels
Changes based on feedback: 1. Remove redundant value type display - Type information doesn't add value to the diff output - Users can see the type from the value itself 2. Replace "old/new" with file-based labels - Extract meaningful short names from filenames - webpack-development-client.yaml -> "dev-client" - webpack-production-server.yaml -> "prod-server" - Falls back to "left"/"right" if no pattern matches 3. Show values in a clearer format: Before: Old value: "development" New value: "production" After: Values: dev-client: "development" prod-client: "production" 4. Design supports future N-way comparison - Format naturally extends to comparing 3+ configs - Could show dev-client, dev-server, prod-client, prod-server all in one view - Labels make it clear which value comes from which file Example output: 3. [~] mode What it does: Defines the environment mode (development, production, or none). Affects: Minification, tree-shaking, source maps Values: dev: "development" prod: "production" Impact: Enabling production optimizations Much clearer which config has which value! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent fc71e14 commit 0633d0d

File tree

2 files changed

+72
-13
lines changed

2 files changed

+72
-13
lines changed

package/configDiffer/formatter.ts

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export class DiffFormatter {
2525
formatContextual(result: DiffResult): string {
2626
const lines: string[] = []
2727

28+
// Extract short names from filenames
29+
const leftLabel = this.getShortLabel(result.metadata.leftFile, "left")
30+
const rightLabel = this.getShortLabel(result.metadata.rightFile, "right")
31+
2832
lines.push("=".repeat(80))
2933
lines.push("Webpack/Rspack Configuration Comparison")
3034
lines.push("=".repeat(80))
@@ -62,21 +66,67 @@ export class DiffFormatter {
6266
sortedEntries.forEach((entry, index) => {
6367
if (entry.operation === "unchanged") return
6468

65-
lines.push(this.formatContextualEntry(entry, index + 1))
69+
lines.push(
70+
this.formatContextualEntry(entry, index + 1, leftLabel, rightLabel)
71+
)
6672
lines.push("")
6773
})
6874

6975
lines.push("=".repeat(80))
7076
lines.push("")
7177
lines.push("Legend:")
72-
lines.push(" [+] = Added in right config")
73-
lines.push(" [-] = Removed from right config")
74-
lines.push(" [~] = Changed between configs")
78+
lines.push(` [+] = Added in ${rightLabel}`)
79+
lines.push(` [-] = Removed from ${rightLabel}`)
80+
lines.push(` [~] = Changed between configs`)
7581
lines.push("")
7682

7783
return lines.join("\n")
7884
}
7985

86+
private getShortLabel(
87+
filename: string | undefined,
88+
fallback: string
89+
): string {
90+
if (!filename) return fallback
91+
92+
// Extract meaningful short name from filename
93+
// Examples:
94+
// webpack-development-client.yaml -> dev-client
95+
// webpack-production-server.yaml -> prod-server
96+
// shakapacker-config-exports/webpack-development-client.yaml -> dev-client
97+
const basename = filename.split("/").pop() || filename
98+
const withoutExt = basename.replace(/\.(yaml|yml|json|js|ts)$/, "")
99+
100+
// Try to extract env-type pattern
101+
const match = withoutExt.match(
102+
/(development|production|test|dev|prod).*?(client|server)/i
103+
)
104+
if (match) {
105+
const env = match[1]
106+
.toLowerCase()
107+
.replace("development", "dev")
108+
.replace("production", "prod")
109+
const type = match[2].toLowerCase()
110+
return `${env}-${type}`
111+
}
112+
113+
// Try to extract just the env
114+
const envMatch = withoutExt.match(/(development|production|test|dev|prod)/i)
115+
if (envMatch) {
116+
return envMatch[1]
117+
.toLowerCase()
118+
.replace("development", "dev")
119+
.replace("production", "prod")
120+
}
121+
122+
// Fall back to basename without extension, shortened
123+
if (withoutExt.length > 20) {
124+
return withoutExt.substring(0, 17) + "..."
125+
}
126+
127+
return withoutExt
128+
}
129+
80130
// Keep formatDetailed as an alias for backward compatibility
81131
formatDetailed(result: DiffResult): string {
82132
return this.formatContextual(result)
@@ -94,7 +144,12 @@ export class DiffFormatter {
94144
)
95145
}
96146

97-
private formatContextualEntry(entry: DiffEntry, index: number): string {
147+
private formatContextualEntry(
148+
entry: DiffEntry,
149+
index: number,
150+
leftLabel: string,
151+
rightLabel: string
152+
): string {
98153
const lines: string[] = []
99154
const symbol =
100155
entry.operation === "added"
@@ -124,14 +179,17 @@ export class DiffFormatter {
124179
}
125180
}
126181

127-
// Show the change
182+
// Show the values from each file with their labels
183+
lines.push(` Values:`)
128184
if (entry.operation === "added") {
129-
lines.push(` Added value: ${this.formatValue(entry.newValue)}`)
185+
lines.push(` ${leftLabel}: <not set>`)
186+
lines.push(` ${rightLabel}: ${this.formatValue(entry.newValue)}`)
130187
} else if (entry.operation === "removed") {
131-
lines.push(` Removed value: ${this.formatValue(entry.oldValue)}`)
188+
lines.push(` ${leftLabel}: ${this.formatValue(entry.oldValue)}`)
189+
lines.push(` ${rightLabel}: <not set>`)
132190
} else if (entry.operation === "changed") {
133-
lines.push(` Old value: ${this.formatValue(entry.oldValue)}`)
134-
lines.push(` New value: ${this.formatValue(entry.newValue)}`)
191+
lines.push(` ${leftLabel}: ${this.formatValue(entry.oldValue)}`)
192+
lines.push(` ${rightLabel}: ${this.formatValue(entry.newValue)}`)
135193

136194
// Add impact analysis for specific keys
137195
const impact = this.analyzeImpact(entry)

test/configDiffer/formatter.test.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,13 @@ describe("DiffFormatter", () => {
118118
expect(output).toContain("changedKey")
119119
})
120120

121-
test("shows old and new values for changed entries", () => {
121+
test("shows values with file labels for changed entries", () => {
122122
const formatter = new DiffFormatter()
123123
const output = formatter.formatDetailed(mockResult)
124124

125-
expect(output).toContain("Old value:")
126-
expect(output).toContain("New value:")
125+
expect(output).toContain("Values:")
126+
// Should have left/right labels or extracted short names
127+
expect(output).toMatch(/(left|right|config\d):/i)
127128
})
128129
})
129130
})

0 commit comments

Comments
 (0)