command_kit 0.1.0 → 0.3.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +18 -3
  3. data/.rubocop.yml +141 -0
  4. data/ChangeLog.md +165 -0
  5. data/Gemfile +3 -0
  6. data/README.md +186 -118
  7. data/Rakefile +3 -2
  8. data/command_kit.gemspec +4 -4
  9. data/examples/command.rb +1 -1
  10. data/gemspec.yml +7 -0
  11. data/lib/command_kit/arguments/argument.rb +2 -2
  12. data/lib/command_kit/arguments.rb +36 -7
  13. data/lib/command_kit/colors.rb +702 -53
  14. data/lib/command_kit/command.rb +2 -3
  15. data/lib/command_kit/commands/auto_load.rb +8 -1
  16. data/lib/command_kit/commands/help.rb +3 -2
  17. data/lib/command_kit/commands/subcommand.rb +1 -1
  18. data/lib/command_kit/commands.rb +24 -9
  19. data/lib/command_kit/env/path.rb +1 -1
  20. data/lib/command_kit/file_utils.rb +46 -0
  21. data/lib/command_kit/help/man.rb +17 -33
  22. data/lib/command_kit/inflector.rb +47 -17
  23. data/lib/command_kit/interactive.rb +9 -0
  24. data/lib/command_kit/main.rb +7 -9
  25. data/lib/command_kit/man.rb +44 -0
  26. data/lib/command_kit/open_app.rb +69 -0
  27. data/lib/command_kit/options/option.rb +41 -27
  28. data/lib/command_kit/options/option_value.rb +3 -2
  29. data/lib/command_kit/options/parser.rb +17 -22
  30. data/lib/command_kit/options.rb +102 -14
  31. data/lib/command_kit/os/linux.rb +157 -0
  32. data/lib/command_kit/os.rb +159 -11
  33. data/lib/command_kit/package_manager.rb +200 -0
  34. data/lib/command_kit/pager.rb +46 -4
  35. data/lib/command_kit/printing/indent.rb +4 -4
  36. data/lib/command_kit/printing.rb +14 -3
  37. data/lib/command_kit/program_name.rb +9 -0
  38. data/lib/command_kit/sudo.rb +40 -0
  39. data/lib/command_kit/terminal.rb +5 -0
  40. data/lib/command_kit/version.rb +1 -1
  41. data/spec/arguments/argument_spec.rb +1 -1
  42. data/spec/arguments_spec.rb +84 -1
  43. data/spec/colors_spec.rb +357 -70
  44. data/spec/command_spec.rb +77 -6
  45. data/spec/commands/auto_load_spec.rb +33 -2
  46. data/spec/commands_spec.rb +101 -29
  47. data/spec/env/path_spec.rb +6 -0
  48. data/spec/exception_handler_spec.rb +1 -1
  49. data/spec/file_utils_spec.rb +59 -0
  50. data/spec/fixtures/template.erb +5 -0
  51. data/spec/help/man_spec.rb +54 -57
  52. data/spec/inflector_spec.rb +70 -8
  53. data/spec/man_spec.rb +46 -0
  54. data/spec/open_app_spec.rb +85 -0
  55. data/spec/options/option_spec.rb +38 -2
  56. data/spec/options/option_value_spec.rb +55 -0
  57. data/spec/options/parser_spec.rb +0 -10
  58. data/spec/options_spec.rb +328 -0
  59. data/spec/os/linux_spec.rb +164 -0
  60. data/spec/os_spec.rb +200 -13
  61. data/spec/package_manager_spec.rb +806 -0
  62. data/spec/pager_spec.rb +71 -6
  63. data/spec/printing/indent_spec.rb +7 -5
  64. data/spec/printing_spec.rb +23 -1
  65. data/spec/program_name_spec.rb +8 -0
  66. data/spec/sudo_spec.rb +51 -0
  67. data/spec/terminal_spec.rb +30 -0
  68. data/spec/usage_spec.rb +1 -1
  69. metadata +23 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: acf8c9763694ffe7ac298e158863a3165c5d8f1a2209d1cac5b01e9c60d9dd85
