git_models 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.dependabot/config.yml +10 -0
- data/.github/workflows/gem_release.yml +37 -0
- data/.gitignore +61 -0
- data/.jenkins/Jenkinsfile +80 -0
- data/.jenkins/ruby_build_pod.yml +18 -0
- data/.rspec +3 -0
- data/.rubocop.yml +51 -0
- data/Appraisals +14 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +25 -0
- data/Gemfile.lock +237 -0
- data/README.md +6 -0
- data/Rakefile +28 -0
- data/app/models/concerns/branch.rb +55 -0
- data/app/models/concerns/commit.rb +44 -0
- data/app/models/concerns/repository.rb +28 -0
- data/app/models/concerns/user.rb +33 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_4.gemfile +26 -0
- data/gemfiles/rails_5.gemfile +26 -0
- data/gemfiles/rails_6.gemfile +26 -0
- data/git_models.gemspec +27 -0
- data/lib/git_models.rb +6 -0
- data/lib/git_models/test_helpers.rb +60 -0
- data/lib/git_models/version.rb +5 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +7 -0
- data/spec/dummy/app/models/branch.rb +8 -0
- data/spec/dummy/app/models/commit.rb +8 -0
- data/spec/dummy/app/models/repository.rb +8 -0
- data/spec/dummy/app/models/user.rb +8 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +36 -0
- data/spec/dummy/bin/spring +16 -0
- data/spec/dummy/bin/update +31 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config.ru +7 -0
- data/spec/dummy/config/application.rb +25 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/credentials.yml.enc +1 -0
- data/spec/dummy/config/database.yml +27 -0
- data/spec/dummy/config/environment.rb +8 -0
- data/spec/dummy/config/environments/development.rb +63 -0
- data/spec/dummy/config/environments/production.rb +96 -0
- data/spec/dummy/config/environments/test.rb +55 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
- data/spec/dummy/config/initializers/assets.rb +16 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +27 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/session_store.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +39 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config/spring.rb +8 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/migrate/20161123065534_create_users_table.rb +16 -0
- data/spec/dummy/db/migrate/20161123184217_create_commits_repositories_branches.rb +37 -0
- data/spec/dummy/db/schema.rb +53 -0
- data/spec/dummy/spec/models/branch_spec.rb +84 -0
- data/spec/dummy/spec/models/commit_spec.rb +60 -0
- data/spec/dummy/spec/models/user_spec.rb +64 -0
- data/spec/dummy/spec/spec_helper.rb +48 -0
- metadata +231 -0
data/README.md
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
# Git Models
|
2
|
+
The GitModels is collect of Rails models that can be used to store data retrieved from Git.
|
3
|
+
|
4
|
+
## Code Status
|
5
|
+
[![Build Status](https://semaphoreci.com/api/v1/mikeweaver/git_models/branches/master/badge.svg)](https://semaphoreci.com/mikeweaver/git_models)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/github/mikeweaver/git_models/badge.svg?branch=master)](https://coveralls.io/github/mikeweaver/git_models?branch=master)
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'coveralls/rake/task'
|
6
|
+
require "bundler/gem_tasks"
|
7
|
+
require 'bundler/audit/task'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new
|
10
|
+
Coveralls::RakeTask.new
|
11
|
+
Bundler::Audit::Task.new
|
12
|
+
|
13
|
+
desc "db"
|
14
|
+
namespace :db do
|
15
|
+
desc "test"
|
16
|
+
namespace :test do
|
17
|
+
desc "prepare"
|
18
|
+
task :prepare do
|
19
|
+
system <<~EOS
|
20
|
+
set -ex
|
21
|
+
cd spec/dummy
|
22
|
+
rake db:create && rake db:test:prepare
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task default: :spec
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hobo_fields'
|
4
|
+
|
5
|
+
module GitModels
|
6
|
+
module Branch
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
fields do
|
11
|
+
git_updated_at :datetime, null: false
|
12
|
+
name :text, limit: 1024, null: false
|
13
|
+
timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
validates :name, uniqueness: { scope: :repository, message: 'Branch names must be unique within each repository' }
|
17
|
+
|
18
|
+
belongs_to :author, class_name: 'User', inverse_of: :branches, required: true
|
19
|
+
belongs_to :repository, class_name: 'Repository', inverse_of: :branches, required: true
|
20
|
+
|
21
|
+
scope :branches_not_updated_since, lambda { |checked_at_date| where('branches.updated_at < ?', checked_at_date) }
|
22
|
+
|
23
|
+
scope :from_repository, lambda { |repository_name|
|
24
|
+
joins(:repository).where('repositories.name = ?', repository_name)
|
25
|
+
}
|
26
|
+
|
27
|
+
scope :with_name, lambda { |name| where(name: name) }
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
name
|
31
|
+
end
|
32
|
+
|
33
|
+
def =~(other)
|
34
|
+
name =~ other
|
35
|
+
end
|
36
|
+
|
37
|
+
def <=>(other)
|
38
|
+
name <=> other.name
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class_methods do
|
43
|
+
def create_from_git_data!(branch_data)
|
44
|
+
repository = ::Repository.create!(branch_data.repository_name)
|
45
|
+
branch = where(repository: repository, name: branch_data.name).first_or_initialize
|
46
|
+
branch.git_updated_at = branch_data.last_modified_date
|
47
|
+
branch.updated_at = Time.current # force updated time
|
48
|
+
u = ::User.create_from_git_data!(branch_data)
|
49
|
+
branch.author = u
|
50
|
+
branch.save!
|
51
|
+
branch
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hobo_fields'
|
4
|
+
|
5
|
+
module GitModels
|
6
|
+
module Commit
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
fields do
|
11
|
+
sha :text, limit: 40, null: false
|
12
|
+
message :text, limit: 1024, null: false
|
13
|
+
timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
validates :sha, uniqueness: { message: 'SHAs must be globally unique' }
|
17
|
+
validates :sha, format: { without: /[0]{40}/ }
|
18
|
+
|
19
|
+
belongs_to :author, class_name: 'User', inverse_of: :commits, required: true
|
20
|
+
|
21
|
+
def short_sha
|
22
|
+
sha[0, 7]
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
sha
|
27
|
+
end
|
28
|
+
|
29
|
+
def <=>(other)
|
30
|
+
sha <=> other.sha
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class_methods do
|
35
|
+
def create_from_git_commit!(git_commit)
|
36
|
+
commit = where(sha: git_commit.sha).first_or_initialize
|
37
|
+
commit.message = git_commit.message.truncate(1024)
|
38
|
+
commit.author = ::User.create_from_git_data!(git_commit)
|
39
|
+
commit.save!
|
40
|
+
commit
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hobo_fields'
|
4
|
+
|
5
|
+
module GitModels
|
6
|
+
module Repository
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
fields do
|
11
|
+
name :text, limit: 1024, null: false
|
12
|
+
timestamps
|
13
|
+
end
|
14
|
+
|
15
|
+
validates :name, uniqueness: true
|
16
|
+
|
17
|
+
has_many :branches, class_name: 'Branch', dependent: :destroy
|
18
|
+
end
|
19
|
+
|
20
|
+
class_methods do
|
21
|
+
def create!(name)
|
22
|
+
branch = where(name: name).first_or_initialize
|
23
|
+
branch.save!
|
24
|
+
branch
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'hobo_fields'
|
4
|
+
|
5
|
+
module GitModels
|
6
|
+
module User
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
fields do
|
11
|
+
name :text, limit: 255, null: false
|
12
|
+
email :text, limit: 255, null: false
|
13
|
+
timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
validates :name, uniqueness: { scope: :email }
|
17
|
+
|
18
|
+
has_many :branches, class_name: 'Branch', foreign_key: 'author_id'
|
19
|
+
has_many :commits, class_name: 'Commit', foreign_key: 'author_id'
|
20
|
+
end
|
21
|
+
|
22
|
+
class_methods do
|
23
|
+
def create_from_git_data!(branch_data)
|
24
|
+
where(name: branch_data.author_name, email: branch_data.author_email).first_or_create!
|
25
|
+
end
|
26
|
+
|
27
|
+
def users_with_emails(email_filter_list)
|
28
|
+
# if filter is empty, return all users, otherwise only return users whose emails are in the list
|
29
|
+
all.select { |user| email_filter_list.empty? || email_filter_list.include?(user.email.downcase) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "bundler", "~> 1.17"
|
7
|
+
gem "bundler-audit", require: false
|
8
|
+
gem "climate_control"
|
9
|
+
gem "coveralls", require: false
|
10
|
+
gem "database_cleaner"
|
11
|
+
gem "git_lib", "~> 1.2", git: "git@github.com:Invoca/git_lib", ref: "785505fd4d55eb6968a75cdb546365d935d8655b"
|
12
|
+
gem "hobo_fields", "~> 3.0", git: "git@github.com:Invoca/hobo_fields", ref: "e9623e9c3aa98a4822ef61d1f1e87d0ff8001ffc"
|
13
|
+
gem "pry"
|
14
|
+
gem "rails", ">= 4.2"
|
15
|
+
gem "rake"
|
16
|
+
gem "rspec", "~> 3.5"
|
17
|
+
gem "rspec-core"
|
18
|
+
gem "rspec_junit_formatter"
|
19
|
+
gem "rspec-rails"
|
20
|
+
gem "rubocop", "~> 0.45.0", require: false
|
21
|
+
gem "rubocop-rspec", require: false
|
22
|
+
gem "sqlite3", "~> 1.3.6"
|
23
|
+
gem "tzinfo-data"
|
24
|
+
gem "activesupport", "~> 4.2"
|
25
|
+
|
26
|
+
gemspec path: "../"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "bundler", "~> 1.17"
|
7
|
+
gem "bundler-audit", require: false
|
8
|
+
gem "climate_control"
|
9
|
+
gem "coveralls", require: false
|
10
|
+
gem "database_cleaner"
|
11
|
+
gem "git_lib", "~> 1.2", git: "git@github.com:Invoca/git_lib", ref: "785505fd4d55eb6968a75cdb546365d935d8655b"
|
12
|
+
gem "hobo_fields", "~> 3.0", git: "git@github.com:Invoca/hobo_fields", ref: "e9623e9c3aa98a4822ef61d1f1e87d0ff8001ffc"
|
13
|
+
gem "pry"
|
14
|
+
gem "rails", ">= 4.2"
|
15
|
+
gem "rake"
|
16
|
+
gem "rspec", "~> 3.5"
|
17
|
+
gem "rspec-core"
|
18
|
+
gem "rspec_junit_formatter"
|
19
|
+
gem "rspec-rails"
|
20
|
+
gem "rubocop", "~> 0.45.0", require: false
|
21
|
+
gem "rubocop-rspec", require: false
|
22
|
+
gem "sqlite3", "~> 1.3.6"
|
23
|
+
gem "tzinfo-data"
|
24
|
+
gem "activesupport", "~> 5.2"
|
25
|
+
|
26
|
+
gemspec path: "../"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "bundler", "~> 1.17"
|
7
|
+
gem "bundler-audit", require: false
|
8
|
+
gem "climate_control"
|
9
|
+
gem "coveralls", require: false
|
10
|
+
gem "database_cleaner"
|
11
|
+
gem "git_lib", "~> 1.2", git: "git@github.com:Invoca/git_lib", ref: "785505fd4d55eb6968a75cdb546365d935d8655b"
|
12
|
+
gem "hobo_fields", "~> 3.0", git: "git@github.com:Invoca/hobo_fields", ref: "e9623e9c3aa98a4822ef61d1f1e87d0ff8001ffc"
|
13
|
+
gem "pry"
|
14
|
+
gem "rails", ">= 4.2"
|
15
|
+
gem "rake"
|
16
|
+
gem "rspec", "~> 3.5"
|
17
|
+
gem "rspec-core"
|
18
|
+
gem "rspec_junit_formatter"
|
19
|
+
gem "rspec-rails"
|
20
|
+
gem "rubocop", "~> 0.45.0", require: false
|
21
|
+
gem "rubocop-rspec", require: false
|
22
|
+
gem "sqlite3", "~> 1.4"
|
23
|
+
gem "tzinfo-data"
|
24
|
+
gem "activesupport", "~> 6.0"
|
25
|
+
|
26
|
+
gemspec path: "../"
|
data/git_models.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'git_models/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'git_models'
|
9
|
+
spec.version = GitModels::VERSION
|
10
|
+
spec.authors = ['Invoca Development']
|
11
|
+
spec.email = ['development@invoca.com']
|
12
|
+
spec.summary = "Rails models for Git data."
|
13
|
+
spec.homepage = "https://github.com/Invoca/git_models"
|
14
|
+
|
15
|
+
spec.metadata = {
|
16
|
+
'allowed_push_host' => "https://rubygems.org"
|
17
|
+
}
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ['app', 'lib']
|
23
|
+
|
24
|
+
spec.add_dependency 'rails', '>= 4.2', '< 7'
|
25
|
+
spec.add_dependency 'hobo_fields', '~> 3.0'
|
26
|
+
spec.add_dependency 'git_lib', '~> 1.2'
|
27
|
+
end
|
data/lib/git_models.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GitModels
|
4
|
+
module TestHelpers
|
5
|
+
def self.create_branch(repository_name: 'repository_name',
|
6
|
+
name: 'path/branch',
|
7
|
+
last_modified_date: Time.current,
|
8
|
+
author_name: 'Author Name',
|
9
|
+
author_email: 'author@email.com')
|
10
|
+
git_data = Git::TestHelpers.create_branch(
|
11
|
+
repository_name: repository_name,
|
12
|
+
name: name,
|
13
|
+
last_modified_date: last_modified_date,
|
14
|
+
author_name: author_name,
|
15
|
+
author_email: author_email
|
16
|
+
)
|
17
|
+
::Branch.create_from_git_data!(git_data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create_branches(repository_name: 'repository_name',
|
21
|
+
author_name: 'Author Name',
|
22
|
+
author_email: 'author@email.com',
|
23
|
+
count: 2)
|
24
|
+
branches = []
|
25
|
+
(0..count - 1).each do |i|
|
26
|
+
branches << create_branch(
|
27
|
+
repository_name: repository_name,
|
28
|
+
name: "path/#{author_name}/branch#{i}",
|
29
|
+
last_modified_date: DateTime.current,
|
30
|
+
author_name: author_name,
|
31
|
+
author_email: author_email
|
32
|
+
)
|
33
|
+
end
|
34
|
+
branches
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.create_commit(sha: '1234567890123456789012345678901234567890',
|
38
|
+
message: 'Commit message',
|
39
|
+
author_name: 'Author Name',
|
40
|
+
author_email: 'author@email.com')
|
41
|
+
commit = ::Commit.create(sha: sha, message: message)
|
42
|
+
commit.author = ::User.first_or_create!(name: author_name, email: author_email)
|
43
|
+
commit.save!
|
44
|
+
commit
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.create_commits(author_name: 'Author Name', author_email: 'author@email.com', count: 2)
|
48
|
+
commits = []
|
49
|
+
(0..count - 1).each do |i|
|
50
|
+
commits << create_commit(
|
51
|
+
sha: (i + 1).to_s.ljust(40, '0'),
|
52
|
+
message: "Commit message #{i + 1}",
|
53
|
+
author_name: author_name,
|
54
|
+
author_email: author_email
|
55
|
+
)
|
56
|
+
end
|
57
|
+
commits
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
|
5
|
+
// vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require rails-ujs
|
14
|
+
//= require activestorage
|
15
|
+
//= require turbolinks
|
16
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
+
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
3
|
+
//
|
4
|
+
//= require action_cable
|
5
|
+
//= require_self
|
6
|
+
//= require_tree ./channels
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
this.App || (this.App = {});
|
10
|
+
|
11
|
+
App.cable = ActionCable.createConsumer();
|
12
|
+
|
13
|
+
}).call(this);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
|
6
|
+
* vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|