@@ -2,6 +2,7 @@ import consola from 'consola';
2
2
import assert from 'node:assert' ;
3
3
import { readFile , writeFile } from 'node:fs/promises' ;
4
4
import { parseArgs } from 'node:util' ;
5
+ import { cli } from 'textlint' ;
5
6
import {
6
7
cpRf ,
7
8
exists ,
@@ -139,17 +140,61 @@ async function saveTranslation(
139
140
file : string ,
140
141
content : string ,
141
142
forceWrite : boolean
142
- ) : Promise < void > {
143
+ ) : Promise < string | null > {
143
144
const outputFile = getLocalizedFilePath ( file ) ;
144
145
const shouldSave = forceWrite || ( await promptForSave ( outputFile ) ) ;
145
146
146
147
if ( ! shouldSave ) {
147
- return ;
148
+ consola . info ( '翻訳結果は保存されませんでした。' ) ;
149
+ return null ;
148
150
}
149
151
150
152
await ensureEnglishFile ( file ) ;
151
153
await writeFile ( outputFile , content ) ;
152
- consola . success ( `保存しました` ) ;
154
+ consola . success ( `翻訳結果を保存しました: ${ outputFile } ` ) ;
155
+ return outputFile ;
156
+ }
157
+
158
+ /**
159
+ * 翻訳ファイルと原文ファイルの行数比較バリデーション
160
+ */
161
+ async function validateLineCount (
162
+ originalFile : string ,
163
+ translatedFile : string
164
+ ) : Promise < void > {
165
+ async function getLineCount ( filePath : string ) {
166
+ const content = await readFile ( filePath , 'utf-8' ) ;
167
+ return content . split ( '\n' ) . length ;
168
+ }
169
+
170
+ const [ originalLines , translatedLines ] = await Promise . all ( [
171
+ getLineCount ( originalFile ) ,
172
+ getLineCount ( translatedFile ) ,
173
+ ] ) ;
174
+
175
+ const lineDiff = Math . abs ( originalLines - translatedLines ) ;
176
+
177
+ if ( lineDiff === 0 ) {
178
+ consola . success ( `行数バリデーション: OK` ) ;
179
+ } else {
180
+ consola . warn (
181
+ `行数バリデーション: 注意 - 原文: ${ originalLines } 行, 翻訳: ${ translatedLines } 行 (差分: ${ lineDiff } 行`
182
+ ) ;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * textlintの実行
188
+ */
189
+ async function runTextlint ( file : string ) : Promise < void > {
190
+ const ok = await cli . execute ( `${ file } ` ) . then ( ( code ) => code === 0 ) ;
191
+ if ( ok ) {
192
+ consola . success ( `textlint: OK` ) ;
193
+ } else {
194
+ consola . warn (
195
+ `textlint: エラーが検出されました。修正が完了してから提出してください。`
196
+ ) ;
197
+ }
153
198
}
154
199
155
200
/**
@@ -166,7 +211,17 @@ async function main() {
166
211
const translated = await translateFile ( file , googleApiKey , geminiModel ) ;
167
212
168
213
console . log ( translated ) ;
169
- await saveTranslation ( file , translated , ! ! write ) ;
214
+ const savedFile = await saveTranslation ( file , translated , ! ! write ) ;
215
+ if ( ! savedFile ) {
216
+ return ;
217
+ }
218
+
219
+ // 翻訳結果の分析
220
+ consola . start ( `翻訳結果を分析...` ) ;
221
+ // 原文ファイルとの行数比較
222
+ await validateLineCount ( getEnFilePath ( savedFile ) , savedFile ) ;
223
+ // textlintの実行
224
+ await runTextlint ( savedFile ) ;
170
225
}
171
226
172
227
main ( ) . catch ( ( error ) => {
0 commit comments