git_models 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.dependabot/config.yml +10 -0
  3. data/.github/workflows/gem_release.yml +37 -0
  4. data/.gitignore +61 -0
  5. data/.jenkins/Jenkinsfile +80 -0
  6. data/.jenkins/ruby_build_pod.yml +18 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +51 -0
  9. data/Appraisals +14 -0
  10. data/CHANGELOG.md +25 -0
  11. data/Gemfile +25 -0
  12. data/Gemfile.lock +237 -0
  13. data/README.md +6 -0
  14. data/Rakefile +28 -0
  15. data/app/models/concerns/branch.rb +55 -0
  16. data/app/models/concerns/commit.rb +44 -0
  17. data/app/models/concerns/repository.rb +28 -0
  18. data/app/models/concerns/user.rb +33 -0
  19. data/gemfiles/.bundle/config +2 -0
  20. data/gemfiles/rails_4.gemfile +26 -0
  21. data/gemfiles/rails_5.gemfile +26 -0
  22. data/gemfiles/rails_6.gemfile +26 -0
  23. data/git_models.gemspec +27 -0
  24. data/lib/git_models.rb +6 -0
  25. data/lib/git_models/test_helpers.rb +60 -0
  26. data/lib/git_models/version.rb +5 -0
  27. data/spec/dummy/Rakefile +6 -0
  28. data/spec/dummy/app/assets/config/manifest.js +3 -0
  29. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  30. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  31. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  32. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  33. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  34. data/spec/dummy/app/models/application_record.rb +7 -0
  35. data/spec/dummy/app/models/branch.rb +8 -0
  36. data/spec/dummy/app/models/commit.rb +8 -0
  37. data/spec/dummy/app/models/repository.rb +8 -0
  38. data/spec/dummy/app/models/user.rb +8 -0
  39. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  40. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  41. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  42. data/spec/dummy/bin/bundle +3 -0
  43. data/spec/dummy/bin/rails +4 -0
  44. data/spec/dummy/bin/rake +4 -0
  45. data/spec/dummy/bin/setup +36 -0
  46. data/spec/dummy/bin/spring +16 -0
  47. data/spec/dummy/bin/update +31 -0
  48. data/spec/dummy/bin/yarn +11 -0
  49. data/spec/dummy/config.ru +7 -0
  50. data/spec/dummy/config/application.rb +25 -0
  51. data/spec/dummy/config/boot.rb +5 -0
  52. data/spec/dummy/config/credentials.yml.enc +1 -0
  53. data/spec/dummy/config/database.yml +27 -0
  54. data/spec/dummy/config/environment.rb +8 -0
  55. data/spec/dummy/config/environments/development.rb +63 -0
  56. data/spec/dummy/config/environments/production.rb +96 -0
  57. data/spec/dummy/config/environments/test.rb +55 -0
  58. data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
  59. data/spec/dummy/config/initializers/assets.rb +16 -0
  60. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  61. data/spec/dummy/config/initializers/content_security_policy.rb +27 -0
  62. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  63. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  64. data/spec/dummy/config/initializers/inflections.rb +18 -0
  65. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  66. data/spec/dummy/config/initializers/session_store.rb +5 -0
  67. data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
  68. data/spec/dummy/config/locales/en.yml +33 -0
  69. data/spec/dummy/config/puma.rb +39 -0
  70. data/spec/dummy/config/routes.rb +5 -0
  71. data/spec/dummy/config/spring.rb +8 -0
  72. data/spec/dummy/config/storage.yml +34 -0
  73. data/spec/dummy/db/migrate/20161123065534_create_users_table.rb +16 -0
  74. data/spec/dummy/db/migrate/20161123184217_create_commits_repositories_branches.rb +37 -0
  75. data/spec/dummy/db/schema.rb +53 -0
  76. data/spec/dummy/spec/models/branch_spec.rb +84 -0
  77. data/spec/dummy/spec/models/commit_spec.rb +60 -0
  78. data/spec/dummy/spec/models/user_spec.rb +64 -0
  79. data/spec/dummy/spec/spec_helper.rb +48 -0
  80. metadata +231 -0
@@ -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)
@@ -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,2 @@
1
+ ---
2
+ BUNDLE_RETRY: "1"
@@ -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: "../"
@@ -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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../app/models/concerns/user.rb'
4
+ require_relative '../app/models/concerns/repository.rb'
5
+ require_relative '../app/models/concerns/branch.rb'
6
+ require_relative '../app/models/concerns/commit.rb'
@@ -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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitModels
4
+ VERSION = '1.2.0'
5
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env rake
2
+ # frozen_string_literal: true
3
+
4
+ require File.expand_path('config/application', __dir__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -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
+ */