UNPKG

@ysfe/c-gdc

Version:

命令行工具: 提供按group批量 clone gitlab repo 能力

138 lines (128 loc) 4.67 kB
import Axios from 'axios' import simpleGit from 'simple-git' import { prompt } from 'enquirer' import * as fs from 'fs' import path from 'path' const axios = Axios.create({ baseURL: 'http://gitlab.yslocal.com', withCredentials: true, headers: { 'Content-Type': 'application/x-www-form-urlencoded', Host: 'gitlab.yslocal.com' } }) /** 导出服务 */ export default class CommandGitDeepClone { opt!: { Cookie: string } async command() { // if don't has options, exec user input await this.inputGitUser() // ! login 实现太难, 直接贴 cookie 吧 // pull git group let groups = await this.pullAllGroup() // filter should clone group groups = await this.filterCloneGroup(groups) // pull all projects info const projects = await this.pullProject(groups) // cloen console.log('> 共计:', projects.length, '个项目') this.clones(projects) } async filterCloneGroup(groups: Array<string>): Promise<Array<string>> { const { isConfirm } = (await prompt({ type: 'select', name: 'isConfirm', message: 'clones project from all group?', choices: ['yes', 'no'] })) as any if (isConfirm !== 'yes') { try { const { selected } = (await prompt({ type: 'multiselect', name: 'selected', message: 'Pick your favorite colors', choices: groups })) as any groups = selected } catch (error) { // } } return groups } /** if can't get params in command, that get git user in readline */ async inputGitUser() { const query = [] let cookie: any if (!this.opt?.Cookie) { query.push({ type: 'input', name: 'Cookie', message: 'gitlab session (登录后, 从cookie中查看)' }) const response: { Cookie: string } = await prompt(query) cookie = response.Cookie } else { cookie = this.opt.Cookie } // input this.opt = { Cookie: cookie.includes('=') ? cookie : '_gitlab_session=' + cookie } } /** pull git group from your gitlab */ async pullAllGroup(): Promise<Array<string>> { const { data } = await axios.get('/dashboard/groups.json', { headers: { Cookie: this.opt.Cookie } }) const groups = data.map((item: any) => { return item['relative_path']?.replace(/^\//, '') }) return groups } async pullProject(groups: Array<string>, pageIndex: number = 1): Promise<Array<string>> { console.log('fetching...') let projects: Array<string> = [] for (const group of groups) { const p = path.normalize(`/groups/${group}/-/children.json${pageIndex > 1 ? '?page=' + pageIndex : ''}`) console.log('> pull', p) const { data, headers } = await axios.get(p, { headers: { Cookie: this.opt.Cookie } }) for (const project of data) { const { type, relative_path } = project if (type === 'group') { const children = await this.pullProject([relative_path]) projects = [...projects, ...children] } else { projects.push(relative_path) } } if (headers['x-total-pages'] > 1 && pageIndex < headers['x-total-pages']) { const children = await this.pullProject(groups, pageIndex + 1) projects = [...projects, ...children] } } return projects } /** 执行 clone */ async clones(projects: Array<string>) { let p try { const inp = (await prompt({ type: 'input', name: 'p', message: '输入一个本地地址, 用来clone 这些仓库:' })) as any p = inp.p } catch (error) { // } if (!fs.existsSync(p)) return console.log(`> path not exist:`, p) if (!fs.statSync(p).isDirectory()) return console.log(`> path not a directory:`, p) for (const pro of projects) { const repo = `http://gitlab.yslocal.com${pro}` if (fs.existsSync(p + pro)) continue await simpleGit().clone(repo, p + pro) console.log('> cloned', repo) } } }