跳转至

利用go-enry分析代码语言

GitHub Linguist是GitHub用于检测代码仓库语言的工具,可以分析代码仓库的文件有哪些语言及其占比。本文介绍Go语言的实现enry工具

准备工作

获取go-enry

Bash
go get github.com/go-enry/go-enry/v2

使用go-enry

Go
import "github.com/go-enry/go-enry/v2"

基于文件名称的推断

go-enry可以根据文本名称或者扩展名,来获取文件的相关信息。

准确度:低

Go
1
2
3
4
5
6
7
// 根据 文件扩展名 获取语言信息,适用于各类编程语言,根据文件扩展名,自动识别语言
lang, safe := enry.GetLanguageByExtension("hello.go")
fmt.Println(lang, safe) // Go true

// 根据 文件名 获取语言信息,适用于 `.zshrc` `nginx.conf` 等专用的文件名
lang, safe = enry.GetLanguageByFilename("nginx.conf")
fmt.Println(lang, safe) // Nginx true

基于文本内容的推断

go-enry可以根据文本的内容,获取文件的相关信息

准确度:中

Go
// 根据 文本的第一行 获取语言信息
lang, safe := enry.GetLanguageByShebang([]byte("#!/usr/bin/bash\necho hello world"))
fmt.Println(lang, safe) // Shell true

// 根据 Vim/Emacs的模式行 获取语言信息
lang, safe = enry.GetLanguageByModeline([]byte("/* vim: set ft=cpp: */"))
fmt.Println(lang, safe) // C++ true

// 利用 内置分类器 和给定的 语言列表 获取语言信息
lang, safe = enry.GetLanguageByClassifier([]byte("def foo():\n    pass"), []string{"C++", "Python", "Matlab"})
fmt.Println(lang, safe) // Python false

基于文件名称和内容的推断

go-enry还可以根据文件名称和文本内容,获取文件的相关信息

准确度:高

Info

如果使用 enry.GetLanguage 方法,则会返回可能的语言列表中的第一个语言(字母顺序,可能不准确)

Go
1
2
3
4
5
langs := enry.GetLanguages("a.m", []byte("a=1"))
fmt.Println(langs) // [M MATLAB Mathematica Mercury Objective-C MUF Limbo]

langs = enry.GetLanguages("a.py", []byte("a=1"))
fmt.Println(langs) // [Python]

判断文件性质

go-enry还提供了一些判断文件性质的工具方法

Go
fp := "/Users/lzwang/example.png"
// 判断是否是图片
fmt.Println(enry.IsImage(fp)) // true
// 判断是否是 vendor 类型的文件
fmt.Println(enry.IsVendor(fp)) // false
// 判断是否是 . 开头的文件/系统隐藏文件
fmt.Println(enry.IsDotFile(fp))           // false
fmt.Println(enry.IsDotFile(".gitignore")) // true
// 判断是否是测试文件
fmt.Println(enry.IsTest("a.py"))      // false
fmt.Println(enry.IsTest("test_a.py")) // true
// 判断是否是配置文件
fmt.Println(enry.IsConfiguration(fp))            // false
fmt.Println(enry.IsConfiguration("config.yaml")) // true
// 判断是否是文档文件
fmt.Println(enry.IsDocumentation(fp))          // false
fmt.Println(enry.IsDocumentation("README.md")) // true

fb, _ := os.ReadFile(fp)
// 判断是否是二进制文件
fmt.Println(enry.IsBinary(fb)) // true
// 判断是否是生成的文件
fmt.Println(enry.IsGenerated(fp, fb)) // false

参考