修复远程仓库信息获取问题。

This commit is contained in:
Ivan Li 2021-02-23 20:19:39 +08:00
parent dfaee1fb56
commit ab6c56e55a
9 changed files with 62 additions and 17 deletions

View File

@ -8,4 +8,6 @@ db:
port: 5432 port: 5432
database: fennec database: fennec
username: fennec username: fennec
password: password:
workspaces:
root: '/Users/ivanli/Projects/fennec/workspaces'

View File

@ -11,7 +11,7 @@
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start", "start": "nest start",
"start:dev": "nest start --watch", "start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch", "start:debug": "DEBUG=simple-git,simple-git:* nest start --debug --watch",
"start:prod": "node dist/main", "start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest", "test": "jest",

View File

@ -15,7 +15,7 @@ export class Branch implements BranchSummaryBranch {
} }
@ObjectType() @ObjectType()
export class BranchesList { export class BranchList {
detached: boolean; detached: boolean;
current: string; current: string;
all: string[]; all: string[];

View File

@ -13,7 +13,7 @@ export class LogFields {
} }
@ObjectType() @ObjectType()
export class LogsList implements LogResult<DefaultLogFields> { export class LogList implements LogResult<DefaultLogFields> {
@Field(() => [LogFields]) @Field(() => [LogFields])
all: LogFields[]; all: LogFields[];
total: number; total: number;

View File

@ -3,9 +3,10 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { Project } from '../projects/project.entity'; import { Project } from '../projects/project.entity';
import { ReposResolver } from './repos.resolver'; import { ReposResolver } from './repos.resolver';
import { ReposService } from './repos.service'; import { ReposService } from './repos.service';
import { ConfigModule } from '@nestjs/config';
@Module({ @Module({
imports: [TypeOrmModule.forFeature([Project])], imports: [TypeOrmModule.forFeature([Project]), ConfigModule],
providers: [ReposResolver, ReposService], providers: [ReposResolver, ReposService],
}) })
export class ReposModule {} export class ReposModule {}

View File

@ -1,21 +1,21 @@
import { Args, Query, Resolver } from '@nestjs/graphql'; import { Args, Query, Resolver } from '@nestjs/graphql';
import { ListLogsArgs } from './dtos/list-logs.args'; import { ListLogsArgs } from './dtos/list-logs.args';
import { ReposService } from './repos.service'; import { ReposService } from './repos.service';
import { LogsList } from './dtos/logs-list.model'; import { LogList } from './dtos/log-list.model';
import { ListBranchesArgs } from './dtos/list-branches.args'; import { ListBranchesArgs } from './dtos/list-branches.args';
import { BranchesList } from './dtos/branches-list.model'; import { BranchList } from './dtos/branch-list.model';
@Resolver() @Resolver()
export class ReposResolver { export class ReposResolver {
con constructor(private readonly service: ReposService) {}
@Query(() => LogsList) @Query(() => LogList)
async listLogs(@Args('listLogsArgs') dto: ListLogsArgs) { async listLogs(@Args('listLogsArgs') dto: ListLogsArgs) {
return await this.service.listLogs(dto); return await this.service.listLogs(dto);
} }
@Query(() => BranchesList) @Query(() => BranchList)
async ListBranchesArgs( async ListBranchesArgs(
@Args('listBranchesArgs') dto: ListBranchesArgs, @Args('listBranchesArgs') dto: ListBranchesArgs,
): Promise<BranchesList> { ): Promise<BranchList> {
return await this.service.listBranches(dto).then((data) => { return await this.service.listBranches(dto).then((data) => {
return { return {
...data, ...data,

View File

@ -2,6 +2,11 @@ import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm'; import { getRepositoryToken } from '@nestjs/typeorm';
import { Project } from '../projects/project.entity'; import { Project } from '../projects/project.entity';
import { ReposService } from './repos.service'; import { ReposService } from './repos.service';
import { ConfigService } from '@nestjs/config';
import { rm, unlink } from 'fs/promises';
import { join } from 'path';
const workspacesRoot = '/Users/ivanli/Projects/fennec/workspaces';
describe('ReposService', () => { describe('ReposService', () => {
let service: ReposService; let service: ReposService;
@ -24,6 +29,14 @@ describe('ReposService', () => {
provide: getRepositoryToken(Project), provide: getRepositoryToken(Project),
useFactory: repositoryMockFactory, useFactory: repositoryMockFactory,
}, },
{
provide: ConfigService,
useValue: {
get() {
return workspacesRoot;
},
},
},
], ],
}).compile(); }).compile();
@ -34,10 +47,13 @@ describe('ReposService', () => {
expect(service).toBeDefined(); expect(service).toBeDefined();
}); });
describe('listLogs', () => { describe('listLogs', () => {
beforeEach(async () => {
await rm(join(workspacesRoot, 'test1'), { recursive: true });
});
it('should be return logs', async () => { it('should be return logs', async () => {
const result = await service.listLogs({ projectId: '1' }); const result = await service.listLogs({ projectId: '1' });
expect(result).toBeDefined(); expect(result).toBeDefined();
}, 10_000); }, 20_000);
}); });
describe('listBranch', () => { describe('listBranch', () => {
it('should be return branches', async () => { it('should be return branches', async () => {

View File

@ -8,18 +8,35 @@ import { Repository } from 'typeorm';
import { Project } from '../projects/project.entity'; import { Project } from '../projects/project.entity';
import { ListBranchesArgs } from './dtos/list-branches.args'; import { ListBranchesArgs } from './dtos/list-branches.args';
import { ListLogsArgs } from './dtos/list-logs.args'; import { ListLogsArgs } from './dtos/list-logs.args';
import { ConfigService } from '@nestjs/config';
import { log } from 'console';
@Injectable() @Injectable()
export class ReposService { export class ReposService {
constructor( constructor(
@InjectRepository(Project) @InjectRepository(Project)
private readonly projectRepository: Repository<Project>, private readonly projectRepository: Repository<Project>,
private readonly configService: ConfigService,
) {} ) {}
async getGit(project: Project) { async getGit(project: Project) {
const workspacePath = join(__dirname, '../../workspaces', project.name); const workspacePath = join(
await access(workspacePath, F_OK).catch(() => mkdir(workspacePath)); this.configService.get<string>('workspaces.root'),
return gitP(workspacePath); project.name,
);
const firstInit = await access(workspacePath, F_OK)
.then(() => false)
.catch(async () => {
await mkdir(workspacePath);
return true;
});
const git = gitP(workspacePath);
if (firstInit) {
await git.init();
await git.addRemote('origin', project.sshUrl);
// await git.clone(project.sshUrl, workspacePath);
}
return git;
} }
async listLogs(dto: ListLogsArgs) { async listLogs(dto: ListLogsArgs) {
@ -27,8 +44,17 @@ export class ReposService {
id: dto.projectId, id: dto.projectId,
}); });
const git = await this.getGit(project); const git = await this.getGit(project);
await git.fetch(); await git
return git.log(); .outputHandler((command, stdout, stderr) => {
stdout.pipe(process.stdout);
stderr.pipe(process.stderr);
})
.fetch();
// await git.checkoutBranch('master', 'origin/master');
return await git.log({
'--branches': dto.branch ?? '',
'--remotes': 'origin',
});
} }
async listBranches(dto: ListBranchesArgs) { async listBranches(dto: ListBranchesArgs) {

View File