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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e405de9a698335b307d33abbf151c898a9cde8ff
4
- data.tar.gz: 6d63faf1798bbe981406d5792a06845d5ecee2f7
3
+ metadata.gz: 656d4c9a85eceaa230fe84711819956a3d746a71
4
+ data.tar.gz: 69c06229897d87ec0a65115b28b01eec85dfa5b2
5
5
  SHA512:
6
- metadata.gz: 7871b687d36c40ee1519866af02a3fbf603e20b3fe163599ef9b153d235f1db4a58ffbfd06cee090048ec943d2c6afd1da12af72de24eda00aac90323db47b0a
7
- data.tar.gz: 59c178ba9192e930789cb239304e81223eb781501f75a2cc2ae49dde805d933ce86e76cd94d7640bff5519c3d983dc95f8e2e090dfc6556d7c91ed2bb70edf76
6
+ metadata.gz: 36c139d8de7c19a488b0e73ed06f2461e6a177c65c62abc548b58ce36a715e3b574d08edb62c765c357fccb35a8754972eca0a411ccff303e5b58aef38599de7
7
+ data.tar.gz: 79a89a232bdae551740952c7827ebac93568006cce890f63eb913b5e3bf4fb111729a06bbfff4042659581ae0d11d390d30a399433c8b1d89d2e6a44fb6e8c3c
@@ -17,6 +17,10 @@ Metrics/LineLength:
17
17
  Metrics/MethodLength:
18
18
  Enabled: false
19
19
 
20
+ Metrics/BlockLength:
21
+ Exclude:
22
+ - spec/**/*_spec.rb
23
+
20
24
  Metrics/PerceivedComplexity:
21
25
  Enabled: false
22
26
 
@@ -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
@@ -1,3 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ group :test do
4
+ gem 'semantic_puppet'
5
+ end
6
+
3
7
  gemspec
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.3.1.
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
- Install the `metadata-json-lint` gem:
21
+ via Gemfile:
22
+ ``` ruby
23
+ gem 'metadata-json-lint'
24
+ ```
12
25
 
13
- ```shell
14
- gem install metadata-json-lint
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
@@ -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
- # Fields required to be in metadata.json
79
- # From: https://docs.puppetlabs.com/puppet/latest/reference/modules_publishing.html#write-a-metadatajson-file
80
- required_fields = %w[name version author license summary source dependencies]
81
- required_fields.each do |field|
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
 
@@ -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 = '1.2.2'
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
@@ -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
@@ -1 +1 @@
1
- Field 'summary' exceeds 144 characters in metadata.json
1
+ (ERROR) summary: The property 'summary' was not of a maximum string length of 144
@@ -1 +1 @@
1
- Required field 'name' not found in metadata.json.
1
+ (ERROR) required_fields: The file did not contain a required property of 'name'
@@ -1 +1 @@
1
- Tags must be in an array. Currently it's a String.
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: 1.2.2
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-02 00:00:00.000000000 Z
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.0.0
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.0.0
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: '0'
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