GitHub Archive分析 - 2015最受矚目的項目們

你應該見過很多對GitHub上等等開源項目進行的分析文章。聽說國外甚至有人靠分析Github上的項目解決了畢業論文……(要是個人畢業論文也能這麼解決就行了XD) 藉助於Google Big Query和來自於GitHub Archive的數據歸檔,對GitHub上的項目進行簡單的數據分析並不困難。下文我將試圖分析2015年GitHub上被收藏(starred)最多的5000個項目,進而求出2015年最受矚目的編程語言排行。javascript

GitHub Archive這個網站經過GitHub的API,按期抓取GitHub的事件數據,並上傳到Google Big Query,供熱心羣衆分析。它在官網上介紹了如何用Google Big Query來分析數據前端

Google Big Query容許用戶建立項目,上傳數據歸檔,並經過SQL來查詢這些數據。下圖就是GitHub Archive在Big Query上,存儲着2016-02-01這一天數據的項目java

github-star-20160201

咱們能夠看到它的schema定義,基本上相似於GitHub事件API返回的數據格式。其中一些重要的字段以下:react

  • type 事件類型。好比jeresig建立了項目processing-js,那麼這個事件的類型就是CreateEvent。你能夠上GitHub事件相關的文檔裏查到各類事件對應的類型。git

  • repo.name 項目名,在上面例子中,是jeresig/processing-jsgithub

  • actor.login 該事件的主人公,在上面例子中,是jeresiggolang

因而咱們小試牛刀,運行下面的Query,查詢jeresig去年一年push的次數:(這裏用TABLE_DATE_RANGE函數用於匹配從githubarchive:day.events_20150101githubarchive:day.evnets_20151231全部的表)編程

SELECT COUNT(*) FROM 
    TABLE_DATE_RANGE([githubarchive:day.events_], 
        TIMESTAMP('2015-01-01'), 
        TIMESTAMP('2015-12-31'))
    WHERE type = 'PushEvent' and actor.login = 'jeresig'

得出的結果爲json

github-jeresig-push

稍微複雜點,運行下面的Query,查詢jeresig去年一年內提了Pull Request的項目和各自提的次數:bootstrap

SELECT COUNT(*) AS num, repo.name FROM 
    TABLE_DATE_RANGE([githubarchive:day.events_], 
        TIMESTAMP('2015-01-01'), 
        TIMESTAMP('2015-12-31'))
    WHERE type = 'PullRequestEvent' and actor.login = 'jeresig'
    GROUP BY repo.name ORDER BY num DESC

把關注點從人轉向項目,讓咱們迴歸主題,查詢去年一年間最受矚目的那些項目們,並粗略地分析下它們。經過查GitHub的API文檔,咱們知道用戶star一個項目時會觸發一個WatchEvent(對的,就是WatchEvent)。因此咱們能夠遍歷下去年全部的WatchEvent事件,按repo_name進行分組,計算每組的數目,並截取前5000名。寫出來的Query以下:

SELECT COUNT(*) AS star, repo.name FROM 
      TABLE_DATE_RANGE([githubarchive:day.events_], 
        TIMESTAMP('2015-01-01'), 
        TIMESTAMP('2015-12-31'))
      WHERE type = 'WatchEvent' 
      GROUP BY repo.name ORDER BY star DESC LIMIT 5000

我把Big Query查詢到的數據保存成github-star-2015.csv,分享到百度網盤上,有須要的人能夠下載:http://pan.baidu.com/s/1dElWKHr

如今,我宣佈,2015年最受矚目的項目前十的名單新鮮出爐啦!(請腦補最應景的BGM)

~/doc head -11 github-star-2015.csv 
star,repo_name
38318,FreeCodeCamp/FreeCodeCamp
25861,facebook/react-native
25479,apple/swift
24344,sindresorhus/awesome
22917,facebook/react
22093,jlevy/the-art-of-command-line
20401,NARKOZ/hacker-scripts
19736,twbs/bootstrap
17885,google/material-design-lite
17568,airbnb/javascript

