本文翻譯自Contributing Codehtml
-----------------------------------------java
Apache Flink是由自願的代碼貢獻者維護、優化及擴展的。Apache Flink社區鼓勵任何人貢獻源代碼。爲了使得代碼貢獻者及複查者之便利,以及保存高質量的代碼基礎,咱們遵循着一個貢獻代碼的過程,該過程將在本文檔中詳細描述。git
本文包括有關向Flink貢獻代碼所需知曉的全部事宜,描述了從前期準備,測試以及代碼提交的過程,同時解釋了代碼編寫的準則以及Flink基礎代碼的代碼風格,此外給出了部署開發環境的教程。github
重要:請在進行代碼貢獻以前仔細閱讀該文檔,遵循下述的過程及準則十分重要。不然,你的 pull request可能不會被接受或須要大量返工。特別地,在開始一個實現新特性的 pull request時,你須要打開一個JIRA ticket,而且與開發社區在有關是否須要該特性達成一致。web
請肯定你的貢獻與一個JIRA的issue相關,這是Flink社區貢獻代碼時遵循的一個廣泛規定,除了修復瑣碎bug(trivial hot fixes),該規定覆蓋了包括bug修正、優化或新特性等等狀況。若是你想要修復找到的bug,或是想要添加新特性,或是想優化Flink,請遵循Flie a bug report和Propose an improvement or a new feature準則,在實現以前,打開一個Flink的JIRA的issue。apache
若是JIRA的issue的描述代表其解決方案會涉及到基礎代碼的敏感部分、它足夠複雜或是會添加大量新代碼,Flink社區可能須要一份設計文檔(大多數貢獻的代碼都不須要設計文檔)。該文檔的目的在於保證issue的總體解決方法是合理且經由社區贊成的。須要文檔的JIRA的issue將打上requires-design-doc的標籤,該標籤能夠由任何以爲文檔是必要的社區成員添加上去。一個好的issue描述能夠幫助人們決定該issue是否須要一份設計文檔。設計文檔必須添加或連接到JIRA的issue中,且須要知足如下幾個方面:intellij-idea
1. 整體方法的概述oracle
2. API改變的列表(改變的接口,新的或過時的配置參數,改變的行爲等等)app
3. 涉及到的主體組件( main component)和類eclipse
4. 該方法已知的缺陷
任何人均可以添加設計文檔,包括issue的提出者和解決者
JIRA issue的代碼貢獻中,那些須要文檔的貢獻須要其文檔被社區以lazy consensus的方式接受後才能夠添加到Flink的基礎代碼中。請在編寫代碼以前檢查並確認是否須要設計文檔。
請儘量遵循如下規則:
1. 請重視JIRA的issue中記錄歸檔的討論或需求。
2. 若是須要設計文檔,則儘量遵循該文檔的設計。若是你的實現和文檔設計誤差過大,請實時更新文檔並與社區達成一致。少許的誤差是容許的,不過在提交代碼時請指出這些變更之處。
3. 嚴格遵循coding guidelines and the code style。
4. 不要在一次代碼貢獻中混淆入其餘不相關的issue
請隨時隨意提問,不論發送郵件給dev mailing list仍是在JIRA issue中評論均可。
有關部署開發環境,見下面第四部分所述。
提交前驗證代碼的合規性十分重要,主要驗證如下幾點:
1. 保證代碼能夠編譯
2. 驗證經過全部已存在的新的測試
3. 檢查代碼風格不違規
4. 保證沒有不相關或沒必要要的格式上的變更
你能夠經過如下命令編譯代碼、運行並測試、檢查部分代碼風格:
mvn clean verify
請注意,有些Flink的基礎代碼的測試比較奇詭(flaky)並可能意外地失敗,Flink社區正在努力提高這些測試的質量,但有的測試沒法繼續優化,如包括外部依賴的測試等。咱們將全部奇詭的測試維護在JIRA中,並加上了test-stability標籤。若是你遇到彷佛與你的改變無關的測試失敗的狀況,請查看或擴展已知奇詭測試的列表。
請注意,爲了驗證你貢獻的代碼,咱們針對Java,Scala,Hadoop不一樣版本的組合形式運行不一樣的編譯profile。咱們鼓勵每一個貢獻者使用continuous integration服務,它將在你每次push一個change時自動測試代碼。Best practices一文中有如何將Travis集成到你的Github倉庫的教程。
除了自動測試以外,請檢查你的修改,並移除諸如沒必要要的格式修改等無關的修改。
爲了使得merge更加方便,請將這些新的修改rebase到主倉庫master分支的最新版本。也請遵循下文代碼編寫引導(本文2.1),清除你的commit歷史,且將你的全部提交 squash到一個合適的集合中。請在rebase以及commit squash後對你的代碼進行屢次驗證。
Flink工程經過GitHub Mirror,以Pull request的形式接受代碼貢獻。Pull request是一個提供補丁的簡單方法,它經過提供一個代碼分支的指針的方式來包含修改。
經過將咱們的貢獻push回到咱們fork的Flink倉庫來啓用一個pull request
git push origin myBrance
進入你的fork倉庫網址(https://github.com/<your-user-name>/flink),而且使用"Create Pull Request"按鈕來建立一個pull request。確保base fork是 apache/flink master而且head fork包括了你的修改的分支。給你的pull request一個有意義的描述而且發送過來。
固然,你也能夠經過JIRA issue來添加一個補丁。
1. 每一個pull request僅負責一個修改。請不要將不一樣的無關改變混合到一個pull request中。相反地,請用多個獨立pull request對應JIRA issue。這保證pull request是topic相關的,從而能夠更加方便地merge,而且一般只會引發與該topic有關的衝突。
2. 不要再pull request中包含WIP(仍在開發中)。咱們認爲pull request是要不作會任何改進地merge到當前穩定主分支上去的。所以,一個pull request不該當爲「work in progress」的。僅在你確信該pull request能夠順利merge到當前主branch中時纔開始一個pull request。而若是你想要對你的代碼的意見,請發佈你的工做分支的連接。
3. Commit信息。一個pull request必須與一個JIRA issue相關;若是你想解決一個JIRA上沒有的問題,請建立一個issue。最新的commit信息應當引用該issue,例如,"[FLINK-633] Fix NullPointerException for empty UDF parameters"。如此,該pull request會自動給它的內容加上描述,如以何種方式修復了什麼bug
4. 複覈commit。若是你在pull request上獲得要求修改的評論,commit這些修改。不要rebase以及squash這些commit。這樣才能讓他人獨立查看cleanup的部分。不然複查者就須要再一次從新複查整個集合。
1. Exception swallowing。不要swallow異常並打印堆棧軌跡,而應該查看相似的類是如何處理異常的並加以模仿。
2. 錯誤信息要有意義。給出的錯誤信息要有意義,試着猜想異常爲什麼被拋出而且給出能夠幫助到用戶解決問題的信息。
1. 須要經過全部測試。任何沒法經過測試或沒法編譯的pull request不會再進一步進行審查。咱們建議將你的GitHub私人帳號與Travis CI鏈接(像Flink的Github倉庫)。請注意以前有關奇詭測試的說明。
2. 須要測試新特性。全部新特性都須要由測試來嚴格保證。在接下來的merge中拋出或是破壞某特性。若是沒有該特性沒有測試來保證,這些問題將沒法被意識到。全部未被測試覆蓋的東西都是浮於表面的。
3. 使用合適的測試機制。請使用單元測試來孤立測試功能,例如方法等。單元測試應當以亞秒級執行而且應當考慮全部狀況。類的單元測試的名字應當是"*Test"。使用繼承測試來實現long-running測試。
1. 文檔更新。許多系統中的改變一樣會影響到文檔(JavaDocs文檔和在目錄docs/下的用戶文檔)。 pull request和補丁須要更新對應的文檔,不然提交的改變將不會被源碼接受。有關如何更新文檔見於貢獻文檔指導一文。
2. 公共方法的Javadocs。全部公共方法和類須要JavaDoc。請填寫有意義的文檔,一個好的文檔應當是簡明扼要而富含信息的。若你改變了簽名或是已有文檔的方法的行爲,請務必同時更新JavaDoc。
1. 不要從新排版。請不要對源碼文件從新排版,若你或你的IDE自動移除/替換了空白字符,從新排版代碼或是自動註釋後,代碼差異(diff)將不可辨識。一樣的,其餘影響相同文件的補丁將沒法進行merge操做。請配置您的IDE使其不會自動重排版。咱們可能會拒絕帶有過多或沒必要要的代碼重排版的pull request
1. Apache license header。確保你的源碼文件中包含Apache License header,RAT插件將會在你編譯代碼時檢查是否含有該header。
2. Tabs 或是 space。咱們使用tab(而不是space)做爲縮進符號。這只是因爲咱們開始時就使用tab,但不要將它們混用十分重要,不然會引起merge或diff時的衝突。
3. Block。全部if,for,while,do等語句必須包含在大括號封裝的代碼塊中(即便只有一行代碼,一樣須要大括號包圍代碼塊),以下代碼所示,這將有效避免諸如Apple的SSL library的goto bug等問題。
for(…){ … }
4. 不要在import語句中使用通配符。不要再核心文件中的import語句中使用通配符,它們會在adding到代碼(adding to the code)甚至有時在重構(refactoring)期間產生一些問題。在導入operator和function時,異常將出如今Tuple類,與Tuple相關的支持類以及Flink user程序。測試則是user程序的特殊用例。
5. 不要留下沒用的import語句。請移除全部沒用的import語句。
6. 使用Guava檢測。爲了增長代碼的同質性,請一導致用Guava方法checkNotNull和checkArgument來檢測,而不是使用Apache Commons Validate
7. Supress warnings:若是它們suppress warning沒法避免(如"unchecked"或"serial"等),請添加聲明註解(annotation)。
8. 註釋。請爲代碼添加有關邏輯的註釋。能夠經過添加JavaDoc,或是經過不對方法作任何註釋而繼承原來的註釋等方法添加。不要自動生成註釋,避免諸如"i++; // increment by one"這樣無用的註釋
1. Travis:Flink已經預先針對Travis CI作了配置,使其能夠很方便地在你的私人fork的倉庫中啓用(它使用GitHub來進行身份認證,因此你不須要另外一個帳號來進行驗證)。能夠簡單地添加Travis CI的hook到你的倉庫(settings -> webhooks & services -> add service),並啓用Travis上對flink倉庫的測試。
1. 類Unix環境(咱們使用Linux,Mac OS X, Cygwin)
2. git
3. Maven(至少爲版本3.0.4)
4. Java 7或8
Apache Flink的源代碼存儲在git倉庫中,並鏡像存儲在Github。Github上交換代碼通常講倉庫fork到你的私人Github帳戶倉庫。爲此,你須要一個Github帳戶或免費建立一個。Fork一個倉庫意味着Github爲你建立了一個倉庫的副本,該操做能夠經過點擊倉庫站點頁面中右上角的fork按鈕完成。一旦你將Flink倉庫fork到你的私人帳戶,你就能夠將該倉庫clone到你的本地設備上。經過如下命令,源碼將會下載到名爲flink的目錄下。
git clone https://github.com/<your-user-name>/flink.git
若是你處於防火牆保護之下,你可能須要爲Maven和你的IDE提供代理設置。例如WikipediaEditsSourceTest經過IRC通訊,而且須要一個SOCKS proxy server來繞過。
Flink的提交者們使用IntelliJ IDEA和Eclipse IDE來開發Flink基礎代碼。
5.4.1 IDE的最低要求:
· 支持JAVA和Scala語言,同時支持兩者的混合項目。
· 支持Java和Scala的Maven。
5.4.2 IntelliJ IDEA
IntelliJ IDE自帶支持Maven,而且提供了Scala開發的插件
IntelliJ下載地址:https://www.jetbrains.com/idea/
IntelliJ Scala Plugin:http://plugins.jetbrains.com/plugin/?id=1347
有關IntelliJ的設置,請看Setting up IntelliJ一文指導
5.4.3 Eclipse Scala IDE
對於Eclipse用戶,咱們建議基於Eclipse Kepler,使用Scala IDE 3.0.3。儘管該版本有些舊,但咱們發現這是Flink等複雜項目運行最爲魯棒的版本。
進一步細節以及更新的Scala IDE版本的指導在How to setup Eclipse文檔中。
注意:在開始下列部署以前,確保經過使用該一次如下命令來運行編譯程序(mvn clean install -DskipTests,詳情見上文)
1. 下載Scala IDE(推薦)或是安裝Eclipse Kepler的插件。下載連接和指令見於How to setup Eclipse
2. 向Scala編譯器添加添加"macroparadise"編譯器插件。打開"Winodw" -> "Preferences" -> "Scala" -> "Complier" -> "Advanced",並添加"Xplugin"域和macroparadise的jar文件的路徑(一般是"/home/-your-user-/.m2/repository/org/scalamacros/paradise_2.10.4/2.0.1/pardise_2.10.4-2.0.1.jar")。注意:若是你沒有jar文件,多是因爲你沒有運行命令行來編譯生成。
3. 導入Flink Maven工程("File" -> "Import" -> "Maven" -> "Existing Maven Projects")
4. 在導入期間,Eclipse將會自動詢問是否自動安裝額外Maven build helper插件。
5. 關閉"flink-java8"工程,因爲Eclipse Kepler不支持Java 8,你沒法開發此工程
5.4.4 導入源碼
Apache Flink使用Apache Maven做爲編譯工具,大多數IDE均可以導入Maven工程。
爲了從源碼編譯Flink,咱們能夠打開一個終端,導航到Flink源碼的根目錄,並調用命令"mvn clean package"。該命令將編譯Flink並運行全部測試,Flink最終將安裝在目錄build-target。
爲了編譯Flink時不運行測試,你能夠調用命令"mvn -DskipTests clean package"
只有ASF的infrastructure team具備Github鏡像的管理員訪問權限,所以,提交者須要將修改push到ASF的git倉庫。
Main source倉庫
ASF writable:https://git-wip-us.apache.org/repos/asf/flink.git
ASF read-only:git://git.apache.org/repos/asf/flink.git
ASF read-only:https://github.com/apache/flink.git
注意:Flink不使用Oracle JDK 6編譯,但它可使用Oracle JDK 6運行。
若是你想要爲Hadoop1編譯,經過命令"mvn clean package -DskipTests -Dhadoop.profile=1"來激活編譯profile。
7、快照版本(每夜構建Nightly builds)
Apache Flink 1.1-SNAPSHOT是咱們最新的開發版本。
你能夠下載咱們打包的每夜構建版本,它包括最新的開發代碼,由此可使用還未發佈的新特性。僅有經過全部測試的編譯版本纔會發佈在此處。
· Hadoop 1: flink-1.1-SNAPSHOT-bin-hadoop1.tgz
· Hadoop 2 和YARN :flink-1.1-SNAPSHOT-bin-hadoop2.tgz
添加Apache Snapshot repository到你的Maven的pom.xml:
1 <repositories> 2 <repository> 3 <id>apache.snapshots</id> 4 <name>Apache Development Snapshot Repository</name> 5 <url>https://repository.apache.org/content/repositories/snapshots/</url> 6 <releases><enabled>false</enabled></releases> 7 <snapshots><enabled>true</enabled></snapshots> 8 </repository> 9 </repositories>
至此,你就能夠將版本1.1-SNAPSHOT(或版本1.1-SNAPSHOT-hadoop1來兼容舊的1.x版本hadoop)的Apache Flink包括到一個Maven依賴中了。