gifts 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +9 -0
- data/gifts.gemspec +32 -0
- data/lib/gifts.rb +22 -0
- data/lib/gifts/commit_table.rb +70 -0
- data/lib/gifts/database.rb +49 -0
- data/lib/gifts/diff_table.rb +55 -0
- data/lib/gifts/file_table.rb +51 -0
- data/lib/gifts/repo_table.rb +31 -0
- data/lib/gifts/table_base.rb +18 -0
- data/lib/gifts/term_table.rb +28 -0
- data/lib/gifts/user_table.rb +19 -0
- data/lib/gifts/version.rb +3 -0
- data/spec/.gitkeeper +0 -0
- data/vendor/lib/LICENSE-grit +22 -0
- data/vendor/lib/LICENSE-grit_ext +22 -0
- data/vendor/lib/gifts/grit.rb +73 -0
- data/vendor/lib/gifts/grit/actor.rb +52 -0
- data/vendor/lib/gifts/grit/blame.rb +70 -0
- data/vendor/lib/gifts/grit/blob.rb +126 -0
- data/vendor/lib/gifts/grit/commit.rb +324 -0
- data/vendor/lib/gifts/grit/commit_stats.rb +128 -0
- data/vendor/lib/gifts/grit/config.rb +44 -0
- data/vendor/lib/gifts/grit/diff.rb +97 -0
- data/vendor/lib/gifts/grit/errors.rb +10 -0
- data/vendor/lib/gifts/grit/git-ruby.rb +262 -0
- data/vendor/lib/gifts/grit/git-ruby/commit_db.rb +52 -0
- data/vendor/lib/gifts/grit/git-ruby/git_object.rb +353 -0
- data/vendor/lib/gifts/grit/git-ruby/internal/file_window.rb +58 -0
- data/vendor/lib/gifts/grit/git-ruby/internal/loose.rb +137 -0
- data/vendor/lib/gifts/grit/git-ruby/internal/pack.rb +398 -0
- data/vendor/lib/gifts/grit/git-ruby/internal/raw_object.rb +44 -0
- data/vendor/lib/gifts/grit/git-ruby/repository.rb +784 -0
- data/vendor/lib/gifts/grit/git.rb +501 -0
- data/vendor/lib/gifts/grit/index.rb +222 -0
- data/vendor/lib/gifts/grit/lazy.rb +35 -0
- data/vendor/lib/gifts/grit/merge.rb +45 -0
- data/vendor/lib/gifts/grit/ref.rb +98 -0
- data/vendor/lib/gifts/grit/repo.rb +722 -0
- data/vendor/lib/gifts/grit/ruby1.9.rb +15 -0
- data/vendor/lib/gifts/grit/status.rb +153 -0
- data/vendor/lib/gifts/grit/submodule.rb +88 -0
- data/vendor/lib/gifts/grit/tag.rb +97 -0
- data/vendor/lib/gifts/grit/tree.rb +125 -0
- data/vendor/lib/gifts/grit_ext.rb +41 -0
- data/vendor/lib/gifts/grit_ext/actor.rb +15 -0
- data/vendor/lib/gifts/grit_ext/blob.rb +26 -0
- data/vendor/lib/gifts/grit_ext/commit.rb +15 -0
- data/vendor/lib/gifts/grit_ext/diff.rb +23 -0
- data/vendor/lib/gifts/grit_ext/tag.rb +10 -0
- data/vendor/lib/gifts/grit_ext/tree.rb +10 -0
- data/vendor/lib/gifts/grit_ext/version.rb +7 -0
- metadata +256 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Sato Hiroyuki
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Gifts
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'gifts'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install gifts
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/gifts.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
vendor = File.expand_path('../vendor/lib', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(vendor) unless $LOAD_PATH.include?(vendor)
|
6
|
+
require 'gifts/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |gem|
|
9
|
+
gem.name = "gifts"
|
10
|
+
gem.version = Gifts::VERSION
|
11
|
+
gem.authors = ["Sato Hiroyuki"]
|
12
|
+
gem.email = ["sathiroyuki@gmail.com"]
|
13
|
+
gem.description = %q{Git Fulltext Search library}
|
14
|
+
gem.summary = %q{Git Fulltext Search library}
|
15
|
+
gem.homepage = ""
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib", "vendor/lib"]
|
21
|
+
|
22
|
+
gem.add_dependency "posix-spawn", "~> 0.3.6"
|
23
|
+
gem.add_dependency "mime-types", "~> 1.15"
|
24
|
+
gem.add_dependency "diff-lcs", "~> 1.1"
|
25
|
+
gem.add_dependency "charlock_holmes", "~> 0.6.9"
|
26
|
+
gem.add_dependency "rroonga", "~> 2.1.3"
|
27
|
+
|
28
|
+
gem.add_development_dependency "rake"
|
29
|
+
gem.add_development_dependency "rspec"
|
30
|
+
gem.add_development_dependency "pry"
|
31
|
+
gem.add_development_dependency "mocha"
|
32
|
+
end
|
data/lib/gifts.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "groonga"
|
2
|
+
require 'fileutils'
|
3
|
+
require 'delegate'
|
4
|
+
require 'forwardable'
|
5
|
+
require 'charlock_holmes'
|
6
|
+
|
7
|
+
require "gifts/grit"
|
8
|
+
require "gifts/grit_ext"
|
9
|
+
|
10
|
+
require "gifts/version"
|
11
|
+
require "gifts/database"
|
12
|
+
require "gifts/table_base"
|
13
|
+
require "gifts/repo_table"
|
14
|
+
require "gifts/commit_table"
|
15
|
+
require "gifts/file_table"
|
16
|
+
require "gifts/diff_table"
|
17
|
+
require "gifts/term_table"
|
18
|
+
require "gifts/user_table"
|
19
|
+
|
20
|
+
module Gifts
|
21
|
+
# Your code goes here...
|
22
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Gifts
|
2
|
+
class CommitTable < TableBase
|
3
|
+
StatusProcessing = 0
|
4
|
+
StatusCompleted = 1
|
5
|
+
StatusTimeout = 2
|
6
|
+
|
7
|
+
def table_name
|
8
|
+
"commit"
|
9
|
+
end
|
10
|
+
|
11
|
+
def define_schema
|
12
|
+
Groonga::Schema.define do |schema|
|
13
|
+
schema.create_table(table_name, type: :hash) do |table|
|
14
|
+
table.reference("author", "user")
|
15
|
+
table.time("authored_date")
|
16
|
+
table.reference("committer", "user")
|
17
|
+
table.time("committed_date")
|
18
|
+
table.string("message")
|
19
|
+
table.reference("repo")
|
20
|
+
table.string("rev")
|
21
|
+
table.int32("status")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def add(git_repo, db_repo)
|
27
|
+
result = []
|
28
|
+
|
29
|
+
offset = 0
|
30
|
+
count = 100
|
31
|
+
processed_prev_commit = false
|
32
|
+
|
33
|
+
begin
|
34
|
+
commits = Grit::Commit.find_all(git_repo, nil, { all: true, date_order: true, max_count: count, skip: offset })
|
35
|
+
commits.each do |git_commit|
|
36
|
+
key = db_repo.id.to_s + ":" + git_commit.id
|
37
|
+
|
38
|
+
if key == db_repo.last_commit_key
|
39
|
+
processed_prev_commit = true
|
40
|
+
break
|
41
|
+
|
42
|
+
else
|
43
|
+
author = @db.users.add(git_commit.author.name)
|
44
|
+
committer = @db.users.add(git_commit.committer.name)
|
45
|
+
|
46
|
+
db_commit =
|
47
|
+
table[key] ||
|
48
|
+
table.add(
|
49
|
+
key,
|
50
|
+
author: author,
|
51
|
+
authored_date: git_commit.authored_date,
|
52
|
+
committer: committer,
|
53
|
+
committed_date: git_commit.committed_date,
|
54
|
+
message: git_commit.message,
|
55
|
+
repo: db_repo,
|
56
|
+
rev: git_commit.id,
|
57
|
+
status: StatusProcessing
|
58
|
+
)
|
59
|
+
|
60
|
+
db_diffs = @db.diffs.add(git_commit, db_commit)
|
61
|
+
result << db_commit
|
62
|
+
end
|
63
|
+
end
|
64
|
+
offset += count
|
65
|
+
end until commits.count == 0 || processed_prev_commit
|
66
|
+
|
67
|
+
result
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Gifts
|
2
|
+
class Database
|
3
|
+
attr_reader :repos, :commits, :files, :diffs, :terms, :users
|
4
|
+
|
5
|
+
def self.open(filename)
|
6
|
+
if File.exist?(filename)
|
7
|
+
database = Groonga::Database.open(filename)
|
8
|
+
else
|
9
|
+
FileUtils.mkdir_p(File.dirname filename)
|
10
|
+
database = Groonga::Database.create(path: filename)
|
11
|
+
end
|
12
|
+
|
13
|
+
database = Database.new(database)
|
14
|
+
|
15
|
+
if block_given?
|
16
|
+
begin
|
17
|
+
yield database
|
18
|
+
ensure
|
19
|
+
database.close
|
20
|
+
end
|
21
|
+
else
|
22
|
+
database
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(database)
|
27
|
+
@database = database
|
28
|
+
|
29
|
+
# Tables need initialized in the order corresponding to referenced.
|
30
|
+
@repos = RepoTable.new(self)
|
31
|
+
@users = UserTable.new(self)
|
32
|
+
@commits = CommitTable.new(self)
|
33
|
+
@files = FileTable.new(self)
|
34
|
+
@diffs = DiffTable.new(self)
|
35
|
+
@terms = TermTable.new(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def close
|
39
|
+
unless closed?
|
40
|
+
@database.close
|
41
|
+
@database = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def closed?
|
46
|
+
@database.nil? or @database.closed?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Gifts
|
2
|
+
class DiffTable < TableBase
|
3
|
+
def table_name
|
4
|
+
"diff"
|
5
|
+
end
|
6
|
+
|
7
|
+
def define_schema
|
8
|
+
Groonga::Schema.define do |schema|
|
9
|
+
schema.create_table(table_name, type: :hash) do |table|
|
10
|
+
table.reference("commit")
|
11
|
+
table.reference("file")
|
12
|
+
table.text("diff")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(git_commit, db_commit)
|
18
|
+
if db_commit.status == CommitTable::StatusProcessing
|
19
|
+
result = []
|
20
|
+
|
21
|
+
begin
|
22
|
+
git_commit.diffs.each do |git_diff|
|
23
|
+
next if git_diff.diff.nil?
|
24
|
+
|
25
|
+
db_file = @db.files.add(git_commit, git_diff, db_commit)
|
26
|
+
|
27
|
+
if db_file && db_file.type == FileTable::TypeText
|
28
|
+
key = db_commit.id.to_s + ":" + db_file.id.to_s
|
29
|
+
db_diff =
|
30
|
+
table[key] ||
|
31
|
+
table.add(
|
32
|
+
key,
|
33
|
+
commit: db_commit,
|
34
|
+
file: db_file,
|
35
|
+
diff: git_diff.diff
|
36
|
+
)
|
37
|
+
result << db_diff
|
38
|
+
end
|
39
|
+
end
|
40
|
+
rescue Grit::Git::GitTimeout => e
|
41
|
+
puts "Timeout commit:#{git_commit.id}"
|
42
|
+
db_commit.status = CommitTable::StatusTimeout
|
43
|
+
else
|
44
|
+
db_commit.status = CommitTable::StatusCompleted
|
45
|
+
end
|
46
|
+
|
47
|
+
result
|
48
|
+
else
|
49
|
+
records = table.select do |record|
|
50
|
+
record.commit == db_commit
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Gifts
|
2
|
+
class FileTable < TableBase
|
3
|
+
TypeText = 1
|
4
|
+
TypeBinary = 2
|
5
|
+
|
6
|
+
def table_name
|
7
|
+
"file"
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_schema
|
11
|
+
Groonga::Schema.define do |schema|
|
12
|
+
schema.create_table(table_name, type: :hash) do |table|
|
13
|
+
table.string("encoding")
|
14
|
+
table.string("ext")
|
15
|
+
table.reference("last_commit", "commit")
|
16
|
+
table.string("path")
|
17
|
+
table.reference("repo")
|
18
|
+
table.int32("type")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def add(git_commit, git_diff, db_commit)
|
24
|
+
path = git_diff.new_path
|
25
|
+
file = (git_commit.tree / path)
|
26
|
+
if file.nil? && git_commit.parents.count > 0
|
27
|
+
path = git_diff.old_path
|
28
|
+
file = (git_commit.parents.first.tree / path)
|
29
|
+
end
|
30
|
+
return if file.nil?
|
31
|
+
|
32
|
+
key = db_commit.repo.id.to_s + ":" + path
|
33
|
+
return table[key] if table[key] && table[key].last_commit.committed_date > db_commit.committed_date
|
34
|
+
|
35
|
+
ext = File.extname(path).sub(".", "")
|
36
|
+
|
37
|
+
t = table[key] || table.add(key, repo: db_commit.repo, path: path, ext: ext)
|
38
|
+
t.last_commit = db_commit
|
39
|
+
|
40
|
+
detection = CharlockHolmes::EncodingDetector.detect(file.data)
|
41
|
+
if detection[:type] == :binary
|
42
|
+
t.type = TypeBinary
|
43
|
+
else
|
44
|
+
t.type = TypeText
|
45
|
+
t.encoding = detection[:encoding]
|
46
|
+
end
|
47
|
+
|
48
|
+
t
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Gifts
|
2
|
+
class RepoTable < TableBase
|
3
|
+
def table_name
|
4
|
+
"repo"
|
5
|
+
end
|
6
|
+
|
7
|
+
def define_schema
|
8
|
+
Groonga::Schema.define do |schema|
|
9
|
+
schema.create_table(table_name, type: :hash) do |table|
|
10
|
+
table.string("path")
|
11
|
+
table.string("last_commit_key")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(path)
|
17
|
+
path = File.expand_path(path)
|
18
|
+
|
19
|
+
git_repo = Grit::Repo.new(path)
|
20
|
+
db_repo = table[path] || table.add(path, path: path)
|
21
|
+
|
22
|
+
db_commits = @db.commits.add(git_repo, db_repo)
|
23
|
+
|
24
|
+
# update last commit key
|
25
|
+
db_repo.last_commit_key = db_commits.first.key if db_commits.count > 0
|
26
|
+
pp "add", db_commits.count, db_repo.last_commit_key
|
27
|
+
|
28
|
+
db_repo
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Gifts
|
2
|
+
class TableBase
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
def_delegators :table, :count, :records, :select, :size
|
6
|
+
|
7
|
+
def initialize(database)
|
8
|
+
@db = database
|
9
|
+
define_schema
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def table
|
15
|
+
Groonga[table_name]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Gifts
|
2
|
+
class TermTable < TableBase
|
3
|
+
def table_name
|
4
|
+
"term"
|
5
|
+
end
|
6
|
+
|
7
|
+
def define_schema
|
8
|
+
Groonga::Schema.define do |schema|
|
9
|
+
schema.create_table(
|
10
|
+
"term",
|
11
|
+
type: :patricia_trie,
|
12
|
+
normalizer: :NormalizerAuto,
|
13
|
+
default_tokenizer: "TokenBigram"
|
14
|
+
) do |table|
|
15
|
+
table.index("commit.message", with_position: true)
|
16
|
+
|
17
|
+
table.index("diff.commit", with_position: true)
|
18
|
+
table.index("diff.diff", with_position: true)
|
19
|
+
|
20
|
+
table.index("file.ext", with_position: true)
|
21
|
+
table.index("file.path", with_position: true)
|
22
|
+
|
23
|
+
table.index("user.name", with_position: true)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|