metadata-json-lint 1.1.0 → 1.2.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 +4 -4
- data/lib/metadata_json_lint.rb +94 -51
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26b0284277b14da2149836312d2f7470eeb42fec
|
4
|
+
data.tar.gz: 1f700550be689ad9379a1bfb5a617f4de64a18db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0160d90cb4707dc94deb44d16f9a3d22dcd15f9f6b7749c054b8354ea593089407de42e679040a052c634637d6718d636f7abec41c3cd0e2811ee439d2a9211
|
7
|
+
data.tar.gz: 9cbad4cbd0437415b6c347a05491a4a17f5324ca2c4472fc02772701fc7c37ebbda5a2c95106cbf5305f8afe11b4bc224e9de13ce4b74967eb9fed593da3743f
|
data/lib/metadata_json_lint.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'spdx-licenses'
|
3
3
|
require 'optparse'
|
4
|
-
|
4
|
+
|
5
|
+
require 'metadata-json-lint/version_requirement'
|
5
6
|
|
6
7
|
module MetadataJsonLint
|
7
8
|
def options
|
8
9
|
@options ||= Struct.new(
|
9
10
|
:fail_on_warnings,
|
10
11
|
:strict_license,
|
11
|
-
:strict_dependencies
|
12
|
+
:strict_dependencies,
|
13
|
+
:format
|
12
14
|
).new(
|
13
15
|
true, # fail_on_warnings
|
14
16
|
true, # strict_license
|
15
|
-
false # strict_dependencies
|
17
|
+
false, # strict_dependencies
|
18
|
+
'text', # format
|
16
19
|
)
|
17
20
|
end
|
18
21
|
module_function :options
|
@@ -32,6 +35,10 @@ module MetadataJsonLint
|
|
32
35
|
opts.on('--[no-]fail-on-warnings', "Fail on any warnings. Defaults to '#{options[:fail_on_warnings]}'.") do |v|
|
33
36
|
options[:fail_on_warnings] = v
|
34
37
|
end
|
38
|
+
|
39
|
+
opts.on('-f', '--format FORMAT', %i[text json], 'The format in which results will be output (text, json)') do |format|
|
40
|
+
options[:format] = format
|
41
|
+
end
|
35
42
|
end.parse!
|
36
43
|
|
37
44
|
mj = if ARGV[0].nil?
|
@@ -49,6 +56,9 @@ module MetadataJsonLint
|
|
49
56
|
module_function :run
|
50
57
|
|
51
58
|
def parse(metadata)
|
59
|
+
@errors = []
|
60
|
+
@warnings = []
|
61
|
+
|
52
62
|
# Small hack to use the module settings as defaults but allow overriding for different rake tasks
|
53
63
|
options = options().clone
|
54
64
|
# Configuration from rake tasks
|
@@ -65,111 +75,144 @@ module MetadataJsonLint
|
|
65
75
|
abort("Error: Unable to parse metadata.json: #{e.exception}")
|
66
76
|
end
|
67
77
|
|
68
|
-
error_state = false
|
69
|
-
|
70
78
|
# Fields required to be in metadata.json
|
71
79
|
# From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file
|
72
|
-
required_fields = %w
|
80
|
+
required_fields = %w[name version author license summary source dependencies]
|
73
81
|
required_fields.each do |field|
|
74
82
|
if parsed[field].nil?
|
75
|
-
|
76
|
-
error_state = true
|
83
|
+
error :required_fields, "Required field '#{field}' not found in metadata.json."
|
77
84
|
end
|
78
85
|
end
|
79
86
|
|
80
|
-
|
87
|
+
validate_dependencies!(parsed['dependencies']) if parsed['dependencies']
|
81
88
|
|
82
89
|
# Deprecated fields
|
83
90
|
# From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file
|
84
|
-
deprecated_fields = %w
|
91
|
+
deprecated_fields = %w[types checksum]
|
85
92
|
deprecated_fields.each do |field|
|
86
93
|
unless parsed[field].nil?
|
87
|
-
|
88
|
-
error_state = true
|
94
|
+
error :deprecated_fields, "Deprecated field '#{field}' found in metadata.json."
|
89
95
|
end
|
90
96
|
end
|
91
97
|
|
92
98
|
# The nested 'requirements' name of 'pe' is deprecated as well.
|
93
99
|
# https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/puppet-users/nkRPvG4q0Oo/GmXa109aJQAJ
|
94
|
-
|
100
|
+
validate_requirements!(parsed['requirements']) if parsed['requirements']
|
95
101
|
|
96
102
|
# Summary can not be over 144 characters:
|
97
103
|
# From: https://forge.puppetlabs.com/razorsedge/snmp/3.3.1/scores
|
98
104
|
if !parsed['summary'].nil? && parsed['summary'].size > 144
|
99
|
-
|
100
|
-
error_state = true
|
105
|
+
error :summary, 'Field \'summary\' exceeds 144 characters in metadata.json.'
|
101
106
|
end
|
102
107
|
|
103
108
|
# Shoulds/recommendations
|
104
109
|
# From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file
|
105
110
|
#
|
106
111
|
if !parsed['license'].nil? && !SpdxLicenses.exist?(parsed['license']) && parsed['license'] != 'proprietary'
|
107
|
-
|
108
|
-
|
112
|
+
msg = "License identifier #{parsed['license']} is not in the SPDX list: http://spdx.org/licenses/"
|
113
|
+
|
114
|
+
options[:strict_license] == true ? error(:license, msg) : warn(:license, msg)
|
109
115
|
end
|
110
116
|
|
111
117
|
if !parsed['tags'].nil? && !parsed['tags'].is_a?(Array)
|
112
|
-
|
113
|
-
error_state = true
|
118
|
+
error :tags, "Tags must be in an array. Currently it's a #{parsed['tags'].class}."
|
114
119
|
end
|
115
120
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
+
if !@errors.empty? || !@warnings.empty?
|
122
|
+
result = @errors.empty? ? "Warnings found in #{metadata}" : "Errors found in #{metadata}"
|
123
|
+
|
124
|
+
case options[:format]
|
125
|
+
when :json
|
126
|
+
puts JSON.fast_generate(:result => result, :warnings => @warnings, :errors => @errors)
|
127
|
+
else
|
128
|
+
@warnings.each { |warn| puts "(WARN) #{warn}" }
|
129
|
+
@errors.each { |err| puts "(ERROR) #{err}" }
|
130
|
+
puts result
|
131
|
+
end
|
132
|
+
|
133
|
+
if !@errors.empty? || (!@warnings.empty? && (options[:fail_on_warnings] == true))
|
134
|
+
exit(1)
|
135
|
+
end
|
121
136
|
end
|
137
|
+
|
138
|
+
exit(0)
|
122
139
|
end
|
123
140
|
module_function :parse
|
124
141
|
|
125
|
-
def
|
126
|
-
error_state = false
|
142
|
+
def validate_requirements!(requirements)
|
127
143
|
requirements.each do |requirement|
|
128
144
|
if requirement['name'] == 'pe'
|
129
|
-
|
130
|
-
error_state = true
|
145
|
+
warn :requirements, "The 'pe' requirement is no longer supported by the Forge."
|
131
146
|
end
|
132
147
|
end
|
133
|
-
error_state
|
134
148
|
end
|
135
|
-
module_function :
|
149
|
+
module_function :validate_requirements!
|
136
150
|
|
137
|
-
def
|
138
|
-
error_state = false
|
151
|
+
def validate_dependencies!(deps)
|
139
152
|
dep_names = []
|
140
153
|
deps.each do |dep|
|
141
154
|
if dep_names.include?(dep['name'])
|
142
|
-
|
143
|
-
error_state = true
|
155
|
+
warn :dependencies, "Duplicate dependencies on #{dep['name']}"
|
144
156
|
end
|
145
157
|
dep_names << dep['name']
|
146
158
|
|
147
|
-
# Open ended dependency
|
148
|
-
# From: https://docs.puppet.com/puppet/latest/reference/modules_metadata.html#best-practice-set-an-upper-bound-for-dependencies
|
149
159
|
begin
|
150
|
-
|
151
|
-
puts "Warning: Dependency #{dep['name']} has an open " \
|
152
|
-
"ended dependency version requirement #{dep['version_requirement']}"
|
153
|
-
error_state = true if options[:strict_dependencies]
|
160
|
+
requirement = VersionRequirement.new(dep.fetch('version_requirement', ''))
|
154
161
|
rescue ArgumentError => e
|
155
162
|
# Raised when the version_requirement provided could not be parsed
|
156
|
-
|
157
|
-
error_state = true
|
163
|
+
error :dependencies, "Invalid 'version_requirement' field in metadata.json: #{e}"
|
158
164
|
end
|
165
|
+
validate_version_requirement!(dep, requirement)
|
159
166
|
|
160
167
|
# 'version_range' is no longer used by the forge
|
161
168
|
# See https://tickets.puppetlabs.com/browse/PUP-2781
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
169
|
+
if dep.key?('version_range')
|
170
|
+
warn :dependencies, "Dependency #{dep['name']} has a 'version_range' attribute " \
|
171
|
+
'which is no longer used by the forge.'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
module_function :validate_dependencies!
|
176
|
+
|
177
|
+
def validate_version_requirement!(dep, requirement)
|
178
|
+
# Open ended dependency
|
179
|
+
# From: https://docs.puppet.com/puppet/latest/reference/modules_metadata.html#best-practice-set-an-upper-bound-for-dependencies
|
180
|
+
if requirement.open_ended?
|
181
|
+
msg = "Dependency #{dep['name']} has an open " \
|
182
|
+
"ended dependency version requirement #{dep['version_requirement']}"
|
183
|
+
options[:strict_dependencies] == true ? error(:dependencies, msg) : warn(:dependencies, msg)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Mixing operator and wildcard version syntax
|
187
|
+
# From: https://docs.puppet.com/puppet/latest/modules_metadata.html#version-specifiers
|
188
|
+
# Supported in Puppet 5 and higher, but the syntax is unclear and incompatible with older versions
|
189
|
+
return unless requirement.mixed_syntax?
|
190
|
+
warn(:dependencies, 'Mixing "x" or "*" version syntax with operators is not recommended in ' \
|
191
|
+
"metadata.json, use one style in the #{dep['name']} dependency: #{dep['version_requirement']}")
|
192
|
+
end
|
193
|
+
module_function :validate_version_requirement!
|
194
|
+
|
195
|
+
def format_error(check, msg)
|
196
|
+
case options[:format]
|
197
|
+
when :json
|
198
|
+
{ :check => check, :msg => msg }
|
199
|
+
else
|
200
|
+
"#{check}: #{msg}"
|
166
201
|
end
|
167
|
-
error_state
|
168
202
|
end
|
169
|
-
module_function :
|
203
|
+
module_function :format_error
|
204
|
+
|
205
|
+
def warn(check, msg)
|
206
|
+
@warnings ||= []
|
207
|
+
|
208
|
+
@warnings << format_error(check, msg)
|
209
|
+
end
|
210
|
+
module_function :warn
|
211
|
+
|
212
|
+
def error(check, msg)
|
213
|
+
@errors ||= []
|
170
214
|
|
171
|
-
|
172
|
-
SemanticPuppet::VersionRange.parse(module_end).end == SemanticPuppet::Version::MAX
|
215
|
+
@errors << format_error(check, msg)
|
173
216
|
end
|
174
|
-
module_function :
|
217
|
+
module_function :error
|
175
218
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metadata-json-lint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vox Pupuli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spdx-licenses
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: rubocop
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|