rubocop-schema-gen 0.1.0 → 0.1.1

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
  SHA256:
3
- metadata.gz: 9896f77d8a3c4c39bd31f21878bffdb2d8979dee897b5fe38b3ef090bd11043d
4
- data.tar.gz: bfa9fe9b715b977f1dc973f48e80eafe59a448545bbef559247055bd98cfc5bd
3
+ metadata.gz: d13b27e5b62cc1a35d64acf5a81f2c6443aae1d0e9597207634bb7defa2a6b34
4
+ data.tar.gz: 78ac1aadadf7a5f23700615d717262fa0601e54ac772f8a5f2a790fe3dcd37bf
5
5
  SHA512:
6
- metadata.gz: 074f101c7a87e0ce7e1de730a82b6bc83682bf0068d60519c1b042ca6bbcc7d3ca574e5ed47f3fec0f2cb63ce3639b98ab2915b90644b1e349aa4c589c3d6cab
7
- data.tar.gz: aeafc3e4661bed171c7d182ffbf6c752ded81d002623984bd0e146072c70fca9609d79410a8f5c23fe031c49caf15755d8ad5a3fe120955e7f23b9ddbd813398
6
+ metadata.gz: 4293f202f9132881733e84b280e1b4ba93df2ab1b9567efb7ae48703835dc4d3e5aebb8a797f05453766e7929a3efe5c2c150b8d575611c6c959deeefc290a5c
7
+ data.tar.gz: b61fcf727e203d2ca162eba0bd081c9bf008d8606774e8c16cd6727bd35c9e3f144606a375efdce1c115ae35001a04411cf70aebe09ecddd4cbf046b9ced3b6d
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
- --format documentation
1
+ --format progress
2
2
  --color
3
3
  --require spec_helper
data/.rubocop.yml CHANGED
@@ -16,7 +16,7 @@ require:
16
16
  AllCops:
17
17
  SuggestExtensions: false
18
18
  NewCops: enable
19
- TargetRubyVersion: 3.0
19
+ TargetRubyVersion: 2.4
20
20
 
21
21
  Layout/HashAlignment:
22
22
  EnforcedColonStyle: table
@@ -36,3 +36,39 @@ Style/StringConcatenation:
36
36
 
37
37
  Style/StderrPuts:
38
38
  Enabled: false
39
+
40
+ Lint/AmbiguousOperator:
41
+ Enabled: false
42
+
43
+ Lint/AmbiguousRegexpLiteral:
44
+ Enabled: false
45
+
46
+ Lint/AmbiguousBlockAssociation:
47
+ Enabled: false
48
+
49
+ Style/StabbyLambdaParentheses:
50
+ EnforcedStyle: require_no_parentheses
51
+
52
+ Layout/SpaceInLambdaLiteral:
53
+ EnforcedStyle: require_space
54
+
55
+ Metrics/AbcSize:
56
+ Max: 18
57
+
58
+ Metrics/ParameterLists:
59
+ Exclude:
60
+ - lib/rubocop/schema/cli.rb
61
+
62
+ Metrics/BlockLength:
63
+ IgnoredMethods:
64
+ - describe
65
+
66
+ Style/FormatStringToken:
67
+ Enabled: false
68
+
69
+ RSpec/NamedSubject:
70
+ Enabled: false
71
+
72
+ RSpec/MultipleExpectations:
73
+ Exclude:
74
+ - spec/rubocop/schema/cli_spec.rb
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 2.4.10
data/.travis.yml CHANGED
@@ -2,5 +2,9 @@
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
+ - 2.4.10
6
+ - 2.5.8
7
+ - 2.6.6
8
+ - 2.7.3
5
9
  - 3.0.0
6
- before_install: gem install bundler -v 2.1.4
10
+ before_install: gem install bundler -v 1.17.3
data/Gemfile CHANGED
@@ -5,6 +5,11 @@ gemspec
5
5
 
