forspell 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9ec99d8b67f987cb0cb0305b2af98796b971ea1a6fd61fe946ffe8685e5cacaf
4
+ data.tar.gz: 85cce6671e87533b82551377270fc4bf665b854e764a6c4358595d4cfd7622b7
5
+ SHA512:
6
+ metadata.gz: 25c10c8d9218fd566ae1847f3d66aac56f183099459cd467239bb63f82fecfabce77e5da39b0edaf8c647b97a5db65f33e2021a9580d229fe9d3d42a4fffbfa7
7
+ data.tar.gz: e9034da3163e853dfcb3dad1a90be1ae3f6fcd8990b8d1a0e6aecddaf692c9f748ba3bca993de3333695181a1b8b730688bfefa1830ff73582884155c519f588
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Forspell
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/forspell.svg)](http://badge.fury.io/rb/forspell)
4
+ [![Build Status](https://travis-ci.org/kkuprikov/forspell.svg?branch=master)](https://travis-ci.org/kkuprikov/forspell)
5
+
6
+ **Forspell** is spellchecker for code and documentation. It uses well-known [hunspell](https://en.wikipedia.org/wiki/Hunspell) tool and dictionary, provides customizable output, and could be easily integrated into CI pipeline.
7
+
8
+ Example of output:
9
+
10
+ ![](https://user-images.githubusercontent.com/713419/55152630-d775a600-5161-11e9-9c56-d9fb45d8a3a4.png)
11
+
12
+ ## Features
13
+
14
+ * Able to check Markdown files and comments inside Ruby, C and C++ source code;
15
+ * Correctly skips over code examples and identifiers inside comments and Markdown most of the time;
16
+ * Distributed with latest en-US hunspell dictionaries, but can be set to use any other dictionary;
17
+ * Includes by default custom Ruby ecosystem-related dictionary (so it will not report as misspelled words like "Gemfile", "args", "middleware" and alike);
18
+ * It is easy to create custom dictionary for your project, so your internal terms would not be reported as misspellings;
19
+ * Option to auto-generate initial custom dictionary;
20
+ * Several output formats, including pretty colorized human-readable, YAML and JSON.
21
+
22
+ ## Installation
23
+
24
+ ```
25
+ gem install forspell
26
+ ```
27
+
28
+ `forspell` requires `libhunspell` >= 1.2.0 to be installed, see [hunspell site](https://github.com/hunspell/hunspell) for installation instructions (it is probably as easy as `<yourpackagemanager> install hunspell` on most of Linuxes and MacOS).
29
+
30
+ ## Usage
31
+
32
+ ```
33
+ $ forspell --help
34
+ Usage: forspell [list of files and folders] [options]
35
+
36
+ Options:
37
+ -e, --exclude pathes List of pathes to exclude
38
+ -d, --dictionary path Path to main hunspell dictionary to use (by default, forspell's en_US)
39
+ -c, --custom pathes Pathes to custom dictionaries
40
+ -f, --format format_name Output formats: readable (default), json, yaml
41
+ --gen-dictionary Generate custom dictionary
42
+ -l, --logfile path Log to specified path
43
+ -v, --verbose Verbose mode
44
+ --help
45
+ ```
46
+
47
+ forspell automatically loads command-line arguments from `.forspell` file in current folder, if it is present.
48
+
49
+ ### Dictionaries
50
+
51
+ As already said, forspell uses hunspell dictionaries to check spelling. By default, it is `en_US` modern dictionary, distributed with forspell itself, but you can specify any other with `-d` option. If you have `/some/custom/path/fr_FR.aff` and `/some/custom/path/fr_FR.dic`, than you can use it instead of `en_US` with `-d /some/custom/path/fr_FR`.
52
+
53
+ In addition to the main dictionary, forspell also includes (and always uses) small auxiliary dictionary with words specific for Ruby ecosystem, you can review it in [forspell repo](https://github.com/kkuprikov/forspell/blob/master/lib/forspell/ruby.dict).
54
+
55
+ You can also add your project's **custom dictionary** with internal terms, for them not to obstruct spellchecker's output. Custom dictionary (or several) can be passed with `-c` option. Also, `forspell.dict` would be automatically read, if present in current directory. Format of custom dictionary:
56
+
57
+ * Each word on its own line.
58
+ * Line contains either just `word` (means only this word in this form).
59
+ * ...or `word: example` -- in this case, "example" should be existing word from the main dictionary, and it means your custom term can have the same forms as example word. For example, "subclass: class" will mean that "subclass", "subclasses" and "subclass'" should be considered correct.
60
+ * `#` marks comments.
61
+
62
+ For larger projects, it is handy to generate custom dictionary with `forspell your,project,pathes --gen-dictionary`. This will create `forspell.dict` with all misspelling found in your project, you can proceed by deleting genuine errors and leave what should be considered correct internal terms.
63
+
64
+ ## Integration with CI
65
+
66
+ Forspell return codes:
67
+
68
+ * 0 - when no errors found
69
+ * 1 - when there are any errors
70
+ * 2 - when it could not process with provided options, i.e. no dictionary found, no directories for checking supplied.
71
+
72
+ To integrate forspell with, say, TravisCI, you would add to `.travis.yml`:
73
+
74
+ * `sudo apt-get install hunspell` into `before_install` section
75
+ * Just `forspell` into `script` section (given you have proper `.forspell` file with all options what to check and how to output)
76
+
77
+ ## Authors
78
+
79
+ * [Kirill Kuprikov](https://github.com/kkuprikov)
80
+ * [Victor Shepelev](https://github.com/zverok)
81
+
82
+ ## License
83
+
84
+ MIT
85
+
86
+ ## Contributing
87
+
88
+ Feel free to create an issue or open a pull request!
@@ -0,0 +1,72 @@
1
+ #!/bin/sh
2
+
3
+ # Clone multiple repositories.
4
+
5
+ echo "=== CLONENATOR ==="
6
+
7
+ array=( "https://github.com/rspec/rspec-core.git"
8
+ "https://github.com/halostatue/diff-lcs/"
9
+ "https://github.com/rspec/rspec-expectations.git"
10
+ "https://github.com/rspec/rspec-mocks.git"
11
+ "https://github.com/rspec/rspec.git"
12
+ "https://github.com/rspec/rspec-support.git"
13
+ "https://github.com/erikhuda/thor.git"
14
+ "https://github.com/tzinfo/tzinfo.git"
15
+ "https://github.com/rtomayko/tilt.git"
16
+ "https://github.com/ruby-concurrency/thread_safe.git"
17
+ "https://github.com/rack-test/rack-test.git"
18
+ "https://github.com/seattlerb/minitest.git"
19
+ "https://github.com/sparklemotion/nokogiri.git"
20
+ "https://github.com/mikel/mail.git"
21
+ "https://github.com/ffi/ffi.git"
22
+ "https://github.com/lostisland/faraday.git"
23
+ "https://github.com/lautis/uglifier.git"
24
+ "https://github.com/rest-client/rest-client.git"
25
+ "https://github.com/pry/pry.git"
26
+ "https://github.com/eventmachine/eventmachine.git"
27
+ "https://github.com/redis/redis-rb.git"
28
+ "https://github.com/sinatra/sinatra.git"
29
+ "https://github.com/rails/jbuilder.git"
30
+ "https://github.com/ruby/rdoc.git"
31
+ "https://github.com/sparklemotion/http-cookie.git"
32
+ "https://github.com/mileszs/wicked_pdf.git"
33
+ "https://github.com/kjvarga/sitemap_generator.git"
34
+ "https://github.com/oivoodoo/devise_masquerade.git"
35
+ "https://github.com/norman/friendly_id.git"
36
+ "https://github.com/alexreisner/geocoder.git"
37
+ "https://github.com/RubyMoney/money-rails.git"
38
+ "https://github.com/ryanb/letter_opener.git"
39
+ "https://github.com/varvet/pundit.git"
40
+ "https://github.com/plataformatec/devise.git"
41
+ "https://github.com/thoughtbot/factory_bot.git"
42
+ "https://github.com/teamcapybara/capybara.git"
43
+ "https://github.com/paper-trail-gem/paper_trail.git"
44
+ "https://github.com/aasm/aasm.git"
45
+ "https://github.com/rubysherpas/paranoia.git"
46
+ ""
47
+ ""
48
+ ""
49
+ ""
50
+ ""
51
+ ""
52
+ ""
53
+ ""
54
+ ""
55
+ ""
56
+ ""
57
+ ""
58
+ ""
59
+ ""
60
+ ""
61
+ ""
62
+ )
63
+
64
+ cd ~/gem_src
65
+
66
+ for element in ${array[@]}
67
+ do
68
+ echo "clonning $element"
69
+ git clone $element
70
+ done
71
+
72
+ echo "=== DONE ==="
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ require 'yaml'
3
+ require 'pry'
4
+ require 'csv'
5
+
6
+ class DictionaryCreator
7
+ attr_reader :result
8
+
9
+ def initialize(path: '../test/popular_gems/json/')
10
+ @path = path
11
+ @data = {}
12
+ @result = {}
13
+ end
14
+
15
+ def process
16
+ (Dir.entries(@path) - ['.', '..']).each do |filename|
17
+ # binding.pry
18
+ @data[filename] = YAML.load_file("#{@path}#{filename}")
19
+ end
20
+
21
+ @data.each_pair do |log_filename, data|
22
+ next if data == false
23
+
24
+ gem_name = log_filename.split('.').first
25
+ data.each do |data_entry|
26
+ data_entry[:errors].each do |error|
27
+ if @result[error]
28
+ @result[error] = @result[error].merge(count: @result.dig(error, :count) + 1, gems: (@result.dig(error, :gems) + [gem_name]).uniq)
29
+ else
30
+ @result[error] = { count: 1, gems: [gem_name] }
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ self
37
+ end
38
+ end
39
+
40
+ # DictionaryCreator.new.process.result
41
+
42
+ CSV.open('../ruby_dict.csv', 'wb') do |csv|
43
+ csv << ['word', 'count', 'gems', 'should_include?']
44
+ DictionaryCreator.new.process.result.each_pair do |word, data|
45
+ csv << [word, data[:count], data[:gems].join(', '), nil]
46
+ end
47
+ end
data/exe/forspell ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/forspell/cli'
3
+
4
+ Forspell::CLI.new(ARGV).call
data/exe/generate_logs ADDED
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+ cd ~/forspell
3
+ rm ./test/popular_gems/json/*.log
4
+
5
+ for var in $(ls ../gem_src/)
6
+ do
7
+ ./bin/forspell ../gem_src/$var test/popular_gems/json/$var.log
8
+ done
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'slop'
4
+ require 'backports/2.5.0/hash/slice'
5
+ require_relative 'runner'
6
+ require_relative 'speller'
7
+ require_relative 'reporter'
8
+ require_relative 'file_list'
9
+
10
+ module Forspell
11
+ class CLI
12
+ ERROR_CODE = 2
13
+ CONFIG_PATH = File.join(Dir.pwd, '.forspell')
14
+ DEFAULT_CUSTOM_DICT = File.join(Dir.pwd, 'forspell.dict')
15
+
16
+ FORMATS = %w[readable yaml json].freeze
17
+ FORMAT_ERR = "must be one of the following: #{FORMATS.join(', ')}"
18
+ DEFINITIONS = proc do |o|
19
+ o.array '-e', '--exclude-paths', 'List of paths to exclude'
20
+ o.string '-d', '--dictionary-path', 'Path to main hunspell dictionary to use (by default, forspell\'s en_US)', default: 'en_US'
21
+ o.array '-c', '--custom-paths', 'Paths to custom dictionaries', default: []
22
+ o.string '-f', '--format', 'Output formats: readable(default), JSON, YAML', default: 'readable'
23
+ o.boolean '--gen-dictionary', 'Generate custom dictionary'
24
+ o.string '-l', '--logfile', 'Log to specified path'
25
+ o.bool '-v', '--verbose', 'Verbose mode'
26
+ o.on '--help' do
27
+ puts o
28
+ exit
29
+ end
30
+ end
31
+
32
+ def initialize options
33
+ @options = options
34
+ end
35
+
36
+ def call
37
+ init_options
38
+ create_files_list
39
+ init_speller
40
+ init_reporter
41
+ run
42
+ end
43
+
44
+ private
45
+
46
+ def create_files_list
47
+ @files = FileList.new(paths: @opts.arguments, exclude_paths: @opts[:exclude_paths])
48
+ end
49
+
50
+ def init_options
51
+ @options += File.read(CONFIG_PATH).tr("\n", ' ').split(' ') if File.exist?(CONFIG_PATH)
52
+
53
+ @opts = Slop.parse(@options, &DEFINITIONS)
54
+
55
+ if @opts.arguments.empty?
56
+ puts 'Usage: forspell paths to check [options]'
57
+ puts 'Type --help for more info'
58
+ exit(ERROR_CODE)
59
+ end
60
+
61
+ @opts[:format] = 'dictionary' if @opts[:gen_dictionary]
62
+ @opts[:format] = @opts[:format]&.downcase
63
+ end
64
+
65
+ def init_speller
66
+ @opts[:custom_paths].each do |path|
67
+ next if File.exist?(path)
68
+
69
+ puts "Custom dictionary not found: #{path}"
70
+ exit(ERROR_CODE)
71
+ end
72
+
73
+ @opts[:custom_paths] << DEFAULT_CUSTOM_DICT if File.exist?(DEFAULT_CUSTOM_DICT)
74
+
75
+ @speller = Speller.new(@opts[:dictionary_path], *@opts[:custom_paths])
76
+ end
77
+
78
+ def init_reporter
79
+ @reporter = Reporter.new(**@opts.to_hash.slice(:logfile, :format, :verbose))
80
+ end
81
+
82
+ def run
83
+ runner = Forspell::Runner.new(files: @files, speller: @speller, reporter: @reporter)
84
+ runner.call
85
+ exit @reporter.finalize
86
+ rescue Forspell::FileList::PathLoadError => path
87
+ @reporter.path_load_error path
88
+ exit ERROR_CODE
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,205 @@
1
+ SET UTF-8
2
+ TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
3
+ ICONV 1
4
+ ICONV ’ '
5
+ NOSUGGEST !
6
+
7
+ # ordinal numbers
8
+ COMPOUNDMIN 1
9
+ # only in compounds: 1th, 2th, 3th
10
+ ONLYINCOMPOUND c
11
+ # compound rules:
12
+ # 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
13
+ # 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
14
+ COMPOUNDRULE 2
15
+ COMPOUNDRULE n*1t
16
+ COMPOUNDRULE n*mp
17
+ WORDCHARS 0123456789
18
+
19
+ PFX A Y 1
20
+ PFX A 0 re .
21
+
22
+ PFX I Y 1
23
+ PFX I 0 in .
24
+
25
+ PFX U Y 1
26
+ PFX U 0 un .
27
+
28
+ PFX C Y 1
29
+ PFX C 0 de .
30
+
31
+ PFX E Y 1
32
+ PFX E 0 dis .
33
+
34
+ PFX F Y 1
35
+ PFX F 0 con .
36
+
37
+ PFX K Y 1
38
+ PFX K 0 pro .
39
+
40
+ SFX V N 2
41
+ SFX V e ive e
42
+ SFX V 0 ive [^e]
43
+
44
+ SFX N Y 3
45
+ SFX N e ion e
46
+ SFX N y ication y
47
+ SFX N 0 en [^ey]
48
+
49
+ SFX X Y 3
50
+ SFX X e ions e
51
+ SFX X y ications y
52
+ SFX X 0 ens [^ey]
53
+
54
+ SFX H N 2
55
+ SFX H y ieth y
56
+ SFX H 0 th [^y]
57
+
58
+ SFX Y Y 1
59
+ SFX Y 0 ly .
60
+
61
+ SFX G Y 2
62
+ SFX G e ing e
63
+ SFX G 0 ing [^e]
64
+
65
+ SFX J Y 2
66
+ SFX J e ings e
67
+ SFX J 0 ings [^e]
68
+
69
+ SFX D Y 4
70
+ SFX D 0 d e
71
+ SFX D y ied [^aeiou]y
72
+ SFX D 0 ed [^ey]
73
+ SFX D 0 ed [aeiou]y
74
+
75
+ SFX T N 4
76
+ SFX T 0 st e
77
+ SFX T y iest [^aeiou]y
78
+ SFX T 0 est [aeiou]y
79
+ SFX T 0 est [^ey]
80
+
81
+ SFX R Y 4
82
+ SFX R 0 r e
83
+ SFX R y ier [^aeiou]y
84
+ SFX R 0 er [aeiou]y
85
+ SFX R 0 er [^ey]
86
+
87
+ SFX Z Y 4
88
+ SFX Z 0 rs e
89
+ SFX Z y iers [^aeiou]y
90
+ SFX Z 0 ers [aeiou]y
91
+ SFX Z 0 ers [^ey]
92
+
93
+ SFX S Y 4
94
+ SFX S y ies [^aeiou]y
95
+ SFX S 0 s [aeiou]y
96
+ SFX S 0 es [sxzh]
97
+ SFX S 0 s [^sxzhy]
98
+
99
+ SFX P Y 3
100
+ SFX P y iness [^aeiou]y
101
+ SFX P 0 ness [aeiou]y
102
+ SFX P 0 ness [^y]
103
+
104
+ SFX M Y 1
105
+ SFX M 0 's .
106
+
107
+ SFX B Y 3
108
+ SFX B 0 able [^aeiou]
109
+ SFX B 0 able ee
110
+ SFX B e able [^aeiou]e
111
+
112
+ SFX L Y 1
113
+ SFX L 0 ment .
114
+
115
+ REP 90
116
+ REP a ei
117
+ REP ei a
118
+ REP a ey
119
+ REP ey a
120
+ REP ai ie
121
+ REP ie ai
122
+ REP alot a_lot
123
+ REP are air
124
+ REP are ear
125
+ REP are eir
126
+ REP air are
127
+ REP air ere
128
+ REP ere air
129
+ REP ere ear
130
+ REP ere eir
131
+ REP ear are
132
+ REP ear air
133
+ REP ear ere
134
+ REP eir are
135
+ REP eir ere
136
+ REP ch te
137
+ REP te ch
138
+ REP ch ti
139
+ REP ti ch
140
+ REP ch tu
141
+ REP tu ch
142
+ REP ch s
143
+ REP s ch
144
+ REP ch k
145
+ REP k ch
146
+ REP f ph
147
+ REP ph f
148
+ REP gh f
149
+ REP f gh
150
+ REP i igh
151
+ REP igh i
152
+ REP i uy
153
+ REP uy i
154
+ REP i ee
155
+ REP ee i
156
+ REP j di
157
+ REP di j
158
+ REP j gg
159
+ REP gg j
160
+ REP j ge
161
+ REP ge j
162
+ REP s ti
163
+ REP ti s
164
+ REP s ci
165
+ REP ci s
166
+ REP k cc
167
+ REP cc k
168
+ REP k qu
169
+ REP qu k
170
+ REP kw qu
171
+ REP o eau
172
+ REP eau o
173
+ REP o ew
174
+ REP ew o
175
+ REP oo ew
176
+ REP ew oo
177
+ REP ew ui
178
+ REP ui ew
179
+ REP oo ui
180
+ REP ui oo
181
+ REP ew u
182
+ REP u ew
183
+ REP oo u
184
+ REP u oo
185
+ REP u oe
186
+ REP oe u
187
+ REP u ieu
188
+ REP ieu u
189
+ REP ue ew
190
+ REP ew ue
191
+ REP uff ough
192
+ REP oo ieu
193
+ REP ieu oo
194
+ REP ier ear
195
+ REP ear ier
196
+ REP ear air
197
+ REP air ear
198
+ REP w qu
199
+ REP qu w
200
+ REP z ss
201
+ REP ss z
202
+ REP shun tion
203
+ REP shun sion
204
+ REP shun cion
205
+ REP size cise