4
- data.tar.gz: 98669568909de27878be028ae8b0251ddc6e8a4740af23037bd234d06778b2ce
3
+ metadata.gz: 306f055fa898d4d82c14ba8e79b397ae413280bb7144ce69e1787081620827e9
4
+ data.tar.gz: e79e640f7d4ae566401e7543d3ba98aa42b1e2396657734e29ab3cd3b383b41c
5
5
  SHA512:
6
- metadata.gz: b04269a04b5d474f2a17724e04fa015fe5c1eefdbba9f53cf06c49c727c369ae3ba9a77e336c09f69fc3e7c8b6e5f77fa98abe7912c022213489d5b04191f5bb
7
- data.tar.gz: 01c43327289df1e30970e618b2d133e26bc5e6cdd3d65cc6fad7cbc369e44085fd164cb0b93a241df6508e3019fbfed658f83191e958457ec6f7ecfed86b88b3
6
+ metadata.gz: ee4268377db8c2398b5157feda9fa106a0b156537c6085b71fcfd8c7710f898c3bc0ef5d4408d9c6cbcae932e4f4ee4dd49070003e6c5734da06da33fbbace9a
7
+ data.tar.gz: 03b6a48369bea030002f9432d0d8645d8c0f5cdefba81778922e73a54f267611419bdb63e5033e98b09aa1c6ae97af1e8c3b8135cb7ed4b807fce666c6c379b8
@@ -3,19 +3,20 @@ name: CI
3
3
  on: [ push, pull_request ]
4
4
 
5
5
  jobs:
6
+ # run tests
6
7
  tests:
7
8
  runs-on: ubuntu-latest
8
9
  strategy:
9
10
  fail-fast: false
10
11
  matrix:
11
12
  ruby:
12
- # - 2.4
13
- # - 2.5
14
- # - 2.6
15
13
  - 2.7
16
14
  - 3.0
15
+ - 3.1
17
16
  # TODO: uncomment when jruby supports ruby >= 2.7
18
17
  # - jruby
18
+ # TODO: uncomment when truffleruby supports splatting empty kwargs
19
+ # - truffleruby
19
20
  name: Ruby ${{ matrix.ruby }}
20
21
  steps:
21
22
  - uses: actions/checkout@v2
@@ -27,3 +28,17 @@ jobs:
27
28
  run: bundle install --jobs 4 --retry 3
28
29
  - name: Run tests
29
30
  run: bundle exec rake test