6
6
  gem 'rake', '~> 12.0'
7
7
  gem 'rspec', '~> 3.0'
8
- gem 'rubocop', '~> 1.13.0', require: false
8
+ gem 'rubocop', require: false
9
+ gem 'rubocop-minitest', require: false
10
+ gem 'rubocop-performance', require: false
11
+ gem 'rubocop-rails', require: false
9
12
  gem 'rubocop-rake', require: false
10
13
  gem 'rubocop-rspec', require: false
14
+ gem 'vcr'
15
+ gem 'webmock'
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2021 Neil E. Pearson
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md CHANGED
@@ -1,44 +1,39 @@
1
- # Rubocop::Schema
1
+ # RuboCop Config Schema Generator
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rubocop/schema`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ This gem generates a JSON schema for your RuboCop configuration files, which you can use in your IDE (e.g. RubyMine) for autocompletion and validation.
6
4
 
7
5
  ## Installation
8
6
 
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'rubocop-schema'
13
- ```
14
-
15
- And then execute:
7
+ $ gem install rubocop-schema-gem
16
8
 
17
- $ bundle install
9
+ ## Usage
18
10
 
19
- Or install it yourself as:
11
+ Change to a directory containing a `Gemfile.lock`, which the generator will use to target your version of `rubocop`, and any extensions you may be using (e.g. `rubocop-rails`).
20
12
 
21
- $ gem install rubocop-schema
13
+ ```
14
+ $ cd ./my_project
15
+ $ rubocop-schema-gen
16
+ Generating rubocop-1.13.1-config-schema.json … complete in 5.2s
17
+ ```
22
18
 
23
- ## Usage
19
+ The name of the generated file is based on your gem version(s). You can override it with an argument.
24
20
 
25
- TODO: Write usage instructions here
21
+ ```
22
+ $ rubocop-schema-gen rubocop-schema.json
23
+ Generating rubocop-schema.json … complete in 0.7s
24
+ ```
26
25
 
27
- ## Development
26
+ Pass `-` to write to standard output.
28
27
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
+ The generator caches pages from https://raw.githubusercontent.com/rubocop in `~/.rubocop-schema-cache`.
30
29
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
+ Please refer to your IDE's documentation regarding applying the schema to your `.rubocop.yml` file.
32
31
 
33
32
  ## Contributing
34
33
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rubocop-schema. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/rubocop-schema/blob/master/CODE_OF_CONDUCT.md).
34
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hx/rubocop-schema. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/hx/rubocop-schema/blob/master/CODE_OF_CONDUCT.md).
36
35
 
37
36
 
38
37
  ## License
39
38
 
40
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
-
42
- ## Code of Conduct
43
-
44
- Everyone interacting in the Rubocop::Schema project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rubocop-schema/blob/master/CODE_OF_CONDUCT.md).
39
+ The gem is available as open source under the terms of the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
@@ -1,9 +1,7 @@
1
1
  type: object
2
2
  additionalProperties: true
3
3
 
4
- propertyNames:
5
- type: string
6
- pattern: '^[A-Z][A-Za-z]*$'
4
+ propertyNames: { $ref: '#/definitions/attributeName' }
7
5
 
8
6
  properties:
9
7
  Enabled: { type: boolean }
@@ -41,6 +41,10 @@ definitions:
41
41
  - type: array
42
42
  items: { type: string }
43
43
 
44
+ attributeName:
45
+ type: string
46
+ pattern: '^[A-Z][A-Za-z]*$'
47
+
44
48
  properties:
45
49
  inherit_from: { type: string }
46
50
 
data/bin/console CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'bundler/setup'
4
4
  require 'rubocop/schema'
5
+ require 'rubocop/schema/cli'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bundler/setup'
3
+ Dir.chdir File.expand_path('..', __dir__) do
4
+ require 'bundler/setup'
5
+ end
4
6
  require 'rubocop/schema'
