写一个复制 GitHub 仓库目录结构的cli

1,551 阅读2分钟

现在有很多生成项目目录结构的cli,但是很多时候不能满足自己的痛点,而且cli下载多了自己容易记不清谁对谁了。

在我的经验中,我想要生成的目录结构以及一些配置文件往往和一个github repo一致,所以我就有了这种需求:复制一个github仓库的目录结构和配置文件。

毕竟删改比重新写快多了

所以我就打算用nodejs写了一个脚手架。

思路

如何使用github api?

github提供了一个访问github各种数据的api,参考这里。但是原生的接口比较难用,我用的是官方推荐的nodejs访问github api的框架octonode。 同时,使用githubAPI需要提供一个access_token,在这里获取,无token的ip每小时最多使用60次,登录的用户没小时可以使用5000次。

如何获一个github项目的目录结构

github 提供的访问一个项目目录的api,返回的结果是一个数组,数组的元素是项目根目录下每个文件或目录的一些信息。 大概长这样

{
  "type": "file",
  "encoding": "base64",
  "size": 5362,
  "name": "README.md",
  "path": "README.md",
  "content": "encoded content ...",
  "sha": "3d21ec53a331a6f037a91c368710b99387d012c1",
  "url": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
  "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
  "html_url": "https://github.com/octokit/octokit.rb/blob/master/README.md",
  "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/README.md",
  "_links": {
    "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
    "self": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
    "html": "https://github.com/octokit/octokit.rb/blob/master/README.md"
  }
}

type属性告诉我们它是file还是dir,如果是文件,我们可以通过 download_url来下载它。 这是我写的下载函数:

const fs = require('fs')

const request = require('request')
const {ensureFileSync} = require('ensure-path')

module.exports = (fileLocation, url) => {
  ensureFileSync(fileLocation)
  request(url, (err, res, body) => {
    if (err) return console.log(err)
    fs.writeFile(fileLocation, body, () => {})
  })
}

传入两个参数,希望存储文件的目录和下载链接,就可下载了。

接下来说一下如何查看某仓库的根目录信息或者某个子目录的信息,这里就用到之前说的octonode了。

npm i octonode

const github = require('octonode')
let token = YOU_TOKEN
const client = github.client(token)
client.get('/repos/:owner/:repo/contents', {}, (err, status, body, headers) => {
    if (err) return console.err(err)
    //you code
    // body 就是上面所说的数组
  })

既然知道如何获取目录结构以及下载单个文件,后面的代码就很好写了。有兴趣的可以看一下我的仓库

如何使用

$ npm i nclone -g

//$ nclone [repo] [targetDir] [-t=YOU_ACCESS_TOKEN] [-d=10] [-f=1]
$ nclone saltfish666/nclone ./nclone
  • 第一个参数repo 一个github仓库 ,必须按照 USER/REPO 即 saltfish666/nclone 的结构来写

  • targetDir 文件存储位置

warnning: 如何有重名的文件会重写本地文件

  • -t 就是github Token,你不写也行,默认是我自己的,(反正没人用,每小时5000次应该不会超标)

  • -d dirDepth 就是你希望复制的目录深度,默认是10

  • -f fileDepth 就是你希望复制的文件深度,你默认是1