metadata-json-lint 2.0.1 → 2.4.0
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 +5 -5
- data/.gitignore +2 -1
- data/.rubocop.yml +2 -1
- data/.travis.yml +10 -3
- data/CHANGELOG.md +64 -3
- data/Gemfile +4 -0
- data/HISTORY.md +107 -0
- data/LICENSE +174 -9
- data/README.md +17 -16
- data/Rakefile +14 -0
- data/lib/metadata-json-lint/schema.rb +21 -3
- data/lib/metadata-json-lint/semantic_puppet_loader.rb +47 -0
- data/lib/metadata-json-lint/version_requirement.rb +39 -5
- data/lib/metadata_json_lint.rb +55 -2
- data/metadata-json-lint.gemspec +10 -8
- data/spec/metadata_json_lint_spec.rb +37 -0
- data/tests/duplicate-dep/metadata.json +1 -5
- data/tests/duplicate-requirement/Rakefile +2 -0
- data/tests/duplicate-requirement/expected +1 -0
- data/tests/duplicate-requirement/metadata.json +87 -0
- data/tests/non_array_requirements/Rakefile +2 -0
- data/tests/non_array_requirements/expected +1 -0
- data/tests/non_array_requirements/metadata.json +61 -0
- data/tests/requirements_eol_version/Rakefile +2 -0
- data/tests/requirements_eol_version/expected +2 -0
- data/tests/requirements_eol_version/metadata.json +92 -0
- data/tests/test.sh +16 -3
- metadata +52 -18
data/README.md
CHANGED
@@ -8,8 +8,6 @@ metadata-json-lint is compatible with Ruby versions 2.0.0, 2.1.9, 2.3.1, and 2.4
|
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
11
|
-
Puppet 4.9.0 and newer:
|
12
|
-
|
13
11
|
via `gem` command:
|
14
12
|
``` shell
|
15
13
|
gem install metadata-json-lint
|
@@ -20,19 +18,6 @@ via Gemfile:
|
|
20
18
|
gem 'metadata-json-lint'
|
21
19
|
```
|
22
20
|
|
23
|
-
**Puppet 4.8.x and older:**
|
24
|
-
|
25
|
-
via `gem` command:
|
26
|
-
``` shell
|
27
|
-
gem install metadata-json-lint semantic_puppet
|
28
|
-
```
|
29
|
-
|
30
|
-
via Gemfile:
|
31
|
-
``` ruby
|
32
|
-
gem 'metadata-json-lint'
|
33
|
-
gem 'semantic_puppet
|
34
|
-
```
|
35
|
-
|
36
21
|
## Usage
|
37
22
|
|
38
23
|
### Testing with metadata-json-lint
|
@@ -56,7 +41,7 @@ rake metadata_lint
|
|
56
41
|
To set options for the Rake task, include them when you define the task:
|
57
42
|
|
58
43
|
```ruby
|
59
|
-
require '
|
44
|
+
require 'metadata_json_lint'
|
60
45
|
task :metadata_lint do
|
61
46
|
MetadataJsonLint.parse('metadata.json') do |options|
|
62
47
|
options.strict_license = false
|
@@ -76,6 +61,22 @@ MetadataJsonLint.options.strict_license = false
|
|
76
61
|
* `--[no-]strict-dependencies`: Whether to fail if module version dependencies are open-ended. Defaults to `false`.
|
77
62
|
* `--[no-]strict-license`: Whether to fail on strict license check. Defaults to `true`.
|
78
63
|
* `--[no-]fail-on-warnings`: Whether to fail on warnings. Defaults to `true`.
|
64
|
+
* `--[no-]strict-puppet-version`: Whether to fail if Puppet version requirements are open-ended or no longer supported. Defaults to `false`.
|
65
|
+
|
66
|
+
|
67
|
+
## Make a new release
|
68
|
+
|
69
|
+
To make a new release, we need to install the release gem group:
|
70
|
+
|
71
|
+
```sh
|
72
|
+
bundle install --path .vendor/ --with release
|
73
|
+
```
|
74
|
+
|
75
|
+
Afterwards export a GitHub access token (otherwise you might run into API rate limits):
|
76
|
+
|
77
|
+
```sh
|
78
|
+
export CHANGELOG_GITHUB_TOKEN=...
|
79
|
+
```
|
79
80
|
|
80
81
|
## Contributors
|
81
82
|
|
data/Rakefile
CHANGED
@@ -13,3 +13,17 @@ end
|
|
13
13
|
|
14
14
|
require 'rspec/core/rake_task'
|
15
15
|
RSpec::Core::RakeTask.new(:spec)
|
16
|
+
|
17
|
+
begin
|
18
|
+
require 'github_changelog_generator/task'
|
19
|
+
|
20
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
21
|
+
config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file."
|
22
|
+
config.exclude_labels = %w[duplicate question invalid wontfix wont-fix skip-changelog]
|
23
|
+
config.user = 'voxpupuli'
|
24
|
+
config.project = 'metadata-json-lint'
|
25
|
+
config.future_release = "v#{Gem::Specification.load("#{config.project}.gemspec").version}"
|
26
|
+
end
|
27
|
+
rescue LoadError
|
28
|
+
puts 'no github_changelog_generator gem available'
|
29
|
+
end
|
@@ -141,10 +141,28 @@ module MetadataJsonLint
|
|
141
141
|
|
142
142
|
private
|
143
143
|
|
144
|
+
def semver_full_regex
|
145
|
+
@semver_full_regex ||= begin
|
146
|
+
# Version string matching regexes
|
147
|
+
numeric = '(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)' # Major . Minor . Patch
|
148
|
+
pre = '(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?' # Prerelease
|
149
|
+
build = '(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?' # Build
|
150
|
+
full = numeric + pre + build
|
151
|
+
|
152
|
+
/\A#{full}\Z/
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
144
156
|
def semver_validator(value)
|
145
|
-
SemanticPuppet::Version
|
146
|
-
|
147
|
-
|
157
|
+
if defined?(SemanticPuppet::Version)
|
158
|
+
begin
|
159
|
+
SemanticPuppet::Version.parse(value)
|
160
|
+
rescue SemanticPuppet::Version::ValidationFailure => e
|
161
|
+
raise JSON::Schema::CustomFormatError, "must be a valid semantic version: #{e.message}"
|
162
|
+
end
|
163
|
+
elsif value.match(semver_full_regex).nil?
|
164
|
+
raise JSON::Schema::CustomFormatError, "must be a valid semantic version: Unable to parse '#{value}' as a semantic version identifier"
|
165
|
+
end
|
148
166
|
end
|
149
167
|
end
|
150
168
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MetadataJsonLint
|
2
|
+
# Attempts the various methods of loading SemanticPuppet.
|
3
|
+
module SemanticPuppetLoader
|
4
|
+
def try_load
|
5
|
+
try_load_puppet
|
6
|
+
return if defined?(SemanticPuppet)
|
7
|
+
|
8
|
+
try_load_semantic
|
9
|
+
return if defined?(SemanticPuppet)
|
10
|
+
|
11
|
+
try_load_semantic_puppet
|
12
|
+
return if defined?(SemanticPuppet)
|
13
|
+
|
14
|
+
warn 'Could not find semantic_puppet gem, falling back to internal functionality. Version checks may be less robust.'
|
15
|
+
end
|
16
|
+
module_function :try_load
|
17
|
+
|
18
|
+
# Most modern Puppet versions have SemanticPuppet vendored in the proper
|
19
|
+
# namespace and automatically load it at require time.
|
20
|
+
def try_load_puppet
|
21
|
+
require 'puppet'
|
22
|
+
rescue LoadError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
module_function :try_load_puppet
|
26
|
+
|
27
|
+
# Older Puppet 4.x versions have SemanticPuppet vendored but under the
|
28
|
+
# Semantic namespace and require it on demand, so we need to load it
|
29
|
+
# ourselves and then alias it to SemanticPuppet for convenience.
|
30
|
+
def try_load_semantic
|
31
|
+
require 'semantic'
|
32
|
+
Kernel.const_set('SemanticPuppet', Semantic)
|
33
|
+
rescue LoadError
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
module_function :try_load_semantic
|
37
|
+
|
38
|
+
# If Puppet is not available or is a version that does not have
|
39
|
+
# SemanticPuppet vendored, try to load the external gem.
|
40
|
+
def try_load_semantic_puppet
|
41
|
+
require 'semantic_puppet'
|
42
|
+
rescue LoadError
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
module_function :try_load_semantic_puppet
|
46
|
+
end
|
47
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
require 'puppet'
|
2
|
-
require 'semantic_puppet' unless Puppet.version >= '4.9.0'
|
3
|
-
|
4
1
|
module MetadataJsonLint
|
5
2
|
# Parses a string module version requirement with semantic_puppet and
|
6
3
|
# provides methods to analyse it for lint warnings
|
7
4
|
class VersionRequirement
|
8
5
|
def initialize(requirement)
|
9
6
|
@requirement = requirement
|
10
|
-
|
7
|
+
|
8
|
+
if defined?(SemanticPuppet::VersionRange)
|
9
|
+
@range = SemanticPuppet::VersionRange.parse(requirement)
|
10
|
+
raise ArgumentError, "Range matches no versions: \"#{requirement}\"" if @range == SemanticPuppet::VersionRange::EMPTY_RANGE
|
11
|
+
elsif requirement.match(/\A[a-z0-9*.\-^~><=|\t ]*\Z/i).nil?
|
12
|
+
raise ArgumentError, "Unparsable version range: \"#{requirement}\""
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
16
|
# Whether the range uses a comparison operator (e.g. >=) with a wildcard
|
@@ -26,7 +29,38 @@ module MetadataJsonLint
|
|
26
29
|
end
|
27
30
|
|
28
31
|
def open_ended?
|
29
|
-
|
32
|
+
if range
|
33
|
+
range.end == SemanticPuppet::Version::MAX
|
34
|
+
else
|
35
|
+
# Empty requirement strings are open-ended.
|
36
|
+
return true if requirement.strip.empty?
|
37
|
+
|
38
|
+
# Strip superfluous whitespace.
|
39
|
+
range_set = requirement.gsub(/([><=~^])(?:\s+|\s*v)/, '\1')
|
40
|
+
|
41
|
+
# Split on logical OR
|
42
|
+
ranges = range_set.split(/\s*\|\|\s*/)
|
43
|
+
|
44
|
+
# Returns true if any range includes a '>' but not a corresponding '<'
|
45
|
+
# which should be the only way to declare an open-ended range.
|
46
|
+
ranges.select { |r| r.include?('>') }.any? { |r| !r.include?('<') }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def puppet_eol?
|
51
|
+
true if range.begin < SemanticPuppet::Version.parse(MIN_PUPPET_VER)
|
52
|
+
end
|
53
|
+
|
54
|
+
def ver_range
|
55
|
+
range
|
56
|
+
end
|
57
|
+
|
58
|
+
def min
|
59
|
+
range.begin
|
60
|
+
end
|
61
|
+
|
62
|
+
def max
|
63
|
+
range.end
|
30
64
|
end
|
31
65
|
|
32
66
|
private
|
data/lib/metadata_json_lint.rb
CHANGED
@@ -2,20 +2,27 @@ require 'json'
|
|
2
2
|
require 'spdx-licenses'
|
3
3
|
require 'optparse'
|
4
4
|
|
5
|
+
require 'metadata-json-lint/semantic_puppet_loader'
|
6
|
+
MetadataJsonLint::SemanticPuppetLoader.try_load
|
7
|
+
|
5
8
|
require 'metadata-json-lint/schema'
|
6
9
|
require 'metadata-json-lint/version_requirement'
|
7
10
|
|
8
11
|
module MetadataJsonLint
|
12
|
+
MIN_PUPPET_VER = '4.10.0'.freeze
|
13
|
+
|
9
14
|
def options
|
10
15
|
@options ||= Struct.new(
|
11
16
|
:fail_on_warnings,
|
12
17
|
:strict_license,
|
13
18
|
:strict_dependencies,
|
19
|
+
:strict_puppet_version,
|
14
20
|
:format
|
15
21
|
).new(
|
16
22
|
true, # fail_on_warnings
|
17
23
|
true, # strict_license
|
18
24
|
false, # strict_dependencies
|
25
|
+
false, # strict_puppet_version
|
19
26
|
'text', # format
|
20
27
|
)
|
21
28
|
end
|
@@ -37,6 +44,10 @@ module MetadataJsonLint
|
|
37
44
|
options[:fail_on_warnings] = v
|
38
45
|
end
|
39
46
|
|
47
|
+
opts.on('--[no-]strict-puppet-version', "Fail on strict Puppet Version check based on current supported Puppet versions. Defaults to '#{options[:strict_puppet_version]}'.") do |v|
|
48
|
+
options[:strict_puppet_version] = v
|
49
|
+
end
|
50
|
+
|
40
51
|
opts.on('-f', '--format FORMAT', %i[text json], 'The format in which results will be output (text, json)') do |format|
|
41
52
|
options[:format] = format
|
42
53
|
end
|
@@ -126,15 +137,55 @@ module MetadataJsonLint
|
|
126
137
|
end
|
127
138
|
module_function :parse
|
128
139
|
|
140
|
+
def validate_requirements_unique(requirements)
|
141
|
+
names = requirements.map { |x| x['name'] }
|
142
|
+
counts = Hash.new(0)
|
143
|
+
|
144
|
+
names.each { |name| counts[name.downcase] += 1 }
|
145
|
+
|
146
|
+
counts.each do |k, v|
|
147
|
+
error :requirements, "Duplicate entries in the 'requirements' list with the name '#{k}'" if v > 1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
module_function :validate_requirements_unique
|
151
|
+
|
129
152
|
def validate_requirements!(requirements)
|
153
|
+
return unless requirements.is_a?(Array)
|
154
|
+
|
130
155
|
requirements.each do |requirement|
|
131
156
|
if requirement['name'] == 'pe'
|
132
157
|
warn :requirements, "The 'pe' requirement is no longer supported by the Forge."
|
133
158
|
end
|
159
|
+
|
160
|
+
begin
|
161
|
+
puppet_req = VersionRequirement.new(requirement.fetch('version_requirement', ''))
|
162
|
+
rescue ArgumentError => e
|
163
|
+
# Raised when the version_requirement provided could not be parsed
|
164
|
+
error :requirements, "Invalid 'version_requirement' field in metadata.json: #{e}"
|
165
|
+
end
|
166
|
+
|
167
|
+
validate_puppet_ver!(puppet_req) unless puppet_req.instance_variable_get('@requirement').nil?
|
134
168
|
end
|
169
|
+
|
170
|
+
validate_requirements_unique(requirements)
|
135
171
|
end
|
136
172
|
module_function :validate_requirements!
|
137
173
|
|
174
|
+
def validate_puppet_ver!(requirement)
|
175
|
+
if options[:strict_puppet_version] && requirement.open_ended?
|
176
|
+
warn(:requirement, "Puppet has an open ended version requirement #{requirement.ver_range}")
|
177
|
+
end
|
178
|
+
|
179
|
+
if options[:strict_puppet_version] && requirement.puppet_eol?
|
180
|
+
warn(:requirement, "#{requirement.min} is no longer supported. Minimum supported version is #{MIN_PUPPET_VER}")
|
181
|
+
end
|
182
|
+
|
183
|
+
return unless requirement.mixed_syntax?
|
184
|
+
warn(:requirement, 'Mixing "x" or "*" version syntax with operators is not recommended in ' \
|
185
|
+
"metadata.json, use one style in the puppet version: #{requirement.instance_variable_get('@requirement')}")
|
186
|
+
end
|
187
|
+
module_function :validate_puppet_ver!
|
188
|
+
|
138
189
|
def validate_dependencies!(deps)
|
139
190
|
dep_names = []
|
140
191
|
deps.each do |dep|
|
@@ -148,6 +199,8 @@ module MetadataJsonLint
|
|
148
199
|
rescue ArgumentError => e
|
149
200
|
# Raised when the version_requirement provided could not be parsed
|
150
201
|
error :dependencies, "Invalid 'version_requirement' field in metadata.json: #{e}"
|
202
|
+
# Skip to the next dependency
|
203
|
+
next
|
151
204
|
end
|
152
205
|
validate_version_requirement!(dep, requirement)
|
153
206
|
|
@@ -164,10 +217,10 @@ module MetadataJsonLint
|
|
164
217
|
def validate_version_requirement!(dep, requirement)
|
165
218
|
# Open ended dependency
|
166
219
|
# From: https://docs.puppet.com/puppet/latest/reference/modules_metadata.html#best-practice-set-an-upper-bound-for-dependencies
|
167
|
-
if requirement.open_ended?
|
220
|
+
if options[:strict_dependencies] && requirement.open_ended?
|
168
221
|
msg = "Dependency #{dep['name']} has an open " \
|
169
222
|
"ended dependency version requirement #{dep['version_requirement']}"
|
170
|
-
|
223
|
+
warn(:dependencies, msg)
|
171
224
|
end
|
172
225
|
|
173
226
|
# Mixing operator and wildcard version syntax
|
data/metadata-json-lint.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'date'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'metadata-json-lint'
|
5
|
-
s.version = '2.0
|
5
|
+
s.version = '2.4.0'
|
6
6
|
s.date = Date.today.to_s
|
7
7
|
s.summary = 'metadata-json-lint /path/to/metadata.json'
|
8
8
|
s.description = 'Utility to verify Puppet metadata.json files'
|
@@ -19,14 +19,16 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.required_ruby_version = '>= 2.0.0'
|
20
20
|
s.add_runtime_dependency 'spdx-licenses', '~> 1.0'
|
21
21
|
s.add_runtime_dependency 'json-schema', '~> 2.8'
|
22
|
-
s.
|
22
|
+
s.add_development_dependency 'pry'
|
23
23
|
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'semantic_puppet'
|
24
25
|
s.add_development_dependency 'rspec'
|
25
|
-
s.add_development_dependency 'rubocop'
|
26
|
+
s.add_development_dependency 'rubocop', '~> 0.50.0'
|
26
27
|
s.post_install_message = '
|
27
|
-
|
28
|
-
|
29
|
-
your Gemfile if you
|
30
|
-
|
31
|
-
|
28
|
+
----------------------------------------------------------
|
29
|
+
For the most accurate results, the semantic_puppet
|
30
|
+
gem should be included within your Gemfile if you
|
31
|
+
use Puppet <= 4.8.x
|
32
|
+
----------------------------------------------------------
|
33
|
+
'.gsub(/^ /, '')
|
32
34
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
describe MetadataJsonLint do
|
2
|
+
describe '.validate_requirements!' do
|
3
|
+
context 'empty requirements' do
|
4
|
+
let :requirements do
|
5
|
+
[]
|
6
|
+
end
|
7
|
+
|
8
|
+
it { expect { described_class.validate_requirements!(requirements) }.not_to raise_error }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'with pe' do
|
12
|
+
let :requirements do
|
13
|
+
[
|
14
|
+
{ 'name' => 'pe' }
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
it do
|
19
|
+
expect(described_class).to receive('warn').with(:requirements, "The 'pe' requirement is no longer supported by the Forge.")
|
20
|
+
expect { described_class.validate_requirements!(requirements) }.not_to raise_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with invalid requirement' do
|
25
|
+
let :requirements do
|
26
|
+
[
|
27
|
+
{ 'name' => 'puppet', 'version_requirement' => 'a' }
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
it do
|
32
|
+
expect(described_class).to receive('error').with(:requirements, "Invalid 'version_requirement' field in metadata.json: Unparsable version range: \"a\"")
|
33
|
+
expect { described_class.validate_requirements!(requirements) }.not_to raise_error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Duplicate entries in the 'requirements' list with the name 'puppet'
|
@@ -0,0 +1,87 @@
|
|
1
|
+
{
|
2
|
+
"name": "puppetlabs-postgresql",
|
3
|
+
"version": "3.4.1",
|
4
|
+
"author": "Inkling/Puppet Labs",
|
5
|
+
"summary": "PostgreSQL defined resource types",
|
6
|
+
"license": "Apache-2.0",
|
7
|
+
"source": "git://github.com/puppetlabs/puppet-postgresql.git",
|
8
|
+
"project_page": "https://github.com/puppetlabs/puppet-postgresql",
|
9
|
+
"issues_url": "https://github.com/puppetlabs/puppet-postgresql/issues",
|
10
|
+
"operatingsystem_support": [
|
11
|
+
{
|
12
|
+
"operatingsystem": "RedHat",
|
13
|
+
"operatingsystemrelease": [
|
14
|
+
"5",
|
15
|
+
"6",
|
16
|
+
"7"
|
17
|
+
]
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"operatingsystem": "CentOS",
|
21
|
+
"operatingsystemrelease": [
|
22
|
+
"5",
|
23
|
+
"6",
|
24
|
+
"7"
|
25
|
+
]
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"operatingsystem": "OracleLinux",
|
29
|
+
"operatingsystemrelease": [
|
30
|
+
"5",
|
31
|
+
"6",
|
32
|
+
"7"
|
33
|
+
]
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"operatingsystem": "Scientific",
|
37
|
+
"operatingsystemrelease": [
|
38
|
+
"5",
|
39
|
+
"6",
|
40
|
+
"7"
|
41
|
+
]
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"operatingsystem": "Debian",
|
45
|
+
"operatingsystemrelease": [
|
46
|
+
"6",
|
47
|
+
"7"
|
48
|
+
]
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"operatingsystem": "Ubuntu",
|
52
|
+
"operatingsystemrelease": [
|
53
|
+
"10.04",
|
54
|
+
"12.04",
|
55
|
+
"14.04"
|
56
|
+
]
|
57
|
+
}
|
58
|
+
],
|
59
|
+
"requirements": [
|
60
|
+
{
|
61
|
+
"name": "puppet",
|
62
|
+
"version_requirement": "5.5.1"
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"name": "puppet",
|
66
|
+
"version_requirement": "6.11.0"
|
67
|
+
}
|
68
|
+
],
|
69
|
+
"dependencies": [
|
70
|
+
{
|
71
|
+
"name": "puppetlabs/stdlib",
|
72
|
+
"version_requirement": "4.x"
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"name": "puppetlabs/firewall",
|
76
|
+
"version_requirement": ">= 0.0.4"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"name": "puppetlabs/apt",
|
80
|
+
"version_requirement": ">=1.1.0 <2.0.0"
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"name": "puppetlabs/concat",
|
84
|
+
"version_requirement": ">= 1.1.0 <2.0.0"
|
85
|
+
}
|
86
|
+
]
|
87
|
+
}
|