gitlab-security_report_schemas 0.1.2.min15.0.0.max15.2.1 → 0.1.3.min15.0.0.max15.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/README.md +0 -3
- data/Rakefile +0 -9
- data/gem_version +1 -1
- data/gitlab-security_report_schemas.gemspec +1 -0
- data/lib/gitlab/security_report_schemas/configuration.rb +0 -3
- data/lib/gitlab/security_report_schemas/version.rb +1 -1
- data/lib/gitlab/security_report_schemas.rb +0 -4
- metadata +16 -8
- data/lib/gitlab/security_report_schemas/release/bundler.rb +0 -34
- data/lib/gitlab/security_report_schemas/release/gemfile.rb +0 -49
- data/lib/gitlab/security_report_schemas/release/issue.rb +0 -77
- data/lib/gitlab/security_report_schemas/release/merge_request.rb +0 -84
- data/lib/gitlab/security_report_schemas/release/templates/issue_description.erb +0 -15
- data/lib/gitlab/security_report_schemas/release/workflow.rb +0 -108
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ba052a7936e82d5a5888c8adfd340bac1929ea5bb51215cdad3c78b108984c4
|
4
|
+
data.tar.gz: 53e80aab76684b7a4fe2e6ae7e6cb2e567b814e27e7cc237c6f604e27c90a964
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bebe86108042279de541e80deaefd90561840502d9db291940728e5d988d71b057f775abdc807f698fcf98d710d8b2f7dde3d41ce747f2de004bc903bbbeeb75
|
7
|
+
data.tar.gz: 29aa663c77051ab73feecbeea252f87c957ef51508069e03c81376720959c4cd138b7a0ef769136d32c795c2bb5725885aad8700a05ee56252dcc5f58485c608
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gitlab-security_report_schemas (0.1.
|
4
|
+
gitlab-security_report_schemas (0.1.3.min15.0.0.max15.2.1)
|
5
5
|
activesupport (>= 6, < 8)
|
6
6
|
json_schemer (~> 2.3.0)
|
7
|
+
mutex_m (~> 0.3.0)
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: https://rubygems.org/
|
@@ -31,6 +32,7 @@ GEM
|
|
31
32
|
simpleidn (~> 0.2)
|
32
33
|
method_source (1.0.0)
|
33
34
|
minitest (5.16.2)
|
35
|
+
mutex_m (0.3.0)
|
34
36
|
parallel (1.22.1)
|
35
37
|
parser (3.1.2.0)
|
36
38
|
ast (~> 2.4.1)
|
data/README.md
CHANGED
@@ -50,7 +50,6 @@ bundle exec security-reports-schemas $FILE_PATH
|
|
50
50
|
| Key | Description |
|
51
51
|
|-----------------------------|-----------------------------------------------------------------------------------------------|
|
52
52
|
| `GITLAB_PUSH_ACCESS_TOKEN` | Own project access token used to push new schema versions. Requires `write_repository` scope. |
|
53
|
-
| `GITLAB_ISSUE_ACCESS_TOKEN` | Project access token used to create an issue on `gitlab-org/gitlab`. Requires `api` scopes. |
|
54
53
|
| `GEM_HOST_API_KEY` | rubygems.org API key |
|
55
54
|
|
56
55
|
#### Configuration
|
@@ -59,8 +58,6 @@ bundle exec security-reports-schemas $FILE_PATH
|
|
59
58
|
|---------------------------|--------------------------------------------------------|----------------------------------------|
|
60
59
|
| `SCHEMAS_PATH` | `./schemas` | Schema storage location |
|
61
60
|
| `SCHEMA_PROJECT` | `gitlab-org/security-products/security-report-schemas` | Where to source schemas |
|
62
|
-
| `GITLAB_PROJECT` | `gitlab-org/gitlab` | Project to open MRs for |
|
63
|
-
| `ISSUE_TARGET_PROJECT_ID` | `278964` (`gitlab-org/gitlab`) | Project ID for which to open an issue. |
|
64
61
|
|
65
62
|
## Maintenance
|
66
63
|
|
data/Rakefile
CHANGED
@@ -41,15 +41,6 @@ task integrity_check: :prepare_schemas do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
namespace :release do
|
45
|
-
desc "Open patch Issue on gitlab-org/gitlab to update its Gemfile to use the current gem version"
|
46
|
-
task :issue do
|
47
|
-
require "gitlab/security_report_schemas"
|
48
|
-
|
49
|
-
Gitlab::SecurityReportSchemas::Release::Workflow.execute
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
44
|
def cleanup_schema_dir
|
54
45
|
puts "Cleaning the schemas directory..."
|
55
46
|
|
data/gem_version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3.min15.0.0.max15.2.1
|
@@ -8,9 +8,6 @@ module Gitlab
|
|
8
8
|
schemas_path: -> { SecurityReportSchemas.root_path.join("schemas") },
|
9
9
|
deprecated_versions: -> { [] },
|
10
10
|
schema_project: -> { "gitlab-org/security-products/security-report-schemas" },
|
11
|
-
gitlab_project: -> { "gitlab-org/gitlab" },
|
12
|
-
issue_target_project_id: -> { "278964" }, # gitlab-org/gitlab
|
13
|
-
gitlab_issue_access_token: nil,
|
14
11
|
ci_server_host: nil
|
15
12
|
}.freeze
|
16
13
|
|
@@ -6,10 +6,6 @@ require_relative "security_report_schemas/configuration"
|
|
6
6
|
require_relative "security_report_schemas/schema_ver"
|
7
7
|
require_relative "security_report_schemas/version"
|
8
8
|
require_relative "security_report_schemas/validator"
|
9
|
-
require_relative "security_report_schemas/release/bundler"
|
10
|
-
require_relative "security_report_schemas/release/gemfile"
|
11
|
-
require_relative "security_report_schemas/release/issue"
|
12
|
-
require_relative "security_report_schemas/release/workflow"
|
13
9
|
|
14
10
|
module Gitlab
|
15
11
|
# The `gitlab-security_report_schemas` gem contains JSON schemas and utilities
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-security_report_schemas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3.min15.0.0.max15.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 2.3.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mutex_m
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.3.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.3.0
|
47
61
|
description:
|
48
62
|
email:
|
49
63
|
- gitlab_rubygems@gitlab.com
|
@@ -73,12 +87,6 @@ files:
|
|
73
87
|
- lib/gitlab/security_report_schemas/cli/schema_downloader.rb
|
74
88
|
- lib/gitlab/security_report_schemas/cli/validator.rb
|
75
89
|
- lib/gitlab/security_report_schemas/configuration.rb
|
76
|
-
- lib/gitlab/security_report_schemas/release/bundler.rb
|
77
|
-
- lib/gitlab/security_report_schemas/release/gemfile.rb
|
78
|
-
- lib/gitlab/security_report_schemas/release/issue.rb
|
79
|
-
- lib/gitlab/security_report_schemas/release/merge_request.rb
|
80
|
-
- lib/gitlab/security_report_schemas/release/templates/issue_description.erb
|
81
|
-
- lib/gitlab/security_report_schemas/release/workflow.rb
|
82
90
|
- lib/gitlab/security_report_schemas/schema.rb
|
83
91
|
- lib/gitlab/security_report_schemas/schema_ver.rb
|
84
92
|
- lib/gitlab/security_report_schemas/utils/string_refinements.rb
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module SecurityReportSchemas
|
5
|
-
module Release
|
6
|
-
# Wrapper around bundle(1).
|
7
|
-
module Bundler
|
8
|
-
extend self
|
9
|
-
|
10
|
-
def install!
|
11
|
-
run("bundle install")
|
12
|
-
end
|
13
|
-
|
14
|
-
def checksum!
|
15
|
-
run("bundle exec bundler-checksum init")
|
16
|
-
end
|
17
|
-
|
18
|
-
def verify_checksum!
|
19
|
-
run("bundle exec bundler-checksum verify")
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def run(command)
|
25
|
-
# Bundler modifies RUBYOPT and RUBYLIB which makes bundle(1) attempt
|
26
|
-
# to load from our gem environment instead of from the GitLab environment.
|
27
|
-
::Bundler.with_unbundled_env do
|
28
|
-
system(command) || raise("non-zero exit code: `#{command}`")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "tempfile"
|
4
|
-
|
5
|
-
module Gitlab
|
6
|
-
module SecurityReportSchemas
|
7
|
-
module Release
|
8
|
-
# Changes or adds a dependency version to a Gemfile.
|
9
|
-
class Gemfile
|
10
|
-
SUBSTITUTION_REGEX_TEMPLATE = %{gem ['"]%s['"], ['"](.*)['"]}
|
11
|
-
FEATURE_CATEGORY = :vulnerability_management
|
12
|
-
|
13
|
-
def self.update!(workflow)
|
14
|
-
File.open(workflow.gemfile_path, "r+").tap do |file|
|
15
|
-
new(file).rewrite!(workflow.class::DEPENDENCY, workflow.gem_version)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_reader :file
|
20
|
-
|
21
|
-
def initialize(file)
|
22
|
-
@file = file
|
23
|
-
end
|
24
|
-
|
25
|
-
private_class_method :new
|
26
|
-
|
27
|
-
def rewrite!(dependency, version)
|
28
|
-
contents = file.read
|
29
|
-
|
30
|
-
file.seek(0)
|
31
|
-
file.truncate(0)
|
32
|
-
file.puts(substituted_content(contents, dependency, version))
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def substituted_content(contents, dependency, version)
|
38
|
-
regex = Regexp.new(SUBSTITUTION_REGEX_TEMPLATE % dependency)
|
39
|
-
dep = "gem '#{dependency}', '#{version}'"
|
40
|
-
|
41
|
-
return contents.gsub!(regex, dep) if contents.match(regex)
|
42
|
-
|
43
|
-
contents.concat("#{dep}, feature_category: #{FEATURE_CATEGORY.inspect}")
|
44
|
-
contents.concat("\n") unless contents.end_with?("\n")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module SecurityReportSchemas
|
5
|
-
module Release
|
6
|
-
# GitLab Issue creation.
|
7
|
-
class Issue
|
8
|
-
API_ROOT = "https://gitlab.com/api/v4"
|
9
|
-
DESCRIPTION_TEMPLATE = "issue_description.erb"
|
10
|
-
|
11
|
-
def self.create!(workflow)
|
12
|
-
new(workflow).execute!
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_reader :workflow
|
16
|
-
|
17
|
-
def initialize(workflow)
|
18
|
-
@workflow = workflow
|
19
|
-
end
|
20
|
-
|
21
|
-
def execute!
|
22
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
23
|
-
http.use_ssl = true
|
24
|
-
|
25
|
-
case response = http.request(request)
|
26
|
-
when Net::HTTPSuccess then extract_url(JSON.parse(response.body))
|
27
|
-
else raise "Failed to create issue: #{response.code} -- #{response.message}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def uri
|
32
|
-
URI(File.join(API_ROOT, "projects", workflow.target_project_id.to_s, "issues"))
|
33
|
-
end
|
34
|
-
|
35
|
-
def body
|
36
|
-
{
|
37
|
-
title: workflow.commit_message,
|
38
|
-
description: description
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
def headers
|
43
|
-
{
|
44
|
-
"Content-Type" => "application/json",
|
45
|
-
"Authorization" => "Bearer #{workflow.access_token}"
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
def description
|
50
|
-
description_template.result_with_hash(gem_version: workflow.gem_version, patch: workflow.patch)
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def request
|
56
|
-
Net::HTTP::Post.new(uri, headers).tap do |req|
|
57
|
-
req.body = body.to_json
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def extract_url(body)
|
62
|
-
body["web_url"]
|
63
|
-
end
|
64
|
-
|
65
|
-
def description_template
|
66
|
-
ERB.new(File.read(description_template_path))
|
67
|
-
end
|
68
|
-
|
69
|
-
def description_template_path
|
70
|
-
Gitlab::SecurityReportSchemas.root_path.join(
|
71
|
-
"lib", "gitlab", "security_report_schemas", "release", "templates", DESCRIPTION_TEMPLATE
|
72
|
-
)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "net/http"
|
4
|
-
require "uri"
|
5
|
-
require "erb"
|
6
|
-
require "json"
|
7
|
-
|
8
|
-
module Gitlab
|
9
|
-
module SecurityReportSchemas
|
10
|
-
module Release
|
11
|
-
# GitLab merge request creation.
|
12
|
-
class MergeRequest
|
13
|
-
API_ROOT = "https://gitlab.com/api/v4"
|
14
|
-
DESCRIPTION_TEMPLATE = "mr_description.erb"
|
15
|
-
|
16
|
-
def self.create!(workflow)
|
17
|
-
new(workflow).execute!
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_reader :workflow
|
21
|
-
|
22
|
-
def initialize(workflow)
|
23
|
-
@workflow = workflow
|
24
|
-
end
|
25
|
-
|
26
|
-
def execute!
|
27
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
28
|
-
http.use_ssl = true
|
29
|
-
|
30
|
-
case response = http.request(request)
|
31
|
-
when Net::HTTPSuccess then extract_url(JSON.parse(response.body))
|
32
|
-
else raise "Failed to create merge request: #{response.code} -- #{response.message}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def uri
|
37
|
-
URI(File.join(API_ROOT, "projects", workflow.target_project_id.to_s, "merge_requests"))
|
38
|
-
end
|
39
|
-
|
40
|
-
def body
|
41
|
-
{
|
42
|
-
source_branch: workflow.branch_name,
|
43
|
-
target_branch: workflow.class::TARGET_BRANCH,
|
44
|
-
title: workflow.commit_message,
|
45
|
-
description: description
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
def headers
|
50
|
-
{
|
51
|
-
"Content-Type" => "application/json",
|
52
|
-
"Authorization" => "Bearer #{workflow.access_token}"
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
def description
|
57
|
-
description_template.result_with_hash(gem_version: workflow.gem_version)
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def request
|
63
|
-
Net::HTTP::Post.new(uri, headers).tap do |req|
|
64
|
-
req.body = body.to_json
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def extract_url(body)
|
69
|
-
body["web_url"]
|
70
|
-
end
|
71
|
-
|
72
|
-
def description_template
|
73
|
-
ERB.new(File.read(description_template_path))
|
74
|
-
end
|
75
|
-
|
76
|
-
def description_template_path
|
77
|
-
Gitlab::SecurityReportSchemas.root_path.join(
|
78
|
-
"lib", "gitlab", "security_report_schemas", "release", "templates", DESCRIPTION_TEMPLATE
|
79
|
-
)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
This is an automatically generated Issue to update the version of [`gitlab-security_report_schemas`](https://gitlab.com/gitlab-org/ruby/gems/gitlab-security_report_schemas/) to <%= gem_version %>.
|
2
|
-
|
3
|
-
### Patch
|
4
|
-
|
5
|
-
```diff
|
6
|
-
<%= patch %>
|
7
|
-
```
|
8
|
-
|
9
|
-
### Background
|
10
|
-
|
11
|
-
GitLab Secure schemas are used as part of [Security scanner integration](https://docs.gitlab.com/ee/development/integrations/secure.html) to ensure that reports produced by analyzers are able to be parsed successfully by GitLab. Each JSON report indicates which version of the Secure schema it conforms to. When the report is parsed, the file is validated using the appropriate schema and will be rejected if it does not succeed.
|
12
|
-
|
13
|
-
@gitlab-org/maintainers/security-report-schemas please someone assign themselves to this Issue.
|
14
|
-
|
15
|
-
/label ~section::sec
|
@@ -1,108 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "git"
|
4
|
-
|
5
|
-
module Gitlab
|
6
|
-
module SecurityReportSchemas
|
7
|
-
module Release
|
8
|
-
# The release workflow that updates a GitLab repository's Gemfile
|
9
|
-
# dependency on this gem to an existing version published on rubygems.org
|
10
|
-
# and creates a merge request for the change.
|
11
|
-
class Workflow
|
12
|
-
DEPENDENCY = "gitlab-security_report_schemas"
|
13
|
-
COMMIT_MESSAGE = "Bump `#{DEPENDENCY}' to v%s"
|
14
|
-
BRANCH_NAME = "#{DEPENDENCY}-v%s"
|
15
|
-
TARGET_BRANCH = "master"
|
16
|
-
|
17
|
-
def self.execute(configuration = Gitlab::SecurityReportSchemas.configuration)
|
18
|
-
new(configuration).execute
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_reader :configuration
|
22
|
-
|
23
|
-
def initialize(configuration)
|
24
|
-
@configuration = configuration
|
25
|
-
end
|
26
|
-
|
27
|
-
def execute
|
28
|
-
gitlab_repository # ensure repository is cloned
|
29
|
-
|
30
|
-
update_gemfile!
|
31
|
-
install_dependencies!
|
32
|
-
|
33
|
-
issue_url = create_issue!
|
34
|
-
|
35
|
-
puts "Successfully created Issue: #{issue_url}"
|
36
|
-
end
|
37
|
-
|
38
|
-
def patch
|
39
|
-
gitlab_repository.diff.patch
|
40
|
-
end
|
41
|
-
|
42
|
-
def gemfile_path
|
43
|
-
gitlab_repository_path.join("Gemfile")
|
44
|
-
end
|
45
|
-
|
46
|
-
def gem_version
|
47
|
-
File.read(gem_version_file).strip
|
48
|
-
end
|
49
|
-
|
50
|
-
def branch_name
|
51
|
-
BRANCH_NAME % gem_version
|
52
|
-
end
|
53
|
-
|
54
|
-
def commit_message
|
55
|
-
COMMIT_MESSAGE % gem_version
|
56
|
-
end
|
57
|
-
|
58
|
-
def target_project_id
|
59
|
-
configuration.issue_target_project_id
|
60
|
-
end
|
61
|
-
|
62
|
-
def access_token
|
63
|
-
configuration.gitlab_issue_access_token
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def gitlab_repository
|
69
|
-
@gitlab_repository ||= if File.exist?(gitlab_repository_path)
|
70
|
-
Git.open(gitlab_repository_path)
|
71
|
-
else
|
72
|
-
Git.clone(configuration.gitlab_repository, gitlab_repository_path, depth: 1)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def update_gemfile!
|
77
|
-
Gitlab::SecurityReportSchemas::Release::Gemfile.update!(self)
|
78
|
-
end
|
79
|
-
|
80
|
-
def install_dependencies!
|
81
|
-
bundle do
|
82
|
-
install!
|
83
|
-
checksum!
|
84
|
-
verify_checksum!
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def bundle(&block)
|
89
|
-
Dir.chdir(gitlab_repository_path) do
|
90
|
-
Gitlab::SecurityReportSchemas::Release::Bundler.module_eval(&block)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def create_issue!
|
95
|
-
Gitlab::SecurityReportSchemas::Release::Issue.create!(self)
|
96
|
-
end
|
97
|
-
|
98
|
-
def gitlab_repository_path
|
99
|
-
Gitlab::SecurityReportSchemas.root_path.join("tmp", "gitlab")
|
100
|
-
end
|
101
|
-
|
102
|
-
def gem_version_file
|
103
|
-
Gitlab::SecurityReportSchemas.root_path.join("gem_version")
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|