jets-git 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: adfdc0534b83b46a4302ac4680ed364768af3307a445ebdc40adfc76d9aa9c14
4
+ data.tar.gz: 7dd52b79322e598fca76fc3eb700ca4c670c32f14c4b7d7b51990141b5d137f7
5
+ SHA512:
6
+ metadata.gz: 664548444a428ba36a4ef6ea944c3006c7f59a0bb5d093cd3dbd0afb2b6078e4dd0b6ba970c2eb0b2c9e790c6cae53a5e1bce4e97528b7686624c8cdacdf8730
7
+ data.tar.gz: 46d9794e787d10da0457012ac43991511af8eb76713b9d13bdfca91fe52de0b0b9b171d8513bdb5a6c231592a8a6a84f60e2eb0fa5273d22caae09cb0f781a01
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --color
3
+ --format documentation
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
5
+
6
+ ## [0.2.0] - 2023-12-11
7
+ - rename git_message attribute
8
+
9
+ ## [0.1.0]
10
+ - Initial Release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Tung Nguyen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Jets Git
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/jets-git.svg)](http://badge.fury.io/rb/jets-git)
4
+
5
+ [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
6
+
7
+ [![BoltOps Learn Badge](https://img.boltops.com/boltops-learn/boltops-learn.png)](https://learn.boltops.com)
8
+
9
+ Gathers git information for Jets.
10
+
11
+ This library gathers information from your local git repo or the build system [jets](https://rubyonjets.com) runs on. It supports:
12
+
13
+ * **azure**: Azure Pipelines.
14
+ * **bitbucket**: BitBucket Pipelines.
15
+ * **circleci**: CircleCI.
16
+ * **codebuild**: AWS CodeBuild
17
+ * **custom**: Custom control.
18
+ * **github**: Github Actions.
19
+ * **gitlab**: Gitlab Pipelines.
20
+ * **local**: Local git repo.
21
+
22
+ ## Custom Control
23
+
24
+ You can set these variables if you have a custom build system and need more control over what is set. Example:
25
+
26
+ JETS_GIT_CUSTOM=1
27
+ JETS_GIT_CUSTOM_BRANCH=main
28
+ JETS_GIT_CUSTOM_SHA=abcdefgh
29
+ JETS_GIT_CUSTOM_URL=https://github.com/owner/repo
30
+ JETS_GIT_CUSTOM_MESSAGE="commit message"
31
+
32
+ The `JETS_GIT_CUSTOM=1` tells the library to use the Custom information.
33
+
34
+ ## Disabling
35
+
36
+ If you need to turn off the gathering of any git information, you can set it.
37
+
38
+ JETS_GIT_DISABLED=1
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ Bundler.setup
5
+ require "bundler/gem_tasks"
6
+ require "rspec/core/rake_task"
7
+
8
+ task :default => :spec
9
+
10
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,25 @@
1
+ require "zeitwerk"
2
+
3
+ module Jets
4
+ module Git
5
+ class Autoloader
6
+ class Inflector < Zeitwerk::Inflector
7
+ def camelize(basename, _abspath)
8
+ map = { version: "VERSION" }
9
+ map[basename.to_sym] || super
10
+ end
11
+ end
12
+
13
+ class << self
14
+ def setup
15
+ loader = Zeitwerk::Loader.new
16
+ loader.inflector = Inflector.new
17
+ lib = File.expand_path("../..", __dir__)
18
+ loader.push_dir(lib)
19
+ loader.ignore("#{lib}/jets-git.rb")
20
+ loader.setup
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,64 @@
1
+ module Jets::Git
2
+ class Azure
3
+ def params
4
+ params = {
5
+ git_system: 'azure',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ # git_message: nil,
10
+ # git_version: nil,
11
+ }
12
+ params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ if pr_number
18
+ message = ENV['BUILD_SOURCEVERSIONMESSAGE']
19
+ md = message.match(/Merge pull request \d+ from (.*) into (.*)/)
20
+ if md
21
+ # IE: BUILD_SOURCEVERSIONMESSAGE=Merge pull request 2 from feature into main
22
+ # Its a bit weird but with azure repos with check policy trigger
23
+ md[1]
24
+ else # GitHub and Bitbucket PR has actual branch though
25
+ # IE: SYSTEM_PULLREQUEST_SOURCEBRANCH=feature
26
+ message
27
+ end
28
+ else # push
29
+ ENV['BUILD_SOURCEBRANCHNAME']
30
+ end
31
+ end
32
+
33
+ def git_sha
34
+ ENV['BUILD_SOURCEVERSION']
35
+ end
36
+
37
+ def git_url
38
+ "#{host}/#{full_repo}"
39
+ end
40
+
41
+ # IE: BUILD_REPOSITORY_URI=https://tongueroo@dev.azure.com/tongueroo/infra-project/_git/infra-ci
42
+ def host
43
+ uri = URI(ENV['BUILD_REPOSITORY_URI'])
44
+ "#{uri.scheme}://#{uri.host}"
45
+ end
46
+
47
+ # IE: BUILD_REPOSITORY_URI=https://tongueroo@dev.azure.com/tongueroo/infra-project/_git/infra-ci
48
+ def full_repo
49
+ uri = URI(ENV['BUILD_REPOSITORY_URI'])
50
+ org = uri.path.split('/')[1] # since there's a leading /
51
+ repo = ENV['BUILD_REPOSITORY_NAME'] # tongueroo
52
+ "#{org}/#{repo}"
53
+ end
54
+
55
+ # IE: SYSTEM_PULLREQUEST_PULLREQUESTID=2
56
+ def pr_number
57
+ ENV['SYSTEM_PULLREQUEST_PULLREQUESTID']
58
+ end
59
+
60
+ def build_type
61
+ ENV['SYSTEM_PULLREQUEST_PULLREQUESTID'] ? 'pull_request' : 'push'
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,30 @@
1
+ module Jets::Git
2
+ class Bitbucket
3
+ def params
4
+ params = {
5
+ git_system: 'bitbucket',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ # git_message: nil,
10
+ # git_version: nil,
11
+ }
12
+ params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ ENV['BITBUCKET_BRANCH']
18
+ end
19
+
20
+ def git_sha
21
+ ENV['BITBUCKET_COMMIT']
22
+ end
23
+
24
+ def git_url
25
+ host = ENV['BITBUCKET_HOST'] || 'https://bitbucket.org'
26
+ full_repo = ENV['BITBUCKET_REPO_FULL_NAME']
27
+ "#{host}/#{full_repo}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ module Jets::Git
2
+ class Circleci
3
+ def params
4
+ params = {
5
+ git_system: 'circleci',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ # git_message: nil,
10
+ # git_version: nil,
11
+ }
12
+ # params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ ENV['CIRCLE_BRANCH']
18
+ end
19
+
20
+ def git_sha
21
+ ENV['CIRCLE_SHA1']
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,45 @@
1
+ module Jets::Git
2
+ class Codebuild
3
+ def params
4
+ params = {
5
+ git_system: 'codebuild',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ # git_message: nil,
10
+ # git_version: nil,
11
+ }
12
+ params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ ENV['CODEBUILD_SOURCE_VERSION']
18
+ end
19
+
20
+ def git_sha
21
+ ENV['CODEBUILD_RESOLVED_SOURCE_VERSION']
22
+ end
23
+
24
+ def git_url
25
+ "#{host}/#{full_repo}"
26
+ end
27
+
28
+ def host
29
+ uri = URI(ENV['CODEBUILD_SOURCE_REPO_URL']) # https://github.com/ORG/REPO
30
+ "#{uri.scheme}://#{uri.host}"
31
+ end
32
+
33
+ # ORG/REPO
34
+ def full_repo
35
+ uri = URI(repo_url)
36
+ uri.path.sub(/^\//,'')
37
+ end
38
+
39
+ # https://github.com/ORG/REPO
40
+ def repo_url
41
+ # https://github.com/ORG/REPO.git
42
+ ENV['CODEBUILD_SOURCE_REPO_URL'].sub('.git','')
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,32 @@
1
+ module Jets::Git
2
+ class Custom
3
+ def params
4
+ params = {
5
+ git_system: 'custom',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ git_message: git_message,
10
+ # git_version: nil,
11
+ }
12
+ params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ ENV['JETS_GIT_CUSTOM_BRANCH']
18
+ end
19
+
20
+ def git_sha
21
+ ENV['JETS_GIT_CUSTOM_SHA']
22
+ end
23
+
24
+ def git_url
25
+ ENV['JETS_GIT_CUSTOM_URL']
26
+ end
27
+
28
+ def git_message
29
+ ENV['JETS_GIT_CUSTOM_MESSAGE']
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ module Jets::Git
2
+ module GitCli
3
+ def git?
4
+ git_folder? && git_installed?
5
+ end
6
+
7
+ def git_folder?
8
+ File.exist?(".git")
9
+ end
10
+
11
+ def git_installed?
12
+ system "type git > /dev/null 2>&1"
13
+ end
14
+
15
+ def git(args, on_error: :nil)
16
+ out = `git #{args}`.strip
17
+ unless $?.success?
18
+ case on_error
19
+ when :raise
20
+ raise Jets::Git::Error, "ERROR: git #{args} failed".color(:red)
21
+ when :nil
22
+ return
23
+ end
24
+ end
25
+ out
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ module Jets::Git
2
+ class Github
3
+ def params
4
+ params = {
5
+ git_system: 'github',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ # git_message: nil,
10
+ # git_version: nil,
11
+ }
12
+ params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ if build_type == "pull_request"
18
+ pr.dig('pull_request','head','ref')
19
+ else # push
20
+ ENV['GITHUB_REF_NAME']
21
+ end
22
+ end
23
+
24
+ def git_sha
25
+ if build_type == "pull_request"
26
+ pr.dig('pull_request','head','sha')
27
+ else # push
28
+ ENV['GITHUB_SHA']
29
+ end
30
+ end
31
+
32
+ def git_url
33
+ host = ENV['GITHUB_SERVER_URL'] || 'https://github.com'
34
+ full_repo = ENV['GITHUB_REPOSITORY']
35
+ "#{host}/#{full_repo}"
36
+ end
37
+
38
+ # GitHub webhook JSON payload in file and path is set in GITHUB_EVENT_PATH
39
+ def pr
40
+ return {} unless ENV['GITHUB_EVENT_PATH']
41
+ JSON.load(IO.read(ENV['GITHUB_EVENT_PATH']))
42
+ end
43
+
44
+ def build_type
45
+ ENV['GITHUB_EVENT_NAME']
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ module Jets::Git
2
+ class Gitlab
3
+ def params
4
+ params = {
5
+ git_system: 'gitlab',
6
+ git_branch: git_branch,
7
+ git_sha: git_sha,
8
+ git_dirty: false,
9
+ # git_message: nil,
10
+ # git_version: nil,
11
+ }
12
+ params[:git_url] = git_url if git_url
13
+ params
14
+ end
15
+
16
+ def git_branch
17
+ ENV['CI_COMMIT_REF_NAME']
18
+ end
19
+
20
+ def git_sha
21
+ ENV['CI_COMMIT_SHA']
22
+ end
23
+
24
+ def git_url
25
+ host = ENV['CI_SERVER_URL'] || 'https://gitlab.com'
26
+ full_repo = ENV['CI_PROJECT_PATH']
27
+ "#{host}/#{full_repo}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ module Jets::Git
2
+ class Info
3
+ extend Memoist
4
+ # Not using options but trying to future proof initialize
5
+ def initialize(options={})
6
+ @options = options
7
+ end
8
+
9
+ def user
10
+ User.new
11
+ end
12
+ memoize :user
13
+
14
+ # Best effort to get git info
15
+ def params
16
+ return {} if ENV['JETS_GIT_DISABLED']
17
+ strategy_class.new.params
18
+ end
19
+
20
+ def strategy_class
21
+ env_map = {
22
+ BITBUCKET_COMMIT: Bitbucket,
23
+ CIRCLECI: Circleci,
24
+ CODEBUILD_CI: Codebuild,
25
+ GITHUB_ACTIONS: Github,
26
+ GITLAB_CI: Gitlab,
27
+ JETS_GIT_CUSTOM: Custom,
28
+ SYSTEM_TEAMFOUNDATIONSERVERURI: Azure,
29
+ }
30
+ found = env_map.find do |env_key, strategy_class|
31
+ ENV[env_key.to_s]
32
+ end
33
+ found ? found[1] : Local
34
+ end
35
+ memoize :strategy_class
36
+ end
37
+ end
@@ -0,0 +1,55 @@
1
+ module Jets::Git
2
+ class Local
3
+ include GitCli
4
+ extend Memoist
5
+
6
+ def params
7
+ return {} unless git? && git_branch
8
+ params = {
9
+ git_system: 'local',
10
+ git_branch: git_branch,
11
+ git_sha: git_sha,
12
+ git_dirty: git_dirty?,
13
+ git_message: git_message,
14
+ git_version: git_version,
15
+ }
16
+ params[:git_url] = git_url if git_url
17
+ params
18
+ end
19
+
20
+ def git_message
21
+ git "log -1 --pretty=%B"
22
+ end
23
+
24
+ def git_branch
25
+ git "rev-parse --abbrev-ref HEAD"
26
+ end
27
+
28
+ def git_sha
29
+ git "rev-parse HEAD"
30
+ end
31
+
32
+ def git_url
33
+ # IE: git "config --get remote.origin.url"
34
+ git "config --get remote.#{git_remote}.url"
35
+ end
36
+
37
+ def git_dirty?
38
+ !git("status --porcelain").empty?
39
+ end
40
+
41
+ def git_version
42
+ git "--version", on_error: :raise
43
+ end
44
+
45
+ # discover git remote name. in case it's not origin
46
+ def git_remote
47
+ # 2>&1 to suppress error message
48
+ # "fatal: not a git repository (or any parent up to mount point /path)\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).\n"
49
+ `git remote 2>&1`
50
+ return unless $?.success?
51
+ `git remote`.strip # IE: origin or blank string
52
+ end
53
+ memoize :git_remote
54
+ end
55
+ end
@@ -0,0 +1,30 @@
1
+ module Jets::Git
2
+ class User
3
+ extend Memoist
4
+ include GitCli
5
+
6
+ def first_name
7
+ name.split(" ").first
8
+ end
9
+
10
+ def name
11
+ git_config["user.name"]
12
+ end
13
+
14
+ def email
15
+ git_config["user.email"]
16
+ end
17
+
18
+ def git_config
19
+ return {} if ENV['JETS_GIT_DISABLED']
20
+ return {} unless git?
21
+ list = git("config --list")
22
+ lines = list.split("\n")
23
+ # Other values in the git config are not needed.
24
+ # And can cause .to_h to bomb and throw an error.
25
+ lines.select! { |l| l =~ /^user\./ }
26
+ lines.map { |l| l.split("=") }.to_h
27
+ end
28
+ memoize :git_config
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jets
4
+ module Git
5
+ VERSION = "0.2.0"
6
+ end
7
+ end
data/lib/jets/git.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "memoist"
5
+
6
+ require_relative "git/autoloader"
7
+ Jets::Git::Autoloader.setup
8
+
9
+ module Jets
10
+ module Git
11
+ class Error < StandardError; end
12
+ end
13
+ end
data/lib/jets-git.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative "jets/git"
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jets-git
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Tung Nguyen
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-12-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: memoist
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rainbow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: zeitwerk
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Gathers git information for Jets.
98
+ email:
99
+ - tongueroo@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".rspec"
105
+ - CHANGELOG.md
106
+ - LICENSE.txt
107
+ - README.md
108
+ - Rakefile
109
+ - lib/jets-git.rb
110
+ - lib/jets/git.rb
111
+ - lib/jets/git/autoloader.rb
112
+ - lib/jets/git/azure.rb
113
+ - lib/jets/git/bitbucket.rb
114
+ - lib/jets/git/circleci.rb
115
+ - lib/jets/git/codebuild.rb
116
+ - lib/jets/git/custom.rb
117
+ - lib/jets/git/git_cli.rb
118
+ - lib/jets/git/github.rb
119
+ - lib/jets/git/gitlab.rb
120
+ - lib/jets/git/info.rb
121
+ - lib/jets/git/local.rb
122
+ - lib/jets/git/user.rb
123
+ - lib/jets/git/version.rb
124
+ homepage: https://github.com/rubyonjets/jets-git
125
+ licenses:
126
+ - MIT
127
+ metadata:
128
+ homepage_uri: https://github.com/rubyonjets/jets-git
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 2.7.0
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.4.20
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Jets Git Library
148
+ test_files: []