我也終於用上Powershell了

背景

眾所周知,GacUI的源代碼在github上是以一個organization來維護的,不同的模塊放在了不同的repo裡面。起初這是為了互相依賴的時候,方便並行開發,但是隨之而來的問題就是如何才能簡單的更新依賴。好在我用的是C++,那麼我其實只要把整個項目的代碼合併成一對或者少數幾對.h文件和.cpp文件就可以了。一來比起直接給你用幾百個文件可以節省80%以上的編譯時間,二來很多著名的庫也是這麼乾的,想必大家都可以接受。於是我當然也就採取了這種辦法。

那麼互相更新就很容易了。每一個repo有一個Release文件夾,每當需要更新的時候就跑個腳本把所有的C++代碼都粘起來,然後正確處理掉那些#include,最後放在Release文件夾就可以了。每個repo也有一個Import文件夾,裡面的代碼是從隔壁repo的Release複製過來的。那麼這個跨版本的依賴關係就成立了。上游repo不管怎麼更新,我的Import只要不變,那我仍然依賴的是舊的模塊。有些時候特別方便。

其實我一開始也想過用git submodule,但是這個煞筆東西不能解決菱形依賴的問題,which在軟體開發的過程中基本上是不可避免的,於是只好棄療,用我現在的辦法了。

然而這帶來一個問題,就是互相更新依賴的時候特別煩,要跑很多腳本。因此我在剛開始的時候是用C#來干這個事情的,後來把這個巨大的程序的不同的部分抽出來成為獨立的程序,用bat粘起來。再後來為了方便我移植到Ubuntu,不想亂七八糟折騰,我就把他們都用C++和Vlpp重寫了一遍。那麼最近我做的事情,就是把所有的bat都換成了powershell的ps1了。

總的來講,其實bat調用msbuild才更方便,因為msbuild官方就只給你cmd的環境。但是現在Windows 10為了推廣powershell,淘汰落後的cmd,竟然默認把「在這裡打開cmd」隱藏了,只有powershell了。再加上Github for Windows已經在powershell裡面把git配置好了,我就覺得現在是個機會,因此花了幾天時間學習powershell,把整個腳本重新做出來了。

使用GacUI的同學會發現,我其實在Release裡面附帶了幾個小的bat文件,用來跑UI的XML描述,生成跨平台的代碼(當然在這裡主要解決的是跨x86和x64的問題)。現在這個bat沒有了,都換成ps1了(逃

PowerShell

之前我也算是大規模使用過bash和cmd的人了,對於如何在這兩門垃圾語言裡面使用數據結構具有豐富的經驗,這使得我一直很想自己開發一門為了命令行優化與法的腳本語言。當然因為有別的事情干,我一直沒有做。這幾天學習powershell之後,我覺得這個東西就做得挺好,除了命名方式有一點不對我胃口以外。不過這並不重要,因為我早就習慣了在不同的語言裡面使用不同的習慣了。當然從一開始是JavaScript那個語言規範逼的,他媽的大括弧換行還能改變程序的意思,這是我人生中第一次有這樣的體驗。

總的來說,我覺得powershell有以下幾個優點

  1. 很簡單,裝完Windows就有了,不用折騰。
  2. powershell具有豐富的和Windows交互的能力,而且很多軟體也支持,譬如說SQLServer也可以用powershell來管理。
  3. powershell的設計是具有一致性的,你不需要總是去記得各個不同的命令之間微妙的區別,特別是rm *遇到一個叫做-rf的文件怎麼辦的時候的問題,在powershell就不存在。因為powershell是有語法的,參數不同的位置的-rf,代表的到底是參數名還是文件名,是可以通過語義分析找到的(逃
  4. powershell的字元轉義不多,特殊語法基本沒有,而且名字也是完整的單詞,不會看著什麼sed/grep一臉懵逼。我在不知道的時候,怎樣也想不到正則表達式相關的命令叫這個。在這裡我就想到之前在ubuntu下面也是做如何掃描硬碟輸出makefile的腳本,正則表達式跟數組混在一起這代碼簡直不能看,現在我都不知道自己在寫什麼了。
  5. powershell是區分類型的,也就是說你不可能把array和string搞混,大多數情況下運行前就能給你抓到,因為powershell的編譯器是有類型推導的,跟F#一樣(雖然沒有那麼厲害)。他會整個文件讀進去,一行一行校對完沒問題,再給你執行。有一次甚至抓到了我不小心把null傳進一個需要string的參數的命令裡面的錯誤,看到這個報錯的時候簡直驚呆了。
  6. 最重要的,他能調用.net類庫。再也不需要去找別人寫的命令了,有什麼系統管理的事情是.net做不了的,沒有(逃。甚至是遇到一些極端情況,我還可以藉助.net的力量來調用Windows API——而不用先用C++/C#寫最後編譯完code和binary一大堆文件都打包在一起——你只要在powershell裡面框起來直接寫C#就可以了。
  7. powershell啟動進程的語法很方便,也很自由,基本上可以做到跟.net裡面使用Process類一樣多的事情。這使得我最終調用msbuild的時候非常方便。我寫了個powershell的函數,模擬了Developer Command Prompt for VS2015的啟動過程,然後在裡面接著跑一堆命令來編譯我的代碼。
  8. powershell能寫函數,有異常處理。需要中斷的時候無論callstack有多少東西一個throw就出來了。最外面catch一下善後,拜拜。到處jump和if error變數的日子一去不復返。
  9. 流行的Linux發行版上也有powershell。

尾聲

總的來說,我其實最終是要完成一件事情,就是在我往github送代碼的時候,有一個伺服器可以監視我的活動,然後自動build我的代碼,把所有的unit test跑一遍,如果過了的話就更新依賴,重新測試,打包GacUI,發布release,更新網站上面的函數參考文檔,所有事情一氣呵成。不過目前遠遠沒這麼自動化,但是powershell讓我看到了希望,用bash和cmd的時候想都不敢想。

當然在這裡不得不指出,bash已經這麼爛了,但是我由於先學bash後學cmd,體驗了一把由奢入儉難的過程,他媽的cmd更爛。不過反現在都能用powershell了,管他麻痹(逃


推薦閱讀:

Android獲取應用大小
Groovy 的現狀見解
Android Studio 簡單配置多渠道包案例
Atomic Red Team:針對安防設計的新型自動化測試框架
如何使用MATLAB寫測試(6): 用Tag分類你的測試

TAG:编程 | 运维 | 自动化测试 |