31
+
32
+ # rubocop linting
33
+ rubocop:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - name: Set up Ruby
38
+ uses: ruby/setup-ruby@v1
39
+ with:
40
+ ruby-version: 2.7
41
+ - name: Install dependencies
42
+ run: bundle install --jobs 4 --retry 3
43
+ - name: Run rubocop
44
+ run: bundle exec rubocop --parallel
data/.rubocop.yml ADDED
@@ -0,0 +1,141 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ SuggestExtensions: false
4
+ TargetRubyVersion: 2.7
5
+
6
+ #
7
+ # our rules
8
+ #
9
+
10
+ Layout/FirstArrayElementIndentation: { Exclude: ['spec/**/*'] }
11
+ Layout/LineLength: { Enabled: false }
12
+ Layout/SpaceAroundEqualsInParameterDefault: { EnforcedStyle: no_space }
13
+ Lint/ConstantDefinitionInBlock: { Exclude: ['spec/**/*'] }
14
+ Metrics: { Enabled: false }
15
+ Style/SymbolArray: { EnforcedStyle: brackets }
16
+ Style/IfInsideElse: { Enabled: false } # Offense count: 1
17
+ Style/PercentLiteralDelimiters:
18
+ Enabled: true
19
+ PreferredDelimiters:
20
+ default: '{}'
21
+ '%i': '[]'
22
+ '%I': '[]'
23
+ '%w': '[]'
24
+ '%W': '[]'
25
+
26
+ #
27
+ # rules that are in flux
28
+ #
29
+
30
+ # consider enabling these and autocorrecting?
31
+ # Layout/SpaceAfterComma
32
+ # Layout/SpaceAroundKeyword
33
+ # Layout/SpaceBeforeComma
34
+ # Layout/SpaceInsideHashLiteralBraces
35
+ # Layout/SpaceInsideParens
36
+ # Layout/TrailingWhitespace
37
+ # Lint/UnreachableLoop
38
+ # Lint/UnusedBlockArgument
39
+ # Style/ClassCheck
40
+ # Style/Documentation
41
+ # Style/ExpandPathArguments
42
+ # Style/GlobalStdStream
43
+ # Style/HashSyntax
44
+ # Style/KeywordParametersOrder
45
+ # Style/MethodCallWithoutArgsParentheses
46
+ # Style/MutableConstant
47
+ # Style/QuotedSymbols: { EnforcedStyle: double_quotes }
48
+ # Style/RedundantReturn
49
+ # Style/SafeNavigation
50
+ # Style/SpecialGlobalVars
51
+ # Style/StringLiterals: { EnforcedStyle: double_quotes }
52
+ # Style/WordArray
53
+
54
+ # these have been fixed
55
+ # Gemspec/DuplicatedAssignment: { Enabled: false } # Offense count: 1
56
+ # Layout/ElseAlignment: { Enabled: false } # Offense count: 1
57
+ # Layout/EndAlignment: { Enabled: false } # Offense count: 1
58
+ # Lint/DuplicateMethods: { Enabled: false } # Offense count: 1
59
+ # Lint/UselessAssignment: { Enabled: false } # Offense count: 1
60
+ # Style/Encoding: { Enabled: false } # Offense count: 2
61
+ # Style/RedundantBegin: { Enabled: false } # Offense count: 2
62
+ # Style/RedundantInterpolation: { Enabled: false } # Offense count: 1
63
+ # Style/TrailingCommaInArrayLiteral: { Enabled: false } # Offense count: 1
64
+
65
+ #
66
+ # This list was generated with:
67
+ # bundle exec rubocop --auto-gen-config --exclude-limit 1
68
+ #
69
+
70
+ # > 10 violations
71
+ Layout/AssignmentIndentation: { Enabled: false } # Offense count: 11
72
+ Layout/EmptyLinesAroundClassBody: { Enabled: false } # Offense count: 76
73
+ Layout/HashAlignment: { Enabled: false } # Offense count: 28
74
+ Layout/SpaceAfterComma: { Enabled: false } # Offense count: 141
75
+ Layout/SpaceInsideHashLiteralBraces: { Enabled: false } # Offense count: 57
76
+ Layout/TrailingWhitespace: { Enabled: false } # Offense count: 50
77
+ Naming/RescuedExceptionsVariableName: { Enabled: false } # Offense count: 11
78
+ Style/BlockDelimiters: { Enabled: false } # Offense count: 17
79
+ Style/ClassCheck: { Enabled: false } # Offense count: 10
80
+ Style/ClassEqualityComparison: { Enabled: false } # Offense count: 16
81
+ Style/FrozenStringLiteralComment: { Enabled: false } # Offense count: 77
82
+ Style/GlobalStdStream: { Enabled: false } # Offense count: 13
83
+ Style/GuardClause: { Enabled: false } # Offense count: 10
84
+ Style/IfUnlessModifier: { Enabled: false } # Offense count: 13
85
+ Style/MethodCallWithoutArgsParentheses: { Enabled: false } # Offense count: 10
86
+ Style/SpecialGlobalVars: { Enabled: false } # Offense count: 28
87
+ Style/StringLiterals: { Enabled: false } # Offense count: 774
88
+ Lint/ElseLayout: { Enabled: false } # Offense count: 22
89
+
90
+ # < 10 violations
91
+ Layout/EmptyLinesAroundModuleBody: { Enabled: false } # Offense count: 5
92
+ Layout/ExtraSpacing: { Enabled: false } # Offense count: 6
93
+ Layout/FirstHashElementIndentation: { Enabled: false } # Offense count: 4
94
+ Layout/ParameterAlignment: { Enabled: false } # Offense count: 9
95
+ Layout/SpaceAroundKeyword: { Enabled: false } # Offense count: 7
96
+ Layout/SpaceBeforeComma: { Enabled: false } # Offense count: 4
97
+ Layout/SpaceInsideParens: { Enabled: false } # Offense count: 4
98
+ Lint/EmptyClass: { Enabled: false } # Offense count: 3
99
+ Lint/SuppressedException: { Enabled: false } # Offense count: 4
100
+ Lint/UnusedMethodArgument: { Enabled: false } # Offense count: 5
101
+ Style/AccessorGrouping: { Enabled: false } # Offense count: 7
102
+ Style/Documentation: { Enabled: false } # Offense count: 3
103
+ Style/ExpandPathArguments: { Enabled: false } # Offense count: 8
104
+ Style/HashSyntax: { Exclude: ['Rakefile'] } # Offense count: 3
105
+ Style/KeywordParametersOrder: { Enabled: false } # Offense count: 8
106
+ Style/Lambda: { Enabled: false } # Offense count: 3
107
+ Style/MutableConstant: { Enabled: false } # Offense count: 4
108
+ Style/RaiseArgs: { Enabled: false } # Offense count: 4
109
+ Style/RedundantReturn: { Enabled: false } # Offense count: 7
110
+ Style/SafeNavigation: { Enabled: false } # Offense count: 5
111
+ Style/StringConcatenation: { Enabled: false } # Offense count: 8
112
+ Style/WordArray: { Enabled: false } # Offense count: 4
113
+
114
+ # 1 or 2 violations
115
+ Layout/ArgumentAlignment: { Enabled: false } # Offense count: 1
116
+ Layout/BlockAlignment: { Enabled: false } # Offense count: 1
117
+ Layout/IndentationWidth: { Enabled: false } # Offense count: 2
118
+ Layout/SpaceAroundOperators: { Enabled: false } # Offense count: 1
119
+ Layout/SpaceBeforeBlockBraces: { Enabled: false } # Offense count: 1
120
+ Lint/MissingSuper: { Enabled: false } # Offense count: 2
121
+ Lint/RescueException: { Enabled: false } # Offense count: 1
122
+ Lint/UnreachableLoop: { Enabled: false } # Offense count: 1
123
+ Lint/UnusedBlockArgument: { Enabled: false } # Offense count: 1
124
+ Naming/MethodParameterName: { Enabled: false } # Offense count: 1
125
+ Style/EmptyMethod: { Enabled: false } # Offense count: 2
126
+ Style/HashConversion: { Enabled: false } # Offense count: 1
127
+ Style/MultilineMemoization: { Enabled: false } # Offense count: 1
128
+ Style/NumericPredicate: { Enabled: false } # Offense count: 1
129
+ Style/OptionalArguments: { Enabled: false } # Offense count: 1
130
+ Style/ParenthesesAroundCondition: { Enabled: false } # Offense count: 1
131
+ Style/PreferredHashMethods: { Enabled: false } # Offense count: 1
132
+ Style/QuotedSymbols: { Enabled: false } # Offense count: 1
133
+ Style/RedundantException: { Enabled: false } # Offense count: 1
134
+ Style/RedundantRegexpEscape: { Enabled: false } # Offense count: 1
135
+ Style/RegexpLiteral: { Enabled: false } # Offense count: 1
136
+ Style/RescueStandardError: { Enabled: false } # Offense count: 1
137
+ Style/SoleNestedConditional: { Enabled: false } # Offense count: 1
138
+ Style/TrailingCommaInHashLiteral: { Enabled: false } # Offense count: 2
139
+
140
+ # rubocop cannot tell that rubygems_mfa_required is enabled in gemspec.yml
141
+ Gemspec/RequireMFA: { Enabled: false }
data/ChangeLog.md CHANGED
@@ -1,3 +1,167 @@
1
+ ### 0.3.0 / 2021-12-26
2
+
3
+ * Added {CommandKit::FileUtils}.
4
+
5
+ #### CommandKit::FileUtils
6
+
7
+ * Added {CommandKit::FileUtils#erb #erb}.
8
+
9
+ #### CommandKit::Colors
10
+
11
+ * Added {CommandKit::Colors::ANSI::RESET_FG RESET_FG}.
12
+ * Added {CommandKit::Colors::ANSI.bright_black bright_black}.
13
+ * Added {CommandKit::Colors::ANSI.gray gray}.
14
+ * Added {CommandKit::Colors::ANSI.bright_red bright_red}.
15
+ * Added {CommandKit::Colors::ANSI.bright_green bright_green}.
16
+ * Added {CommandKit::Colors::ANSI.bright_yellow bright_yellow}.
17
+ * Added {CommandKit::Colors::ANSI.bright_blue bright_blue}.
18
+ * Added {CommandKit::Colors::ANSI.bright_magenta bright_magenta}.
19
+ * Added {CommandKit::Colors::ANSI.bright_cyan bright_cyan}.
20
+ * Added {CommandKit::Colors::ANSI.bright_white bright_white}.
21
+ * Added {CommandKit::Colors::ANSI.on_bright_black on_bright_black}.
22
+ * Added {CommandKit::Colors::ANSI.on_gray on_gray}.
23
+ * Added {CommandKit::Colors::ANSI.on_bright_red on_bright_red}.
24
+ * Added {CommandKit::Colors::ANSI.on_bright_green on_bright_green}.
25
+ * Added {CommandKit::Colors::ANSI.on_bright_yellow on_bright_yellow}.
26
+ * Added {CommandKit::Colors::ANSI.on_bright_blue on_bright_blue}.
27
+ * Added {CommandKit::Colors::ANSI.on_bright_magenta on_bright_magenta}.
28
+ * Added {CommandKit::Colors::ANSI.on_bright_cyan on_bright_cyan}.
29
+ * Added {CommandKit::Colors::ANSI.on_bright_white on_bright_white}.
30
+
31
+ #### ComandKit::Options
32
+
33
+ * Allow grouping options into categories:
34
+
35
+ option :opt1, category: 'Foo Options',
36
+ desc: 'Option 1'
37
+
38
+ option :opt2, category: 'Foo Options',
39
+ desc: 'Option 1'
40
+
41
+ * Allow options to have multi-line descriptions:
42
+
43
+ option :opt1, short: '-o',
44
+ desc: [
45
+ 'line1',
46
+ 'line2',
47
+ '...'
48
+ ]
49
+
50
+ #### CommandKit::Arguments
51
+
52
+ * Allow arguments to have multi-line descriptions:
53
+
54
+ argument :arg1, desc: [
55
+ 'line1',
56
+ 'line2',
57
+ '...'
58
+ ]
59
+
60
+
61
+ #### CommandKit::ProgramName
62
+
63
+ * Added {CommandKit::ProgramName#command_name}.
64
+
65
+ ### 0.2.2 / 2021-12-26
66
+
67
+ #### CommandKit::Help::Man
68
+
69
+ * Raise a `NotImplementedError` exception in {CommandKit::Help::Man#help_man
70
+ #help_man} if {CommandKit::Help::Man::ClassMethods#man_dir .man_dir} was not
71
+ set.
72
+
73
+ ### 0.2.1 / 2021-11-16
74
+
75
+ * Ensure that all error messages end with a period.
76
+ * Documentation fixes.
77
+ * Opt-in to [rubygem.org MFA requirement](https://guides.rubygems.org/mfa-requirement-opt-in/).
78
+
79
+ #### CommandKit::Printing
80
+
81
+ * Auto-detect whether {CommandKit::CommandName#command_name #command_name} is
82
+ available, and if so, prepend the command name to all error messages.
83
+
84
+ #### CommandKit::Help::Man
85
+
86
+ * Expand the path given to
87
+ {CommandKit::Help::Man::ClassMethods#man_dir man_dir}.
88
+ * If {CommandKit::Help::Man::ClassMethods#man_dir man_dir} is not set, fallback
89
+ to regular `--help` output.
90
+
91
+ #### CommandKit::Arguments
92
+
93
+ * Include {CommandKit::Usage} and {CommandKit::Printing} into
94
+ {CommandKit::Arguments}.
95
+
96
+ #### CommandKit::Options
97
+
98
+ * Include {CommandKit::Arguments} into {CommandKit::Options}.
99
+ * Ensure that {CommandKit::Options::Parser#main} runs before
100
+ {CommandKit::Arguments#main}.
101
+ * Ensure that {CommandKit::Options#help} also calls
102
+ {CommandKit::Arguments#help_arguments}.
103
+ * Always prepopulate {CommandKit::Options#options #options} with option's
104
+ default values.
105
+ * Note: if an option has a default value but the option's value is not
106
+ required (ex: `value: {required: false, default: "foo"}`), and the option's
107
+ flag is given but no value is given (ex: `--option-flag --some-other-flag`),
108
+ the option's value in {CommandKit::Options#options #options} will be `nil`
109
+ _not_ the option's default value (`"foo"`). This helps indicate that the
110
+ option's flag was given but no value was given with it.
111
+
112
+ #### CommandKit::Options::OptionValue
113
+
114
+ * When a `Class` is passed to {CommandKit::Options::OptionValue.default_usage},
115
+ demodularize the class name before converting it to underscored/uppercase.
116
+
117
+ #### CommandKit::Command
118
+
119
+ * Fixed the inclusion order of {CommandKit::Options} and
120
+ {CommandKit::Arguments}.
121
+
122
+ #### CommandKit::Commands
123
+
124
+ * Define the `COMMAND` and `ARGS` arguments.
125
+ * Correctly duplicate the {CommandKit::Env#env env} (which can be either `ENV`
126
+ or a `Hash`) to work on ruby-3.1.0-preview1.
127
+ * Print command aliases that were set explicitly
128
+ (ex: `command_aliases['rm'] = 'remove'`) in {CommandKit::Commands#help}.
129
+ * Print help and exit with status `1` if no command is given. This matches the
130
+ behavior of the `git` command.
131
+
132
+ #### CommandKit::Commands::AutoLoad
133
+
134
+ * Ensure that any explicit command aliases are added to the command's
135
+ {CommandKit::Commands::ClassMethods#command_aliases command_aliases}.
136
+
137
+ ### 0.2.0 / 2021-08-31
138
+
139
+ * Added {CommandKit::Colors::ANSI#on_black}.
140
+ * Added {CommandKit::Colors::ANSI#on_red}.
141
+ * Added {CommandKit::Colors::ANSI#on_green}.
142
+ * Added {CommandKit::Colors::ANSI#on_yellow}.
143
+ * Added {CommandKit::Colors::ANSI#on_blue}.
144
+ * Added {CommandKit::Colors::ANSI#on_magenta}.
145
+ * Added {CommandKit::Colors::ANSI#on_cyan}.
146
+ * Added {CommandKit::Colors::ANSI#on_white}.
147
+ * Added {CommandKit::Man}.
148
+ * Added {CommandKit::OS#bsd?}.
149
+ * Added {CommandKit::OS#freebsd?}.
150
+ * Added {CommandKit::OS#netbsd?}.
151
+ * Added {CommandKit::OS#openbsd?}.
152
+ * Added {CommandKit::OS#os}.
153
+ * Added {CommandKit::OS#unix?}.
154
+ * Added {CommandKit::OS::Linux}.
155
+ * Added {CommandKit::OpenApp}.
156
+ * Added {CommandKit::PackageManager}.
157
+ * Added {CommandKit::Pager#pipe_to_pager}.
158
+ * Added {CommandKit::Sudo}.
159
+ * Added {CommandKit::Terminal#tty?}.
160
+ * Refactor {CommandKit::Inflector.camelize} and
161
+ {CommandKit::Inflector.underscore} to use StringScanner.
162
+ * Allow {CommandKit::OS#initialize} to accept an `os:` keyword to override the
163
+ detected OS.
164
+
1
165
  ### 0.1.0 / 2021-07-16
2
166
 
3
167
  * Initial release:
@@ -21,6 +185,7 @@
21
185
  * {CommandKit::Options}
22
186
  * {CommandKit::Options::Quiet}
23
187
  * {CommandKit::Options::Verbose}
188
+ * {CommandKit::OS}
24
189
  * {CommandKit::Pager}
25
190
  * {CommandKit::Printing}
26
191
  * {CommandKit::Printing::Indent}
data/Gemfile CHANGED
@@ -6,9 +6,12 @@ group :development do
6
6
  gem 'rake'
7
7
  gem 'rubygems-tasks', '~> 0.2'
8
8
 
9
+ gem 'rubocop', '~> 1.18'
10
+
9
11
  gem 'rspec', '~> 3.0'
10
12
  gem 'simplecov', '~> 0.20', require: false
11
13
 
12
14
  gem 'kramdown'
13
15
  gem 'yard', '~> 0.9'
16
+ gem 'yard-spellcheck', require: false
14
17
  end