5
7
  require 'rubocop/schema/cli'
6
8
  require 'json'
7
9
 
8
- RuboCop::Schema::CLI.new(Dir.pwd, ENV, ARGV).run
10
+ RuboCop::Schema::CLI.new.run
@@ -2,9 +2,6 @@ require 'pathname'
2
2
  require 'rubocop'
3
3
 
4
4
  require 'rubocop/schema/version'
5
- require 'rubocop/schema/cache'
6
- require 'rubocop/schema/scraper'
7
- require 'rubocop/schema/lockfile_inspector'
8
5
 
9
6
  module RuboCop
10
7
  module Schema
@@ -0,0 +1,53 @@
1
+ require 'rubocop/schema/ascii_doc/stringifier'
2
+ require 'rubocop/schema/helpers'
3
+
4
+ module RuboCop
5
+ module Schema
6
+ module AsciiDoc
7
+ class Base
8
+ include Helpers
9
+
10
+ # @param [Asciidoctor::AbstractBlock] ascii_block
11
+ def initialize(ascii_block)
12
+ @root = ascii_block
13
+ scan
14
+ end
15
+
16
+ protected
17
+
18
+ # @return [Asciidoctor::Document]
19
+ attr_reader :root
20
+
21
+ def scan
22
+ raise NotImplementedError
23
+ end
24
+
25
+ def link_text(str)
26
+ # The Asciidoctor API doesn't provide access to the raw title, or parts of it.
27
+ # If performance becomes an issue, this could become a regexp or similarly crude solution.
28
+ Nokogiri::HTML(str).at_css('a')&.text
29
+ end
30
+
31
+ # @param [Asciidoctor::Table] table
32
+ # @return [Array<Hash>] A hash for each row, with table headings as keys
33
+ def table_to_hash(table)
34
+ headings = table.rows.head.first.map(&:text)
35
+ table.rows.body.map do |row|
36
+ headings.each_with_index.map do |heading, i|
37
+ [heading, strip_html(row[i].text)]
38
+ end.to_h
39
+ end
40
+ end
41
+
42
+ def stringify_section(section)
43
+ @stringifier ||= Stringifier.new
44
+ @stringifier.stringify section
45
+ end
46
+
47
+ def presence(str)
48
+ str unless str.strip == ''
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,93 @@
1
+ require 'rubocop/schema/ascii_doc/base'
2
+ require 'rubocop/schema/value_objects'
3
+
4
+ module RuboCop
5
+ module Schema
6
+ module AsciiDoc
7
+ class Cop < Base
8
+ # @return [String]
9
+ attr_reader :name
10
+
11
+ # @return [String]
12
+ attr_reader :description
13
+
14
+ # @return [TrueClass, FalseClass]
15
+ attr_reader :enabled_by_default
16
+
17
+ # @return [TrueClass, FalseClass]
18
+ attr_reader :supports_autocorrect
19
+
20
+ # @return [Array<Attribute>]
21
+ attr_reader :attributes
22
+
23
+ ATTRS = public_instance_methods(false).freeze
24
+
25
+ def to_h
26
+ ATTRS.map { |k| [k, __send__(k)] }.to_h
27
+ end
28
+
29
+ protected
30
+
31
+ def scan
32
+ @name = root.title
33
+ read_stats_table
34
+ read_description
35
+ read_attributes
36
+ end
37
+
38
+ private
39
+
40
+ def read_stats_table
41
+ return unless stats_table
42
+
43
+ @enabled_by_default = stats_table['Enabled by default'] == 'Enabled'
44
+ @supports_autocorrect = stats_table['Supports autocorrection'] == 'Yes'
45
+ end
46
+
47
+ def read_description
48
+ blocks = root.blocks[find_description_range]
49
+ @description = blocks.map(&method(:stringify_section)).join("\n\n") if blocks.any?
50
+ end
51
+
52
+ def read_attributes
53
+ return unless attr_table_block
54
+
55
+ @attributes = table_to_hash(attr_table_block).map do |row|
56
+ Attribute.new(
57
+ name: row['Name'],
58
+ default: presence(row['Default value']),
59
+ type: presence(row['Configurable values'])
60
+ )
61
+ end
62
+ end
63
+
64
+ def find_description_range
65
+ top = stats_table_block ? root.blocks.index(stats_table_block) + 1 : 0
66
+ bottom = root.blocks.index(root.sections.first) || 0
67
+ top..(bottom - 1)
68
+ end
69
+
70
+ # @return [Asciidoctor::Block, nil]
71
+ def stats_table_block
72
+ @stats_table_block ||= root
73
+ .query(context: :table) { |t| t.rows.head.first.first.text == 'Enabled by default' }
74
+ .first
75
+ end
76
+
77
+ # @return [Asciidoctor::Block, nil]
78
+ def attr_table_block
79
+ @attr_table_block ||= root
80
+ .query(context: :section) { |s| s.title == 'Configurable attributes' }
81
+ &.first
82
+ &.query(context: :table)
83
+ &.first
84
+ end
85
+
86
+ # @return [Array<Hash>, nil]
87
+ def stats_table
88
+ @stats_table ||= stats_table_block && table_to_hash(stats_table_block).first
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubocop/schema/ascii_doc/base'
2
+ require 'rubocop/schema/ascii_doc/cop'
3
+
4
+ module RuboCop
5
+ module Schema
6
+ module AsciiDoc
7
+ class Department < Base
8
+ # @return [Array<Cop>]
9
+ attr_reader :cops
10
+
11
+ protected
12
+
13
+ def scan
14
+ @cops = root
15
+ .query(context: :section) { |s| s.title.start_with? "#{root.title}/" }
16
+ .map &Cop.method(:new)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubocop/schema/ascii_doc/base'
2
+
3
+ module RuboCop
4
+ module Schema
5
+ module AsciiDoc
6
+ class Index < Base
7
+ # @return [Array<string>]
8
+ attr_reader :department_names
9
+
10
+ protected
11
+
12
+ def scan
13
+ @department_names = root
14
+ .query(context: :section) { |s| s.title.start_with? 'Department ' }
15
+ .map { |section| link_text section.title }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ require 'rubocop/schema/helpers'
2
+
3
+ module RuboCop
4
+ module Schema
5
+ module AsciiDoc
6
+ class Stringifier
7
+ include Helpers
8
+
9
+ # @param [Asciidoctor::Section] section
10
+ def stringify(section)
11
+ method = :"stringify_#{section.context}"
12
+ raise "Don't know what to do with #{section.context}" unless private_methods(false).include? method
13
+
14
+ __send__(method, section)
15
+ end
16
+
17
+ private
18
+
19
+ # @param [Asciidoctor::Section] section
20
+ def stringify_paragraph(section)
21
+ section.lines.join ' '
22
+ end
23
+
24
+ alias stringify_admonition stringify_paragraph
25
+ alias stringify_listing stringify_paragraph
26
+
27
+ # @param [Asciidoctor::Section] section
28
+ def stringify_literal(section)
29
+ section.lines.map { |l| " #{l}" }.join "\n"
30
+ end
31
+
32
+ # @param [Asciidoctor::Section] section
33
+ def stringify_ulist(section)
34
+ section.blocks.map { |b| " - #{strip_html b.text}" }.join "\n\n" # TODO: single newline
35
+ end
36
+
37
+ # @param [Asciidoctor::Section] section
38
+ def stringify_olist(section)
39
+ section.blocks.map.with_index { |b, i| " #{i + 1}. #{strip_html b.text}" }.join "\n\n" # TODO: single newline
40
+ end
41
+
42
+ # @param [Asciidoctor::Section] section
43
+ def stringify_dlist(section)
44
+ strip_html section.convert # Too hard, just go HTML for now
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end