metadata-json-lint 1.2.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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