metadata-json-lint 1.2.2 → 2.0.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/.rubocop.yml +4 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +4 -0
- data/README.md +25 -4
- data/lib/metadata-json-lint/schema.rb +150 -0
- data/lib/metadata_json_lint.rb +5 -17
- data/metadata-json-lint.gemspec +12 -3
- data/spec/schema_spec.rb +38 -0
- data/tests/long_summary/expected +1 -1
- data/tests/noname/expected +1 -1
- data/tests/tags_no_array/expected +1 -1
- metadata +20 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 656d4c9a85eceaa230fe84711819956a3d746a71
|
4
|
+
data.tar.gz: 69c06229897d87ec0a65115b28b01eec85dfa5b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36c139d8de7c19a488b0e73ed06f2461e6a177c65c62abc548b58ce36a715e3b574d08edb62c765c357fccb35a8754972eca0a411ccff303e5b58aef38599de7
|
7
|
+
data.tar.gz: 79a89a232bdae551740952c7827ebac93568006cce890f63eb913b5e3bf4fb111729a06bbfff4042659581ae0d11d390d30a399433c8b1d89d2e6a44fb6e8c3c
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
|
+
## 2.0.0
|
9
|
+
|
10
|
+
### Changes
|
11
|
+
* The `semantic_puppet` gem is no longer included as a runtime dependency due to conflicts with Puppet 5.x libraries that break the `puppet module` command. As such, `semantic_puppet` must be added to a user's Gemfile in Puppet <= 4.x. See [Installation](https://github.com/voxpupuli/metadata-json-lint#installation) docs for more info
|
12
|
+
* `metadata-json-lint` now officially only supports Ruby >= 2.0.0
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
* Fix puppet 5.x `semantic_puppet` conflicts ([#79](https://github.com/voxpupuli/metadata-json-lint/issues/79))
|
16
|
+
* Clarify Ruby >= 2.x only support ([#74](https://github.com/voxpupuli/metadata-json-lint/issues/74))
|
17
|
+
|
8
18
|
## 1.2.2
|
9
19
|
|
10
20
|
### Fixed
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,14 +4,35 @@ The metadata-json-lint tool validates and lints `metadata.json` files in Puppet
|
|
4
4
|
|
5
5
|
## Compatibility
|
6
6
|
|
7
|
-
metadata-json-lint is compatible with Ruby versions 2.0.0, 2.1.9, and 2.
|
7
|
+
metadata-json-lint is compatible with Ruby versions 2.0.0, 2.1.9, 2.3.1, and 2.4.1.
|
8
8
|
|
9
9
|
## Installation
|
10
|
+
**NOTE: `metadata-json-lint` has a dependency on the `semantic_puppet` gem if you're on
|
11
|
+
Puppet 4 or earlier. This dependency was removed from the gemspec file due to a conflict
|
12
|
+
in Puppet 5 where the `semantic_puppet` ruby gem conflicts with a version of
|
13
|
+
`semantic_puppet` bundled with the core Puppet 5 code.**
|
14
|
+
|
15
|
+
### Puppet 5
|
16
|
+
via `gem` command:
|
17
|
+
``` shell
|
18
|
+
gem install metadata-json-lint
|
19
|
+
```
|
10
20
|
|
11
|
-
|
21
|
+
via Gemfile:
|
22
|
+
``` ruby
|
23
|
+
gem 'metadata-json-lint'
|
24
|
+
```
|
12
25
|
|
13
|
-
|
14
|
-
gem
|
26
|
+
### Puppet 4 and earlier
|
27
|
+
via `gem` command:
|
28
|
+
``` shell
|
29
|
+
gem install metadata-json-lint semantic_puppet
|
30
|
+
```
|
31
|
+
|
32
|
+
via Gemfile:
|
33
|
+
``` ruby
|
34
|
+
gem 'metadata-json-lint'
|
35
|
+
gem 'semantic_puppet'
|
15
36
|
```
|
16
37
|
|
17
38
|
## Usage
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'json-schema'
|
2
|
+
|
3
|
+
module MetadataJsonLint
|
4
|
+
# Provides validation of metadata.json against a JSON schema document
|
5
|
+
# maintained in this class. Provides a good first pass over the metadata with
|
6
|
+
# type checking and basic format/length validations.
|
7
|
+
#
|
8
|
+
# rubocop:disable Metrics/ClassLength # schema data structure is quite large
|
9
|
+
class Schema
|
10
|
+
# Based on https://docs.puppet.com/puppet/latest/modules_metadata.html
|
11
|
+
#
|
12
|
+
# rubocop:disable Style/TrailingCommaInLiteral # easier to modify individual lines
|
13
|
+
def schema
|
14
|
+
{
|
15
|
+
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
16
|
+
'properties' => {
|
17
|
+
'author' => {
|
18
|
+
'type' => 'string',
|
19
|
+
},
|
20
|
+
'data_provider' => {
|
21
|
+
'type' => %w[null string],
|
22
|
+
},
|
23
|
+
'dependencies' => {
|
24
|
+
'type' => 'array',
|
25
|
+
'items' => {
|
26
|
+
'properties' => {
|
27
|
+
'name' => {
|
28
|
+
'type' => 'string',
|
29
|
+
'pattern' => '^\w+[/-][a-z][a-z0-9_]*$',
|
30
|
+
},
|
31
|
+
'version_requirement' => {
|
32
|
+
'type' => 'string',
|
33
|
+
},
|
34
|
+
},
|
35
|
+
'required' => %w[
|
36
|
+
name
|
37
|
+
],
|
38
|
+
},
|
39
|
+
},
|
40
|
+
'description' => {
|
41
|
+
'type' => 'string',
|
42
|
+
},
|
43
|
+
'issues_url' => {
|
44
|
+
'type' => 'string',
|
45
|
+
'format' => 'uri',
|
46
|
+
},
|
47
|
+
'license' => {
|
48
|
+
'type' => 'string',
|
49
|
+
},
|
50
|
+
'operatingsystem_support' => {
|
51
|
+
'type' => 'array',
|
52
|
+
'items' => {
|
53
|
+
'properties' => {
|
54
|
+
'operatingsystem' => {
|
55
|
+
'type' => 'string',
|
56
|
+
},
|
57
|
+
'operatingsystemrelease' => {
|
58
|
+
'type' => 'array',
|
59
|
+
'items' => {
|
60
|
+
'type' => 'string',
|
61
|
+
},
|
62
|
+
},
|
63
|
+
},
|
64
|
+
'required' => %w[
|
65
|
+
operatingsystem
|
66
|
+
],
|
67
|
+
},
|
68
|
+
},
|
69
|
+
'name' => {
|
70
|
+
'type' => 'string',
|
71
|
+
'pattern' => '^\w+-[a-z][a-z0-9_]*$',
|
72
|
+
},
|
73
|
+
'project_page' => {
|
74
|
+
'type' => 'string',
|
75
|
+
'format' => 'uri',
|
76
|
+
},
|
77
|
+
# Undocumented but in use: https://tickets.puppetlabs.com/browse/DOCUMENT-387
|
78
|
+
'requirements' => {
|
79
|
+
'type' => 'array',
|
80
|
+
'items' => {
|
81
|
+
'properties' => {
|
82
|
+
'name' => {
|
83
|
+
'type' => 'string',
|
84
|
+
},
|
85
|
+
'version_requirement' => {
|
86
|
+
'type' => 'string',
|
87
|
+
},
|
88
|
+
},
|
89
|
+
'required' => %w[
|
90
|
+
name
|
91
|
+
],
|
92
|
+
},
|
93
|
+
},
|
94
|
+
'source' => {
|
95
|
+
'type' => 'string',
|
96
|
+
},
|
97
|
+
'summary' => {
|
98
|
+
'type' => 'string',
|
99
|
+
'maxLength' => 144,
|
100
|
+
},
|
101
|
+
'tags' => {
|
102
|
+
'type' => 'array',
|
103
|
+
'items' => {
|
104
|
+
'type' => 'string'
|
105
|
+
},
|
106
|
+
},
|
107
|
+
'version' => {
|
108
|
+
'type' => 'string',
|
109
|
+
'format' => 'semver',
|
110
|
+
},
|
111
|
+
},
|
112
|
+
# from https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file
|
113
|
+
'required' => %w[
|
114
|
+
author
|
115
|
+
dependencies
|
116
|
+
license
|
117
|
+
name
|
118
|
+
source
|
119
|
+
summary
|
120
|
+
version
|
121
|
+
],
|
122
|
+
}
|
123
|
+
end
|
124
|
+
# rubocop:enable Style/TrailingCommaInLiteral
|
125
|
+
|
126
|
+
def validate(data, options = {})
|
127
|
+
JSON::Validator.register_format_validator('semver', method(:semver_validator))
|
128
|
+
|
129
|
+
JSON::Validator.fully_validate(schema, data, options.merge(errors_as_objects: true)).map do |error|
|
130
|
+
field = error[:fragment].split('/')[1]
|
131
|
+
field = 'root' if field.nil? || field.empty?
|
132
|
+
|
133
|
+
message = error[:message]
|
134
|
+
.sub(/ in schema [\w-]+/, '') # remove schema UUID, not needed in output
|
135
|
+
.sub(%r{'#/}, "'") # remove root #/ prefix from document paths
|
136
|
+
.sub("property ''", 'file') # call the root #/ node the file
|
137
|
+
|
138
|
+
{ field: field, message: message }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def semver_validator(value)
|
145
|
+
SemanticPuppet::Version.parse(value)
|
146
|
+
rescue SemanticPuppet::Version::ValidationFailure => e
|
147
|
+
raise JSON::Schema::CustomFormatError, "must be a valid semantic version: #{e.message}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/lib/metadata_json_lint.rb
CHANGED
@@ -2,6 +2,7 @@ require 'json'
|
|
2
2
|
require 'spdx-licenses'
|
3
3
|
require 'optparse'
|
4
4
|
|
5
|
+
require 'metadata-json-lint/schema'
|
5
6
|
require 'metadata-json-lint/version_requirement'
|
6
7
|
|
7
8
|
module MetadataJsonLint
|
@@ -75,13 +76,10 @@ module MetadataJsonLint
|
|
75
76
|
abort("Error: Unable to parse metadata.json: #{e.exception}")
|
76
77
|
end
|
77
78
|
|
78
|
-
#
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if parsed[field].nil?
|
83
|
-
error :required_fields, "Required field '#{field}' not found in metadata.json."
|
84
|
-
end
|
79
|
+
# Validate basic structure against JSON schema
|
80
|
+
schema_errors = Schema.new.validate(parsed)
|
81
|
+
schema_errors.each do |err|
|
82
|
+
error (err[:field] == 'root' ? :required_fields : err[:field]), err[:message]
|
85
83
|
end
|
86
84
|
|
87
85
|
validate_dependencies!(parsed['dependencies']) if parsed['dependencies']
|
@@ -99,12 +97,6 @@ module MetadataJsonLint
|
|
99
97
|
# https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/puppet-users/nkRPvG4q0Oo/GmXa109aJQAJ
|
100
98
|
validate_requirements!(parsed['requirements']) if parsed['requirements']
|
101
99
|
|
102
|
-
# Summary can not be over 144 characters:
|
103
|
-
# From: https://forge.puppetlabs.com/razorsedge/snmp/3.3.1/scores
|
104
|
-
if !parsed['summary'].nil? && parsed['summary'].size > 144
|
105
|
-
error :summary, 'Field \'summary\' exceeds 144 characters in metadata.json.'
|
106
|
-
end
|
107
|
-
|
108
100
|
# Shoulds/recommendations
|
109
101
|
# From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file
|
110
102
|
#
|
@@ -113,10 +105,6 @@ module MetadataJsonLint
|
|
113
105
|
warn(:license, msg)
|
114
106
|
end
|
115
107
|
|
116
|
-
if !parsed['tags'].nil? && !parsed['tags'].is_a?(Array)
|
117
|
-
error :tags, "Tags must be in an array. Currently it's a #{parsed['tags'].class}."
|
118
|
-
end
|
119
|
-
|
120
108
|
if !@errors.empty? || !@warnings.empty?
|
121
109
|
result = @errors.empty? ? "Warnings found in #{metadata}" : "Errors found in #{metadata}"
|
122
110
|
|
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 = '
|
5
|
+
s.version = '2.0.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'
|
@@ -16,10 +16,19 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.homepage = 'http://github.com/voxpupuli/metadata-json-lint'
|
17
17
|
s.license = 'Apache-2.0'
|
18
18
|
|
19
|
+
s.required_ruby_version = '>= 2.0.0'
|
19
20
|
s.add_runtime_dependency 'spdx-licenses', '~> 1.0'
|
20
|
-
s.add_runtime_dependency 'json'
|
21
|
-
s.add_runtime_dependency 'semantic_puppet', '>= 0.1.2', '< 2.0.0'
|
21
|
+
s.add_runtime_dependency 'json-schema', '~> 2.8'
|
22
22
|
s.add_development_dependency 'rake'
|
23
23
|
s.add_development_dependency 'rspec'
|
24
24
|
s.add_development_dependency 'rubocop'
|
25
|
+
s.requirements << 'semantic_puppet >= 0.1.2 < 2.0.0'
|
26
|
+
s.post_install_message = <<-EOS
|
27
|
+
-------------------------------------------------------------------
|
28
|
+
If your puppet is <= 4.x, then the semantic_puppet gem MUST
|
29
|
+
be in your Gemfile!!
|
30
|
+
|
31
|
+
On puppet >= 5.x, semantic_puppet will break functionality!
|
32
|
+
-------------------------------------------------------------------
|
33
|
+
EOS
|
25
34
|
end
|
data/spec/schema_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
describe MetadataJsonLint::Schema do
|
2
|
+
describe '#schema' do
|
3
|
+
it { expect(subject.schema).to be_a(Hash) }
|
4
|
+
end
|
5
|
+
|
6
|
+
describe '#validate' do
|
7
|
+
let(:minimal) { { author: '', dependencies: [], license: 'A', name: 'a-a', source: '', summary: '', version: '1.0.0' } }
|
8
|
+
|
9
|
+
context 'with empty hash' do
|
10
|
+
subject { described_class.new.validate({}) }
|
11
|
+
it { is_expected.to be_a(Array) }
|
12
|
+
it { expect(subject.size).to eq(7) }
|
13
|
+
it { is_expected.to include(field: 'root', message: "The file did not contain a required property of 'author'") }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with minimal entries' do
|
17
|
+
subject { described_class.new.validate(minimal) }
|
18
|
+
it { is_expected.to eq([]) }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with validation error on entry' do
|
22
|
+
subject { described_class.new.validate(minimal.merge(summary: 'A' * 145)) }
|
23
|
+
it { is_expected.to eq([{ field: 'summary', message: "The property 'summary' was not of a maximum string length of 144" }]) }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with validation error on nested entry' do
|
27
|
+
subject { described_class.new.validate(minimal.merge(dependencies: [{ name: 'in###id' }])) }
|
28
|
+
it { expect(subject.size).to eq(1) }
|
29
|
+
it { is_expected.to include(field: 'dependencies', message: a_string_matching(%r{The property 'dependencies/0/name' value "in###id" did not match the regex})) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with semver validation failure' do
|
33
|
+
subject { described_class.new.validate(minimal.merge(version: 'a')) }
|
34
|
+
it { expect(subject.size).to eq(1) }
|
35
|
+
it { is_expected.to include(field: 'version', message: a_string_matching(/The property 'version' must be a valid semantic version/)) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/tests/long_summary/expected
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
(ERROR) summary: The property 'summary' was not of a maximum string length of 144
|
data/tests/noname/expected
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
(ERROR) required_fields: The file did not contain a required property of 'name'
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
(ERROR) tags: The property 'tags' of type string did not match the following type: array
|
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:
|
4
|
+
version: 2.0.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-06-
|
11
|
+
date: 2017-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spdx-licenses
|
@@ -25,39 +25,19 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: json
|
28
|
+
name: json-schema
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
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: semantic_puppet
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.1.2
|
48
|
-
- - "<"
|
31
|
+
- - "~>"
|
49
32
|
- !ruby/object:Gem::Version
|
50
|
-
version: 2.
|
33
|
+
version: '2.8'
|
51
34
|
type: :runtime
|
52
35
|
prerelease: false
|
53
36
|
version_requirements: !ruby/object:Gem::Requirement
|
54
37
|
requirements:
|
55
|
-
- - "
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: 0.1.2
|
58
|
-
- - "<"
|
38
|
+
- - "~>"
|
59
39
|
- !ruby/object:Gem::Version
|
60
|
-
version: 2.
|
40
|
+
version: '2.8'
|
61
41
|
- !ruby/object:Gem::Dependency
|
62
42
|
name: rake
|
63
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,9 +99,11 @@ files:
|
|
119
99
|
- Rakefile
|
120
100
|
- bin/metadata-json-lint
|
121
101
|
- lib/metadata-json-lint/rake_task.rb
|
102
|
+
- lib/metadata-json-lint/schema.rb
|
122
103
|
- lib/metadata-json-lint/version_requirement.rb
|
123
104
|
- lib/metadata_json_lint.rb
|
124
105
|
- metadata-json-lint.gemspec
|
106
|
+
- spec/schema_spec.rb
|
125
107
|
- spec/spec_helper.rb
|
126
108
|
- spec/version_requirement_spec.rb
|
127
109
|
- tests/bad_license/Rakefile
|
@@ -187,7 +169,13 @@ homepage: http://github.com/voxpupuli/metadata-json-lint
|
|
187
169
|
licenses:
|
188
170
|
- Apache-2.0
|
189
171
|
metadata: {}
|
190
|
-
post_install_message:
|
172
|
+
post_install_message: |2
|
173
|
+
-------------------------------------------------------------------
|
174
|
+
If your puppet is <= 4.x, then the semantic_puppet gem MUST
|
175
|
+
be in your Gemfile!!
|
176
|
+
|
177
|
+
On puppet >= 5.x, semantic_puppet will break functionality!
|
178
|
+
-------------------------------------------------------------------
|
191
179
|
rdoc_options: []
|
192
180
|
require_paths:
|
193
181
|
- lib
|
@@ -195,19 +183,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
195
183
|
requirements:
|
196
184
|
- - ">="
|
197
185
|
- !ruby/object:Gem::Version
|
198
|
-
version:
|
186
|
+
version: 2.0.0
|
199
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
188
|
requirements:
|
201
189
|
- - ">="
|
202
190
|
- !ruby/object:Gem::Version
|
203
191
|
version: '0'
|
204
|
-
requirements:
|
192
|
+
requirements:
|
193
|
+
- semantic_puppet >= 0.1.2 < 2.0.0
|
205
194
|
rubyforge_project:
|
206
195
|
rubygems_version: 2.4.5
|
207
196
|
signing_key:
|
208
197
|
specification_version: 4
|
209
198
|
summary: metadata-json-lint /path/to/metadata.json
|
210
199
|
test_files:
|
200
|
+
- spec/schema_spec.rb
|
211
201
|
- spec/spec_helper.rb
|
212
202
|
- spec/version_requirement_spec.rb
|
213
203
|
- tests/bad_license/Rakefile
|