Skip to content

Commit b83f1fd

Browse files
authored
feat: print transformed files for each rule (#81)
1 parent 3fb68f3 commit b83f1fd

File tree

3 files changed

+197
-35
lines changed

3 files changed

+197
-35
lines changed

bin/vue-codemod.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import { transform as packageTransform } from '../src/packageTransformation'
1919

2020
import type { TransformationModule } from '../src/runTransformation'
2121
import { formatterOutput } from '../src/report'
22+
import { ruleDescripition } from '../src/ruleDescription'
2223

2324
const debug = createDebug('vue-codemod:cli')
24-
const log = console.log.bind(console)
2525
let processFilePath: string[] = []
2626

2727
const {
@@ -52,7 +52,8 @@ const {
5252
alias: 'f',
5353
type: 'string',
5454
describe: 'Specify an output report formatter',
55-
default: 'detail'
55+
default: 'table',
56+
choices: ['table', 'detail', 'log']
5657
})
5758
.example([
5859
[
@@ -68,6 +69,18 @@ const {
6869
.alias('h', 'help')
6970
.alias('v', 'version').argv
7071

72+
let logger: Console = console
73+
if (formatter === 'log') {
74+
let options = {
75+
flags: 'w', //
76+
encoding: 'utf8' // utf8编码
77+
}
78+
79+
let stdout = fs.createWriteStream('./vue_codemod.log', options)
80+
81+
logger = new console.Console(stdout)
82+
}
83+
7184
// TODO: port the `Runner` interface of jscodeshift
7285
async function main() {
7386
if (
@@ -108,7 +121,7 @@ async function main() {
108121
)
109122
if (packageTransform()) {
110123
processFilePath.push('package.json')
111-
global.outputReport['package.json'] = 1
124+
global.outputReport['package transformation'] = 1
112125
}
113126
}
114127

@@ -135,10 +148,11 @@ async function main() {
135148
}
136149
if (packageTransform()) {
137150
processFilePath.push('package.json')
151+
global.outputReport['package transformation'] = 1
138152
}
139153
}
140154

141-
formatterOutput(processFilePath, formatter)
155+
formatterOutput(processFilePath, formatter, logger)
142156
}
143157
/**
144158
* process files by Transformation
@@ -151,8 +165,10 @@ function processTransformation(
151165
transformationName: string,
152166
transformationModule: TransformationModule
153167
) {
154-
log(`Processing use ${transformationName} transformation`)
155-
168+
console.time(`\x1B[0mProcessing use \x1B[1m${transformationName} transformation\x1B[0m\x1B[33m`)
169+
if (formatter === 'log')
170+
logger.time(`Processing use ${transformationName} transformation`)
171+
let ruleProcessFile: string[] = []
156172
const extensions = ['.js', '.ts', '.vue', '.jsx', '.tsx']
157173
for (const p of resolvedPaths) {
158174
debug(`Processing ${p}…`)
@@ -180,6 +196,7 @@ function processTransformation(
180196

181197
if (retainedSource != result) {
182198
fs.writeFileSync(p, result)
199+
ruleProcessFile.push(p)
183200
if (processFilePath.indexOf(p) == -1) {
184201
processFilePath.push(p)
185202
} else {
@@ -190,6 +207,23 @@ function processTransformation(
190207
console.error(e)
191208
}
192209
}
210+
if (ruleProcessFile.length) {
211+
console.timeEnd(`\x1B[0mProcessing use \x1B[1m${transformationName} transformation\x1B[0m\x1B[33m`)
212+
if (formatter === 'log')
213+
logger.timeEnd(`Processing use ${transformationName} transformation`)
214+
if (
215+
ruleDescripition.hasOwnProperty(transformationName) &&
216+
(formatter === 'detail' || formatter === 'log')
217+
) {
218+
let ruleOutput: { [key: string]: any } = {}
219+
ruleOutput.rule_name = transformationName
220+
// @ts-ignore
221+
ruleOutput.website = ruleDescripition[transformationName].description
222+
ruleOutput.transformed_files = ruleProcessFile
223+
console.log('\x1B[0m', ruleOutput)
224+
if (formatter === 'log') logger.log(ruleOutput)
225+
}
226+
}
193227
}
194228

195229
main().catch(err => {

src/report.ts

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as fs from 'fs'
21
import { table } from 'table'
32

43
export function pushManualList(
@@ -62,7 +61,11 @@ export function getCntFunc(key: string, outputObj: { [key: string]: number }) {
6261
return cntFunc
6362
}
6463

65-
export function formatterOutput(processFilePath: string[], formatter: string) {
64+
export function formatterOutput(
65+
processFilePath: string[],
66+
formatter: string,
67+
logger: Console
68+
) {
6669
// normal output
6770
const processFilePathList = processFilePath.join('\n')
6871
const totalChanged = Object.keys(global.outputReport).reduce(
@@ -75,21 +78,21 @@ export function formatterOutput(processFilePath: string[], formatter: string) {
7578
? 100
7679
: ((100 * totalChanged) / totalDetected).toFixed(2)
7780

78-
console.log(`--------------------------------------------------`)
81+
console.log(`\x1B[0m--------------------------------------------------`)
7982
console.log(`Processed file:\n${processFilePathList}`)
8083
console.log(`Processed ${processFilePath.length} files`)
8184

8285
console.log(
83-
'\x1B[44;37;4m%s\x1B[0m',
86+
'\x1B[31;4m%s\x1B[0m',
8487
`${totalDetected} places`,
8588
`need to be transformed`
8689
)
8790
console.log(
88-
'\x1B[44;37;4m%s\x1B[0m',
91+
'\x1B[32;4m%s\x1B[0m',
8992
`${totalChanged} places`,
9093
`was transformed`
9194
)
92-
console.log(`The transformation rate is \x1B[44;37;4m${transRate}%\x1B[0m`)
95+
console.log(`The transformation rate is \x1B[32;4m${transRate}%\x1B[0m`)
9396

9497
if (formatter === 'all') {
9598
console.log('The transformation stats: \n')
@@ -129,16 +132,19 @@ export function formatterOutput(processFilePath: string[], formatter: string) {
129132
totalDetected,
130133
totalChanged,
131134
transRate,
132-
tableStr
135+
tableStr,
136+
logger
133137
)
134138
}
135139

136-
console.log('The list that you need to migrate your codes mannually')
137-
let index = 1
138-
global.manualList.forEach(manual => {
139-
console.log('index:', index++)
140-
console.log(manual)
141-
})
140+
if (global.manualList.length) {
141+
console.log('The list that you need to migrate your codes mannually: ')
142+
let index = 1
143+
global.manualList.forEach(manual => {
144+
console.log('index:', index++)
145+
console.log(manual)
146+
})
147+
}
142148
}
143149

144150
export function logOutput(
@@ -147,17 +153,9 @@ export function logOutput(
147153
totalDetected: number,
148154
totalChanged: number,
149155
transRate: string | number,
150-
tableStr: string
156+
tableStr: string,
157+
logger: Console
151158
) {
152-
let options = {
153-
flags: 'w', //
154-
encoding: 'utf8' // utf8编码
155-
}
156-
157-
let stdout = fs.createWriteStream('./vue_codemod.log', options)
158-
159-
let logger = new console.Console(stdout)
160-
161159
logger.log(`--------------------------------------------------`)
162160
logger.log(`Processed file:\n${processFilePathList}\n`)
163161
logger.log(`Processed ${processFilePath.length} files`)
@@ -166,10 +164,12 @@ export function logOutput(
166164
logger.log(`The transformation rate is ${transRate}%`)
167165
logger.log('The transformation stats: \n')
168166
logger.log(tableStr)
169-
logger.log('The list that you need to migrate your codes mannually')
170-
let index = 1
171-
global.manualList.forEach(manual => {
172-
logger.log('index:', index++)
173-
logger.log(manual)
174-
})
167+
if (global.manualList.length) {
168+
logger.log('The list that you need to migrate your codes mannually')
169+
let index = 1
170+
global.manualList.forEach(manual => {
171+
logger.log('index:', index++)
172+
logger.log(manual)
173+
})
174+
}
175175
}

src/ruleDescription.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
export let ruleDescripition = {
2+
'new-component-api': {
3+
description:
4+
'https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp'
5+
},
6+
'vue-class-component-v8': {
7+
description: 'https://github.com/vuejs/vue-class-component/issues/406'
8+
},
9+
'new-global-api': {
10+
description:
11+
'https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp'
12+
},
13+
'vue-router-v4': {
14+
description: [
15+
'https://next.router.vuejs.org/guide/migration/index.html#new-router-becomes-createrouter',
16+
'https://next.router.vuejs.org/guide/migration/index.html#new-history-option-to-replace-mode',
17+
'https://next.router.vuejs.org/guide/migration/index.html#replaced-onready-with-isready'
18+
]
19+
},
20+
'vuex-v4': {
21+
description: 'new Store (...) => createStore (...)'
22+
},
23+
'define-component': {
24+
description: 'Vue.extend (...) => defineComponent (...)'
25+
},
26+
'new-vue-to-create-app': {
27+
description:
28+
'https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp'
29+
},
30+
'scoped-slots-to-slots': {
31+
description:
32+
'https://v3.vuejs.org/guide/migration/slots-unification.html#overview'
33+
},
34+
'new-directive-api': {
35+
description:
36+
'https://v3.vuejs.org/guide/migration/custom-directives.html#overview'
37+
},
38+
'remove-vue-set-and-delete': {
39+
description:
40+
'https://v3.vuejs.org/guide/migration/introduction.html#removed-apis'
41+
},
42+
'rename-lifecycle': {
43+
description:
44+
'https://v3.vuejs.org/guide/migration/introduction.html#other-minor-changes'
45+
},
46+
'add-emit-declaration': {
47+
description:
48+
'https://v3.vuejs.org/guide/migration/emits-option.html#overview'
49+
},
50+
'tree-shaking': {
51+
description:
52+
'https://v3.vuejs.org/guide/migration/global-api-treeshaking.html'
53+
},
54+
'v-model': {
55+
description: 'https://v3.vuejs.org/guide/migration/v-model.html#overview'
56+
},
57+
'render-to-resolveComponent': {
58+
description:
59+
'https://v3.vuejs.org/guide/migration/render-function-api.html#registered-component'
60+
},
61+
'remove-contextual-h-from-render': {
62+
description:
63+
'https://v3.vuejs.org/guide/migration/render-function-api.html#render-function-argument'
64+
},
65+
'remove-production-tip': {
66+
description:
67+
'https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp'
68+
},
69+
'remove-trivial-root': {
70+
description: 'createApp ({ render: () => h (App) }) => createApp (App)'
71+
},
72+
'vue-as-namespace-import': {
73+
description: 'import Vue from "vue" => import * as Vue from "vue"'
74+
},
75+
'slot-attribute': {
76+
description:
77+
'https://vuejs.org/v2/guide/components-slots.html#Deprecated-Syntax'
78+
},
79+
'slot-default': {
80+
description:
81+
'If component tag did not contain a <slot> element, any content provided between its opening and closing tag would be discarded.'
82+
},
83+
'slot-scope-attribute': {
84+
description:
85+
'https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots-with-the-slot-scope-Attribute'
86+
},
87+
'v-for-template-key': {
88+
description:
89+
'https://v3.vuejs.org/guide/migration/key-attribute.html#overview'
90+
},
91+
'v-else-if-key': {
92+
description:
93+
'https://v3.vuejs.org/guide/migration/key-attribute.html#overview'
94+
},
95+
'transition-group-root': {
96+
description:
97+
'https://v3.vuejs.org/guide/migration/transition-group.html#overview'
98+
},
99+
'v-bind-order-sensitive': {
100+
description: 'https://v3.vuejs.org/guide/migration/v-bind.html#overview'
101+
},
102+
'v-for-v-if-precedence-changed': {
103+
description: 'https://v3.vuejs.org/guide/migration/v-if-v-for.html#overview'
104+
},
105+
'remove-listeners': {
106+
description:
107+
'https://v3.vuejs.org/guide/migration/listeners-removed.html#overview'
108+
},
109+
'v-bind-sync': {
110+
description: 'https://v3.vuejs.org/guide/migration/v-model.html#overview'
111+
},
112+
'remove-v-on-native': {
113+
description:
114+
'https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html#overview'
115+
},
116+
'router-link-event-tag': {
117+
description:
118+
'https://next.router.vuejs.org/guide/migration/index.html#removal-of-event-and-tag-props-in-router-link'
119+
},
120+
'router-link-exact': {
121+
description:
122+
'https://next.router.vuejs.org/guide/migration/index.html#removal-of-the-exact-prop-in-router-link'
123+
},
124+
'router-view-keep-alive-transition': {
125+
description:
126+
'https://next.router.vuejs.org/guide/migration/index.html#router-view-keep-alive-and-transition'
127+
}
128+
}

0 commit comments

Comments
 (0)