Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
boxsnake committed Aug 23, 2022
2 parents 7d46f32 + 5d33ef1 commit 6c5f6fe
Show file tree
Hide file tree
Showing 11 changed files with 563 additions and 405 deletions.
24 changes: 20 additions & 4 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
env:
commonjs: true
es2021: true
node: true
extends:
- standard
- 'eslint:recommended'
- 'plugin:@typescript-eslint/recommended'
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: latest
rules: {}
ecmaVersion: 12
sourceType: module
plugins:
- '@typescript-eslint'
rules:
indent:
- error
- 4
linebreak-style:
- error
- unix
quotes:
- error
- single
semi:
- error
- always
80 changes: 40 additions & 40 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
import UtilArgs from './util/args.js'
import UtilPath from './util/path.js'
import UtilFs from './util/fs.js'
import UtilCompare from './util/compare.js'
import UtilQueue from './util/queue.js'
import UtilArgs from './util/args.js';
import UtilPath from './util/path.js';
import UtilFs from './util/fs.js';
import UtilCompare from './util/compare.js';
import UtilQueue from './util/queue.js';

const argv = UtilArgs.getArgv();

(async function () {
// get summary
const lhsQueue = UtilQueue.createQueue({ concurrency: argv.n })
const lhsFilePattern = UtilPath.resolve(argv.l, '**/*')
const lhsFilePaths = await UtilPath.glob(lhsFilePattern)
const lhsFileSummary = await UtilCompare.getFileSummary(argv.l, lhsFilePaths, lhsQueue)
const rhsQueue = UtilQueue.createQueue({ concurrency: argv.m })
const rhsFilePattern = UtilPath.resolve(argv.r, '**/*')
const rhsFilePaths = await UtilPath.glob(rhsFilePattern)
const rhsFileSummary = await UtilCompare.getFileSummary(argv.r, rhsFilePaths, rhsQueue)

// save file summary
const lhsFileSummaryOutputPath = UtilPath.resolve(argv.o, './file-summary-lhs.json')
UtilFs.writeJson(lhsFileSummaryOutputPath, lhsFileSummary)
const rhsFileSummaryOutputPath = UtilPath.resolve(argv.o, './file-summary-rhs.json')
UtilFs.writeJson(rhsFileSummaryOutputPath, rhsFileSummary)

// compare summary
const compareSummary = UtilCompare.getCompareSummary(lhsFileSummary, rhsFileSummary)

// revalidate compare summary
const compareRevalidateQueueLhs = UtilQueue.createQueue({ concurrency: argv.n })
const compareRevalidateQueueRhs = UtilQueue.createQueue({ concurrency: argv.m })
const compareRevalidateSummary = await UtilCompare.revalidateCompareSummary(compareSummary, compareRevalidateQueueLhs, compareRevalidateQueueRhs)

// save compare summary
const compareSummaryOutputPath = UtilPath.resolve(argv.o, './compare-summary.json')
UtilFs.writeJson(compareSummaryOutputPath, compareRevalidateSummary)

// compare report
const compareReport = UtilCompare.getCompareReport(compareRevalidateSummary)

// save compare report
const compareReportOutputPath = UtilPath.resolve(argv.o, './compare-report.html')
UtilFs.writeFile(compareReportOutputPath, compareReport)
})()
// get summary
const lhsQueue = UtilQueue.createQueue({ concurrency: argv.n });
const lhsFilePattern = UtilPath.resolve(argv.l, '**/*');
const lhsFilePaths = await UtilPath.glob(lhsFilePattern);
const lhsFileSummary = await UtilCompare.getFileSummary(argv.l, lhsFilePaths, lhsQueue);
const rhsQueue = UtilQueue.createQueue({ concurrency: argv.m });
const rhsFilePattern = UtilPath.resolve(argv.r, '**/*');
const rhsFilePaths = await UtilPath.glob(rhsFilePattern);
const rhsFileSummary = await UtilCompare.getFileSummary(argv.r, rhsFilePaths, rhsQueue);

// save file summary
const lhsFileSummaryOutputPath = UtilPath.resolve(argv.o, './file-summary-lhs.json');
UtilFs.writeJson(lhsFileSummaryOutputPath, lhsFileSummary);
const rhsFileSummaryOutputPath = UtilPath.resolve(argv.o, './file-summary-rhs.json');
UtilFs.writeJson(rhsFileSummaryOutputPath, rhsFileSummary);

// compare summary
const compareSummary = UtilCompare.getCompareSummary(lhsFileSummary, rhsFileSummary);

// revalidate compare summary
const compareRevalidateQueueLhs = UtilQueue.createQueue({ concurrency: argv.n });
const compareRevalidateQueueRhs = UtilQueue.createQueue({ concurrency: argv.m });
const compareRevalidateSummary = await UtilCompare.revalidateCompareSummary(compareSummary, compareRevalidateQueueLhs, compareRevalidateQueueRhs);

// save compare summary
const compareSummaryOutputPath = UtilPath.resolve(argv.o, './compare-summary.json');
UtilFs.writeJson(compareSummaryOutputPath, compareRevalidateSummary);