初看這份名單,你會發現去年是React年。前十的名單裏,React就佔了兩。你也許會想起,swift在這一年裏開源了(果粉的力量真強大,一樣也是去年搬到GitHub的golang就擠不進前十名~)。仔細分析下各個項目,你會發現,漲star最快的項目有很多是代碼無關的項目。好比第一名FreeCodeCamp,第四名awesome,第六名the-art-of-command-life,第十名airbnb/javascript(airbnb內部的javascript編程規範)等等,都是如此。另外,一個顯著的發現是,前十名中,前端的項目佔了三個,這還不計算半個前端項目的react-native和前端編碼規範的airbnb/javascript。前端項目三分天下有其一,準確來說,已經接近撐起半邊天了。若是說前幾年的GitHub是Ruby開發者的GitHub,那麼現在的GitHub無疑是前端的GitHub。

藉助GitHub的API,咱們來看看前5000名項目的編程語言使用狀況。題外話,若是GitHub提供了項目全部者能夠給本身的項目打標籤,那麼咱們除了分析下編程語言,還能夠分析下更多方面的內容,好比去年哪一方面的項目最受矚目。要是有機會給GitHub產品部門提意見,我必定會寫上這一點。不過目前就只能分析分析下編程語言了。

因爲GitHub設置了API調用限制,咱們須要先註冊應用,獲取對應的client_idclient_secret,纔能有足夠的調用數量。註冊地址見 https://github.com/settings/applications/new,裏面的數據不須要審覈,我當時是亂填一通的=_=

GitHub提供了查詢某個項目的編程語言使用狀況的API,藉此寫出了下面的腳本,統計前5000個項目中編程語言的佔比:

#!/usr/bin/env ruby
# encoding: UTF-8

require 'json'
require 'net/http'
require 'set'

def get_language_ingredient(repo)
  url = "https://api.github.com/repos/#{repo}/languages"
  # 請改爲你本身的 client_id 和 client_secret
  client_id = '05500dd030f3a5690d8e'
  client_secret = 'b8ba63550e07dd3bf7b5b467824ee9ced1c61192'
  url += "?client_id=#{client_id}&client_secret=#{client_secret}"
  res = Net::HTTP.get_response(URI(url))
  if res.code == '200'
    JSON.parse(res.body)
  else
    puts res.msg
    {}
  end
end

def sum_star_number_per_language(result, repo, star)
  ingredient = get_language_ingredient(repo)
  puts "The language ingredient of #{repo}: #{ingredient}"
  return if ingredient.length == 0
  sum = ingredient.reduce(0){|total, pair| total += pair[1]}
  # 去掉佔比不到1%的語言
  ingredient.reject!{|_, bytes| bytes < sum * 0.01}
  # 若是剩下的語言正好是 JavaScript/CSS/HTML,
  # 則表示它極可能是代碼無關的項目,直接忽略掉
  if Set.new(ingredient.keys) == Set.new(['JavaScript', 'CSS', 'HTML'])
    # CSS框架除外。考慮到有些靜態網站也是CSS比JS多,這裏要求CSS比JS和HTML多得多。
    # 下面的公式隨手寫的,沒有什麼特殊意義,只是強調CSS必定要佔大多數。
    unless ingredient['CSS'] > 2 * ingredient['JavaScript'] + ingredient['HTML']
      return
    end
  end
  # 剩下的按比例分了star數
  sum = ingredient.reduce(0){|total, pair| total += pair[1]}
  ingredient.each_pair do |language, bytes|
    result[language] = result.fetch(language, 0) + (bytes.fdiv(sum) * star).round
  end
end

def output_star_number_per_language(result)
  sum = result.reduce(0){|total, pair| total += pair[1]}
  output = ''
  result.sort {|a, b| b[1] <=> a[1]}.each_with_index do |e, idx|
    output += format("%-4d %-40s %.2f%\n", idx+1, e[0], e[1].fdiv(sum).round(4) * 100)
  end
  output + "\n"
end

result = {}
output = {}
checkpoints = [50, 100, 200, 500, 1000, 2000, 5000]
f = File.new('github-star-2015.csv').each
f.next
f.each_with_index do |line, idx|
  step = idx + 1
  star, repo = line[0...-1].split(',')
  star = star.to_i
  puts format("%-4d %-40s %d", step, repo, star)
  sum_star_number_per_language(result, repo, star)
  puts "The result after #{repo}: #{result}\n\n"
  if checkpoints.include?(step)
    output[step] = output_star_number_per_language(result)
    puts "first #{step}"
    puts output[step]
  end
