你应该见过很多对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
咱们能够看到它的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_20150101
到githubarchive: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
稍微复杂点,运行下面的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_id
和client_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%的语言,剩下的语言按比例分掉star数。之因此不直接把star分到占比最大的语言,是由于有些项目用到多种语言且比例至关,如facebook/react-native.
去掉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上不小一部分的热门项目,是由JavaScript写的。JavaScript一门语言的占比,比第二名和第三名加起来还多出个第六名。这还不包括第十四名的CoffeeScript和第十七名的TypeScript(它们能够编译成JavaScript,严格来讲也是JavaScript你们族的一员)。
另外从每一个checkpoint时输出的数据可见,排名靠前的项目中,JavaScript占的比例要比所有项目中的高。若是咱们选择的样本变小,JavaScript的占比还会升高(都稳拿第一名,排名就不可能升高了)。
另外一个结论是,Go(第五名)和Swift(第六名)这两门语言正处于快速发展的时期。虽然实际应用的状况不如前十名中其它语言普遍,可是从star数中可见,开发者们很是看好这两门语言,关注了许多这方面的项目,同时用这两门语言编写的高质量项目也愈来愈多。
前十名中其它语言的排名却是一点也不出乎意料。Java和Objective-C分居榜眼和探花。剩下几位天然包括了C/C++/Python等等。使人意外的是,C#(第十五名)竟然没能排进前十名。按理说,C#的使用量确定能排在前十。也许C#生态圈里面主要使用的都是微软的商业产品?
最后,我想感谢GitHub Archieve提供的数据归档,没有这些数据就没有本篇分析。