Skip to content

Commit 05cd423

Browse files
committed
Fixes, optimizations and pretty up
1 parent ae79034 commit 05cd423

File tree

12 files changed

+75
-79
lines changed

12 files changed

+75
-79
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515

1616
node_modules
1717

18-
.db
18+
*.db
19+
.DS_Store

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
You can now easily run, any kind of analytics on your Git directory using the SQLite database.
66

7+
![plot](./internal/screenshot.png)
8+
79
## Features ✨
810

911
- Synchronize Git repository data into a SQLite database.
@@ -64,11 +66,13 @@ Once your repository data is synchronized into a SQLite database, you can run va
6466
6. **Authors Who Have Worked on a Specific File**
6567

6668
```sql
67-
SELECT DISTINCT commits.author
68-
FROM commits
69-
JOIN commit_files ON commits.commit_hash = commit_files.commit_hash
70-
JOIN files ON commit_files.file_id = files.file_id
71-
WHERE files.file_path like '%sqlite3%'
69+
SELECT files.file_path, commits.author, COUNT(*) as times_contributed
70+
FROM commits
71+
JOIN commit_files ON commits.commit_hash = commit_files.commit_hash
72+
JOIN files ON commit_files.file_id = files.file_id
73+
WHERE files.file_path LIKE '%connection_adapters/sqlite%'
74+
GROUP BY files.file_path, commits.author
75+
ORDER BY times_contributed DESC;
7276
```
7377

7478
## Installation 📥

internal/screenshot.jpg

905 KB
Loading

internal/screenshot.png

2.21 MB
Loading

lib/branch_base.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
# frozen_string_literal: true
22

3+
require "logger"
34
require "branch_base/database"
45
require "branch_base/repository"
56
require "branch_base/sync"
67
require "branch_base/cli"
78

89
module BranchBase
10+
def self.logger
11+
@logger ||=
12+
Logger
13+
.new($stdout)
14+
.tap do |log|
15+
log.progname = "BranchBase"
16+
17+
log.level = ENV["DEBUG"] ? Logger::DEBUG : Logger::INFO
18+
19+
log.formatter =
20+
proc do |severity, datetime, progname, msg|
21+
"#{datetime}: #{severity} - #{progname}: #{msg}\n"
22+
end
23+
end
24+
end
925
end

lib/branch_base/cli.rb

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,33 @@
55

66
module BranchBase
77
class CLI < Thor
8-
desc "sync REPO_PATH [BRANCH_OR_TAG]",
9-
"Synchronize a specific branch or tag of the Git repository with the SQLite database"
8+
desc "sync REPO_PATH", "Synchronize a Git directory to a SQLite database"
109
def sync(repo_path)
10+
BranchBase.logger.info("Starting sync process for #{repo_path}...")
11+
1112
full_repo_path = File.expand_path(repo_path)
1213

1314
unless File.directory?(File.join(full_repo_path, ".git"))
14-
puts "The specified path is not a valid Git repository: #{full_repo_path}"
15+
BranchBase.logger.error(
16+
"The specified path is not a valid Git repository: #{full_repo_path}",
17+
)
1518
exit(1)
1619
end
1720

1821
repo_name = File.basename(full_repo_path)
19-
db_filename = "#{repo_name}_git_data.db"
22+
db_directory = full_repo_path
23+
db_filename = File.join(db_directory, "#{repo_name}_git_data.db")
2024

2125
database = Database.new(db_filename)
2226
repository = Repository.new(full_repo_path)
27+
start_time = Time.now
2328
sync = Sync.new(database, repository)
2429

2530
sync.run
26-
puts "Repository data synced successfully for"
31+
elapsed_time = Time.now - start_time
32+
BranchBase.logger.info(
33+
"Repository data synced successfully in #{db_filename} in #{elapsed_time.round(2)} seconds",
34+
)
2735
end
2836
end
2937
end

lib/branch_base/sync.rb

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
module BranchBase
44
class Sync
5+
# TODO acctualy see if bulk inserts are faster
56
BATCH_SIZE = 1000
67

78
def initialize(database, repository)
@@ -38,6 +39,10 @@ def sync_repository
3839
end
3940

4041
def sync_branches(repo_id)
42+
BranchBase.logger.debug(
43+
"Syncing branches for repository ID: #{@repo.path}",
44+
)
45+
4146
batched_branches = []
4247

4348
@repo.branches.each do |branch|
@@ -127,6 +132,10 @@ def insert_commit_files(commit, repo_id)
127132
end
128133

129134
def insert_commit_parents(commit)
135+
BranchBase.logger.debug(
136+
"Inserting parent commits for repository: #{@repo.path}",
137+
)
138+
130139
commit.parent_ids.each do |parent_id|
131140
@db.execute(
132141
"INSERT INTO commit_parents (commit_hash, parent_hash) VALUES (?, ?)",
@@ -147,13 +156,27 @@ def insert_branches(batched_branches)
147156
end
148157

149158
def insert_commits(batched_commits)
159+
BranchBase.logger.debug(
160+
"Inserting commits for repository ID: #{@repo.path}",
161+
)
162+
163+
return if batched_commits.empty?
164+
150165
@db.transaction do
151-
batched_commits.each do |data|
152-
@db.execute(
153-
"INSERT INTO commits (commit_hash, repo_id, author, committer, message, timestamp) VALUES (?, ?, ?, ?, ?, ?)",
154-
data,
155-
)
156-
end
166+
values_clause =
167+
batched_commits
168+
.map do |commit_data|
169+
"(#{commit_data.map { |value| "'#{value}'" }.join(", ")})"
170+
end
171+
.join(", ")
172+
173+
sql = <<~SQL
174+
INSERT INTO commits
175+
(commit_hash, repo_id, author, committer, message, timestamp)
176+
VALUES #{values_clause};
177+
SQL
178+
179+
@db.execute(sql)
157180
end
158181
end
159182

spec/branch_base/cli_spec.rb

Lines changed: 0 additions & 52 deletions
This file was deleted.

spec/branch_base/database_spec.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# frozen_string_literal: true
2-
require "branch_base/database"
3-
require "rspec"
2+
require "spec_helper"
43

54
RSpec.describe(BranchBase::Database) do
65
let(:database) { BranchBase::Database.new(":memory:") }

spec/branch_base/repository_spec.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# frozen_string_literal: true
2-
require "branch_base/repository"
3-
require "rugged"
4-
require "rspec"
2+
require "spec_helper"
53
require "test_helper"
64

75
RSpec.describe(BranchBase::Repository) do
@@ -24,7 +22,7 @@
2422
repository.walk { |commit| commit_messages << commit.message.strip }
2523
expect(commit_messages).to contain_exactly(
2624
"Add contributing guidelines",
27-
"Initial commit"
25+
"Initial commit",
2826
)
2927
end
3028
end

spec/branch_base/sync_spec.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
# frozen_string_literal: true
2-
require "branch_base/sync"
3-
require "branch_base/database"
4-
require "branch_base/repository"
52
require "test_helper"
6-
require "rspec"
3+
require "spec_helper"
74

85
RSpec.describe(BranchBase::Sync) do
96
let(:db) { BranchBase::Database.new(":memory:") }

spec/spec_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# the additional setup, and require it from the spec files that actually need
1414
# it.
1515
#
16+
require "branch_base"
17+
1618
# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
1719
RSpec.configure do |config|
1820
# rspec-expectations config goes here. You can use an alternate

0 commit comments

Comments
 (0)