Commit 02f51b2f authored by 薛智杰's avatar 薛智杰

Initial commit

parents
Pipeline #1960 canceled with stages
# 🎨 editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
\ No newline at end of file
{
"extends": "./node_modules/mwts/",
"ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"],
"env": {
"jest": true
}
}
logs/
npm-debug.log
yarn-error.log
node_modules/
package-lock.json
yarn.lock
coverage/
dist/
.idea/
run/
.DS_Store
*.sw*
*.un~
.tsbuildinfo
.tsbuildinfo.*
module.exports = {
...require('mwts/.prettierrc.json')
}
{
"cSpell.words": ["midwayjs"]
}
# my_midway_project
## QuickStart
<!-- add docs here for user -->
see [midway docs][midway] for more detail.
### Development
```bash
$ npm i
$ npm run dev
$ open http://localhost:7001/
```
### Deploy
```bash
$ npm start
```
### npm scripts
- Use `npm run lint` to check code style.
- Use `npm test` to run unit test.
[midway]: https://midwayjs.org
# my_midway_project
## 快速入门
<!-- 在此次添加使用文档 -->
如需进一步了解,参见 [midway 文档][midway]
### 本地开发
```bash
$ npm i
$ npm run dev
$ open http://localhost:7001/
```
### 部署
```bash
$ npm start
```
### 内置指令
- 使用 `npm run lint` 来做代码风格检查。
- 使用 `npm test` 来执行单元测试。
[midway]: https://midwayjs.org
const { Bootstrap } = require('@midwayjs/bootstrap');
Bootstrap.run();
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['<rootDir>/test/fixtures'],
coveragePathIgnorePatterns: ['<rootDir>/test/'],
};
\ No newline at end of file
{
"name": "my-midway-project",
"version": "1.0.0",
"description": "",
"private": true,
"dependencies": {
"@midwayjs/axios": "^3.11.6",
"@midwayjs/bootstrap": "^3.0.0",
"@midwayjs/core": "^3.0.0",
"@midwayjs/decorator": "^3.0.0",
"@midwayjs/info": "^3.0.0",
"@midwayjs/koa": "^3.0.0",
"@midwayjs/logger": "^2.14.0",
"@midwayjs/validate": "^3.0.0"
},
"devDependencies": {
"@midwayjs/cli": "^2.0.0",
"@midwayjs/mock": "^3.0.0",
"@types/jest": "^29.2.0",
"@types/koa": "^2.13.4",
"@types/node": "14",
"cross-env": "^6.0.0",
"jest": "^29.2.2",
"mwts": "^1.0.5",
"ts-jest": "^29.0.3",
"typescript": "~4.8.0"
},
"engines": {
"node": ">=12.0.0"
},
"scripts": {
"start": "NODE_ENV=production node ./bootstrap.js",
"dev": "cross-env NODE_ENV=local midway-bin dev --ts",
"test": "midway-bin test --ts",
"cov": "midway-bin cov --ts",
"lint": "mwts check",
"lint:fix": "mwts fix",
"ci": "npm run cov",
"build": "midway-bin build -c"
},
"midway-bin-clean": [
".vscode/.tsbuildinfo",
"dist"
],
"repository": {
"type": "git",
"url": ""
},
"author": "anonymous",
"license": "MIT"
}
import { MidwayConfig } from '@midwayjs/core';
export default {
// use for cookie sign key, should change to your own and keep security
keys: '1683278121839_1923',
koa: {
port: 7001,
},
gitlab: {
host: 'http://git.quantgroup.cn',
apiToken: 'mKtyVQGpSa1FpQBWRxie',
},
} as MidwayConfig;
import { MidwayConfig } from '@midwayjs/core';
export default {
koa: {
port: null,
},
} as MidwayConfig;
import { Configuration, App } from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import * as validate from '@midwayjs/validate';
import * as info from '@midwayjs/info';
import * as axios from '@midwayjs/axios';
import { join } from 'path';
// import { DefaultErrorFilter } from './filter/default.filter';
// import { NotFoundFilter } from './filter/notfound.filter';
import { ReportMiddleware } from './middleware/report.middleware';
@Configuration({
imports: [
koa,
validate,
{
component: info,
enabledEnvironment: ['local'],
},
axios,
],
importConfigs: [join(__dirname, './config')],
})
export class ContainerLifeCycle {
@App()
app: koa.Application;
async onReady() {
// add middleware
this.app.useMiddleware([ReportMiddleware]);
// add filter
// this.app.useFilter([NotFoundFilter, DefaultErrorFilter]);
}
}
import { Inject, Controller, Get, Query } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { UserService } from '../service/user.service';
@Controller('/api')
export class APIController {
@Inject()
ctx: Context;
@Inject()
userService: UserService;
@Get('/get_user')
async getUser(@Query('uid') uid) {
const user = await this.userService.getUser({ uid });
return { success: true, message: 'OK', data: user };
}
}
import { Controller, Get, Inject } from '@midwayjs/core';
import { GitlabService } from '../service/gitlab.service';
@Controller('/')
export class HomeController {
@Get('/')
async home(): Promise<string> {
return 'Hello Midwayjs!';
}
@Inject()
gitlabService: GitlabService;
@Get('/code')
async codeStat() {
const res = await this.gitlabService.getCodeStat();
return res;
}
}
import { Catch } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
@Catch()
export class DefaultErrorFilter {
async catch(err: Error, ctx: Context) {
// 所有的未分类错误会到这里
return {
success: false,
message: err.message,
};
}
}
import { Catch, httpError, MidwayHttpError } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
@Catch(httpError.NotFoundError)
export class NotFoundFilter {
async catch(err: MidwayHttpError, ctx: Context) {
// 404 错误会到这里
ctx.redirect('/404.html');
}
}
/**
* @description User-Service parameters
*/
export interface IUserOptions {
uid: number;
}
import { Middleware, IMiddleware } from '@midwayjs/core';
import { NextFunction, Context } from '@midwayjs/koa';
@Middleware()
export class ReportMiddleware implements IMiddleware<Context, NextFunction> {
resolve() {
return async (ctx: Context, next: NextFunction) => {
// 控制器前执行的逻辑
const startTime = Date.now();
// 执行下一个 Web 中间件,最后执行到控制器
// 这里可以拿到下一个中间件或者控制器的返回值
const result = await next();
// 控制器之后执行的逻辑
ctx.logger.info(
`Report in "src/middleware/report.middleware.ts", rt = ${
Date.now() - startTime
}ms`
);
// 返回给上一个中间件的结果
return result;
};
}
static getName(): string {
return 'report';
}
}
import { HttpService } from '@midwayjs/axios';
import { Config, ILogger, Inject, Provide } from '@midwayjs/core';
@Provide()
export class GitlabService {
@Inject()
httpService: HttpService;
@Config('gitlab')
gitlabConfig;
@Inject()
logger: ILogger;
// 获取用户所有组
async getGroups() {
const { host, apiToken } = this.gitlabConfig;
const url = `${host}/api/v4/groups?private_token=${apiToken}&per_page=100`;
const { data } = await this.httpService.get(url);
return data;
}
// 获取组下所有项目
async getProjects(groupId) {
const { host, apiToken } = this.gitlabConfig;
const url = `${host}/api/v4/groups/${groupId}/projects?private_token=${apiToken}&per_page=100`;
const { data } = await this.httpService.get(url);
return data;
}
// 获取项目下所有分支
async getBranches(projectId) {
const { host, apiToken } = this.gitlabConfig;
const url = `${host}/api/v4/projects/${projectId}/repository/branches?private_token=${apiToken}&per_page=100`;
const { data } = await this.httpService.get(url);
return data;
}
// 获取分支下所有提交时间是今天的提交
async getCommits(projectId, branchName) {
const todayStart = new Date();
todayStart.setHours(0, 0, 0, 0);
const todayEnd = new Date();
todayEnd.setHours(23, 59, 59, 999);
// convert date to ISO string
const todayStartStr = todayStart.toISOString();
const todayEndStr = todayEnd.toISOString();
const { host, apiToken } = this.gitlabConfig;
const url = `${host}/api/v4/projects/${projectId}/repository/commits?private_token=${apiToken}&ref_name=${branchName}&since=${todayStartStr}&until=${todayEndStr}&per_page=100`;
const { data } = await this.httpService.get(url);
return data;
}
// 获取提交详情
async getCommitDetail(projectId, commitId) {
const { host, apiToken } = this.gitlabConfig;
const url = `${host}/api/v4/projects/${projectId}/repository/commits/${commitId}?private_token=${apiToken}`;
const { data } = await this.httpService.get(url);
return data;
}
async getCodeStat() {
const groups = await this.getGroups();
// console.log(groups);
// 筛选出fe_arch、APP、ui组
const uiGroup = groups.filter(
group =>
group.name === 'fe_arch' || group.name === 'APP' || group.name === 'ui'
);
console.log(uiGroup);
const result = [];
for (const group of uiGroup) {
const projects = await this.getProjects(group.id);
for (const project of projects) {
let branches = await this.getBranches(project.id);
// 过滤最后一次提交时间是在今天的分支
branches = branches.filter(branch => {
const lastCommitDate = new Date(branch.commit.committed_date);
return lastCommitDate.toDateString() === new Date().toDateString();
});
console.log(
`组${group.name} 项目${project.name} 今日有提交的分支:`,
branches.map(item => item.name)
);
for (const branch of branches) {
let commits = await this.getCommits(project.id, branch.name);
// 忽略 merge commits
commits = commits.filter(
commit =>
!commit.title.startsWith('Merge') &&
!commit.message.startsWith('Merge')
);
for (const commit of commits) {
const commitDetail = await this.getCommitDetail(
project.id,
commit.id
);
result.push(commitDetail);
}
}
}
}
// 按作者分组
const authorMap = {};
for (const commit of result) {
const author = commit.author_name;
if (!authorMap[author]) {
authorMap[author] = {
name: author,
commits: [],
additions: 0,
deletions: 0,
};
}
authorMap[author].commits.push(commit);
authorMap[author].additions += commit.stats.additions;
authorMap[author].deletions += commit.stats.deletions;
}
// 按增加行数排序
const authorList = Object.values(authorMap).sort(
(a, b) => b['additions'] - a['additions']
);
return authorList;
}
}
import { Provide } from '@midwayjs/core';
import { IUserOptions } from '../interface';
@Provide()
export class UserService {
async getUser(options: IUserOptions) {
return {
uid: options.uid,
username: 'mockedName',
phone: '12345678901',
email: 'xxx.xxx@xxx.com',
};
}
}
import { createApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework } from '@midwayjs/koa';
describe('test/controller/home.test.ts', () => {
it('should POST /api/get_user', async () => {
// create app
const app = await createApp<Framework>();
// make request
const result = await createHttpRequest(app).get('/api/get_user').query({ uid: 123 });
// use expect by jest
expect(result.status).toBe(200);
expect(result.body.message).toBe('OK');
// close app
await close(app);
});
});
import { createApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework } from '@midwayjs/koa';
describe('test/controller/home.test.ts', () => {
it('should GET /', async () => {
// create app
const app = await createApp<Framework>();
// make request
const result = await createHttpRequest(app).get('/');
// use expect by jest
expect(result.status).toBe(200);
expect(result.text).toBe('Hello Midwayjs!');
// close app
await close(app);
});
});
{
"compileOnSave": true,
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"inlineSourceMap":true,
"noImplicitThis": true,
"noUnusedLocals": true,
"stripInternal": true,
"skipLibCheck": true,
"pretty": true,
"declaration": true,
"forceConsistentCasingInFileNames": true,
"typeRoots": [ "./typings", "./node_modules/@types"],
"outDir": "dist"
},
"exclude": [
"dist",
"node_modules",
"test"
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment