`
DigitalSonic
  • 浏览: 213626 次
社区版块
存档分类
最新评论

从Rails里“借”来的Ruby代码统计程序

阅读更多

以前每做完一个项目,或者完成某个里程碑的时候都喜欢用代码统计工具统计下自己的代码情况,看看多少LOC,多少注释。现在开始用Ruby写程序了,忽然发现竟然找不到支持Ruby的代码统计工具,偏偏自己这次写的东西又与Rails无关,不能用里面的stats……脑子一转,反正有空,就研究下Rails的代码统计代码,整理出来,让它能够单独运行。

由于原来的代码不统计注释,所以我加了对注释和注释率的统计,单行注释和写在代码后的注释都算作一行。另外,把原来的各个Rails目录的统计去掉了,只统计代码和测试,那些controller之类的就不考虑了。基本对原来的程序基本没有什么大修改。

通过命令行方式直接调用,即:ruby code_statistics.rb [<源代码目录> <测试代码目录>]
程序里用以下代码做了简单的判断,默认这两个参数分别是src和test。

 程序的运行效果与Rails里的stats差不多,只是多了些注释方面的统计数据。

显示效果


code_statistics.rb

class CodeStatistics
  def initialize(src, test)
    @pairs = [
      ["Codes",src + "/"],
      ["Tests",test + "/"]
    ].collect { |name, dir| [ name, "#{dir}" ] }.select { |name, dir| File.directory?(dir) }
    @statistics = calculate_statistics
    @total      = calculate_total if @pairs.length > 1
  end

  def to_s
    print_header
    @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
    print_splitter
  
    if @total
      print_line("Total", @total)
      print_splitter
    end

    print_code_test_stats
  end

  private
    def calculate_statistics
      @pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_directory_statistics(pair.last); stats }
    end

    def calculate_directory_statistics(directory, pattern = /.*\.rb$/)
      stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0, "comments" => 0}

      Dir.foreach(directory) do |file_name| 
        if File.stat(directory + "/" + file_name).directory? and (/^\./ !~ file_name)
          newstats = calculate_directory_statistics(directory + "/" + file_name, pattern)
          stats.each { |k, v| stats[k] += newstats[k] }
        end

        next unless file_name =~ pattern

        f = File.open(directory + "/" + file_name)

        while line = f.gets
          stats["lines"]     += 1
          stats["classes"]   += 1 if line =~ /class [A-Z]/
          stats["methods"]   += 1 if line =~ /def [a-z]/
          stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
          stats["comments"]  += 1 if line =~ /^\s*#/ || line =~ /^.*#/
        end
      end

      stats
    end

    def calculate_total
      total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0, "comments" => 0 }
      @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } }
      total
    end

    def calculate_code
      code_loc = 0
      @statistics.each { |k, v| code_loc += v['codelines'] unless k == "Tests" }
      code_loc
    end

    def calculate_tests
      test_loc = 0
      @statistics.each { |k, v| test_loc += v['codelines'] if k == "Tests" }
      test_loc
    end
    
    def calculate_comments
      comments = 0
      @statistics.each { |k, v| comments += v['comments']}
      comments
    end

    def print_header
      print_splitter
      puts "| Name  | Lines |   LOC | Classes | Methods | Comments | M/C | LOC/M | Cm/LOC |"
      print_splitter
    end

    def print_splitter
      puts "+-------+-------+-------+---------+---------+----------+-----+-------+--------|"
    end

    def print_line(name, statistics)
      m_over_c    = (statistics["methods"] / statistics["classes"])   rescue m_over_c = 0
      loc_over_m  = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0
      cm_over_loc = (statistics["comments"].to_f / statistics["codelines"]) rescue cm_over_loc = 0.0

      start = "| #{name.ljust(5)} " 

      puts start + 
           "| #{statistics["lines"].to_s.rjust(5)} " +
           "| #{statistics["codelines"].to_s.rjust(5)} " +
           "| #{statistics["classes"].to_s.rjust(7)} " +
           "| #{statistics["methods"].to_s.rjust(7)} " +
           "| #{statistics["comments"].to_s.rjust(8)} " +
           "| #{m_over_c.to_s.rjust(3)} " +
           "| #{loc_over_m.to_s.rjust(5)} " +
           "|   #{sprintf("%.2f", cm_over_loc.to_s)} |"
    end

    def print_code_test_stats
      code  = calculate_code
      tests = calculate_tests
      commnets = calculate_comments

      puts "  Code LOC: #{code}   Test LOC: #{tests}   Code:Test = 1:#{sprintf("%.1f", tests.to_f/code)}   LOC:Comments = 1:#{sprintf("%.1f", commnets.to_f/(code + tests))}"
      puts ""
    end
end

unless ARGV[0].nil? && ARGV[1].nil?
  CodeStatistics.new(ARGV[0], ARGV[1]).to_s
else
  CodeStatistics.new("src", "test").to_s
end

 

分享到:
评论

相关推荐

    Ruby-Rails日志分析器查看您的视图渲染的速度

    本话题主要关注如何使用Ruby编写日志分析器来洞察Rails应用中视图渲染的速度,从而优化整体性能。 首先,日志文件在Ruby on Rails中扮演着至关重要的角色,它们记录了应用程序运行时的详细信息,包括数据库查询、...

    ruby命令集合(一些有用的命令)

    - `rake stats`: 报告应用程序的代码统计信息,如KLOCs等。 - **测试** - `rake test`: 运行所有单元和功能测试。 - `rake test:functionals`: 运行功能测试。 - `rake test:integration`: 运行集成测试。 - `...

    Beginning Rails 4

    本书覆盖了从安装环境到构建完整 Web 应用程序的全过程,并深入探讨了 Rails 的核心概念与实践技巧。 #### 第1章:介绍 Rails 框架 这一章节首先介绍了当前 Web 开发领域的现状以及 Ruby on Rails 在其中扮演的...

    rails查询学习笔记

    Ruby on Rails,简称Rails,是一款基于Ruby语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,使得开发Web应用更加高效便捷。在Rails中,数据库查询主要通过ActiveRecord来实现,这是一个强大的...

    Ruby-sqltrackerRailsSQL查询跟踪器

    Rails框架是用Ruby语言编写的,广泛用于构建Web应用程序。在复杂的Rails应用中,数据库查询的性能往往成为系统瓶颈,sql_tracker就是为了解决这一问题而诞生的。 在Rails中,每当执行一个数据库查询,都会触发sql....

    Ruby-CoverbandRack中间件帮助测量生产代码覆盖率

    2. **性能分析**:通过对代码执行次数的统计,可以识别出性能瓶颈,从而优化代码。 3. **实时监控**:Coverband可以实时更新代码覆盖率数据,让开发者及时了解代码变动对应用性能的影响。 4. **灵活配置**:开发者...

    Rails3 使用rake启动后台任务

    Rails3 是 Ruby on Rails 框架的一个版本,它在2010年发布,引入了许多新特性并改进了框架的性能。Rake 是 Ruby 的一个构建工具,类似于 Java 的 Ant 或者 Python 的 setup.py,它允许开发者用自然语言定义任务,并...

    敏捷Rails中文教程

    - **在线考试系统**:通过构建一个在线考试系统,展示了如何使用Rails来管理试题、考生信息以及成绩统计等功能。 - **电子拍卖系统**:设计并实现了电子拍卖功能,涉及商品上架、竞价、支付等环节,展示了复杂的业务...

    rails/简易报告整理网页版

    ERB(Embedded Ruby)是Rails视图层的默认模板语言,允许在HTML中嵌入Ruby代码,从而动态渲染页面内容。项目中的视图文件可能包含erb代码,用于根据模型数据生成页面。 综上所述,“rails/简易报告整理网页版”...

    Ruby-mysql2一个现代的简单和非常快速的RubyMysql库

    在实际开发中,结合Rails或其他Ruby框架,mysql2库可以帮助开发者快速构建和扩展数据库驱动的应用程序。同时,由于其开源和活跃的社区支持,遇到问题时通常能找到丰富的文档和社区解答。 总结来说,Ruby-mysql2库是...

    Ruby-geoip搜索GeoIP数据库对于一个给定的主机或IP地址并返回IP地址分配的国家城市ISP和其他信息

    标题中的“Ruby-geoip”指的是一个Ruby编程语言的库,用于查询GeoIP数据库来获取特定IP地址或主机的相关信息。GeoIP数据库是由MaxMind公司提供的,它包含了全球范围内的IP地址与地理位置、国家、城市、ISP(互联网...

    Apress.Practical.Ruby.Projects.Dec.2007

    Ruby语言的设计哲学强调代码的可读性和效率,使得开发者能够快速地构建出高质量的应用程序。 ### 书籍内容概览 《实用的Ruby项目》一书涵盖了多个主题,从基础的Ruby语法到高级的概念,如元编程、并发处理、网络...

    finance-tracker:完整的Ruby on Rails开发人员课程的Finance Tracker应用程序

    3. 在线课程:如“Complete Ruby on Rails Developer”课程,提供实践项目如"Finance Tracker"来加深理解。 通过完成"Finance Tracker"这样的项目,开发者不仅能够掌握Rails的基本用法,还能理解Web应用的生命周期...

    BunkZilla:一个用于管理本科生铺位的 Ruby on Rails 应用程序

    Ruby on Rails(RoR)是一种基于模型-视图-控制器(MVC)架构模式的开源Web应用程序框架,它使用Ruby编程语言。RoR遵循DRY(Don't Repeat Yourself)原则,强调代码重用和简洁性,旨在提高开发效率和可维护性。它...

    Ruby编程语言详解(内容丰富)

    这一点体现在其简洁的语法上,比如无需分号结束语句,以及使用`begin...end`或者直接用`do...end`来代替大括号 `{}` 来定义代码块。 - **示例**: `puts "Hello, World!"` 是一个典型的Ruby示例,无需额外的结束符号...

    在线考试网源代码程序

    1. **Web开发框架**:在线考试系统的开发通常基于成熟的Web框架,如Django、Spring Boot或Ruby on Rails。这些框架提供了一套结构化的开发模式,帮助开发者快速构建动态网页应用。 2. **数据库设计**:源代码会涉及...

    Ruby-RedisDashboard一个用于监控Redis服务器的Sinatra应用

    **Ruby-RedisDashboard:一个Sinatra应用来监控Redis服务器** Ruby-RedisDashboard是基于Sinatra框架构建的一个轻量级Web应用,专为监控Redis服务器设计。这个应用提供了一个直观的界面,可以展示关于Redis服务器的...

    nwrun:用于跟踪 Niles West Track Team 的酷炫统计数据的 Rails 应用程序

    nwrun 是一个基于 Ruby on Rails 框架构建的应用程序,专为追踪 Niles West Track Team 的运动员表现而设计。这个应用集成了多种功能,包括数据处理、对象创建以及使用 JavaScript 图表库来可视化统计数据。 在 ...

    rails-url-shortener:用 Ruby on Rails 开发的个人 URL 缩短器

    Ruby on Rails 是一种流行的 web 应用程序开发框架,它采用 MVC(Model-View-Controller)架构模式,强调“约定优于配置”的开发理念,使得开发过程更加高效和简洁。 【描述】"rails-url-shortener" 项目的核心功能...

    rails open_flash_chart

    "Rails Open Flash Chart" 是一个基于Ruby on Rails框架的库,用于在Web应用程序中生成交互式的Flash图表。这个库允许开发者轻松地创建各种统计图表,如折线图、柱状图、饼图等,以便更好地可视化数据。由于Flash在...

Global site tag (gtag.js) - Google Analytics