亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

關于build tool的構想--從ant說起

2019-11-18 12:53:57
字體:
來源:轉載
供稿:網友

  ant——你要是不會,出門都不好意思跟人打招呼的那個ant,每個人都用過。
  
  它是一個build tool,用xml來描述target,用xml來設置每個task的屬性。
  
  ant的好處我們都體會到了
  
  1。什么都是xml。而xml地球人都知道。
  
  2。功能強大。從編譯java文件到checkin cvs,反正幾乎你想得到的功能它都能作。
  
  3。擴展輕易,假如你發現某個功能ant沒有,自己實現一個Task類就是。
  
  4。一些功能設計得很合理。比如javac和java自動檢查時間戳和依靠關系檢查等等。
  
  但是,用多了,發現缺點也不少
  
  1。什么都是xml。而xml的語法有些時候顯得很繁瑣。
  
  2。xml用來描述邏輯異常笨拙。
  
  3。所有的邏輯都只能在java里用Task實現。要做一些跨越不同Task之間的通訊很困難。比如:先讀取第一個文件的時間戳,再讀取另一個文件中儲存的時間戳,再根據兩個時間戳之間的距離判定下一步調用哪個task或者target。
  
  4。xml的代碼重用困難。很難定義一些常用的xml element作為庫,然后再不同文件甚至項目中重用。
  
  5。對module的支持有限。
  
  仔細想想,其實,需求發展到邏輯重用,模塊治理,不同task通訊等,已經離描述數據這個xml最擅長的領域越來越遠了。
  
  假如把task作為基本的組成元件,那么,上面提出的幾點需求,都是關注于對這些基本元件的治理和組合?;蛘哒f,glue。
  
  到此,口號呼之欲出,那就是:script。
  
  很多script,作為一個完整的語言,是做glue的最理想選手。
  
  下面談談我對一個基于script的built tool的構想。
  
  首先,這個build tool仍然需要答應通過java來自定義task。
  
  我們定義這樣一個接口:
  
  java代碼:
  
  interface Command{
  Object execute(CommandContext ctxt)
  throws Throwable;
  }
  
  我們計劃讓所有的task(我們這里叫它們command)都實現這個接口。
  
  CommandContext負責傳遞一些象log之類的信息。
  
  這個execute返回一個Object,這個值作為這個Command的返回值,可以用來和其它的Command通信。
  
  我們答應這個函數拋出任何異常,這個framework將會處理這些異常。
  
  然后,定義一些基本的Command,比如,ReturnCommand負責直接返回某一個值
  
  java代碼:
  
  class ReturnCommand implements Command{
  PRivate final Object v;
  public Object execute(CommandContext ctxt){
  return v;
  }
  ReturnCommand(Object v){this.v=v;}
  }
  
  PrintCommand負責打印一句話
  java代碼:
  
  class PrintCommand implements Command{
  private final String msg;
  public Object execute(CommandContext ctxt){
  ctxt.getLogger().log(msg);
  return null;
  }
  PrintCommand(String msg){this.msg=msg;}
  }
  
  FailCommand負責報告錯誤
  
  java代碼:
  
  class FailCommand implements Command{
  private final String msg;
  public Object execute(CommandContext ctxt){
  throw new CommandException(msg);
  }
  FailCommand (String msg){this.msg=msg;}
  }
  
  如此等等。這樣的基本元件還有很多,比如file copy, javac, zip, jar等。
  
  但是,假如僅僅如此,那么這個工具的能力最多也就和ant一樣。
  
  我們最需要的,是把不同的command組合起來的能力。
  
  而組合,最常見的,就是順序執行。
  
  java代碼:
  
  class SeqCommand implements Command{
  private final Command c1;
  private final Command c2;
  public Object execute(CommandContext ctxt){
  c1.execute(ctxt);
  return c2.execute(ctxt);
  }
  SeqCommand (Command c1, Command c2){
  this.c1 = c1;
  this.c2 = c2;
  }
  }
  
  上面這個簡單的Command,就負責按照順序執行連續的兩個command。
  
  除了順序執行,還有錯誤處理。我們也許會希望,當某個步驟執行失敗時,去執行另外一個動作,為此,我們需要先定義一個接口來描述錯誤恢復:
  
  java代碼:
  
  interface CommandRecovery{
  Command recover(Throwable th)
  throws Throwable;
  }
  
  當某個command失敗的時候,這個接口會被調用。實現這個接口,可以有選擇地對某一種或者幾種錯誤進行恢復。
  
  然后定義具體的錯誤恢復邏輯
  
  java代碼:
  
  class RecoveredCommand implements Command{
  private final Command c1;
  private final CommandRecovery c2;
  public Object execute(CommandContext ctxt){
  try{
  return c1.execute(ctxt);
  }
  catch(Throwable th){
  return c2.recover(th).execute(ctxt);
  }
  }
  RecoveredCommand (Command c1, CommandRecovery c2){
  this.c1 = c1;
  this.c2 = c2;
  }
  }
  
  有try-catch,就有try-finally,我們也可以定義一個command,讓它保證某個要害動作必然運行
  
  java代碼:
  
  class FinallyCommand implements Command{
  private final Command c1;
  private final Command c2;
  public Object execute(CommandContext ctxt){
  try{
  return c1.execute(ctxt);
  }
  finally{
  c2.execute(ctxt);
  }
  }
  FinallyCommand (Command c1, Command 2){
  this.c1 = c1;
  this.c2 = c2;
  }
  }
  
  前面的順序執行,我們是直接扔掉了前一個command的返回值。但是有些時候,我們也許希望根據第一個command的返回值來決定下一步的走向。為此,仿照CommandRecovery接口,定義CommandBinder接口:
  
  java代碼:
  
  interface CommandBinder{
  Command bind(Object v);
  }
  
  然后定義BoundCommand類:
  
  java代碼:
  
  class BoundCommand implements Command{
  private final Command c1;
  private final CommandBinder c2;
  public Object execute(CommandContext ctxt){
  final Object v = return c1.execute(ctxt);
  return c2.bind(v).execute(ctxt);
  }
  BoundCommand (Command c1, CommandBinder c2){
  this.c1 = c1;
  this.c2 = c2;
  }
  }
  
  先透露一下,這個BoundCommand非常重要,就是它負責在不同的command間傳遞信息。
  
  基本上的框架搭好了,下面,假設我們用一個類似groovy的腳本來寫某個target,我們的目標是先取得當前時間,然后打印出這個時間,然后調用javac,最后在程序結束后,打印程序結束的信息:
  
  java代碼:
  
  new BoundCommand(
  new GetTimeCommand(),
  new CommandBinder(){
  public Command bind(Object v){
  final Command c2 = new PrintCommand("build time is "+v);
  final Command javacc = new JavaCCommand();
  final Command done = new PrintCommand("build sUCcessful");
  return new SeqCommand(c2, new SeqCommand(javacc, done));
  }
  }
  );
  
  上面的代碼,先調用GetTimeCommand,取得當前時間,然后把這個實現傳遞到這個匿名類中去,這個匿名類根據這個時間2,創建了下一步的command c2。
  
  接下來,它調用兩次SeqCommand來表達兩次順序執行。
  
  最終,當這個command被執行的時候,它就會完成我們上面要求的幾個步驟。
  
  不錯,挺好。達到了在步驟間任意傳遞信息的要求。甚至,我們也可以重用某些command或者函數。
  
  唯一一個問題:這個代碼他媽的比xml還惡心!
  
  這還是很簡單的情況,假如我們綜合順序,錯誤處理,分支等等,代碼會丑陋得不忍卒睹。
  
  看來,不是隨便什么script都可以勝任的。
  
  那么,讓我們先靜下心來反過來想想,我們到底希望有什么樣的語法呢?
  
  寫偽碼,應該是這樣:
  
  java代碼:
  
  time <- getCurrentTime
  print time
  javac
  print "success"
  
  我們的目標是:用腳本語言把前面繁雜的java代碼屏蔽起來,讓語法簡潔的腳本自動調用上面那些臃腫的代碼。
  
  幸好,我手頭有一個腳本語言可以達到類似的語法,
  
  java代碼:
  
  do {time=now} $
  info.print time >>
  javac {classpath=...; fork=...; compatibility="1.4";...} >>
  info.print "build successful"
  
  這些do, >>等函數其實是用SeqCommand, BoundCommand等實現的,只不過表面上看不到了。
  
  更加復雜的邏輯,比如包含順序執行,也包含錯誤處理的:
  java代碼:
  
  auto (info.println "build done") $
  do {time=now} $
  info.println ("build starting at " + time) >>
  do {t1 = readFile "file1"} $
  do {t2 = readFile "file2"} $
  let
  diff = t2 - t1;
  writeFile "file3" diff
  end
  
  這段腳本要先讀取當前時間,然后打印build start;然后先后從file1和file2讀取兩個數;然后把這兩個數的差額寫入file3, 最后,無論成功與否,打印build done。
  
  auto函數的意思是:當后面那些東西執行完畢后,無論是否出現exception,都要打印"build done"。
  
  你假如感愛好可以試著用java或者groovy寫寫,看看結果多么可怕。
  
  如此,一個完整的build框架就建立起來了,我們只要填空式地給系統加入各種command實現,一個靈活美麗的build tool就出爐了。
  
  最后,預告一下,基于這個思想的open source 項目Neptune即將啟動,歡迎有志之士參加。
  
  你可以參與這個框架核心的搭建(跟我合作),也可以編寫獨立的各種Command來豐富框架的功能。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲精品久久久久久777| 久久精品国产一区| 777精品视频| 97国产suv精品一区二区62| 日韩精品在线影院| 91精品成人久久| 韩国视频理论视频久久| 欧美在线视频导航| 日韩免费高清在线观看| 日韩欧美aaa| 欧美国产在线视频| 国产成人一区二区三区小说| 日韩一中文字幕| 日韩va亚洲va欧洲va国产| 亚洲自拍av在线| 全球成人中文在线| 日韩免费精品视频| 亚洲精品国偷自产在线99热| 国产精品第8页| 久久精品电影网站| 国产一区二区动漫| 国产精品久久久久aaaa九色| 91欧美视频网站| 国产美女久久精品| 欧美二区在线播放| 国产91精品最新在线播放| 91精品国产自产91精品| 日韩经典一区二区三区| 久久免费在线观看| 亚洲欧美国产va在线影院| 成人精品久久一区二区三区| 国产成人avxxxxx在线看| 亚洲精品99久久久久| 精品色蜜蜜精品视频在线观看| 高清日韩电视剧大全免费播放在线观看| 日韩av片电影专区| 国产欧美日韩综合精品| 尤物yw午夜国产精品视频| 91国产一区在线| 久久久久久久香蕉网| 久久久91精品| 亚洲第一福利视频| 日本午夜在线亚洲.国产| 国产成人av网| 国产999精品久久久影片官网| 久久综合亚洲社区| 亚洲精品aⅴ中文字幕乱码| 91在线观看免费高清完整版在线观看| 欧美激情视频网址| 91精品国产自产在线观看永久| 亚洲摸下面视频| 国产欧美日韩综合精品| 中文字幕免费精品一区高清| 欧美—级a级欧美特级ar全黄| 国产日韩欧美影视| 国产精品av电影| 亚洲国产又黄又爽女人高潮的| 国产精品一区二区女厕厕| 日韩欧美中文第一页| 久久夜色精品国产| 欧美激情精品久久久久久大尺度| 91香蕉电影院| 懂色av影视一区二区三区| 欧美日韩色婷婷| 亚洲国产第一页| 亚洲日本欧美日韩高观看| 精品久久久久久久久中文字幕| 亚洲欧洲中文天堂| 亚洲在线一区二区| 欧美亚洲激情视频| 欧美巨猛xxxx猛交黑人97人| 国产成人短视频| 亚洲欧美在线x视频| 久久九九精品99国产精品| 亚洲国产三级网| 日本三级韩国三级久久| 欧美激情视频给我| 91精品国产自产91精品| 4p变态网欧美系列| 国产99久久精品一区二区| 色99之美女主播在线视频| 在线亚洲午夜片av大片| 一区二区三区回区在观看免费视频| 大量国产精品视频| 久久精品视频在线播放| 日韩高清av在线| 91av视频在线免费观看| 国产91在线播放九色快色| 亚洲欧美综合区自拍另类| 欧美日韩国产区| 国产成人精品亚洲精品| 欧美黄色www| 91天堂在线观看| 成人午夜激情免费视频| 国色天香2019中文字幕在线观看| 在线观看欧美成人| 国产精品狠色婷| 国产精品91久久| 国产精品高清网站| 日韩欧美国产激情| 91系列在线播放| 欧美亚洲成人免费| 久久成人综合视频| 亚洲欧美日韩国产中文| 色综合久久天天综线观看| 日韩视频免费看| 国产精品手机播放| 国产亚洲精品va在线观看| 日日骚久久av| 伊人伊人伊人久久| 国产精品永久免费| 国产欧美日韩专区发布| 亚洲精品美女视频| 国产欧美日韩综合精品| 亚洲国产欧美一区二区三区久久| 欧美日韩性视频在线| 91精品国产综合久久香蕉| 亚洲精品日产aⅴ| 欧美日韩国产成人高清视频| 亚洲国产私拍精品国模在线观看| 欧美另类极品videosbest最新版本| 欧美一级淫片aaaaaaa视频| 51精品在线观看| 国产精品久久999| 欧美国产日韩精品| 欧美专区在线视频| 亚洲国产精品成人va在线观看| 中文字幕久久久av一区| 91在线视频成人| 日韩av一区在线观看| 国产成人在线一区二区| 久久中文久久字幕| 亚洲乱码一区二区| 精品欧美国产一区二区三区| 欧美在线观看一区二区三区| 国产一区二区三区直播精品电影| 日韩不卡中文字幕| 精品国产一区二区三区久久狼5月| 揄拍成人国产精品视频| 亚洲最新视频在线| 欧美人交a欧美精品| 在线免费看av不卡| 亚洲人成绝费网站色www| 精品久久久久久中文字幕大豆网| 在线精品播放av| 久久久人成影片一区二区三区| 北条麻妃久久精品| 日本一区二区三区在线播放| 日韩中文字幕视频| 日av在线播放中文不卡| 色琪琪综合男人的天堂aⅴ视频| 日本久久亚洲电影| 日韩在线观看网址| 国产成人一区二区三区小说| 裸体女人亚洲精品一区| 日本免费在线精品| 亚洲女人初尝黑人巨大| 午夜精品视频在线| 日韩av在线电影网| 亚洲欧美一区二区三区久久| xxxxxxxxx欧美| 中文字幕亚洲综合久久| 亚洲一区美女视频在线观看免费| 欧美午夜无遮挡|