yini-cli 1.3.0-beta → 1.3.1-beta

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.
@@ -3,8 +3,23 @@ import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import YINI from 'yini-parser';
5
5
  import { getSerializer } from '../serializers/index.js';
6
- import { debugPrint, printObject, } from '../utils/print.js';
6
+ import { debugPrint, printObject } from '../utils/print.js';
7
7
  // -------------------------------------------------------------------------
8
+ const reportAction = (action, file, reason) => {
9
+ let txt = '';
10
+ if (reason) {
11
+ txt = `${action.padEnd(6)} "${file}" (${reason})`;
12
+ }
13
+ else {
14
+ txt = `${action.padEnd(6)} "${file}"`;
15
+ }
16
+ if (action === 'skip') {
17
+ console.warn(txt);
18
+ }
19
+ else {
20
+ console.log(txt);
21
+ }
22
+ };
8
23
  /*
9
24
  TODO / SHOULD-DO:
10
25
 
@@ -91,24 +106,46 @@ const doParseFile = (file, commandOptions, outputFormat, outputFile = '') => {
91
106
  debugPrint('outputFormat = ' + outputFormat);
92
107
  const parseOptions = {
93
108
  strictMode: commandOptions.strict ?? false,
94
- failLevel: preferredFailLevel,
95
- includeMetadata: includeMetaData,
109
+ failLevel: commandOptions.bestEffort ? 'ignore-errors' : 'auto',
110
+ includeMetadata: false,
96
111
  };
97
112
  // If --best-effort then override fail-level.
98
- if (commandOptions.bestEffort) {
99
- parseOptions.failLevel = 'ignore-errors';
100
- }
113
+ // if (commandOptions.bestEffort) {
114
+ // parseOptions.failLevel = 'ignore-errors'
115
+ // }
101
116
  try {
102
117
  const parsed = YINI.parseFile(file, parseOptions);
103
118
  const serializer = getSerializer(outputFormat);
104
119
  const output = serializer.serialize(parsed);
105
120
  if (outputFile) {
106
121
  const resolved = path.resolve(outputFile);
107
- enforceWritePolicy(file, resolved, commandOptions.overwrite);
122
+ const canWrite = enforceWritePolicy(file, resolved, commandOptions.overwrite);
123
+ if (!canWrite) {
124
+ if (commandOptions.verbose) {
125
+ console.log(`skip Skipping write to "${resolved}"`);
126
+ }
127
+ return;
128
+ }
129
+ // Double check, if the file was actually changed by comparing the contents.
130
+ if (fs.existsSync(resolved) && fs.statSync(resolved).isFile()) {
131
+ const existing = fs.readFileSync(resolved, 'utf-8');
132
+ // Only write the output file if the content actually changed.
133
+ // Prevents constantly showing meaningless rewrites, in some cases.
134
+ if (existing === output) {
135
+ if (commandOptions.verbose) {
136
+ // console.log(
137
+ // `skip Output unchanged. Skipping write: "${resolved}"`,
138
+ // )
139
+ reportAction('skip', resolved, 'output unchanged');
140
+ }
141
+ return;
142
+ }
143
+ }
108
144
  // Write JSON output to file instead of stdout.
109
145
  fs.writeFileSync(resolved, output, 'utf-8');
110
146
  if (commandOptions.verbose) {
111
- console.log(`Output written to file: "${outputFile}"`);
147
+ // console.log(`write Output written to file: "${outputFile}"`)
148
+ reportAction('write', resolved);
112
149
  }
113
150
  }
114
151
  else {
@@ -123,19 +160,27 @@ const doParseFile = (file, commandOptions, outputFormat, outputFile = '') => {
123
160
  };
124
161
  const enforceWritePolicy = (srcPath, destPath, overwrite) => {
125
162
  if (!fs.existsSync(destPath)) {
126
- return; // File does not exist, OK to write.
163
+ return true; // File does not exist, OK to write.
127
164
  }
128
165
  const srcStat = fs.statSync(srcPath);
129
166
  const destStat = fs.statSync(destPath);
130
- const destIsNewer = destStat.mtimeMs >= srcStat.mtimeMs;
167
+ // Only strictly newer triggers skip overwrite.
168
+ const destIsNewer = destStat.mtimeMs > srcStat.mtimeMs;
131
169
  if (overwrite === true) {
132
- return; // Explicit overwrite, OK.
170
+ return true; // Explicit overwrite, OK.
133
171
  }
134
172
  if (overwrite === false) {
135
173
  throw new Error(`File "${destPath}" already exists. Overwriting disabled (--no-overwrite).`);
136
174
  }
137
175
  // Default policy (overwrite undefined).
138
176
  if (destIsNewer) {
139
- throw new Error(`Destination file "${destPath}" is newer than source. Use --overwrite to force.`);
177
+ // console.warn(
178
+ // // `Destination file "${destPath}" is newer than source. Use --overwrite to force.`,
179
+ // //`Warning: destination file "${destPath}" is newer than source. Skipping write. Use --overwrite to force.`,
180
+ // `Warning: destination "${destPath}" is newer than source "${srcPath}". Skipping write. Use --overwrite to force.`,
181
+ // )
182
+ reportAction('skip', destPath, `newer than source "${srcPath}"`);
183
+ return false;
140
184
  }
185
+ return true;
141
186
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yini-cli",
3
- "version": "1.3.0-beta",
3
+ "version": "1.3.1-beta",
4
4
  "description": "CLI tool for validating and converting YINI configuration files - an INI-like format with real structure, nested sections and strict or lenient modes.",
5
5
  "keywords": [
6
6
  "yini",