沐鳴登錄平台_如何快速識別爛項目

軟件開發是一個非常有意思的複製 + 粘貼活動。開發業務代碼的時候,大部分人都不會不加思索地添加代碼。畢竟,聰明的產品經理/項目經理們,天才式地想出了用代碼行數的方式來計算 KPI,又或者是通過提交次數來進行考核 —— 雖然小步提交是個好東西,但是吧,大部分人不經過練習還是掌握不會的。

最近,我還我的朋友們說到,她們公司的打算強制一天只能提交一次代碼。這絕對是代碼行數計算 KPI 之後的,又一個偉大地創舉式的地發明。如果我有直接頒發諾貝爾獎的權力,我一定給送給他一獎盃。

好了,回到正題。

自上而下的代碼分析

最近,剛好因為項目的關係,需要分析某一系統的代碼行數。通過一系列的複製 + 粘貼和 Excel 操作,我大致有了一套 DIY 的自動化分析方案:自上而下的代碼分析。當然了,這肯定不是我先發明的,在某處一定有論文和代碼、工具。只是我依據自己的想法和需求,完善了一下現有的方案。要知道,已經有大量地代碼分析工具了。

其實總體的思路非常簡單:項目行數 -> 包行數 -> 修改歷史 -> 引用分析。

具體來說,就是:

  1. 通過代碼行數(LOC)統計工具,統計總體的代碼情況。
  2. 結合代碼行數(LOC)統計工具,統計各個包的代碼情況
  3. 獲取 Git 提交歷史,統計出經常修改的包或者是類。
  4. 構建語法樹、製品(如 jar)分析,統計出引用次數最多的包。

唯一麻煩的地方就是做一些自動化。所以,這些功能就被我完善到 Coca 里了,笑~。

好了,讓我們來看個示例。這裏以開源項目 intelli-community (即 IDEA 的社區版)為例。

項目級代碼行數

