Skip to content

Commit 9b6175d

Browse files
committed
Merge branch 'work'
2 parents 84e1c48 + 662a2a3 commit 9b6175d

File tree

10 files changed

+243
-11
lines changed

10 files changed

+243
-11
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@
3030
"deepmerge": "^4.2.2",
3131
"flat": "^5.0.0",
3232
"glob": "^7.1.4",
33+
"ignore": "^5.1.8",
3334
"js-yaml": "^3.13.1",
3435
"json-diff": "^0.5.4",
3536
"json5": "^2.1.0",
3637
"yargs": "^15.1.0"
3738
},
3839
"devDependencies": {
40+
"@sucrase/jest-plugin": "^2.1.0",
3941
"@types/debug": "^4.1.4",
4042
"@types/deep-diff": "^1.0.0",
4143
"@types/deepmerge": "^2.2.0",
@@ -47,7 +49,6 @@
4749
"@types/node": "^12.6.8",
4850
"@types/prettier": "^2.0.0",
4951
"@types/yargs": "^15.0.0",
50-
"@sucrase/jest-plugin": "^2.1.0",
5152
"@typescript-eslint/eslint-plugin": "^3.0.0",
5253
"@typescript-eslint/parser": "^3.0.0",
5354
"@vue/compiler-sfc": "^3.0.11",

src/commands/infuse.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type InfuseOptions = {
3434
unbundleMatch?: string
3535
namespace?: string
3636
dryRun: boolean
37+
ignorePath?: string
3738
}
3839

3940
export const command = 'infuse'
@@ -80,6 +81,11 @@ export const builder = (args: Argv): Argv<InfuseOptions> => {
8081
default: false,
8182
describe: 'run the infuse command, but do not apply them'
8283
})
84+
.option('ignorePath', {
85+
type: 'string',
86+
alias: 'i',
87+
describe: 'path to dot ignore file, i.e. ./.ignore-i18n'
88+
})
8389
}
8490

8591
export const handler = async (args: Arguments<InfuseOptions>) => {
@@ -96,7 +102,7 @@ export const handler = async (args: Arguments<InfuseOptions>) => {
96102
}
97103
debug('namespace dictionary:', nsDictionary)
98104

99-
const sources = readSFC(targetPath)
105+
const sources = readSFC(targetPath, args.ignorePath)
100106
const messages = readLocaleMessages(messagesPath, args.match)
101107

102108
const { sfc, external } = splitLocaleMessages(messages, nsDictionary, args.unbundleTo, args.unbundleMatch)

src/commands/squeeze.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type SqueezeOptions = {
2727
bundleMatch?: string
2828
namespace?: string
2929
output: string
30+
ignorePath?: string
3031
}
3132

3233
export const command = 'squeeze'
@@ -69,6 +70,11 @@ export const builder = (args: Argv): Argv<SqueezeOptions> => {
6970
default: outputDefault,
7071
describe: 'path to output squeezed locale messages'
7172
})
73+
.option('ignorePath', {
74+
type: 'string',
75+
alias: 'i',
76+
describe: 'path to dot ignore file, i.e. ./.ignore-i18n'
77+
})
7278
}
7379