end
puts ''

output.each_pair do |step, rank|
    puts "first #{step}"
    puts rank
end

注意兩點:

  1. 獲取了每一個項目的語言成分後,去掉佔比不到1%的語言,剩下的語言按比例分掉star數。之因此不直接把star分到佔比最大的語言,是由於有些項目用到多種語言且比例至關,如facebook/react-native.

  2. 去掉1%以後,若是剩下的語言正好是JavaScript,CSS和HTML,那麼該項目極可能是代碼無關的(好比一個收集各種資料的靜態網站)。顯然你們關注它的緣故跟任何一門編程語言無關,因此不列入統計之中。可是考慮到CSS框架也正好會有這三門語言,因此當CSS佔比較高時能夠豁免。

下面是最終的結果:

...
first 5000
1    JavaScript                               26.38%
2    Java                                     13.33%
3    Objective-C                              8.21%
4    Python                                   8.09%
5    Go                                       5.44%
6    Swift                                    4.63%
7    C                                        3.88%
8    HTML                                     3.84%
9    C++                                      3.82%
10   Ruby                                     3.60%
11   CSS                                      3.28%
12   PHP                                      2.99%
13   Shell                                    2.67%
14   CoffeeScript                             1.51%
15   C#                                       1.19%
16   VimL                                     0.90%
17   TypeScript                               0.63%
18   Scala                                    0.59%
19   Lua                                      0.46%
20   Clojure                                  0.44%
21   Rust                                     0.39%
22   Haskell                                  0.28%
23   Makefile                                 0.22%
24   Objective-C++                            0.21%
25   Emacs Lisp                               0.21%
26   Jupyter Notebook                         0.21%
27   Perl                                     0.20%
28   TeX                                      0.17%
29   Elixir                                   0.16%
30   Groff                                    0.16%
31   Groovy                                   0.14%
32   R                                        0.12%
33   OCaml                                    0.11%
34   PowerShell                               0.10%
35   Batchfile                                0.10%
36   ApacheConf                               0.08%
37   Erlang                                   0.08%
38   Cucumber                                 0.08%
39   Assembly                                 0.07%
40   Crystal                                  0.06%
41   PureBasic                                0.05%
42   QML                                      0.05%
43   Visual Basic                             0.04%
44   PLpgSQL                                  0.04%
45   Tcl                                      0.04%
46   Dart                                     0.04%
47   Vue                                      0.04%
48   CMake                                    0.03%
49   PLSQL                                    0.03%
50   XSLT                                     0.03%
...

github-star-cake

一個顯而易見的結論:GitHub上不小一部分的熱門項目,是由JavaScript寫的。JavaScript一門語言的佔比,比第二名和第三名加起來還多出個第六名。這還不包括第十四名的CoffeeScript和第十七名的TypeScript(它們能夠編譯成JavaScript,嚴格來講也是JavaScript你們族的一員)。
另外從每一個checkpoint時輸出的數據可見,排名靠前的項目中,JavaScript佔的比例要比所有項目中的高。若是咱們選擇的樣本變小,JavaScript的佔比還會升高(都穩拿第一名,排名就不可能升高了)。

github-star-js-trending

另外一個結論是,Go(第五名)和Swift(第六名)這兩門語言正處於快速發展的時期。雖然實際應用的狀況不如前十名中其它語言普遍,可是從star數中可見,開發者們很是看好這兩門語言,關注了許多這方面的項目,同時用這兩門語言編寫的高質量項目也愈來愈多。

前十名中其它語言的排名卻是一點也不出乎意料。Java和Objective-C分居榜眼和探花。剩下幾位天然包括了C/C++/Python等等。使人意外的是,C#(第十五名)竟然沒能排進前十名。按理說,C#的使用量確定能排在前十。也許C#生態圈裏面主要使用的都是微軟的商業產品?

最後,我想感謝GitHub Archieve提供的數據歸檔,沒有這些數據就沒有本篇分析。

相關文章
相關標籤/搜索