helm-env-delta 1.9.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -40
- package/dist/commandLine.d.ts +3 -0
- package/dist/commandLine.js +25 -7
- package/dist/consoleDiffReporter.js +10 -63
- package/dist/fileDiff.d.ts +7 -1
- package/dist/fileDiff.js +34 -5
- package/dist/fileUpdater.js +7 -4
- package/dist/htmlReporter.js +28 -1
- package/dist/index.js +32 -6
- package/dist/jsonReporter.d.ts +6 -1
- package/dist/jsonReporter.js +6 -1
- package/dist/reporters/htmlStyles.d.ts +1 -1
- package/dist/reporters/htmlStyles.js +175 -26
- package/dist/reporters/htmlTemplate.d.ts +1 -1
- package/dist/reporters/htmlTemplate.js +18 -5
- package/dist/reporters/treeRenderer.d.ts +1 -0
- package/dist/reporters/treeRenderer.js +10 -9
- package/dist/utils/commentOnlyDetector.d.ts +1 -0
- package/dist/utils/commentOnlyDetector.js +18 -0
- package/dist/utils/fileFilter.d.ts +9 -0
- package/dist/utils/fileFilter.js +50 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +7 -4
- package/dist/yamlFormatter.js +4 -1
- package/package.json +2 -2
- package/dist/utils/arrayDiffProcessor.d.ts +0 -14
- package/dist/utils/arrayDiffProcessor.js +0 -43
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ HelmEnvDelta (`hed`) automates environment synchronization for GitOps workflows
|
|
|
56
56
|
|
|
57
57
|
📊 **Multiple Reports** - Console, HTML (visual), and JSON (CI/CD) output formats.
|
|
58
58
|
|
|
59
|
-
🔍 **Discovery Tools** - Preview files (
|
|
59
|
+
🔍 **Discovery Tools** - Preview files (`-l`), inspect config (`--show-config`), filter by filename/content (`-f`), filter by change type (`-m`), validate with comprehensive warnings including unused pattern detection.
|
|
60
60
|
|
|
61
61
|
💡 **Smart Suggestions** - Heuristic analysis (`--suggest`) detects patterns and recommends transforms and stop rules automatically. Control sensitivity with `--suggest-threshold`.
|
|
62
62
|
|
|
@@ -102,28 +102,28 @@ transforms:
|
|
|
102
102
|
### 2️⃣ Preview Changes
|
|
103
103
|
|
|
104
104
|
```bash
|
|
105
|
-
|
|
105
|
+
hed -c config.yaml -D -d
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
### 3️⃣ Execute Sync
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
-
|
|
111
|
+
hed -c config.yaml
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
### 4️⃣ Review in Browser
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
|
|
117
|
+
hed -c config.yaml -H
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
### 5️⃣ Get Smart Suggestions (Optional)
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
|
|
123
|
+
hed -c config.yaml --suggest
|
|
124
124
|
|
|
125
125
|
# Control suggestion sensitivity (0-1, default: 0.3)
|
|
126
|
-
|
|
126
|
+
hed -c config.yaml --suggest --suggest-threshold 0.7
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
Analyzes differences and suggests transforms and stop rules automatically with configurable confidence filtering.
|
|
@@ -281,6 +281,28 @@ helm-env-delta --config example/6-fixed-values/config.yaml --dry-run --diff
|
|
|
281
281
|
- Array filter operators (`env[name=LOG_LEVEL].value`)
|
|
282
282
|
- Combining with skipPath and transforms
|
|
283
283
|
|
|
284
|
+
### 🎨 Example 7: Format-Only Mode
|
|
285
|
+
|
|
286
|
+
Format YAML files without syncing. No source directory required - perfect for standardizing existing files.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Preview which files would be formatted
|
|
290
|
+
helm-env-delta --config example/7-format-only/config.yaml --format-only --list-files
|
|
291
|
+
|
|
292
|
+
# Preview formatting changes
|
|
293
|
+
helm-env-delta --config example/7-format-only/config.yaml --format-only --dry-run
|
|
294
|
+
|
|
295
|
+
# Apply formatting
|
|
296
|
+
helm-env-delta --config example/7-format-only/config.yaml --format-only
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Features shown:**
|
|
300
|
+
|
|
301
|
+
- Format-only mode (no source required)
|
|
302
|
+
- Combining `--format-only` with `--list-files` to preview files
|
|
303
|
+
- Key ordering, array sorting, indentation standardization
|
|
304
|
+
- Minimal config for formatting existing files
|
|
305
|
+
|
|
284
306
|
---
|
|
285
307
|
|
|
286
308
|
## 💡 Smart Configuration Suggestions (Heuristic)
|
|
@@ -647,7 +669,7 @@ Standardize YAML across all environments.
|
|
|
647
669
|
```yaml
|
|
648
670
|
outputFormat:
|
|
649
671
|
indent: 2 # Indentation size
|
|
650
|
-
keySeparator: true # Blank line between top-level keys
|
|
672
|
+
keySeparator: true # Blank line between top-level keys (or second-level keys when single top-level key)
|
|
651
673
|
|
|
652
674
|
keyOrders: # Custom key ordering
|
|
653
675
|
'apps/*.yaml':
|
|
@@ -731,63 +753,80 @@ hed --config <file> [options] # Short alias
|
|
|
731
753
|
|
|
732
754
|
### Options
|
|
733
755
|
|
|
734
|
-
| Flag | Description
|
|
735
|
-
| --------------------------- |
|
|
736
|
-
| `--config <path>` | **Required** - Configuration file
|
|
737
|
-
| `--validate` | Validate config and pattern usage (shows warnings)
|
|
738
|
-
| `--suggest` | Analyze differences and suggest config updates
|
|
739
|
-
| `--suggest-threshold <0-1>` | Minimum confidence for suggestions (default: 0.3)
|
|
740
|
-
| `--dry-run` | Preview changes without writing files
|
|
741
|
-
| `--force` | Override stop rules
|
|
742
|
-
| `--diff` | Show console diff
|
|
743
|
-
| `--diff-html` | Generate HTML report (opens in browser)
|
|
744
|
-
| `--diff-json` | Output JSON to stdout (pipe to jq)
|
|
745
|
-
| `--list-files` | List
|
|
746
|
-
| `--show-config` | Display resolved config after inheritance
|
|
747
|
-
| `--format-only` | Format destination files only (source not required)
|
|
748
|
-
| `--skip-format` | Skip YAML formatting during sync
|
|
749
|
-
| `--
|
|
750
|
-
| `--
|
|
751
|
-
| `--
|
|
756
|
+
| Flag | Short | Description |
|
|
757
|
+
| --------------------------- | ----- | ------------------------------------------------------------------- |
|
|
758
|
+
| `--config <path>` | `-c` | **Required** - Configuration file |
|
|
759
|
+
| `--validate` | | Validate config and pattern usage (shows warnings) |
|
|
760
|
+
| `--suggest` | | Analyze differences and suggest config updates |
|
|
761
|
+
| `--suggest-threshold <0-1>` | | Minimum confidence for suggestions (default: 0.3) |
|
|
762
|
+
| `--dry-run` | `-D` | Preview changes without writing files |
|
|
763
|
+
| `--force` | | Override stop rules |
|
|
764
|
+
| `--diff` | `-d` | Show console diff |
|
|
765
|
+
| `--diff-html` | `-H` | Generate HTML report (opens in browser) |
|
|
766
|
+
| `--diff-json` | `-J` | Output JSON to stdout (pipe to jq) |
|
|
767
|
+
| `--list-files` | `-l` | List files without processing (takes precedence over --format-only) |
|
|
768
|
+
| `--show-config` | | Display resolved config after inheritance |
|
|
769
|
+
| `--format-only` | | Format destination files only (source not required) |
|
|
770
|
+
| `--skip-format` | `-S` | Skip YAML formatting during sync |
|
|
771
|
+
| `--filter <string>` | `-f` | Filter files by filename or content (case-insensitive) |
|
|
772
|
+
| `--mode <type>` | `-m` | Filter by change type: new, modified, deleted, all (default: all) |
|
|
773
|
+
| `--no-color` | | Disable colored output (CI/accessibility) |
|
|
774
|
+
| `--verbose` | | Show detailed debug info |
|
|
775
|
+
| `--quiet` | | Suppress output except errors |
|
|
752
776
|
|
|
753
777
|
### Examples
|
|
754
778
|
|
|
755
779
|
```bash
|
|
756
780
|
# Validate configuration (shows warnings)
|
|
757
|
-
hed
|
|
781
|
+
hed -c config.yaml --validate
|
|
758
782
|
|
|
759
783
|
# Get smart configuration suggestions
|
|
760
|
-
hed
|
|
784
|
+
hed -c config.yaml --suggest
|
|
761
785
|
|
|
762
786
|
# Get only high-confidence suggestions
|
|
763
|
-
hed
|
|
787
|
+
hed -c config.yaml --suggest --suggest-threshold 0.7
|
|
764
788
|
|
|
765
789
|
# Preview files that will be synced
|
|
766
|
-
hed
|
|
790
|
+
hed -c config.yaml -l
|
|
767
791
|
|
|
768
792
|
# Display resolved config (after inheritance)
|
|
769
|
-
hed
|
|
793
|
+
hed -c config.yaml --show-config
|
|
770
794
|
|
|
771
795
|
# Preview with diff
|
|
772
|
-
hed
|
|
796
|
+
hed -c config.yaml -D -d
|
|
773
797
|
|
|
774
798
|
# Visual HTML report
|
|
775
|
-
hed
|
|
799
|
+
hed -c config.yaml -H
|
|
776
800
|
|
|
777
801
|
# CI/CD integration (no colors)
|
|
778
|
-
hed
|
|
802
|
+
hed -c config.yaml -J --no-color | jq '.summary'
|
|
779
803
|
|
|
780
804
|
# Execute sync
|
|
781
|
-
hed
|
|
805
|
+
hed -c config.yaml
|
|
782
806
|
|
|
783
807
|
# Force override stop rules
|
|
784
|
-
hed
|
|
808
|
+
hed -c config.yaml --force
|
|
809
|
+
|
|
810
|
+
# Filter to only process files matching 'prod'
|
|
811
|
+
hed -c config.yaml -f prod -d
|
|
812
|
+
|
|
813
|
+
# Sync only new files
|
|
814
|
+
hed -c config.yaml -m new
|
|
815
|
+
|
|
816
|
+
# Preview modified files only
|
|
817
|
+
hed -c config.yaml -m modified -D -d
|
|
818
|
+
|
|
819
|
+
# Combine filter and mode
|
|
820
|
+
hed -c config.yaml -f deployment -m modified -D -d
|
|
785
821
|
|
|
786
822
|
# Format destination files only (no sync, source not required in config)
|
|
787
|
-
hed
|
|
823
|
+
hed -c config.yaml --format-only
|
|
788
824
|
|
|
789
825
|
# Preview format changes
|
|
790
|
-
hed
|
|
826
|
+
hed -c config.yaml --format-only -D
|
|
827
|
+
|
|
828
|
+
# List files that would be formatted (--list-files takes precedence)
|
|
829
|
+
hed -c config.yaml --format-only -l
|
|
791
830
|
|
|
792
831
|
# Format-only config example (no source needed):
|
|
793
832
|
# destination: './prod'
|
|
@@ -816,13 +855,13 @@ flowchart LR
|
|
|
816
855
|
|
|
817
856
|
```bash
|
|
818
857
|
# 1. Preview changes
|
|
819
|
-
hed
|
|
858
|
+
hed -c config.yaml -D -d
|
|
820
859
|
|
|
821
860
|
# 2. Review in browser
|
|
822
|
-
hed
|
|
861
|
+
hed -c config.yaml -H
|
|
823
862
|
|
|
824
863
|
# 3. Execute sync
|
|
825
|
-
hed
|
|
864
|
+
hed -c config.yaml
|
|
826
865
|
|
|
827
866
|
# 4. Git workflow
|
|
828
867
|
git add prod/
|
package/dist/commandLine.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type ChangeMode = 'new' | 'modified' | 'deleted' | 'all';
|
|
1
2
|
export type SyncCommand = {
|
|
2
3
|
config: string;
|
|
3
4
|
dryRun: boolean;
|
|
@@ -15,5 +16,7 @@ export type SyncCommand = {
|
|
|
15
16
|
noColor: boolean;
|
|
16
17
|
suggest: boolean;
|
|
17
18
|
suggestThreshold: number;
|
|
19
|
+
filter?: string;
|
|
20
|
+
mode: ChangeMode;
|
|
18
21
|
};
|
|
19
22
|
export declare const parseCommandLine: (argv?: string[]) => SyncCommand;
|
package/dist/commandLine.js
CHANGED
|
@@ -13,19 +13,21 @@ const parseCommandLine = (argv) => {
|
|
|
13
13
|
.description('Environment-aware YAML delta and sync for GitOps workflows')
|
|
14
14
|
.version(package_json_1.default.version)
|
|
15
15
|
.requiredOption('-c, --config <file>', 'Path to YAML configuration file')
|
|
16
|
-
.option('--dry-run', 'Preview changes without writing files', false)
|
|
16
|
+
.option('-D, --dry-run', 'Preview changes without writing files', false)
|
|
17
17
|
.option('--force', 'Override stop rules and proceed with changes', false)
|
|
18
|
-
.option('--diff', 'Display console diff for changed files', false)
|
|
19
|
-
.option('--diff-html', 'Generate and open HTML diff report in browser', false)
|
|
20
|
-
.option('--diff-json', 'Output diff as JSON to stdout', false)
|
|
21
|
-
.option('--skip-format', 'Skip YAML formatting (outputFormat section)', false)
|
|
18
|
+
.option('-d, --diff', 'Display console diff for changed files', false)
|
|
19
|
+
.option('-H, --diff-html', 'Generate and open HTML diff report in browser', false)
|
|
20
|
+
.option('-J, --diff-json', 'Output diff as JSON to stdout', false)
|
|
21
|
+
.option('-S, --skip-format', 'Skip YAML formatting (outputFormat section)', false)
|
|
22
22
|
.option('--format-only', 'Format YAML files in destination without syncing', false)
|
|
23
23
|
.option('--validate', 'Validate configuration file and exit', false)
|
|
24
|
-
.option('--list-files', 'List files that would be synced without processing diffs', false)
|
|
24
|
+
.option('-l, --list-files', 'List files that would be synced without processing diffs', false)
|
|
25
25
|
.option('--show-config', 'Display resolved configuration after inheritance and exit', false)
|
|
26
26
|
.option('--suggest', 'Analyze differences and suggest transforms and stop rules', false)
|
|
27
27
|
.option('--suggest-threshold <number>', 'Minimum confidence for suggestions (0-1, default: 0.3)', '0.3')
|
|
28
28
|
.option('--no-color', 'Disable colored output')
|
|
29
|
+
.option('-f, --filter <string>', 'Filter files by filename or content (case-insensitive)')
|
|
30
|
+
.option('-m, --mode <type>', 'Filter by change type: new, modified, deleted, all', 'all')
|
|
29
31
|
.option('--verbose', 'Show detailed debug information', false)
|
|
30
32
|
.option('--quiet', 'Suppress all output except critical errors', false)
|
|
31
33
|
.addHelpText('after', `
|
|
@@ -45,6 +47,15 @@ Examples:
|
|
|
45
47
|
# CI/CD usage with JSON output
|
|
46
48
|
$ helm-env-delta --config config.yaml --diff-json | jq '.summary'
|
|
47
49
|
|
|
50
|
+
# Filter to only process files matching 'prod'
|
|
51
|
+
$ helm-env-delta --config config.yaml -f prod --diff
|
|
52
|
+
|
|
53
|
+
# Sync only new files
|
|
54
|
+
$ helm-env-delta --config config.yaml --mode new
|
|
55
|
+
|
|
56
|
+
# Preview modified files only
|
|
57
|
+
$ helm-env-delta --config config.yaml --mode modified --dry-run --diff
|
|
58
|
+
|
|
48
59
|
Documentation: https://github.com/balazscsaba2006/helm-env-delta
|
|
49
60
|
`);
|
|
50
61
|
program.showSuggestionAfterError(true);
|
|
@@ -63,6 +74,11 @@ Documentation: https://github.com/balazscsaba2006/helm-env-delta
|
|
|
63
74
|
console.error('Error: --suggest-threshold must be a number between 0 and 1');
|
|
64
75
|
process.exit(1);
|
|
65
76
|
}
|
|
77
|
+
const validModes = ['new', 'modified', 'deleted', 'all'];
|
|
78
|
+
if (!validModes.includes(options['mode'])) {
|
|
79
|
+
console.error('Error: --mode must be one of: ' + validModes.join(', '));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
66
82
|
return {
|
|
67
83
|
config: options['config'],
|
|
68
84
|
dryRun: options['dryRun'],
|
|
@@ -79,7 +95,9 @@ Documentation: https://github.com/balazscsaba2006/helm-env-delta
|
|
|
79
95
|
verbose: options['verbose'],
|
|
80
96
|
quiet: options['quiet'],
|
|
81
97
|
suggest: options['suggest'],
|
|
82
|
-
suggestThreshold: threshold
|
|
98
|
+
suggestThreshold: threshold,
|
|
99
|
+
filter: options['filter'],
|
|
100
|
+
mode: options['mode']
|
|
83
101
|
};
|
|
84
102
|
};
|
|
85
103
|
exports.parseCommandLine = parseCommandLine;
|
|
@@ -5,9 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.showConsoleDiff = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
const yaml_1 = __importDefault(require("yaml"));
|
|
9
8
|
const fileDiff_1 = require("./fileDiff");
|
|
10
|
-
const arrayDiffProcessor_1 = require("./utils/arrayDiffProcessor");
|
|
11
9
|
const diffGenerator_1 = require("./utils/diffGenerator");
|
|
12
10
|
const fileType_1 = require("./utils/fileType");
|
|
13
11
|
const serialization_1 = require("./utils/serialization");
|
|
@@ -29,7 +27,7 @@ const formatAddedFiles = (files) => {
|
|
|
29
27
|
if (files.length === 0)
|
|
30
28
|
return '';
|
|
31
29
|
const header = chalk_1.default.green.bold(`\nAdded Files (${files.length}):`);
|
|
32
|
-
const fileList = files.map((file) => chalk_1.default.green(` + ${file}`)).join('\n');
|
|
30
|
+
const fileList = files.map((file) => chalk_1.default.green(` + ${file.path}`)).join('\n');
|
|
33
31
|
return `${header}\n${fileList}\n`;
|
|
34
32
|
};
|
|
35
33
|
const formatDeletedFiles = (files) => {
|
|
@@ -39,30 +37,6 @@ const formatDeletedFiles = (files) => {
|
|
|
39
37
|
const fileList = files.map((file) => chalk_1.default.red(` - ${file}`)).join('\n');
|
|
40
38
|
return `${header}\n${fileList}\n`;
|
|
41
39
|
};
|
|
42
|
-
const formatArrayDiff = (change) => {
|
|
43
|
-
let output = '';
|
|
44
|
-
if (change.removed.length > 0) {
|
|
45
|
-
output += chalk_1.default.red.bold(`\n Removed (${change.removed.length}):\n`);
|
|
46
|
-
for (const item of change.removed) {
|
|
47
|
-
const yaml = yaml_1.default.stringify(item, { indent: 4 });
|
|
48
|
-
const lines = yaml.split('\n').filter((l) => l.trim());
|
|
49
|
-
output += lines.map((l) => chalk_1.default.red(` - ${l}`)).join('\n');
|
|
50
|
-
output += '\n';
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (change.added.length > 0) {
|
|
54
|
-
output += chalk_1.default.green.bold(`\n Added (${change.added.length}):\n`);
|
|
55
|
-
for (const item of change.added) {
|
|
56
|
-
const yaml = yaml_1.default.stringify(item, { indent: 4 });
|
|
57
|
-
const lines = yaml.split('\n').filter((l) => l.trim());
|
|
58
|
-
output += lines.map((l) => chalk_1.default.green(` + ${l}`)).join('\n');
|
|
59
|
-
output += '\n';
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (change.unchanged.length > 0)
|
|
63
|
-
output += chalk_1.default.gray(`\n Unchanged: ${change.unchanged.length} items\n`);
|
|
64
|
-
return output;
|
|
65
|
-
};
|
|
66
40
|
const formatChangedFile = (file, config) => {
|
|
67
41
|
const isYaml = (0, fileType_1.isYamlFile)(file.path);
|
|
68
42
|
const separator = chalk_1.default.yellow('━'.repeat(60));
|
|
@@ -70,48 +44,21 @@ const formatChangedFile = (file, config) => {
|
|
|
70
44
|
const skipPathInfo = skipPaths.length > 0
|
|
71
45
|
? chalk_1.default.dim(`SkipPath patterns applied: ${skipPaths.join(', ')}`)
|
|
72
46
|
: chalk_1.default.dim('No skipPath patterns applied');
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
${colorizedDiff}
|
|
84
|
-
`;
|
|
85
|
-
}
|
|
86
|
-
const arrayInfo = (0, arrayDiffProcessor_1.detectArrayChanges)(file);
|
|
87
|
-
if (!arrayInfo.hasArrays) {
|
|
88
|
-
const destinationContent = (0, serialization_1.serializeForDiff)(file.processedDestContent, true);
|
|
89
|
-
const sourceContent = (0, serialization_1.serializeForDiff)(file.processedSourceContent, true);
|
|
90
|
-
const unifiedDiff = (0, diffGenerator_1.generateUnifiedDiff)(file.path, destinationContent, sourceContent);
|
|
91
|
-
const colorizedDiff = colorizeUnifiedDiff(unifiedDiff);
|
|
92
|
-
return `
|
|
47
|
+
const destinationContent = isYaml
|
|
48
|
+
? (0, serialization_1.serializeForDiff)(file.processedDestContent, true)
|
|
49
|
+
: String(file.processedDestContent);
|
|
50
|
+
const sourceContent = isYaml
|
|
51
|
+
? (0, serialization_1.serializeForDiff)(file.processedSourceContent, true)
|
|
52
|
+
: String(file.processedSourceContent);
|
|
53
|
+
const unifiedDiff = (0, diffGenerator_1.generateUnifiedDiff)(file.path, destinationContent, sourceContent);
|
|
54
|
+
const colorizedDiff = colorizeUnifiedDiff(unifiedDiff);
|
|
55
|
+
return `
|
|
93
56
|
${separator}
|
|
94
57
|
${chalk_1.default.yellow.bold(`File: ${file.path}`)}
|
|
95
58
|
${skipPathInfo}
|
|
96
59
|
|
|
97
60
|
${colorizedDiff}
|
|
98
61
|
`;
|
|
99
|
-
}
|
|
100
|
-
let output = `\n${separator}\n${chalk_1.default.yellow.bold(`File: ${file.path}`)}\n${skipPathInfo}\n`;
|
|
101
|
-
const destinationContent = (0, serialization_1.serializeForDiff)(file.processedDestContent, true);
|
|
102
|
-
const sourceContent = (0, serialization_1.serializeForDiff)(file.processedSourceContent, true);
|
|
103
|
-
const unifiedDiff = (0, diffGenerator_1.generateUnifiedDiff)(file.path, destinationContent, sourceContent);
|
|
104
|
-
const colorizedDiff = colorizeUnifiedDiff(unifiedDiff);
|
|
105
|
-
output += `\n${colorizedDiff}\n`;
|
|
106
|
-
if (arrayInfo.hasChanges) {
|
|
107
|
-
output += chalk_1.default.cyan.bold('\nArray-specific details:\n');
|
|
108
|
-
for (const change of arrayInfo.changes) {
|
|
109
|
-
const pathString = change.path.join('.');
|
|
110
|
-
output += chalk_1.default.cyan(`\n ${pathString}:\n`);
|
|
111
|
-
output += formatArrayDiff(change);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return output;
|
|
115
62
|
};
|
|
116
63
|
const formatChangedFiles = (files, config) => {
|
|
117
64
|
if (files.length === 0)
|
package/dist/fileDiff.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Config, FixedValueConfig, TransformConfig } from './configFile';
|
|
2
2
|
import { FileMap } from './fileLoader';
|
|
3
3
|
export interface FileDiffResult {
|
|
4
|
-
addedFiles:
|
|
4
|
+
addedFiles: AddedFile[];
|
|
5
5
|
deletedFiles: string[];
|
|
6
6
|
changedFiles: ChangedFile[];
|
|
7
7
|
unchangedFiles: string[];
|
|
@@ -21,6 +21,12 @@ export interface ChangedFile {
|
|
|
21
21
|
parsedSource?: unknown;
|
|
22
22
|
parsedDest?: unknown;
|
|
23
23
|
}
|
|
24
|
+
export interface AddedFile {
|
|
25
|
+
path: string;
|
|
26
|
+
originalPath?: string;
|
|
27
|
+
content: string;
|
|
28
|
+
processedContent: string;
|
|
29
|
+
}
|
|
24
30
|
export interface ProcessYamlOptions {
|
|
25
31
|
filePath: string;
|
|
26
32
|
sourceContent: string;
|
package/dist/fileDiff.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.computeFileDiff = exports.getSkipPathsForFile = exports.isFileDiffError = exports.FileDiffError = void 0;
|
|
7
7
|
const yaml_1 = __importDefault(require("yaml"));
|
|
8
|
+
const commentOnlyDetector_1 = require("./utils/commentOnlyDetector");
|
|
8
9
|
const deepEqual_1 = require("./utils/deepEqual");
|
|
9
10
|
const errors_1 = require("./utils/errors");
|
|
10
11
|
const fileType_1 = require("./utils/fileType");
|
|
@@ -13,6 +14,7 @@ const jsonPath_1 = require("./utils/jsonPath");
|
|
|
13
14
|
const patternMatcher_1 = require("./utils/patternMatcher");
|
|
14
15
|
const serialization_1 = require("./utils/serialization");
|
|
15
16
|
const transformer_1 = require("./utils/transformer");
|
|
17
|
+
const yamlFormatter_1 = require("./yamlFormatter");
|
|
16
18
|
const FileDiffErrorClass = (0, errors_1.createErrorClass)('File Diff Error', {
|
|
17
19
|
YAML_PARSE_ERROR: 'YAML file could not be parsed'
|
|
18
20
|
});
|
|
@@ -20,11 +22,36 @@ class FileDiffError extends FileDiffErrorClass {
|
|
|
20
22
|
}
|
|
21
23
|
exports.FileDiffError = FileDiffError;
|
|
22
24
|
exports.isFileDiffError = (0, errors_1.createErrorTypeGuard)(FileDiffError);
|
|
23
|
-
const
|
|
25
|
+
const processAddedFileContent = (filePath, content, transforms, fixedValues, outputFormat) => {
|
|
26
|
+
if (!(0, fileType_1.isYamlFile)(filePath))
|
|
27
|
+
return content;
|
|
28
|
+
try {
|
|
29
|
+
const parsed = yaml_1.default.parse(content);
|
|
30
|
+
const transformed = (0, transformer_1.applyTransforms)(parsed, filePath, transforms);
|
|
31
|
+
const fixedValueRules = (0, fixedValues_1.getFixedValuesForFile)(filePath, fixedValues);
|
|
32
|
+
if (fixedValueRules.length > 0)
|
|
33
|
+
(0, fixedValues_1.applyFixedValues)(transformed, fixedValueRules);
|
|
34
|
+
let processed = yaml_1.default.stringify(transformed);
|
|
35
|
+
processed = (0, yamlFormatter_1.formatYaml)(processed, filePath, outputFormat);
|
|
36
|
+
return processed;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return content;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const detectAddedFiles = (sourceFiles, destinationFiles, config, originalPaths) => {
|
|
24
43
|
const addedFiles = [];
|
|
25
|
-
for (const path of sourceFiles.
|
|
26
|
-
if (!destinationFiles.has(path))
|
|
27
|
-
|
|
44
|
+
for (const [path, content] of sourceFiles.entries())
|
|
45
|
+
if (!destinationFiles.has(path)) {
|
|
46
|
+
const originalPath = originalPaths?.get(path);
|
|
47
|
+
const processedContent = processAddedFileContent(path, content, config.transforms, config.fixedValues, config.outputFormat);
|
|
48
|
+
addedFiles.push({
|
|
49
|
+
path,
|
|
50
|
+
originalPath,
|
|
51
|
+
content,
|
|
52
|
+
processedContent
|
|
53
|
+
});
|
|
54
|
+
}
|
|
28
55
|
return addedFiles;
|
|
29
56
|
};
|
|
30
57
|
const detectDeletedFiles = (sourceFiles, destinationFiles) => {
|
|
@@ -143,6 +170,8 @@ const processYamlFile = (options) => {
|
|
|
143
170
|
parseError.message += destinationHints;
|
|
144
171
|
throw parseError;
|
|
145
172
|
}
|
|
173
|
+
if ((0, commentOnlyDetector_1.isCommentOnlyContent)(destinationContent))
|
|
174
|
+
return undefined;
|
|
146
175
|
const sourceTransformed = (0, transformer_1.applyTransforms)(sourceParsed, filePath, transforms);
|
|
147
176
|
const fixedValueRules = (0, fixedValues_1.getFixedValuesForFile)(filePath, fixedValues);
|
|
148
177
|
if (fixedValueRules.length > 0)
|
|
@@ -225,7 +254,7 @@ const computeFileDiff = (sourceFiles, destinationFiles, config, logger, original
|
|
|
225
254
|
if (skipPathCount > 0)
|
|
226
255
|
logger.debug(` SkipPath patterns: ${skipPathCount}`);
|
|
227
256
|
}
|
|
228
|
-
const addedFiles = detectAddedFiles(sourceFiles, destinationFiles);
|
|
257
|
+
const addedFiles = detectAddedFiles(sourceFiles, destinationFiles, config, originalPaths);
|
|
229
258
|
const deletedFiles = config.prune ? detectDeletedFiles(sourceFiles, destinationFiles) : [];
|
|
230
259
|
const { changedFiles, unchangedFiles } = processChangedFiles(sourceFiles, destinationFiles, config.skipPath, config.transforms, config.fixedValues, originalPaths);
|
|
231
260
|
return { addedFiles, deletedFiles, changedFiles, unchangedFiles };
|
package/dist/fileUpdater.js
CHANGED
|
@@ -9,6 +9,7 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
9
9
|
const yaml_1 = __importDefault(require("yaml"));
|
|
10
10
|
const consoleFormatter_1 = require("./consoleFormatter");
|
|
11
11
|
const arrayMerger_1 = require("./utils/arrayMerger");
|
|
12
|
+
const commentOnlyDetector_1 = require("./utils/commentOnlyDetector");
|
|
12
13
|
const errors_1 = require("./utils/errors");
|
|
13
14
|
const fileType_1 = require("./utils/fileType");
|
|
14
15
|
const fixedValues_1 = require("./utils/fixedValues");
|
|
@@ -248,11 +249,11 @@ const deleteFile = async (relativePath, absoluteDestinationDirectory, dryRun, lo
|
|
|
248
249
|
const addNewFiles = async (files, sourceFiles, context) => {
|
|
249
250
|
if (context.logger.shouldShow('debug'))
|
|
250
251
|
context.logger.debug(`Processing ${files.length} new files`);
|
|
251
|
-
for (const
|
|
252
|
+
for (const addedFile of files)
|
|
252
253
|
try {
|
|
253
|
-
const content = sourceFiles.get(
|
|
254
|
+
const content = sourceFiles.get(addedFile.path);
|
|
254
255
|
await addFile({
|
|
255
|
-
relativePath,
|
|
256
|
+
relativePath: addedFile.path,
|
|
256
257
|
content,
|
|
257
258
|
absoluteDestinationDirectory: context.absoluteDestinationDirectory,
|
|
258
259
|
config: context.config,
|
|
@@ -262,7 +263,7 @@ const addNewFiles = async (files, sourceFiles, context) => {
|
|
|
262
263
|
});
|
|
263
264
|
}
|
|
264
265
|
catch (error) {
|
|
265
|
-
context.errors.push({ operation: 'add', path:
|
|
266
|
+
context.errors.push({ operation: 'add', path: addedFile.path, error: error });
|
|
266
267
|
}
|
|
267
268
|
};
|
|
268
269
|
const updateChangedFiles = async (files, context) => {
|
|
@@ -289,6 +290,8 @@ const formatUnchangedFiles = async (files, destinationFiles, context) => {
|
|
|
289
290
|
if ((0, fileType_1.isYamlFile)(relativePath))
|
|
290
291
|
try {
|
|
291
292
|
const content = destinationFiles.get(relativePath);
|
|
293
|
+
if ((0, commentOnlyDetector_1.isCommentOnlyContent)(content))
|
|
294
|
+
continue;
|
|
292
295
|
const effectiveOutputFormat = context.skipFormat ? undefined : context.config.outputFormat;
|
|
293
296
|
const formatted = (0, yamlFormatter_1.formatYaml)(content, relativePath, effectiveOutputFormat);
|
|
294
297
|
if (formatted !== content) {
|
package/dist/htmlReporter.js
CHANGED
|
@@ -11,6 +11,7 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
11
11
|
const diff2html_1 = require("diff2html");
|
|
12
12
|
const browserLauncher_1 = require("./reporters/browserLauncher");
|
|
13
13
|
const htmlTemplate_1 = require("./reporters/htmlTemplate");
|
|
14
|
+
const treeRenderer_1 = require("./reporters/treeRenderer");
|
|
14
15
|
const diffGenerator_1 = require("./utils/diffGenerator");
|
|
15
16
|
const errors_1 = require("./utils/errors");
|
|
16
17
|
const fileType_1 = require("./utils/fileType");
|
|
@@ -42,6 +43,28 @@ const generateFileSummary = (file) => {
|
|
|
42
43
|
return file.path;
|
|
43
44
|
return `<span class="filename-transform">${file.originalPath} → ${file.path}</span>`;
|
|
44
45
|
};
|
|
46
|
+
const generateAddedFileSummary = (file) => {
|
|
47
|
+
if (!file.originalPath)
|
|
48
|
+
return file.path;
|
|
49
|
+
return `<span class="filename-transform">${file.originalPath} → ${file.path}</span>`;
|
|
50
|
+
};
|
|
51
|
+
const generateAddedFileSection = (file, fileId) => {
|
|
52
|
+
const summary = generateAddedFileSummary(file);
|
|
53
|
+
const escapedContent = (0, treeRenderer_1.escapeHtml)(file.processedContent);
|
|
54
|
+
const filename = file.path.split('/').pop() || file.path;
|
|
55
|
+
return `
|
|
56
|
+
<details class="file-section" id="${fileId}" data-file-id="${fileId}" open>
|
|
57
|
+
<summary>${summary}</summary>
|
|
58
|
+
<div class="content-container">
|
|
59
|
+
<div class="content-actions">
|
|
60
|
+
<button class="copy-btn" data-file-id="${fileId}" title="Copy to clipboard">📋 Copy</button>
|
|
61
|
+
<button class="download-btn" data-file-id="${fileId}" data-filename="${(0, treeRenderer_1.escapeHtml)(filename)}" title="Download file">⬇ Download</button>
|
|
62
|
+
</div>
|
|
63
|
+
<pre class="file-content"><code>${escapedContent}</code></pre>
|
|
64
|
+
</div>
|
|
65
|
+
</details>
|
|
66
|
+
`;
|
|
67
|
+
};
|
|
45
68
|
const generateChangedFileSection = (file, fileId) => {
|
|
46
69
|
const isYaml = (0, fileType_1.isYamlFile)(file.path);
|
|
47
70
|
const summary = generateFileSummary(file);
|
|
@@ -91,7 +114,11 @@ const generateHtmlReport = async (diffResult, formattedFiles, config, dryRun, lo
|
|
|
91
114
|
for (const [index, file] of diffResult.changedFiles.entries())
|
|
92
115
|
changedFileIds.set(file.path, `file-${index}`);
|
|
93
116
|
const changedSections = diffResult.changedFiles.map((file, index) => generateChangedFileSection(file, `file-${index}`));
|
|
94
|
-
const
|
|
117
|
+
const addedFileIds = new Map();
|
|
118
|
+
for (const [index, file] of diffResult.addedFiles.entries())
|
|
119
|
+
addedFileIds.set(file.path, `added-file-${index}`);
|
|
120
|
+
const addedSections = diffResult.addedFiles.map((file, index) => generateAddedFileSection(file, `added-file-${index}`));
|
|
121
|
+
const htmlContent = (0, htmlTemplate_1.generateHtmlTemplate)(diffResult, formattedFiles, trulyUnchangedFiles, metadata, changedSections, changedFileIds, addedSections, addedFileIds);
|
|
95
122
|
await writeHtmlFile(htmlContent, reportPath);
|
|
96
123
|
logger?.log(`✓ HTML report generated: ${reportPath}, opening in browser...`);
|
|
97
124
|
try {
|