rubocop-md 0.1.0.pre → 0.1.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: 1e95074f390ef2a3e4dbe7fe57399cfd4066d661
4
- data.tar.gz: 2717015145fb478f8dbeb7778e1f1423d34b1195
3
+ metadata.gz: 0e46efefca545c73bc0fabdb88966fdb1894d9bf
4
+ data.tar.gz: 2f843d47ab0553f8595f0ef7233cc9095349c070
5
5
  SHA512:
6
- metadata.gz: 6f7dd5441cc1b408114e524be0bf7eae2a9415331801a8157e4d484a610a0661986e9bfc0b462454982fc2e35b0a2d72975e1b464d2b0b65a49c800f87860d21
7
- data.tar.gz: c61d81e351f7be36dac4fbd6ebbcb010f3d8fdd9f33439ff736b379692a89f9b26c50b38935fc93b3d3fd27a03c5c35363497cac7df29a7e4241d8d3e9c4fa33
6
+ metadata.gz: 7e27a59d16c41ad2f3374d764b7172f3041a62e5c5c5809bdce88e644fe6d7f27c2e847123f398ec272f687bf797a4b130def0dbc4b9d3f5be19f2e343ff142a
7
+ data.tar.gz: 795ed0e01b160c7e5ac3ad18dfd50e39adcc96725e91bd210bec64e9008622f70d07f4536125900a794345a25c4979bbe89905ab5a4d8aa733779e62d4eb18f0
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
3
  /Gemfile.lock
4
+ /Gemfile.local
4
5
  /_yardoc/
5
6
  /coverage/
6
7
  /doc/
data/.rubocop.yml CHANGED
@@ -31,6 +31,9 @@ Style/ClassAndModuleChildren:
31
31
  Exclude:
32
32
  - 'test/**/*.rb'
33
33
 
34
+ Layout/EmptyLinesAroundArguments:
35
+ Enabled: false
36
+
34
37
  Layout/SpaceInsideStringInterpolation:
35
38
  EnforcedStyle: no_space
36
39
 
data/.travis.yml CHANGED
@@ -1,5 +1,17 @@
1
1
  sudo: false
2
2
  language: ruby
3
- rvm:
4
- - 2.4.2
5
3
  before_install: gem install bundler -v 1.15.4
4
+
5
+ matrix:
6
+ fast_finish: true
7
+ include:
8
+ - rvm: ruby-head
9
+ gemfile: gemfiles/rubocopmaster.gemfile
10
+ - rvm: jruby-9.1.0.0
11
+ gemfile: Gemfile
12
+ - rvm: 2.4.2
13
+ gemfile: Gemfile
14
+ - rvm: 2.3.1
15
+ gemfile: Gemfile
16
+ - rvm: 2.2.0
17
+ gemfile: Gemfile
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
5
5
  # Specify your gem's dependencies in rubocop-md.gemspec
6
6
  gemspec
7
7
 
8
- gem "pry-byebug"
8
+ gem "pry-byebug", platform: :mri
9
9
 
10
10
  local_gemfile = "Gemfile.local"
11
11
 
