Compare commits
No commits in common. "dfaee1fb56ef328f0b0452d4032b2dc9e4669f34" and "db6b6996637e6c540e45eb2539596944147d0c18" have entirely different histories.
dfaee1fb56
...
db6b699663
3
.gitignore
vendored
3
.gitignore
vendored
@ -32,6 +32,3 @@ lerna-debug.log*
|
|||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
workspaces/*
|
|
||||||
!workspaces/.gitkeep
|
|
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"cSpell.words": [
|
|
||||||
"Repos"
|
|
||||||
]
|
|
||||||
}
|
|
@ -4,7 +4,7 @@ http:
|
|||||||
|
|
||||||
db:
|
db:
|
||||||
postgres:
|
postgres:
|
||||||
host: 192.168.31.194
|
host: 192.168.31.195
|
||||||
port: 5432
|
port: 5432
|
||||||
database: fennec
|
database: fennec
|
||||||
username: fennec
|
username: fennec
|
||||||
|
53
package-lock.json
generated
53
package-lock.json
generated
@ -2056,34 +2056,6 @@
|
|||||||
"chalk": "^4.0.0"
|
"chalk": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@kwsites/file-exists": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^4.1.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "4.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
|
||||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@kwsites/promise-deferred": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="
|
|
||||||
},
|
|
||||||
"@nestjs/cli": {
|
"@nestjs/cli": {
|
||||||
"version": "7.5.4",
|
"version": "7.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-7.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-7.5.4.tgz",
|
||||||
@ -10781,31 +10753,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz",
|
||||||
"integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo="
|
"integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo="
|
||||||
},
|
},
|
||||||
"simple-git": {
|
|
||||||
"version": "2.35.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/simple-git/-/simple-git-2.35.0.tgz",
|
|
||||||
"integrity": "sha512-VuXs2/HyZmZm43Z5IjvU+ahTmURh/Hmb/egmgNdFZuu8OEnW2emCalnL/4jRQkXeJvfzCTnev6wo5jtDmWw0Dw==",
|
|
||||||
"requires": {
|
|
||||||
"@kwsites/file-exists": "^1.1.1",
|
|
||||||
"@kwsites/promise-deferred": "^1.1.1",
|
|
||||||
"debug": "^4.3.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "4.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
|
||||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sisteransi": {
|
"sisteransi": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^6.6.3",
|
"rxjs": "^6.6.3",
|
||||||
"simple-git": "^2.35.0",
|
|
||||||
"typeorm": "^0.2.30"
|
"typeorm": "^0.2.30"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -6,7 +6,6 @@ import { AppController } from './app.controller';
|
|||||||
import { AppResolver } from './app.resolver';
|
import { AppResolver } from './app.resolver';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { ProjectsModule } from './projects/projects.module';
|
import { ProjectsModule } from './projects/projects.module';
|
||||||
import { ReposModule } from './repos/repos.module';
|
|
||||||
import configuration from './commons/config/configuration';
|
import configuration from './commons/config/configuration';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -38,7 +37,6 @@ import configuration from './commons/config/configuration';
|
|||||||
inject: [ConfigService],
|
inject: [ConfigService],
|
||||||
}),
|
}),
|
||||||
ProjectsModule,
|
ProjectsModule,
|
||||||
ReposModule,
|
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService, AppResolver],
|
providers: [AppService, AppResolver],
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import { InputType } from '@nestjs/graphql';
|
import { InputType } from '@nestjs/graphql';
|
||||||
import {
|
import { IsString, IsUrl, MaxLength, MinLength } from 'class-validator';
|
||||||
IsOptional,
|
|
||||||
IsString,
|
|
||||||
IsUrl,
|
|
||||||
MaxLength,
|
|
||||||
MinLength,
|
|
||||||
} from 'class-validator';
|
|
||||||
|
|
||||||
@InputType({ isAbstract: true })
|
@InputType({ isAbstract: true })
|
||||||
export class CreateProjectInput {
|
export class CreateProjectInput {
|
||||||
@ -19,12 +13,11 @@ export class CreateProjectInput {
|
|||||||
@MinLength(2)
|
@MinLength(2)
|
||||||
comment: string;
|
comment: string;
|
||||||
|
|
||||||
@IsUrl({ protocols: ['ssh'] })
|
@IsUrl({ protocols: ['ssh'], require_protocol: false })
|
||||||
@MaxLength(256)
|
@MaxLength(256)
|
||||||
sshUrl: string;
|
sshUrl: string;
|
||||||
|
|
||||||
@IsUrl()
|
@IsUrl()
|
||||||
@IsOptional()
|
|
||||||
@MaxLength(256)
|
@MaxLength(256)
|
||||||
webUrl?: string;
|
webUrl?: string;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ObjectType } from '@nestjs/graphql';
|
import { ObjectType } from '@nestjs/graphql';
|
||||||
|
import { AppBaseEntity } from 'src/commons/entities/app-base-entity';
|
||||||
import { Entity, Column, DeleteDateColumn } from 'typeorm';
|
import { Entity, Column, DeleteDateColumn } from 'typeorm';
|
||||||
import { AppBaseEntity } from '../commons/entities/app-base-entity';
|
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
@Entity()
|
@Entity()
|
||||||
|
@ -7,6 +7,5 @@ import { Project } from './project.entity';
|
|||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([Project])],
|
imports: [TypeOrmModule.forFeature([Project])],
|
||||||
providers: [ProjectsService, ProjectsResolver],
|
providers: [ProjectsService, ProjectsResolver],
|
||||||
exports: [ProjectsService],
|
|
||||||
})
|
})
|
||||||
export class ProjectsModule {}
|
export class ProjectsModule {}
|
||||||
|
@ -25,15 +25,13 @@ export class ProjectsResolver {
|
|||||||
return await this.service.create(dto);
|
return await this.service.create(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => Project)
|
@Mutation(() => Boolean)
|
||||||
async modifyProject(
|
async modifyProject(
|
||||||
@Args('id', { type: () => String }) id: string,
|
@Args('id', { type: () => String }) id: string,
|
||||||
@Args('project', { type: () => UpdateProjectInput })
|
@Args('project', { type: () => UpdateProjectInput })
|
||||||
dto: UpdateProjectInput,
|
dto: UpdateProjectInput,
|
||||||
) {
|
) {
|
||||||
const tmp = await this.service.update(id, dto);
|
return await this.service.update(id, dto);
|
||||||
console.log(tmp);
|
|
||||||
return tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => Number)
|
@Mutation(() => Number)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { BaseDbService } from '../commons/services/base-db.service';
|
import { BaseDbService } from 'src/commons/services/base-db.service';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { CreateProjectInput } from './dtos/create-project.input';
|
import { CreateProjectInput } from './dtos/create-project.input';
|
||||||
import { Project } from './project.entity';
|
import { Project } from './project.entity';
|
||||||
@ -26,8 +26,7 @@ export class ProjectsService extends BaseDbService<Project> {
|
|||||||
|
|
||||||
async update(id: string, dto: CreateProjectInput) {
|
async update(id: string, dto: CreateProjectInput) {
|
||||||
await this.isDuplicateEntityForUpdate(id, dto);
|
await this.isDuplicateEntityForUpdate(id, dto);
|
||||||
const old = await this.findOne(id);
|
await this.repository.update({ id }, dto);
|
||||||
return await this.repository.save(this.repository.merge(old, dto));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: string) {
|
async remove(id: string) {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import { ObjectType, Field } from '@nestjs/graphql';
|
|
||||||
import {
|
|
||||||
LogResult,
|
|
||||||
DefaultLogFields,
|
|
||||||
BranchSummary,
|
|
||||||
BranchSummaryBranch,
|
|
||||||
} from 'simple-git';
|
|
||||||
|
|
||||||
@ObjectType()
|
|
||||||
export class Branch implements BranchSummaryBranch {
|
|
||||||
current: boolean;
|
|
||||||
name: string;
|
|
||||||
commit: string;
|
|
||||||
label: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ObjectType()
|
|
||||||
export class BranchesList {
|
|
||||||
detached: boolean;
|
|
||||||
current: string;
|
|
||||||
all: string[];
|
|
||||||
@Field(() => [Branch])
|
|
||||||
branches: Branch[];
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import { InputType } from '@nestjs/graphql';
|
|
||||||
import { IsUUID } from 'class-validator';
|
|
||||||
|
|
||||||
@InputType()
|
|
||||||
export class ListBranchesArgs {
|
|
||||||
@IsUUID()
|
|
||||||
projectId: string;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import { InputType, ObjectType } from '@nestjs/graphql';
|
|
||||||
import { IsOptional, IsString, IsUUID } from 'class-validator';
|
|
||||||
|
|
||||||
@InputType()
|
|
||||||
export class ListLogsArgs {
|
|
||||||
@IsUUID()
|
|
||||||
projectId: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
branch?: string;
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import { ObjectType, Field } from '@nestjs/graphql';
|
|
||||||
import { LogResult, DefaultLogFields } from 'simple-git';
|
|
||||||
|
|
||||||
@ObjectType()
|
|
||||||
export class LogFields {
|
|
||||||
hash: string;
|
|
||||||
date: string;
|
|
||||||
message: string;
|
|
||||||
refs: string;
|
|
||||||
body: string;
|
|
||||||
author_name: string;
|
|
||||||
author_email: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ObjectType()
|
|
||||||
export class LogsList implements LogResult<DefaultLogFields> {
|
|
||||||
@Field(() => [LogFields])
|
|
||||||
all: LogFields[];
|
|
||||||
total: number;
|
|
||||||
latest: LogFields;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
import { Project } from '../projects/project.entity';
|
|
||||||
import { ReposResolver } from './repos.resolver';
|
|
||||||
import { ReposService } from './repos.service';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [TypeOrmModule.forFeature([Project])],
|
|
||||||
providers: [ReposResolver, ReposService],
|
|
||||||
})
|
|
||||||
export class ReposModule {}
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ReposResolver } from './repos.resolver';
|
|
||||||
|
|
||||||
describe('ReposResolver', () => {
|
|
||||||
let resolver: ReposResolver;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [ReposResolver],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
resolver = module.get<ReposResolver>(ReposResolver);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(resolver).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
import { Args, Query, Resolver } from '@nestjs/graphql';
|
|
||||||
import { ListLogsArgs } from './dtos/list-logs.args';
|
|
||||||
import { ReposService } from './repos.service';
|
|
||||||
import { LogsList } from './dtos/logs-list.model';
|
|
||||||
import { ListBranchesArgs } from './dtos/list-branches.args';
|
|
||||||
import { BranchesList } from './dtos/branches-list.model';
|
|
||||||
|
|
||||||
@Resolver()
|
|
||||||
export class ReposResolver {
|
|
||||||
con
|
|
||||||
@Query(() => LogsList)
|
|
||||||
async listLogs(@Args('listLogsArgs') dto: ListLogsArgs) {
|
|
||||||
return await this.service.listLogs(dto);
|
|
||||||
}
|
|
||||||
@Query(() => BranchesList)
|
|
||||||
async ListBranchesArgs(
|
|
||||||
@Args('listBranchesArgs') dto: ListBranchesArgs,
|
|
||||||
): Promise<BranchesList> {
|
|
||||||
return await this.service.listBranches(dto).then((data) => {
|
|
||||||
return {
|
|
||||||
...data,
|
|
||||||
branches: Object.values(data.branches),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
|
||||||
import { Project } from '../projects/project.entity';
|
|
||||||
import { ReposService } from './repos.service';
|
|
||||||
|
|
||||||
describe('ReposService', () => {
|
|
||||||
let service: ReposService;
|
|
||||||
const repositoryMockFactory = jest.fn(() => ({
|
|
||||||
findOneOrFail: jest.fn(
|
|
||||||
(entity): Project => ({
|
|
||||||
id: '1',
|
|
||||||
// sshUrl: 'ssh://gitea@git.ivanli.cc:7018/ivan/test1.git',
|
|
||||||
sshUrl: 'ssh://gitea@git.ivanli.cc:7018/Fennec/fennec-fe.git',
|
|
||||||
name: 'test1',
|
|
||||||
...entity,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [
|
|
||||||
ReposService,
|
|
||||||
{
|
|
||||||
provide: getRepositoryToken(Project),
|
|
||||||
useFactory: repositoryMockFactory,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<ReposService>(ReposService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(service).toBeDefined();
|
|
||||||
});
|
|
||||||
describe('listLogs', () => {
|
|
||||||
it('should be return logs', async () => {
|
|
||||||
const result = await service.listLogs({ projectId: '1' });
|
|
||||||
expect(result).toBeDefined();
|
|
||||||
}, 10_000);
|
|
||||||
});
|
|
||||||
describe('listBranch', () => {
|
|
||||||
it('should be return branches', async () => {
|
|
||||||
const result = await service.listBranches({ projectId: '1' });
|
|
||||||
expect(result).toBeDefined();
|
|
||||||
}, 10_000);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,41 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
|
||||||
import { F_OK } from 'constants';
|
|
||||||
import { access, mkdir } from 'fs/promises';
|
|
||||||
import { join } from 'path';
|
|
||||||
import { gitP } from 'simple-git';
|
|
||||||
import { Repository } from 'typeorm';
|
|
||||||
import { Project } from '../projects/project.entity';
|
|
||||||
import { ListBranchesArgs } from './dtos/list-branches.args';
|
|
||||||
import { ListLogsArgs } from './dtos/list-logs.args';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ReposService {
|
|
||||||
constructor(
|
|
||||||
@InjectRepository(Project)
|
|
||||||
private readonly projectRepository: Repository<Project>,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async getGit(project: Project) {
|
|
||||||
const workspacePath = join(__dirname, '../../workspaces', project.name);
|
|
||||||
await access(workspacePath, F_OK).catch(() => mkdir(workspacePath));
|
|
||||||
return gitP(workspacePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
async listLogs(dto: ListLogsArgs) {
|
|
||||||
const project = await this.projectRepository.findOneOrFail({
|
|
||||||
id: dto.projectId,
|
|
||||||
});
|
|
||||||
const git = await this.getGit(project);
|
|
||||||
await git.fetch();
|
|
||||||
return git.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
async listBranches(dto: ListBranchesArgs) {
|
|
||||||
const project = await this.projectRepository.findOneOrFail({
|
|
||||||
id: dto.projectId,
|
|
||||||
});
|
|
||||||
const git = await this.getGit(project);
|
|
||||||
return git.branch();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user