Add the git-linguist helper

This commit is contained in:
Vicent Marti
2015-09-04 15:11:29 +02:00
parent b275b5d728
commit 13d1f662d1
3 changed files with 143 additions and 2 deletions

141
bin/git-linguist Executable file
View File

@@ -0,0 +1,141 @@
#!/usr/bin/env ruby
require 'linguist'
require 'rugged'
require 'optparse'
require 'json'
require 'tmpdir'
require 'zlib'
class GitLinguist
attr_reader :repo_path
attr_reader :commit_oid
attr_reader :incremental
def initialize(path, commit_oid, incremental = true)
@repo_path = path
@commit_oid = commit_oid || rugged.head.target_id
@incremental = incremental
end
def linguist
repo = Linguist::Repository.new(rugged, commit_oid)
if incremental && stats = load_language_stats
old_commit_oid, old_stats = stats
# A cache with NULL oid means that we want to froze
# these language stats in place and stop computing
# them (for performance reasons)
return old_stats if old_commit_oid == NULL_OID
repo.load_existing_stats(old_commit_oid, old_stats)
end
result = yield repo
save_language_stats(commit_oid, repo.cache)
result
end
def load_language_stats
version, commit_oid, stats = load_cache
if version == LANGUAGE_STATS_CACHE_VERSION && commit_oid && stats
[commit_oid, stats]
end
end
def save_language_stats(commit_oid, stats)
cache = [LANGUAGE_STATS_CACHE_VERSION, commit_oid, stats]
write_cache(cache)
end
def clear_language_stats
File.unlink(cache_file)
end
def disable_language_stats
save_language_stats(NULL_OID, {})
end
protected
NULL_OID = ("0" * 40).freeze
LANGUAGE_STATS_CACHE = 'language-stats.cache'
LANGUAGE_STATS_CACHE_VERSION = "v3:#{Linguist::VERSION}"
def rugged
@rugged ||= Rugged::Repository.bare(repo_path)
end
def cache_file
File.join(repo_path, LANGUAGE_STATS_CACHE)
end
def write_cache(object)
tmp_path = Dir::Tmpname.make_tmpname(cache_file, nil)
File.open(tmp_path, "wb") do |f|
marshal = Marshal.dump(object)
f.write(Zlib::Deflate.deflate(marshal))
end
File.rename(tmp_path, cache_file)
tmp_path = nil
ensure
(File.unlink(tmp_path) rescue nil) if tmp_path
end
def load_cache
marshal = File.open(cache_file, "rb") { |f| Zlib::Inflate.inflate(f.read) }
Marshal.load(marshal)
rescue SystemCallError, ::Zlib::DataError, ::Zlib::BufError, TypeError
nil
end
end
def git_linguist(args)
incremental = true
commit = nil
git_dir = nil
parser = OptionParser.new do |opts|
opts.banner = "Usage: git-linguist [OPTIONS] stats|breakdown|dump-cache|clear|disable"
opts.on("-f", "--force", "Force a full rescan") { incremental = false }
opts.on("--git-dir=DIR", "Path to the git repository") { |v| git_dir = v }
opts.on("--commit=COMMIT", "Commit to index") { |v| commit = v}
end
parser.parse!(args)
git_dir ||= begin
pwd = Dir.pwd
dotgit = File.join(pwd, ".git")
File.directory?(dotgit) ? dotgit : pwd
end
wrapper = GitLinguist.new(git_dir, commit, incremental)
case args.pop
when "stats"
wrapper.linguist do |linguist|
puts JSON.dump(linguist.languages)
end
when "breakdown"
wrapper.linguist do |linguist|
puts JSON.dump(linguist.breakdown_by_file)
end
when "dump-cache"
puts JSON.dump(wrapper.load_language_stats)
when "clear"
wrapper.clear_language_stats
when "disable"
wrapper.disable_language_stats
else
$stderr.print(parser.help)
exit 1
end
end
git_linguist(ARGV)

View File

@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.license = "MIT"
s.files = Dir['lib/**/*'] - ['lib/linguist/grammars.rb']
s.executables << 'linguist'
s.executables = ['linguist', 'git-linguist']
s.add_dependency 'charlock_holmes', '~> 0.7.3'
s.add_dependency 'escape_utils', '~> 1.1.0'

View File

@@ -1,3 +1,3 @@
module Linguist
VERSION = "4.5.15"
VERSION = "4.6.0.rc3"
end