7480
export const handler = async (args: Arguments<SqueezeOptions>) => {
@@ -85,7 +91,7 @@ export const handler = async (args: Arguments<SqueezeOptions>) => {
8591
console.warn('cannot load external locale messages failed')
8692
}
8793

88-
const meta = squeeze(targetPath, readSFC(targetPath))
94+
const meta = squeeze(targetPath, readSFC(targetPath, args.ignorePath))
8995
const messages = deepmerge(generate(meta), externalMessages)
9096

9197
writeLocaleMessages(messages, args)

src/utils.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import JSON5 from 'json5'
2626
import yaml from 'js-yaml'
2727
import deepmerge from 'deepmerge'
2828
import { promisify } from 'util'
29+
import ignore from 'ignore'
30+
import type { Ignore } from 'ignore'
2931

3032
import { debug as Debug } from 'debug'
3133
const debug = Debug('vue-i18n-locale-message:utils')
@@ -132,15 +134,26 @@ export function stringifyContent (content: any, lang: string, options?: FormatOp
132134
return result
133135
}
134136

135-
export function readSFC (target: string): SFCFileInfo[] {
136-
const targets = resolveGlob(target)
137+
export function readSFC (target: string, ignorePath?: string): SFCFileInfo[] {
138+
let targets = resolveGlob(target)
139+
if ((ignorePath !== undefined)) {
140+
const ig = returnIgnoreInstance(ignorePath)
141+
targets = targets.filter(t => {
142+
if (path.isAbsolute(t)) {
143+
console.debug('Target is absolute path. Please change relative path.')
144+
return !ig.ignores(path.relative('/', t))
145+
} else {
146+
return !ig.ignores(path.relative('./', t))
147+
}
148+
})
149+
}
137150
debug('readSFC: targets = ', targets)
138151

139152
// TODO: async implementation
140-
return targets.map(target => {
141-
const data = fs.readFileSync(target)
153+
return targets.map(t => {
154+
const data = fs.readFileSync(t)
142155
return {
143-
path: target,
156+
path: t,
144157
content: data.toString()
145158
}
146159
})
@@ -413,3 +426,30 @@ export function splitLocaleMessages (
413426

414427
return { sfc: messages, external: metaExternalLocaleMessages }
415428
}
429+
430+
function returnIgnoreInstance (ignorePath: string): Ignore {
431+
const ig = ignore()
432+
if (fs.existsSync(ignorePath)) {
433+
addIgnoreFile(ig, ignorePath)
434+
} else {
435+
console.warn('cannot find ignore file.')
436+
}
437+
return ig
438+
}
439+
440+
function readIgnoreFile (ignorePath: string): string[] {
441+
const ignoreFiles = fs.readFileSync(ignorePath, 'utf8')
442+
.split(/\r?\n/g)
443+
.filter(Boolean)
444+
console.log(`ignoreFiles ${ignoreFiles}`)
445+
return ignoreFiles
446+
}
447+
448+
function addIgnoreFile (
449+
ig: Ignore,
450+
ignorePath: string
451+
): void {
452+
readIgnoreFile(ignorePath).forEach(ignoreRule =>
453+
ig.add(ignoreRule)
454+
)
455+
}

test/commands/__snapshots__/infuse.test.ts.snap

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,87 @@ Object {
250250
}
251251
`;
252252
253+
exports[`ignore option: /path/to/project1/src/App.vue 1`] = `
254+
"
255+
<template>
256+
<p>template</p>
257+
</template>
258+
259+
<script>
260+
export default {}
261+
</script>
262+
263+
<i18n>
264+
{
265+
\\"en\\": {
266+
\\"title\\": \\"Application\\"
267+
},
268+
\\"ja\\": {
269+
\\"title\\": \\"アプリケーション\\"
270+
}
271+
}
272+
</i18n>
273+
"
274+
`;
275+
276+
exports[`ignore option: /path/to/project1/src/components/Modal.vue 1`] = `
277+
"
278+
<template>
279+
<p>template</p>
280+
</template>
281+
282+
<script>
283+
export default {}
284+
</script>
285+
286+
<i18n locale=\\"en\\">
287+
{
288+
\\"ok\\": \\"OK\\",
289+
\\"cancel\\": \\"Cancel\\"
290+
}
291+
</i18n>
292+
293+
<i18n locale=\\"ja\\">
294+
{
295+
\\"ok\\": \\"OK\\",
296+
\\"cancel\\": \\"キャンセル\\"
297+
}
298+
</i18n>
299+
"
300+
`;
301+
302+
exports[`ignore option: /path/to/project1/src/components/nest/RankingTable.vue 1`] = `
303+
"
304+
<template>
305+
<p>template</p>
306+
</template>
307+
308+
<script>
309+
export default {}
310+
</script>
311+
312+
<i18n locale=\\"en\\">
313+
{
314+
\\"headers\\": {
315+
\\"rank\\": \\"Rank\\",
316+
\\"name\\": \\"Name\\",
317+
\\"score\\": \\"Score\\"
318+
}
319+
}
320+
</i18n>
321+
322+
323+
<i18n locale=\\"ja\\">
324+
{
325+
\\"headers\\": {
326+
\\"rank\\": \\"ランク\\",
327+
\\"name\\": \\"名前\\",
328+
\\"score\\": \\"スコア\\"
329+
}
330+
}
331+
</i18n>"
332+
`;
333+
253334
exports[`match option: /path/to/project1/src/App.vue 1`] = `
254335
"
255336
<template>

test/commands/__snapshots__/squeeze.test.ts.snap

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,44 @@ Object {
113113
}
114114
`;
115115

116+
exports[`ignore option 1`] = `
117+
Object {
118+
"/path/to/project1/locales": "{
119+
\\"en\\": {
120+
\\"App\\": {
121+
\\"title\\": \\"Application\\"
122+
},
123+
\\"components\\": {
124+
\\"Modal\\": {
125+
\\"ok\\": \\"OK\\",
126+
\\"cancel\\": \\"Cancel\\"
127+
},
128+
\\"nest\\": {
129+
\\"RankingTable\\": {
130+
\\"headers\\": {
131+
\\"rank\\": \\"Rank\\",
132+
\\"name\\": \\"Name\\",
133+
\\"score\\": \\"Score\\"
134+
}
135+
}
136+
}
137+
}
138+
},
139+
\\"ja\\": {
140+
\\"App\\": {
141+
\\"title\\": \\"アプリケーション\\"
142+
},
143+
\\"components\\": {
144+
\\"Modal\\": {
145+
\\"ok\\": \\"OK\\",
146+
\\"cancel\\": \\"キャンセル\\"
147+
}
148+
}
149+
}
150+
}",
151+
}
152+
`;
153+
116154
exports[`relative path 1`] = `
117155
Object {
118156
"/path/to/project1/locales-1.json": "{

test/commands/infuse.test.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const MOCK_FILES = SFC_FILES.reduce((files, file) => {
2424
const meta = jsonMetaInfo.find(meta => meta.contentPath === file)
2525
return Object.assign(files, { [file]: meta.raw })
2626
}, {})
27+
const MOCK_IGNORE_FILES = '**/Login.vue'
2728

2829
let orgCwd // for process.cwd mock
2930

@@ -41,7 +42,8 @@ import * as utils from '../../src/utils'
4142
jest.mock('fs', () => ({
4243
...jest.requireActual('fs'),
4344
readFileSync: jest.fn(),
44-
writeFileSync: jest.fn()
45+
writeFileSync: jest.fn(),
46+
existsSync: jest.fn().mockImplementation(path => true)
4547
}))
4648
import fs from 'fs'
4749

@@ -270,3 +272,38 @@ test('bundle option', async () => {
270272

271273
expect(output).toMatchSnapshot()
272274
})
275+
276+
test('ignore option', async () => {
277+
// setup mocks
278+
const mockUtils = utils as jest.Mocked<typeof utils>
279+
mockUtils.resolve.mockImplementation((...paths) => paths[0])
280+
mockUtils.loadNamespaceDictionary.mockImplementation(async () => ({}))
281+
mockUtils.splitLocaleMessages.mockImplementation((messages) => ({ sfc: messages }))
282+
const writeFiles = {}
283+
const mockFS = fs as jest.Mocked<typeof fs>
284+
mockFS.readFileSync.mockImplementation(path => {
285+
if (MOCK_FILES[path as string]) {
286+
return MOCK_FILES[path as string]
287+
} else {
288+
return JSON.stringify(json)
289+
}
290+
})
291+
mockFS.writeFileSync.mockImplementation((path, data) => {
292+
writeFiles[path as string] = data.toString()
293+
})
294+
mockFS.readFileSync.mockImplementationOnce(path => MOCK_IGNORE_FILES);
295+
296+
// run
297+
const infuse = await import('../../src/commands/infuse')
298+
const cmd = yargs.command(infuse)
299+
const output = await new Promise(resolve => {
300+
cmd.parse(`infuse --target=${TARGET_PATH}/src --locales=${TARGET_PATH}/locales.json --ignorePath=./test/fixtures/.ignore-i18n`, () => {
301+
resolve(writeFiles)
302+
})
303+
})
304+
305+
// check
306+
for (const [key, value] of Object.entries(output)) {
307+
expect(value).toMatchSnapshot(key)
308+
}
309+
})

test/commands/squeeze.test.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as yargs from 'yargs'
2+
import * as fs from 'fs';
23
import jsonMetaInfo from '../fixtures/meta/json'
34
import external from '../fixtures/external'
45

@@ -16,6 +17,7 @@ const MOCK_FILES = SFC_FILES.reduce((files, file) => {
1617
const meta = jsonMetaInfo.find(meta => meta.contentPath === file)
1718
return Object.assign(files, { [file]: meta.raw })
1819
}, {})
20+
const MOCK_IGNORE_FILES = '**/Login.vue'
1921
let writeFiles = {} // for fs mock
2022
let orgCwd // for process.cwd mock
2123

@@ -39,7 +41,8 @@ jest.mock('fs', () => ({
3941
writeFileSync: jest.fn().mockImplementation((path, data) => {
4042
writeFiles[path as string] = data.toString()
4143
}),
42-
mkdirSync: jest.fn().mockImplementation(path => {})
44+
mkdirSync: jest.fn().mockImplementation(path => {}),
45+
existsSync: jest.fn().mockImplementation(path => true)
4346
}))
4447

4548
// -------------------
@@ -157,3 +160,22 @@ test('bundle options', async () => {
157160

158161
expect(output).toMatchSnapshot()
159162
})
163+
164+
test('ignore option', async () => {
165+
const mockUtils = utils as jest.Mocked<typeof utils>
166+
mockUtils.resolve.mockImplementation((...paths) => paths[0])
167+
mockUtils.loadNamespaceDictionary.mockImplementation(async () => ({}))
168+
mockUtils.getExternalLocaleMessages.mockImplementation(() => ({}))
169+
const mockFS = fs as jest.Mocked<typeof fs>
170+
mockFS.readFileSync.mockImplementationOnce(path => MOCK_IGNORE_FILES);
171+
172+
const squeeze = await import('../../src/commands/squeeze')
173+
const cmd = yargs.command(squeeze)
174+
const output = await new Promise(resolve => {
175+
cmd.parse(`squeeze --target=${TARGET_PATH}/src --output=${TARGET_PATH}/locales --ignorePath=./test/fixtures/.ignore-i18n`, () => {
176+
resolve(writeFiles)
177+
})
178+
})
179+
180+
expect(output).toMatchSnapshot()
181+
})

test/fixtures/.ignore-i18n

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
**/Login.vue

0 commit comments

Comments
 (0)