当前位置:首页 > 开发 > 编程语言 > go语言 > 正文

使用golang统计代码行数

发表于: 2012-09-09   作者:coolxing   来源:转载   浏览次数:
摘要: 有关golang的介绍请参考我的另一篇博文.     本文通过递归遍历src目录, 统计代码行数. 涉及到的知识点有: 1. 目录遍历. 2. 读取文件. 3. 使用channel进行goroutine间的通信. 4. 使用sync包进行传统的共享内存方式的同步. 5. 错误处理. 6. defer语句的使用.     在程序中有详细

有关golang的介绍请参考我的另一篇博文.

 

 

本文通过递归遍历src目录, 统计代码行数. 涉及到的知识点有:

1. 目录遍历.

2. 读取文件.

3. 使用channel进行goroutine间的通信.

4. 使用sync包进行传统的共享内存方式的同步.

5. 错误处理.

6. defer语句的使用.

 

 

在程序中有详细的注释:

 

// a simple go program for computing total line of souce files stored in one dir
package main

import (
	"fmt"
	"bufio"
	"os"
	"sync"
	"strings"
)

var (
	linesum int
	mutex   *sync.Mutex = new(sync.Mutex)
)

var (
	// the dir where souce file stored
	rootPath string = "/home/xing/Dropbox/source/go/src"
	// exclude these sub dirs
	nodirs [5]string = [...]string{"/bitbucket.org", "/github.com", "/goplayer", "/uniqush", "/code.google.com"}
	// the suffix name you care
	suffixname string = ".go"
)

func main() {
	argsLen := len(os.Args)
	if argsLen == 2 {
		rootPath = os.Args[1]
	} else if argsLen == 3 {
		rootPath = os.Args[1]
		suffixname = os.Args[2]
	}
	// sync chan using for waiting
	done := make(chan bool)
	go codeLineSum(rootPath, done)
	<-done

	fmt.Println("total line:", linesum)
}

// compute souce file line number
func codeLineSum(root string, done chan bool) {
	var goes int              // children goroutines number
	godone := make(chan bool) // sync chan using for waiting all his children goroutines finished
	isDstDir := checkDir(root)
	defer func() {
		if pan := recover(); pan != nil {
			fmt.Printf("root: %s, panic:%#v\n", root, pan)
		}

		// waiting for his children done
		for i := 0; i < goes; i++ {
			<-godone
		}

		// this goroutine done, notify his parent
		done <- true
	}()
	if !isDstDir {
		return
	}

	rootfi, err := os.Lstat(root)
	checkerr(err)

	rootdir, err := os.Open(root)
	checkerr(err)
	defer rootdir.Close()

	if rootfi.IsDir() {
		fis, err := rootdir.Readdir(0)
		checkerr(err)
		for _, fi := range fis {
			if strings.HasPrefix(fi.Name(), ".") {
				continue
			}
			goes++
			if fi.IsDir() {
				go codeLineSum(root+"/"+fi.Name(), godone)
			} else {
				go readfile(root+"/"+fi.Name(), godone)
			}
		}
	} else {
		goes = 1 // if rootfi is a file, current goroutine has only one child
		go readfile(root, godone)
	}
}

func readfile(filename string, done chan bool) {
	var line int
	isDstFile := strings.HasSuffix(filename, suffixname)
	defer func() {
		if pan := recover(); pan != nil {
			fmt.Printf("filename: %s, panic:%#v\n", filename, pan)
		}
		if isDstFile {
			addLineNum(line)
			fmt.Printf("file %s complete, line = %d\n", filename, line)
		}
		// this goroutine done, notify his parent
		done <- true
	}()
	if !isDstFile {
		return
	}

	file, err := os.Open(filename)
	checkerr(err)
	defer file.Close()

	reader := bufio.NewReader(file)
	for {
		_, isPrefix, err := reader.ReadLine()
		if err != nil {
			break
		}
		if !isPrefix {
			line++
		}
	}
}

// check whether this dir is the dest dir
func checkDir(dirpath string) bool {
	// 判断该文件夹是否在被排除的范围之内
	for _, dir := range nodirs {
		if rootPath+dir == dirpath {
			return false
		}
	}
	return true
}

func addLineNum(num int) {
	// 获取锁
	mutex.Lock()
	// defer语句在函数返回时调用, 确保锁被释放
	defer mutex.Unlock()
	linesum += num
}

// if error happened, throw a panic, and the panic will be recover in defer function
func checkerr(err error) {
	if err != nil {
		// 在发生错误时调用panic, 程序将立即停止正常执行, 开始沿调用栈往上抛, 直到遇到recover
		// 对于java程序员, 可以将panic类比为exception, 而recover则是try...catch
		panic(err.Error())
	}
}
 

 

使用golang统计代码行数

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
-- Visual Studio 2005 插件开发 代码行数统计器(一) 为你的命令使用自定义图标 当你创建了一个
开发过程中,经常需要统计代码行数,这时可以通过Eclipse的Search功能来实现。 步骤: 1、在Package
源代码行数统计器使用说明 概述 目的: 供QA考核项目度量指标时使用。 内容: 本文主要内容讲解源代
1.程序简介 这个程序使用来统计文件夹中的所有文件中非空行的行数。代码比较简单易懂,使用递归的方
最近忙着在做一个项目,忙里偷闲放松下,想看看整个项目到底有多少行代码,可是找半天还是没找到可
最近忙着在做一个项目,忙里偷闲放松下,想看看整个项目到底有多少行代码,可是找半天还是没找到可
最近忙着在做一个项目,忙里偷闲放松下,想看看整个项目到底有多少行代码,可是找半天还是没找到可
今天公司SQA问我目前项目代码行数有多少,我当时就是想,以前好像写过类似的统计工具但是一时又找不
最近需要有一个项目 需要估计下代码量 所以就想找原来的项目 看下有多少行 然后再估算。于是上网搜
通过 Eclipse 的 search 功能(一个比较间接的方式): 1) 打开 File Search 对话框; 2) 勾选 Regu
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号