Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add manual list #76

Merged
merged 2 commits into from
Jul 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/vue-codemod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ async function main() {

// init global params
global.globalApi = []
global.manualList = []
global.scriptLine = 0
global.outputReport = {}

const resolvedPaths = globby.sync(files as string[])
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@
"globby": "^11.0.2",
"jscodeshift": "^0.11.0",
"lru-cache": "^6.0.0",
"prettier": "^2.3.1",
"readline-sync": "^1.4.10",
"source-map": "^0.6.1",
"table": "^6.7.1",
"vue-eslint-parser": "^7.6.0",
"yargs": "^16.2.0",
"prettier": "^2.3.1"
"yargs": "^16.2.0"
},
"devDependencies": {
"@types/debug": "^4.1.5",
Expand Down
10 changes: 10 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ export type GlobalApi = {
path: string
}

export type ManualList = {
path: string
position: string
name: string
suggest: string
website: string
}

declare global {
// Use to add global variables used by components to main.js
var globalApi: GlobalApi[]
var manualList: ManualList[]
var scriptLine: number
var outputReport: { [key: string]: number }
var subRules: { [key: string]: number }
}
Expand Down
91 changes: 85 additions & 6 deletions src/report.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,51 @@
import * as fs from 'fs'
import { table } from 'table'

export function pushManualList(
path: string,
node: any,
name: string,
suggest: string,
website: string
) {
let index = 0
const filepath = path.split('.')
if (filepath[filepath.length - 1] === 'vue') {
index = global.scriptLine - 1
} else {
index = 0
}
index = node?.value.loc?.start.line + index
let position: string = '[' + index + ',' + node?.value.loc?.start.column + ']'

const list = {
path: path,
position: position,
name: name,
suggest: suggest,
website: website
}
global.manualList.push(list)
}

export function VuePushManualList(
path: string,
node: any,
name: string,
suggest: string,
website: string
) {
let position: string =
'[' + node?.loc?.start.line + ',' + node?.loc?.start.column + ']'
const list = {
path: path,
position: position,
name: name,
suggest: suggest,
website: website
}
global.manualList.push(list)
}

export function getCntFunc(key: string, outputObj: { [key: string]: number }) {
if (!outputObj) {
Expand All @@ -7,9 +54,11 @@ export function getCntFunc(key: string, outputObj: { [key: string]: number }) {
if (!outputObj.hasOwnProperty(key)) {
outputObj[key] = 0
}

function cntFunc(quantity: number = 1) {
outputObj[key] += quantity
}

return cntFunc
}

Expand All @@ -20,9 +69,11 @@ export function formatterOutput(processFilePath: string[], formatter: string) {
(sum, key) => sum + global.outputReport[key],
0
)
const totalDetected = totalChanged
const totalDetected = totalChanged + global.manualList.length
const transRate =
totalDetected == totalChanged ? 100 : (100 * totalChanged) / totalDetected
totalDetected == totalChanged
? 100
: ((100 * totalChanged) / totalDetected).toFixed(2)

console.log(`--------------------------------------------------`)
console.log(`Processed file:\n${processFilePathList}`)
Expand Down Expand Up @@ -54,9 +105,21 @@ export function formatterOutput(processFilePath: string[], formatter: string) {
console.log(global.outputReport)
}

let tableStr: string
let tableOutput: any[][] = [['Rule Names', 'Count']]
for (let i in global.outputReport) {
tableOutput.push([i, global.outputReport[i]])
}
tableStr = table(tableOutput, {
drawHorizontalLine: (lineIndex, rowCount) => {
return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount
},
columns: [{ alignment: 'left' }, { alignment: 'center' }]
})

if (formatter === 'table') {
console.log('The transformation stats: \n')
console.table(global.outputReport)
console.log(tableStr)
}

if (formatter === 'log') {
Expand All @@ -65,17 +128,26 @@ export function formatterOutput(processFilePath: string[], formatter: string) {
processFilePath,
totalDetected,
totalChanged,
transRate
transRate,
tableStr
)
}

console.log('The list that you need to migrate your codes mannually')
let index = 1
global.manualList.forEach(manual => {
console.log('index:', index++)
console.log(manual)
})
}

export function logOutput(
processFilePathList: string,
processFilePath: string[],
totalDetected: number,
totalChanged: number,
transRate: number
transRate: string | number,
tableStr: string
) {
let options = {
flags: 'w', //
Expand All @@ -92,5 +164,12 @@ export function logOutput(
logger.log(`${totalDetected} places`, `need to be transformed`)
logger.log(`${totalChanged} places`, `was transformed`)
logger.log(`The transformation rate is ${transRate}%`)
logger.log('The transformation stats: \n', global.outputReport)
logger.log('The transformation stats: \n')
logger.log(tableStr)
logger.log('The list that you need to migrate your codes mannually')
let index = 1
global.manualList.forEach(manual => {
logger.log('index:', index++)
logger.log(manual)
})
}
2 changes: 2 additions & 0 deletions src/runTransformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ export default function runTransformation(
return source
}

global.scriptLine = descriptor.script.loc.start.line

lang = descriptor.script.lang || 'js'
fileInfo.source = descriptor.script.content
}
Expand Down
10 changes: 9 additions & 1 deletion transformations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,15 @@ const transformationMap: {
'remove-extraneous-import': require('./remove-extraneous-import'),

'router4-onready-to-isready': require('./router/router4-onready-to-isready'),
'router-update-addRoute': require('./router/router-update-addRoute')
'router-update-addRoute': require('./router/router-update-addRoute'),

// manual (must be used at the end of list)
'manual-remove-Vue': require('./manual/manual-remove-Vue'),
'manual-remove-VueRouter': require('./manual/manual-remove-VueRouter'),
'manual-remove-on-off-once': require('./manual/manual-remove-on-off-once'),
'manual-remove-router-star': require('./manual/manual-remove-router-star'),
'manual-remove-config-keycodes': require('./manual/manual-remove-config-keycodes'),
'manual-remove-filter': require('./manual/manual-remove-filter')
}

export const excludedTransformations = [
Expand Down
29 changes: 29 additions & 0 deletions transformations/manual/manual-remove-Vue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import wrap from '../../src/wrapAstTransformation'
import type { ASTTransformation } from '../../src/wrapAstTransformation'
import { pushManualList } from '../../src/report'

export const transformAST: ASTTransformation = context => {
const { root, j, filename } = context

const rootNodes: any = root
.find(j.MemberExpression, {
object: {
name: 'Vue'
}
})
.filter((node: any) => node?.value.property?.name !== 'createApp')
if (rootNodes) {
rootNodes.forEach((node: any) => {
const path = filename
const name = 'remove Vue(global api)'
const suggest =
"The rule of thumb is any APIs that globally mutate Vue's behavior are now moved to the app instance. "
const website =
'https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp'
pushManualList(path, node, name, suggest, website)
})
}
}

export default wrap(transformAST)
export const parser = 'babylon'
25 changes: 25 additions & 0 deletions transformations/manual/manual-remove-VueRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import wrap from '../../src/wrapAstTransformation'
import type { ASTTransformation } from '../../src/wrapAstTransformation'
import { pushManualList } from '../../src/report'

export const transformAST: ASTTransformation = context => {
const { root, j, filename } = context

const rootNodes: any = root.find(j.Identifier, {
name: 'VueRouter'
})
if (rootNodes) {
rootNodes.forEach((node: any) => {
const path = filename
const name = 'remove VueRouter'
const suggest =
"The rule of thumb is any APIs that globally mutate VueRouter's behavior are now moved to the app instance. "
const website =
'https://next.router.vuejs.org/guide/migration/index.html#moved-the-base-option'
pushManualList(path, node, name, suggest, website)
})
}
}

export default wrap(transformAST)
export const parser = 'babylon'
34 changes: 34 additions & 0 deletions transformations/manual/manual-remove-config-keycodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import wrap from '../../src/wrapAstTransformation'
import type { ASTTransformation } from '../../src/wrapAstTransformation'
import { pushManualList } from '../../src/report'

export const transformAST: ASTTransformation = context => {
const { root, j, filename } = context

const rootNodes: any = root.find(j.MemberExpression, {
object: {
object: {
name: 'Vue'
},
property: {
name: 'config'
}
},
property: {
name: 'KeyCodes'
}
})
if (rootNodes) {
rootNodes.forEach((node: any) => {
const path = filename
const name = 'remove keycodes'
const suggest = 'config.keyCodes is no longer supported '
const website =
'https://v3.vuejs.org/guide/migration/keycode-modifiers.html'
pushManualList(path, node, name, suggest, website)
})
}
}

export default wrap(transformAST)
export const parser = 'babylon'
47 changes: 47 additions & 0 deletions transformations/manual/manual-remove-filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import wrap from '../../src/wrapAstTransformation'
import type { ASTTransformation } from '../../src/wrapAstTransformation'
import { pushManualList } from '../../src/report'

export const transformAST: ASTTransformation = context => {
const { root, j, filename } = context

const rootNodes: any = root
.find(j.Identifier, {
name: 'filters'
})
.filter((node: any) => node?.value.property?.name !== 'createApp')
if (rootNodes) {
rootNodes.forEach((node: any) => {
const path = filename
const name = 'remove filters'
const suggest =
'Filters are removed from Vue 3.0 and no longer supported. '
const website =
'https://v3.vuejs.org/guide/migration/filters.html#overview'
pushManualList(path, node, name, suggest, website)
})
}

const rootNodes2: any = root.find(j.MemberExpression, {
object: {
name: 'Vue'
},
property: {
name: 'filter'
}
})
if (rootNodes2) {
rootNodes2.forEach((node: any) => {
const path = filename
const name = 'remove global filters'
const suggest =
'Instead, you can make your global filters available to all components through globalProperties: '
const website =
'https://v3.vuejs.org/guide/migration/filters.html#global-filters'
pushManualList(path, node, name, suggest, website)
})
}
}

export default wrap(transformAST)
export const parser = 'babylon'
30 changes: 30 additions & 0 deletions transformations/manual/manual-remove-on-off-once.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import wrap from '../../src/wrapAstTransformation'
import type { ASTTransformation } from '../../src/wrapAstTransformation'
import { pushManualList } from '../../src/report'

export const transformAST: ASTTransformation = context => {
const { root, j, filename } = context

const rootNodes: any = root
.find(j.Identifier)
.filter(
node =>
node.value.name === '$on' ||
node.value.name === '$once' ||
node.value.name === '$off'
)
if (rootNodes) {
rootNodes.forEach((node: any) => {
const path = filename
const name = 'remove $on $once and $off'
const suggest =
'$on, $off and $once instance methods are removed. Component instances no longer implement the event emitter interface. '
const website =
'https://v3.vuejs.org/guide/migration/events-api.html#overview'
pushManualList(path, node, name, suggest, website)
})
}
}

export default wrap(transformAST)
export const parser = 'babylon'
Loading