All files / src/class/repository local-repository.ts

78% Statements 39/50
64% Branches 16/25
77.78% Functions 7/9
76.6% Lines 36/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 9415x 15x 15x 15x 15x 15x 15x     15x 10x         10x 10x 10x   10x 10x   10x 8x 8x   2x         5x   1x 1x   1x           24x       26x 26x 10x 10x 10x                                             8x   8x 8x 8x   8x         8x 8x         10x      
import git from 'simple-git/promise'
import semver from 'semver'
import { relative, join, isAbsolute, basename } from 'path'
import { Repository } from './repository'
import { TEMPLATE_STORAGE } from '@/consts'
import { logger, dirExist, isRootDirOfRepo, isRelativePath } from '@/utils'
import { Effect } from '@/internal'
 
 
export class LocalRepository extends Repository {
  public absolute: boolean = false
 
  public path: string
 
  constructor(str) {
    super()
    this.type = 'local'
    this.name = basename(str)
 
    const path = str
    const cwd = process.cwd()
 
    if (isAbsolute(path)) {
      this.absolute = true
      this.path = path
    } else {
      this.path = join(cwd, path)
    }
  }
 
  get record(): string | ((projectPath: string) => string) {
    if (this.absolute) return this.path
    /** the path saved in .milirc should be relative to the output folder, rather than process.cwd() */
    return projectPath => {
      const relativePath = relative(projectPath, this.path)
 
      Eif (isRelativePath(relativePath)) return relativePath
      else return `./${relativePath}`
    }
  }
 
  get storage(): string {
    return join(TEMPLATE_STORAGE, encodeURIComponent(this.path), this.version || 'noversion')
  }
 
  public async getVersions(): Promise<string[]> {
    const { path } = this
    if (this.versions) return this.versions
    Eif (!(await git(path).checkIsRepo()) || !await isRootDirOfRepo(path)) {
      this.versions = []
      return this.versions
    }
 
    const tags = await git(path).tags()
 
    if (!tags.all.length) {
      logger.warn([
        'Cannot get template versions, May be caused by the following reasons:',
        `1. repository is not a mili template(${path})`,
        '2. template have not a valid tag to mark the version(e.g. v1.0.0)',
        `3. cannot get versions by command: \`git tags ${path}\``,
      ].join('\n'))
    }
 
    this.versions = tags.all
      .map(tag => semver.clean(tag) || '')
      .filter(tag => Boolean(tag))
      .reverse()
 
    return this.versions
  }
 
  public async download(): Promise<void> {
    const { path, version, storage } = this
 
    await Effect.fs.emptyDir(storage)
    logger.info(`copy template from ${path}`)
    await Effect.fs.copy(path, storage)
 
    Iif (isRootDirOfRepo(storage) && version && version !== 'default') {
      await git(storage).reset('hard')
      await git(storage).checkout(`v${version}`)
 
      logger.info(`template version: ${version}`)
    } else Eif (version !== 'default') {
      logger.warn('Version is unset, use the default files')
    }
  }
 
  public async existed(): Promise<boolean> {
    return await dirExist(this.path)
  }
}