市面上已經有大量的行數統計工具,大家可以自行尋找。這裏我用的是 Coca (GitHub:https://github.com/phodal/coca ),集成了三方用 Go 實現的 CLOC 統計功能。

首先呢,我們要實現的是分析整個項目的行數情況 coca cloc . :

───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
Java                     66554   5172301   688054    512630  3971617     603221
Python                   10017    424614    31629     34876   358109      22329
Kotlin                    6383    602814    89130     35660   478024      51292
Plain Text                4105    635689     5799         0   629890          0
Groovy                    3397    154817    23296     12364   119157       4683
XML                       2549    494074    10056      3008   481010          0
html                      2329     63331     2988      3623    56720          0
SVG                       2124     21078       23        87    20968          0
jsON                      1155    346795      352         0   346443          0
Shell                      535      8295     1138       734     6423        811
Markdown                   425      9660     1434         0     8226          0
Properties File            384     42069     2545      1348    38176          0
YAML                       384      3264      202        55     3007          0
XML Schema                 345    196649    17963         0   178686          0
JavaScript                 169     30569     1562      5151    23856       3895
...
───────────────────────────────────────────────────────────────────────────────
Total                   101908   8389984   898893    629497  6861594     703260
───────────────────────────────────────────────────────────────────────────────
Estimated Cost to Develop $288,297,976
Estimated Schedule Effort 132.017220 months
Estimated People Required 258.681675
───────────────────────────────────────────────────────────────────────────────

嗯,從規模上來看,這真的是一個超級大的項目,接近 700 萬行的規模。所以,我第一次看到的時候,也不知道從哪裡下手,於是我便想着是不是從包(目錄)結構能解決這個問題。

PS:Coca 當前只支持單體分析,考慮有多模塊和微服務系統的存在,我會在未來必要的時候,添加對應的實現。

按目錄分析

簡單來說就是,我們可以按目錄執行 cloc,然後匯總結構即可。

所以,進一步地我們就可以執行 coca cloc . –by-directory,得到一個 CSV 數據,根據自己的需要進行編輯:

package summary Java Python Kotlin Plain Text
platform 1800542 1460686 106 244586 4669
java 1479891 1059828 0 35224 267792
plugins 1765695 983860 70301 151816 150158
android 1865010 769437 52 325659 101848
python 664760 240080 287641 24626 17855
xml 866926 108794 0 207 174471
jps 66671 63437 0 1498 729

還可以繪製成圖表。

除此,我還提供了一個 –top-file –top-size 10 的參數,以了解行數最多的幾個文件。

| LENGTH | COMPLEXITY |             LOCATION              |
|--------|------------|-----------------------------------|
|   1642 |        236 | constraintLayoutHandler.java      |
|   1492 |        375 | constraintComponentUtilities.java |
|   1189 |        166 | CommonActions.java                |
|   1184 |        325 | ConstraintWidget.java             |
|   1169 |        129 | SingleWidgetView.java             |
|   1115 |        213 | ScoutArrange.java                 |
|   1097 |        281 | ScoutWidget.java                  |
|   1081 |        224 | 3d/Rasterize.java                 |
|   1016 |        159 | LayoutlibSceneManager.java        |
|   1014 |        220 | TimeLinePanel.java                |

接着,只需要層層下推,我們就可以分析出哪個是系統最複雜的一部分。如下圖中的複雜點,依次是:platforms、java、plugins、android。

變更頻次

緊接着,我們就可以通過獲取 Git 提交歷史來知道,對應文件的修改變化。這裏,我依舊使用的是 coca git -t。它源自於對於 git log –all –date=short –pretty=”format:[%h] %aN %ad %s” –numstat –reverse –summary 命令的分析結果,有興趣的讀者可以參考 Coca 的源碼,自行編寫不同版本地對應實現。

可怕的是,我在 intellij-community 執行了 coca git -t 之後,生成了一個 241M 的文件,回去 GitHub 看了一眼:累計 290,459 次提交。

在我第一次沒意識到應該記錄下 log 之後,我又重新執行了一遍。最終,拿到了結果:

|                                                                                            ENTITYNAME       | REVSCOUNT | AUTHORCOUNT |
|-------------------------------------------------------------------------------------------------------------|-----------|-------------|
| platform/util/resources/misc/registry.properties                                                            |      2473 |         224 |
| platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java                                 |      1211 |         149 |
| platform/platform-api/resources/messages/IdeBundle.properties                                               |      1209 |         181 |
| platform/platform-resources/src/META-INF/LangExtensions.xml                                                 |      1206 |         192 |
| plugins/InspectionGadgets/InspectionGadgetsAnalysis/resources/messages/InspectionGadgetsBundle.properties   |      1113 |         159 |
| platform/platform-resources-en/src/messages/ActionsBundle.properties                                        |      1004 |         161 |
| platform/platform-resources/src/META-INF/PlatformExtensions.xml                                             |       937 |         162 |
| platform/util//src/com/intellij/util/ui/UIUtil.java                                                         |       779 |         120 |
| platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java                       |       763 |         133 |
| platform/platform-resources/src/META-INF/LangExtensionPoints.xml                                            |       762 |         150 |
| platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java                                   |       684 |         126 |
| java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java                |       675 |         117 |
| platform/platform-resources/src/idea/PlatformActions.xml                                                    |       671 |         139 |

然後,看一眼 registry.properties 是一個有 1800+ 行的配置文件,EditorImpl.java 是一個有 5000+ 行的 Java 代碼,UIUtil.java 也有 3600+ 行……。嗯,效果是不是也相當理想,再看看 UIUtil.java 這一個名字,一看就非常適合重構。

高引用

最後,可能會進入慢的一步,分析代碼,生成 AST。考慮到 IDEA Community 的這個代碼量。我就不重複演示了,以 GitHub 的示例為例 coca count:

+------------+--------------------------------------------------------------------------+
| REFS COUNT |                                  METHOD                                  |
+------------+--------------------------------------------------------------------------+
|          2 | com.phodal.pholedge.book.BookRepository.byId                             |
|          2 | com.phodal.pholedge.book.model.Book.toRepresentation                     |
|          2 | com.phodal.pholedge.book.BookRepository.save                             |
|          2 | com.phodal.coca.analysis.JavaCallApp.parse                               |
|          2 | com.phodal.pholedge.book.BookRepository.save                             |
|          2 | com.phodal.coca.analysis.JavaCallApp.parse                               |
|          1 | com.phodal.pholedge.book.model.Book.save                                 |

最後,我們又回到了這個模型上。

考慮到 AST 的慢的程度,我已經有一個更好的實現方式。

結論

分析代碼是一件很有意思的事情。一番操作下來,能學習到非常有意思的東西。

來自:https://www.phodal.com/blog/how-to-quick-analysis-project-levels/

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/9996