data/README.md CHANGED
@@ -1,7 +1,18 @@
1
- # Rubocop Mardkdown
1
+ [![Gem Version](https://badge.fury.io/rb/rubocop-md.svg)](http://badge.fury.io/rb/rubocop-md)
2
+ [![Travis Status](https://travis-ci.org/palkan/rubocop-md.svg?branch=master)](https://travis-ci.org/palkan/rubocop-md)
2
3
 
3
- Run Rubocop against your Markdown files to make sure that code examples follow style guidelines.
4
+ # Rubocop Markdown
4
5
 
6
+ Run Rubocop against your Markdown files to make sure that code examples follow style guidelines and have valid syntax.
7
+
8
+ ## Features
9
+
10
+ - Analyzes code blocks within Markdown files
11
+ - Shows correct line numbers in output
12
+ - Preserves specified language (i.e., do not try to analyze "\`\`\`sh")
13
+ - **Supports autocorrect 📝**
14
+
15
+ This project was developed to keep [test-prof](https://github.com/palkan/test-prof) guides consistent with Ruby style guide.
5
16
 
6
17
  ## Installation
7
18
 
@@ -21,7 +32,49 @@ Or install it yourself as:
21
32
 
22
33
  ## Usage
23
34
 
24
- TBD
35
+ ### Command line
36
+
37
+ Just require `rubocop-md` in your command:
38
+
39
+ ```sh
40
+ rubocop -r "rubocop-md" ./lib
41
+ ```
42
+
43
+ Autocorrect works too:
44
+
45
+ ```sh
46
+ rubocop -r "rubocop-md" -a ./lib
47
+ ```
48
+
49
+ ### Configuration file
50
+
51
+ First, add `rubocop-md` to your `.rubocop.yml`:
52
+
53
+ ```yml
54
+ require:
55
+ - "rubocop-md"
56
+ ```
57
+
58
+ Additional options:
59
+
60
+ ```yml
61
+ # .rubocop.yml
62
+ Markdown:
63
+ # Whether to run RuboCop against non-valid snippets
64
+ WarnInvalid: true
65
+ ```
66
+
67
+ ## How it works?
68
+
69
+ - Preprocess Markdown source into Ruby source preserving line numbers
70
+ - Let RuboCop do its job
71
+ - Restore Markdown from preprocessed Ruby if it has been autocorrected
72
+
73
+ ## Limitations
74
+
75
+ - RuboCop cache is disabled for Markdown files (because cache knows nothing about preprocessing)
76
+ - Uses naive Regexp-based approach to extract code blocks from Markdown, support only backticks-style code blocks
77
+ - No language detection included; if you do not specify language for your code blocks, you'd better turn `WarnInvalid` off (see above)
25
78
 
26
79
  ## Development
27
80
 
data/config/default.yml CHANGED
@@ -1,3 +1,6 @@
1
+ Markdown:
2
+ WarnInvalid: true
3
+
1
4
  Layout/CommentIndentation:
2
5
  Exclude:
3
6
  - '**/*.md'
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rubocop", github: "bbatsov/rubocop"
4
+
5
+ gemspec path: ".."
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Markdown
5
5
  # Transform source Markdown file into valid Ruby file
6
6
  # by commenting out all non-code lines
7
- module Preprocess
7
+ class Preprocess
8
8
  # This is a regexp to extract code blocks from .md files.
9
9
  #
10
10
  # Only recognizes backticks-style code blocks.
@@ -45,31 +45,6 @@ module RuboCop
45
45
  end
46
46
 
47
47
  class << self
48
- # rubocop:disable Metrics/MethodLength
49
- def call(src)
50
- parts = src.split(MD_REGEXP)
51
-
52
- walker = Walker.new
53
-
54
- parts.each do |part|
55
- if walker.code_body?
56
- next walker.next! if maybe_ruby?(@syntax) && valid_syntax?(part)
57
- end
58
-
59
- if walker.code_attr?
60
- @syntax = part.gsub(/(^\s+|\s+$)/, "")
61
- next walker.next!
62
- end
63
-
64
- comment_lines! part
65
-
66
- walker.next!
67
- end
68
-
69
- parts.join
70
- end
71
- # rubocop:enable Metrics/MethodLength
72
-
73
48
  # Revert preprocess changes.
74
49
  #
75
50
  # When autocorrect is applied, RuboCop re-writes the file
@@ -81,25 +56,62 @@ module RuboCop
81
56
  contents.gsub!(/^##{MARKER}/m, "")
82
57
  File.write(file, contents)
83
58
  end
59
+ end
84
60
 
85
- private
61
+ attr_reader :config
86
62
 
87
- # Check codeblock attribute to prevent from parsing
88
- # non-Ruby snippets and avoid false positives
89
- def maybe_ruby?(syntax)
90
- syntax.empty? || RUBY_TYPES.include?(syntax)
91
- end
63
+ def initialize(file)
64
+ @config = Markdown.config_store.for(file)
65
+ end
92
66
 
93
- # Try to parse with Ripper.
94
- # Invalid Ruby (non-Ruby) code returns `nil`.
95
- def valid_syntax?(src)
96
- !Ripper.sexp(src).nil?
97
- end
67
+ # rubocop:disable Metrics/MethodLength
68
+ def call(src)
69
+ parts = src.split(MD_REGEXP)
70
+
71
+ walker = Walker.new
98
72
 
99
- def comment_lines!(src)
100
- return if src =~ /\A\n\z/
101
- src.gsub!(/^(.)/m, "##{MARKER}\\1")
73
+ parts.each do |part|
74
+ if walker.code_body?
75
+ next walker.next! if maybe_ruby?(@syntax) && valid_syntax?(part)
76
+ end
77
+
78
+ if walker.code_attr?
79
+ @syntax = part.gsub(/(^\s+|\s+$)/, "")
80
+ next walker.next!
81
+ end
82
+
83
+ comment_lines! part
84
+
85
+ walker.next!
102
86
  end
87
+
88
+ parts.join
89
+ end
90
+ # rubocop:enable Metrics/MethodLength
91
+
92
+ private
93
+
94
+ # Check codeblock attribute to prevent from parsing
95
+ # non-Ruby snippets and avoid false positives
96
+ def maybe_ruby?(syntax)
97
+ syntax.empty? || RUBY_TYPES.include?(syntax)
98
+ end
99
+
100
+ # Try to parse with Ripper.
101
+ # Invalid Ruby (non-Ruby) code returns `nil`.
102
+ def valid_syntax?(src)
103
+ return true if warn_invalid?
104
+ !Ripper.sexp(src).nil?
105
+ end
106
+
107
+ # Where to show warning when snippet is not a valid Ruby
108
+ def warn_invalid?
109
+ config["Markdown"] && config["Markdown"].fetch("WarnInvalid", false)
110
+ end
111
+
112
+ def comment_lines!(src)
113
+ return if src =~ /\A\n\z/
114
+ src.gsub!(/^(.)/m, "##{MARKER}\\1")
103
115
  end
104
116
  end
105
117
  end
@@ -2,19 +2,22 @@ module RuboCop
2
2
  module Markdown # :nodoc:
3
3
  MARKDOWN_EXTENSIONS = %w[.md .markdown].freeze
4
4
 
5
- # Merge markdown config into default configuration
6
- # See https://github.com/backus/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
7
- def self.inject!
8
- path = CONFIG_DEFAULT.to_s
9
- hash = ConfigLoader.send(:load_yaml_configuration, path)
10
- config = Config.new(hash, path)
11
- puts "configuration from #{path}" if ConfigLoader.debug?
12
- config = ConfigLoader.merge_with_default(config, path)
13
- ConfigLoader.instance_variable_set(:@default_configuration, config)
14
- end
5
+ class << self
6
+ attr_accessor :config_store
7
+ # Merge markdown config into default configuration
8
+ # See https://github.com/backus/rubocop-rspec/blob/master/lib/rubocop/rspec/inject.rb
9
+ def inject!
10
+ path = CONFIG_DEFAULT.to_s
11
+ hash = ConfigLoader.send(:load_yaml_configuration, path)
12
+ config = Config.new(hash, path)
13
+ puts "configuration from #{path}" if ConfigLoader.debug?
14
+ config = ConfigLoader.merge_with_default(config, path)
15
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
16
+ end
15
17
 
16
- def self.markdown_file?(file)
17
- MARKDOWN_EXTENSIONS.include?(File.extname(file))
18
+ def markdown_file?(file)
19
+ MARKDOWN_EXTENSIONS.include?(File.extname(file))
20
+ end
18
21
  end
19
22
  end
20
23
  end
@@ -22,6 +25,12 @@ end
22
25
  RuboCop::Markdown.inject!
23
26
 
24
27
  RuboCop::Runner.prepend(Module.new do
28
+ # Set config store for Markdown
29
+ def initialize(*)
30
+ super
31
+ RuboCop::Markdown.config_store = @config_store
32
+ end
33
+
25
34
  # Do not cache markdown files, 'cause cache doesn't know about processing.
26
35
  # NOTE: we should involve preprocessing in RuboCop::CachedData#deserialize_offenses
27
36
  def file_offense_cache(file)
@@ -51,7 +60,7 @@ end)
51
60
  RuboCop::ProcessedSource.prepend(Module.new do
52
61
  def parse(src, *args)
53
62
  # only process Markdown files
54
- src = RuboCop::Markdown::Preprocess.call(src) if
63
+ src = RuboCop::Markdown::Preprocess.new(path).call(src) if
55
64
  path.nil? || RuboCop::Markdown.markdown_file?(path)
56
65
  super(src, *args)
57
66
  end
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module Markdown
3
- VERSION = "0.1.0.pre".freeze
3
+ VERSION = "0.1.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-md
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-11 00:00:00.000000000 Z
11
+ date: 2017-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -84,6 +84,7 @@ files:
84
84
  - Rakefile
85
85
  - bin/setup
86
86
  - config/default.yml
87
+ - gemfiles/rubocopmaster.gemfile
87
88
  - lib/rubocop-md.rb
88
89
  - lib/rubocop/markdown.rb
89
90
  - lib/rubocop/markdown/preprocess.rb
@@ -105,9 +106,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
106
  version: '0'
106
107
  required_rubygems_version: !ruby/object:Gem::Requirement
107
108
  requirements:
108
- - - ">"
109
+ - - ">="
109
110
  - !ruby/object:Gem::Version
110
- version: 1.3.1
111
+ version: '0'
111
112
  requirements: []
112
113
  rubyforge_project:
113
114
  rubygems_version: 2.6.13