記錄我開發gpm,Git倉庫管理工具的歷程

前言

記錄下開發的一些事,增強本身對nodejs的應用。共勉!node

有讓你操蛋的事,就有需求

對於常常參與開源貢獻,或者看見某些庫,像試試手的人來講,常常須要git clone https://xxxxlinux

操蛋的是,程序員是懶的,通常不會手動去刪除某個項目,致使於克隆的項目會愈來愈多。git

對於這些項目的管理,則會變得愈來愈困難,放眼放去,全是文件夾。程序員

因此,需求就誕生了。github

雛形

參考於GO的項目管理,發現很是的優雅。shell

GO的項目相似的結構是這樣的npm

https://{source}/{owner}/{name}

- source
    - owner
        - name
        - name
    - owner
        - name
        - name
        - name
- source
    - owner
        - name
        - name

因此就想着寫一個功能與之相似的。json

這樣基本就肯定了一個項目目錄的惟一性。windows

簡單無腦,我只管克隆,卻不用管克隆的項目在哪一個文件夾,想刪就刪。安全

因而,雛形git-clone-cli就誕生了

這只是一個簡單的,代替git clone xxx的工具

開發

隨着需求愈來愈多,已經不能知足簡單的git clone了,因此gpm來了

相對與git clone, 豐富了一些東西,更另咱們方便管理

  • 支持克隆Github, Gitlab等等

  • 多樣的命令,好比list,find,clean,relink,import

  • 支持插件,配置文件,hook

    > 舉個簡單的例子,克隆一個Javascript項目,克隆以後,自動運行 npm install 或 yarn
    > 想要什麼樣的插件,什麼用的hook,隨你配置

那些踩過的坑

權限問題

FIX ME : Windows下,若是克隆到一半,手動中斷進程,則克隆下來的項目是隻讀,沒法修改,沒法刪除。
嘗試經過node修改權限爲777,最後無果, 不了了之。

這樣會致使一些命令由於沒有權限而失敗

交互方式

交互方式的選擇一直是我蛋疼的問題,又要兼容多平臺,又要簡單優雅。

好比 gpm find,搜索某個倉庫,而後獲取相應的信息

方式一:輸入(半)全稱

gpm find @gpmer/gpm.js

優勢:

  • 幾乎能精準搜索

  • 跨終端兼容性好

缺點:

  • 太繁瑣,除了本身的庫,其餘人的庫我看並不記得。

方式二:詢問/篩選

gpm find

會在終端監聽輸入的關鍵字,根據關鍵字篩選出一系列的倉庫。
而後經過上下箭頭,選擇倉庫

優勢:

  • 不必輸入繁瑣的關鍵字,只須要記得大概

缺點:

  • 有兼容性問題,linux和OS X下沒有問題,Windows下兼容pwoerShell和cmd,可是不兼容git bash

unix路徑和windows路徑

Linux和OS X都是unix形式的路徑, 在gpm add xxx, 能夠直接複製路徑, cd到對應的目錄.

Windows下, 獲取到的是Windows風格的路徑, 若是你在使用Git Bash. 很顯然是不能cd的.

折中方案是加個-u, --unix參數, 選擇輸出unix的路徑

添加倉庫以後, 在終端自動cd到項目目錄

在nodejs裏面, 不管怎麼改變工做目錄, 也只是改變了這個(子)進程的工做目錄. 無法改變所使用的終端的工做目錄.

後來終於發現了robotjs自動化工具.

能夠在終端輸入命令, 而後Enter.

惋惜的是, 又是Windows不兼容. 並且robotjs的包還不小, 對於頻繁升級是一種負擔.

所幸就放棄了自動cd到工做目錄的念頭

全局插件

FIX ME: 添加了插件機制,豐富了一些功能。克隆以後,自動運行 npm install 或 yarn。
只須要在命令後面加個參數: gpm add xxx -p <插件名>
要引用全局插件,就必需要知道npm的全局node_modules在哪裏。
很遺憾的是,Windows下,獲取到的位置不正確,致使插件不能正常調用。

項目的.gpmrc配置文件

你能夠在你的項目建立一個.gpmrc配置文件,裏面寫一些hook,好比:

{
  "hooks":{
    "add": "npm install"
  }
}

當經過gpm添加這個項目以後,則運行hooks裏面對應的shell。

FIX ME 問題就在於這個shell,並不安全。若是要是rm -rf /,恰巧又以root權限運行,那就悲劇了。

還有就是多重的shell,好比npm install && npm run build怎麼去運行。

這不是很簡單? 直接 exec("npm isntall && npm run build")就完事了啊

NO, NO, NO. exec()並不優雅並且還有限制,我更喜歡用spawn

可是spawn("npm", "isntall && npm run build".split(" "))這樣是會報錯的. && 不是有效的命令

實際上我是這麼作的,上面的命令拆分紅爲兩條spawn("npm", ["isntall"])spawn("npm", ["run", "build"])

導入已存在的項目

你可能已經在~/project/這個目錄下存放了不少的項目。若是要讓你從新gpm add xxxx一個一個的添加進來,你願意嗎?

程序員要偷懶,因此纔有import這個命令。把已存在的項目,按照source > owner > name的目錄結構擺放好。

這又涉及到一個問題。我又想導入,又不想破壞原來~/project/的結構,這個時候就用到link。

在對應的source > owner > name目錄下,建立一個link,指向~/project/中的項目

問題就來了,當你要刪除這個項目的時候,即刪除source > owner > name,會報錯。link文件須要解除link才能刪除

測試用例

有找過相似mock文件系統的方案,可是都感受不太優雅。

某天忽然頓悟,爲何還有模擬什麼文件系統呢,爲何就不能用真實的呢,臨時建立一個目錄,在這個目錄底下完整地走一遍流程,而後再對比預期,這樣不就行了嗎

總結

從開始寫,到如今,commit有差很少300屢次,前先後後一個多月,也一直是我一我的使用,我我的也以爲比較好用(好過沒有,逃...)

總感受還有不少不完善的地方,可是我的能力和想法都有限,只能慢慢的完善。本身也在使用,打算長期維護。

最後給上項目地址:gpmer/gpm.js

我只是個菜雞 XD,但願有大牛給個PR或者給一些建議

相關文章
相關標籤/搜索