// compare report
const compareReport = UtilCompare.getCompareReport(compareRevalidateSummary);

// save compare report
const compareReportOutputPath = UtilPath.resolve(argv.o, './compare-report.html');
UtilFs.writeFile(compareReportOutputPath, compareReport);
})();
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@
"main": "index.js",
"type": "module",
"license": "MIT",
"private": true,
"private": false,
"scripts": {
"commit": "cz",
"compare": "node index.js",
"lint": "eslint --ext .js .",
"lint": "eslint --ext .js,.ts .",
"release": "semantic-release"
},
"description": "Compare file differences between two directories and generate report",
"keywords": [
"backend",
"cli",
"kongying-cli-plugin",
"kongying-cmd-compare"
],
"dependencies": {
"fs-extra": "^10.0.1",
"globby": "^13.1.1",
Expand All @@ -21,6 +28,8 @@
"yargs": "^17.3.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"commitizen": "^4.2.4",
"cz-conventional-changelog": "3.3.0",
"eslint": "^7.32.0",
Expand All @@ -44,5 +53,8 @@
"@semantic-release/release-notes-generator",
"@semantic-release/github"
]
},
"publishConfig": {
"access": "public"
}
}
214 changes: 214 additions & 0 deletions template/compare.summary.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>文件比对结果</title>
<link rel="stylesheet" type="text/css" href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.6/theme-chalk/index.css">
<style type="text/css">
#app {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: .7rem;
}
.drawer-wrapper {
padding: 0 1rem;
}
.form-component {
width: 100%;
}
.action-wrapper {
flex: none;
margin-bottom: .7rem;
}
.table-wrapper {
position: relative;
flex: auto;
}
.table-component {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<div id="app">
<!-- Popups -->
<el-drawer
:visible.sync="state.filterDrawerVisible"
title="过滤筛选"
direction="rtl"
size="40%"
:wrapperClosable="false"
append-to-body
modal-append-to-body>
<el-form
class="drawer-wrapper"
size="mini"
label-position="left"
label-width="100px">
<el-form-item label="差异类型">
<el-select
v-model="state.filterTypes"
class="form-component"
multiple>
<el-option
v-for="(item, i) in plugins.typeOptions"
:key="i"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
</el-drawer>

<div class="action-wrapper">
<el-button
size="mini"
type="info"
icon="el-icon-search"
circle
@click="popupFilterDrawer">
</el-button>
</div>

<div class="table-wrapper">
<el-table
class="table-component"
:data="compareDataFiltered"
size="mini"
border
height="auto">
<el-empty slot="empty" description="暂无数据"></el-empty>

<el-table-column
label="数字签名"
sortable
sort-by="hash">
</el-table-column>
<el-table-column
label="左侧文件名"
sortable
sort-by="lhs.0.filename">
<template slot-scope="scope">
<template v-if="scope.row.lhs && scope.row.lhs.length > 0">
<div v-for="(item, i) in scope.row.lhs" :key="i">
{{item.filename}}
</div>
</template>
</template>
</el-table-column>
<el-table-column
width="100"
align="center"
sortable
sort-by="type">
<template slot-scope="scope">
<el-button
size="mini"
:type="scope.row.typeOption.type"
:icon="scope.row.typeOption.icon"
circle>
</el-button>
</template>
</el-table-column>
<el-table-column
label="右侧侧文件名"
sortable
sort-by="rhs.0.filename">
<template slot-scope="scope">
<template v-if="scope.row.rhs && scope.row.rhs.length > 0">
<div v-for="(item, i) in scope.row.rhs" :key="i">
{{item.filename}}
</div>
</template>
</template>
</el-table-column>
</el-table>
</div>
</div>

<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.6/index.js"></script>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data() {
return {
compareData: {{__ summary __}},
state: {
filterDrawerVisible: false,
filterTypes: ['add', 'remove', 'same'],
},
plugins: {
typeOptions: [
{
label: '新增',
value: 'add',
type: 'success',
icon: 'el-icon-star-off'
},
{
label: '删除',
value: 'remove',
type: 'danger',
icon: 'el-icon-delete'
},
{
label: '相同',
value: 'same',
type: 'info',
icon: 'el-icon-more-outline'
}
]
}
}
},
computed: {
compareDataFiltered() {
let list = this.compareData || [];
list = this.applyTypeMapper(list);
list = this.applyTypeFilter(list);

return list;
}
},
methods: {
// popups / popdowns
popupFilterDrawer() {
this.state.filterDrawerVisible = true;
},
// Mappers
applyTypeMapper(list = []) {
let typeOptionMap = _.keyBy(this.plugins.typeOptions, 'value');
let listMapped = _.map(list, v => {
let typeKey = v.type || '';
let typeOption = typeOptionMap[typeKey] || {};

v.typeOption = typeOption;

return v;
});

return listMapped;
},
applyTypeFilter(list = []) {
let listFiltered = _.filter(list, v => this.state.filterTypes.indexOf(v.type) !== -1);

return listFiltered;
}
}
})
</script>
</body>
</html>
Loading

0 comments on commit 6c5f6fe

Please sign in to comment.