tty 0.7.0 → 0.8.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/.rspec +2 -2
  3. data/.travis.yml +15 -4
  4. data/CHANGELOG.md +22 -0
  5. data/Gemfile +4 -7
  6. data/README.md +648 -58
  7. data/appveyor.yml +3 -4
  8. data/exe/teletype +18 -0
  9. data/lib/tty.rb +7 -4
  10. data/lib/tty/cli.rb +140 -0
  11. data/lib/tty/cmd.rb +132 -0
  12. data/lib/tty/commands/add.rb +321 -0
  13. data/lib/tty/commands/new.rb +256 -0
  14. data/lib/tty/gemspec.rb +30 -0
  15. data/lib/tty/licenses.rb +34 -0
  16. data/lib/tty/path_helpers.rb +38 -0
  17. data/lib/tty/plugins.rb +20 -12
  18. data/lib/tty/templater.rb +54 -0
  19. data/lib/tty/templates/add/command.rb.tt +31 -0
  20. data/lib/tty/templates/add/gitkeep.tt +1 -0
  21. data/lib/tty/templates/add/namespace.rb.tt +17 -0
  22. data/lib/tty/templates/add/spec/integration/command_spec.rb.tt +20 -0
  23. data/lib/tty/templates/add/spec/integration/sub_command_spec.rb.tt +16 -0
  24. data/lib/tty/templates/add/spec/unit/command_spec.rb.tt +15 -0
  25. data/lib/tty/templates/add/spec/unit/sub_command_spec.rb.tt +15 -0
  26. data/lib/tty/templates/add/test/integration/command_test.rb.tt +23 -0
  27. data/lib/tty/templates/add/test/integration/sub_command_test.rb.tt +19 -0
  28. data/lib/tty/templates/add/test/unit/command_test.rb.tt +16 -0
  29. data/lib/tty/templates/add/test/unit/sub_command_test.rb.tt +16 -0
  30. data/lib/tty/templates/new/agplv3_LICENSE.txt.tt +555 -0
  31. data/lib/tty/templates/new/apache_LICENSE.txt.tt +157 -0
  32. data/lib/tty/templates/new/bsd2_LICENSE.txt.tt +22 -0
  33. data/lib/tty/templates/new/bsd3_LICENSE.txt.tt +26 -0
  34. data/lib/tty/templates/new/exe/newcli.tt +18 -0
  35. data/lib/tty/templates/new/gitkeep.tt +1 -0
  36. data/lib/tty/templates/new/gplv2_LICENSE.txt.tt +255 -0
  37. data/lib/tty/templates/new/gplv3_LICENSE.txt.tt +543 -0
  38. data/lib/tty/templates/new/lgplv3_LICENSE.txt.tt +143 -0
  39. data/lib/tty/templates/new/lib/newcli/cli.rb.tt +24 -0
  40. data/lib/tty/templates/new/lib/newcli/command.rb.tt +124 -0
  41. data/lib/tty/templates/new/mit_LICENSE.txt.tt +20 -0
  42. data/lib/tty/templates/new/mplv2_LICENSE.txt.tt +277 -0
  43. data/lib/tty/version.rb +1 -1
  44. data/spec/fixtures/foo-0.0.1.gemspec +4 -4
  45. data/spec/integration/add_desc_args_spec.rb +341 -0
  46. data/spec/integration/add_force_spec.rb +98 -0
  47. data/spec/integration/add_namespaced_spec.rb +291 -0
  48. data/spec/integration/add_spec.rb +535 -0
  49. data/spec/integration/add_subcommand_spec.rb +259 -0
  50. data/spec/integration/new_author_spec.rb +19 -0
  51. data/spec/integration/new_license_spec.rb +39 -0
  52. data/spec/integration/new_namespaced_spec.rb +228 -0
  53. data/spec/integration/new_spec.rb +354 -0
  54. data/spec/integration/new_test_spec.rb +21 -0
  55. data/spec/integration/start_spec.rb +21 -0
  56. data/spec/spec_helper.rb +47 -16
  57. data/spec/unit/gemspec_spec.rb +17 -0
  58. data/spec/{tty/plugins/load_spec.rb → unit/plugins/activate_spec.rb} +2 -4
  59. data/spec/unit/plugins/load_from_spec.rb +28 -0
  60. data/spec/{tty → unit}/plugins/plugin/load_spec.rb +1 -3
  61. data/spec/{tty → unit}/plugins/plugin/new_spec.rb +1 -3
  62. data/spec/{tty → unit}/tty_spec.rb +1 -3
  63. data/tty.gemspec +25 -15
  64. metadata +186 -49
  65. data/spec/tty/plugins/find_spec.rb +0 -20
  66. data/tasks/metrics/cane.rake +0 -14
  67. data/tasks/metrics/flog.rake +0 -17
  68. data/tasks/metrics/heckle.rake +0 -15
  69. data/tasks/metrics/reek.rake +0 -13
@@ -0,0 +1,354 @@
1
+ RSpec.describe 'teletype new', type: :cli do
2
+
3
+ it "generates cli application" do
4
+ app_name = tmp_path('newcli')
5
+
6
+ output = <<-OUT
7
+ Creating gem 'newcli'...
8
+ create tmp/newcli/Gemfile
9
+ create tmp/newcli/lib/newcli.rb
10
+ create tmp/newcli/lib/newcli/version.rb
11
+ create tmp/newcli/newcli.gemspec
12
+ create tmp/newcli/Rakefile
13
+ create tmp/newcli/README.md
14
+ create tmp/newcli/bin/console
15
+ create tmp/newcli/bin/setup
16
+ create tmp/newcli/.gitignore
17
+ create tmp/newcli/.travis.yml
18
+ create tmp/newcli/.rspec
19
+ create tmp/newcli/spec/spec_helper.rb
20
+ create tmp/newcli/spec/newcli_spec.rb
21
+ append tmp/newcli/README.md
22
+ inject tmp/newcli/newcli.gemspec
23
+ create tmp/newcli/lib/newcli/cli.rb
24
+ create tmp/newcli/lib/newcli/command.rb
25
+ create tmp/newcli/exe/newcli
26
+ create tmp/newcli/LICENSE.txt
27
+ create tmp/newcli/lib/newcli/commands/.gitkeep
28
+ create tmp/newcli/lib/newcli/templates/.gitkeep
29
+ create tmp/newcli/spec/integration/.gitkeep
30
+ create tmp/newcli/spec/support/.gitkeep
31
+ create tmp/newcli/spec/unit/.gitkeep
32
+ Initializing git repo in #{app_name}
33
+
34
+ Your teletype project has been created successfully.
35
+
36
+ Run "teletype help" for more commands.
37
+ OUT
38
+
39
+ command = "teletype new #{app_name} --no-coc --no-color --license mit --no-ext"
40
+ out, err, status = Open3.capture3(command)
41
+
42
+ expect(out).to include(output)
43
+ expect(err).to eq('')
44
+ expect(status.exitstatus).to eq(0)
45
+
46
+ within_dir(app_name) do
47
+
48
+ # doesn't generate coc
49
+ expect(::File.exist?('CODE_OF_CONDUCT.md')).to eq(false)
50
+
51
+ # doesn't generate ext
52
+ expect(::File.exist?("ext/newcli/extconf.rb")).to eq(false)
53
+
54
+ expect(::File.read('LICENSE.txt')).to match(/The MIT License \(MIT\)/)
55
+
56
+ # newcli.gemspec
57
+ gemspec = ::File.read('newcli.gemspec')
58
+
59
+ expect(gemspec).to match(/spec.license\s+= \"MIT\"/)
60
+
61
+ expect(gemspec).to match(%r{
62
+ spec.add_dependency "tty-color", "~> \d+.\d+.\d+"
63
+ spec.add_dependency "tty-command", "~> \d+.\d+.\d+"
64
+ spec.add_dependency "tty-config", "~> \d+.\d+.\d+"
65
+ spec.add_dependency "tty-cursor", "~> \d+.\d+.\d+"
66
+ spec.add_dependency "tty-editor", "~> \d+.\d+.\d+"
67
+ spec.add_dependency "tty-file", "~> \d+.\d+.\d+"
68
+ spec.add_dependency "tty-font", "~> \d+.\d+.\d+"
69
+ spec.add_dependency "tty-markdown", "~> \d+.\d+.\d+"
70
+ spec.add_dependency "tty-pager", "~> \d+.\d+.\d+"
71
+ spec.add_dependency "tty-platform", "~> \d+.\d+.\d+"
72
+ spec.add_dependency "tty-progressbar", "~> \d+.\d+.\d+"
73
+ spec.add_dependency "tty-prompt", "~> \d+.\d+.\d+"
74
+ spec.add_dependency "tty-screen", "~> \d+.\d+.\d+"
75
+ spec.add_dependency "tty-spinner", "~> \d+.\d+.\d+"
76
+ spec.add_dependency "tty-table", "~> \d+.\d+.\d+"
77
+ spec.add_dependency "tty-tree", "~> \d+.\d+.\d+"
78
+ spec.add_dependency "tty-which", "~> \d+.\d+.\d+"
79
+ spec.add_dependency "pastel", "~> \d+.\d+.\d+"
80
+ spec.add_dependency "thor", "~> \d+.\d+.\d+"
81
+ })
82
+
83
+ # exe/newcli
84
+ #
85
+ expect(::File.read('exe/newcli')).to eq(<<-EOS)
86
+ #!/usr/bin/env ruby
87
+ # frozen_string_literal: true
88
+
89
+ lib_path = File.expand_path('../lib', __dir__)
90
+ $:.unshift(lib_path) if !$:.include?(lib_path)
91
+ require 'newcli/cli'
92
+
93
+ Signal.trap('INT') do
94
+ warn(\"\\n\#{caller.join(\"\\n\")}: interrupted\")
95
+ exit(1)
96
+ end
97
+
98
+ begin
99
+ Newcli::CLI.start
100
+ rescue Newcli::CLI::Error => err
101
+ puts \"ERROR: \#{err.message}\"
102
+ exit 1
103
+ end
104
+ EOS
105
+
106
+ # lib/newcli/cli.rb
107
+ #
108
+ expect(::File.read('lib/newcli/cli.rb')).to eq(<<-EOS)
109
+ # frozen_string_literal: true
110
+
111
+ require 'thor'
112
+
113
+ module Newcli
114
+ # Handle the application command line parsing
115
+ # and the dispatch to various command objects
116
+ #
117
+ # @api public
118
+ class CLI < Thor
119
+ # Error raised by this runner
120
+ Error = Class.new(StandardError)
121
+
122
+ desc 'version', 'newcli version'
123
+ def version
124
+ require_relative 'version'
125
+ puts \"v\#{Newcli::VERSION}\"
126
+ end
127
+ map %w(--version -v) => :version
128
+ end
129
+ end
130
+ EOS
131
+
132
+ # lib/newcli/cmd.rb
133
+ #
134
+ expect(::File.read('lib/newcli/command.rb')).to eq(<<-EOS)
135
+ # frozen_string_literal: true
136
+
137
+ require 'forwardable'
138
+
139
+ module Newcli
140
+ class Command
141
+ extend Forwardable
142
+
143
+ def_delegators :command, :run
144
+
145
+ # Execute this command
146
+ #
147
+ # @api public
148
+ def execute(*)
149
+ raise(
150
+ NotImplementedError,
151
+ "\#{self.class}#\#{__method__} must be implemented"
152
+ )
153
+ end
154
+
155
+ # The external commands runner
156
+ #
157
+ # @see http://www.rubydoc.info/gems/tty-command
158
+ #
159
+ # @api public
160
+ def command(**options)
161
+ require 'tty-command'
162
+ TTY::Command.new(options)
163
+ end
164
+
165
+ # The cursor movement
166
+ #
167
+ # @see http://www.rubydoc.info/gems/tty-cursor
168
+ #
169
+ # @api public
170
+ def cursor
171
+ require 'tty-cursor'
172
+ TTY::Cursor
173
+ end
174
+
175
+ # Open a file or text in the user's preferred editor
176
+ #
177
+ # @see http://www.rubydoc.info/gems/tty-editor
178
+ #
179
+ # @api public
180
+ def editor
181
+ require 'tty-editor'
182
+ TTY::Editor
183
+ end
184
+
185
+ # File manipulation utility methods
186
+ #
187
+ # @see http://www.rubydoc.info/gems/tty-file
188
+ #
189
+ # @api public
190
+ def generator
191
+ require 'tty-file'
192
+ TTY::File
193
+ end
194
+
195
+ # Terminal output paging
196
+ #
197
+ # @see http://www.rubydoc.info/gems/tty-pager
198
+ #
199
+ # @api public
200
+ def pager(**options)
201
+ require 'tty-pager'
202
+ TTY::Pager.new(options)
203
+ end
204
+
205
+ # Terminal platform and OS properties
206
+ #
207
+ # @see http://www.rubydoc.info/gems/tty-pager
208
+ #
209
+ # @api public
210
+ def platform
211
+ require 'tty-platform'
212
+ TTY::Platform.new
213
+ end
214
+
215
+ # The interactive prompt
216
+ #
217
+ # @see http://www.rubydoc.info/gems/tty-prompt
218
+ #
219
+ # @api public
220
+ def prompt(**options)
221
+ require 'tty-prompt'
222
+ TTY::Prompt.new(options)
223
+ end
224
+
225
+ # Get terminal screen properties
226
+ #
227
+ # @see http://www.rubydoc.info/gems/tty-screen
228
+ #
229
+ # @api public
230
+ def screen
231
+ require 'tty-screen'
232
+ TTY::Screen
233
+ end
234
+
235
+ # The unix which utility
236
+ #
237
+ # @see http://www.rubydoc.info/gems/tty-which
238
+ #
239
+ # @api public
240
+ def which(*args)
241
+ require 'tty-which'
242
+ TTY::Which.which(*args)
243
+ end
244
+
245
+ # Check if executable exists
246
+ #
247
+ # @see http://www.rubydoc.info/gems/tty-which
248
+ #
249
+ # @api public
250
+ def exec_exist?(*args)
251
+ require 'tty-which'
252
+ TTY::Which.exist?(*args)
253
+ end
254
+ end
255
+ end
256
+ EOS
257
+
258
+ # Ensure executable
259
+ #
260
+ unless Gem.win_platform?
261
+ expect(::File.executable?("exe/newcli")).to eq(true)
262
+ end
263
+ end
264
+ end
265
+
266
+ it "generates C extensions boilerplate" do
267
+ app_name = tmp_path('newcli')
268
+
269
+ output = <<-OUT
270
+ create tmp/newcli/ext/newcli/extconf.rb
271
+ create tmp/newcli/ext/newcli/newcli.h
272
+ create tmp/newcli/ext/newcli/newcli.c
273
+ OUT
274
+
275
+ command = "teletype new #{app_name} --ext --no-color --license mit"
276
+ out, err, status = Open3.capture3(command)
277
+
278
+ expect(out).to include(output)
279
+ expect(err).to eq('')
280
+ expect(status.exitstatus).to eq(0)
281
+
282
+ within_dir(app_name) do
283
+ expect(::File.exist?("ext/newcli/extconf.rb")).to eq(true)
284
+ end
285
+ end
286
+
287
+ it "generates code of conduct file" do
288
+ app_name = tmp_path('newcli')
289
+
290
+ output = <<-OUT
291
+ create tmp/newcli/CODE_OF_CONDUCT.md
292
+ OUT
293
+
294
+ command = "teletype new #{app_name} --coc --no-color --license mit"
295
+ out, err, status = Open3.capture3(command)
296
+
297
+ expect(out).to match(output)
298
+ expect(err).to eq('')
299
+ expect(status.exitstatus).to eq(0)
300
+
301
+ within_dir(app_name) do
302
+ expect(::File.exist?("CODE_OF_CONDUCT.md")).to eq(true)
303
+ end
304
+ end
305
+
306
+ it "fails without cli name" do
307
+ output = <<-OUT.unindent
308
+ ERROR: 'teletype new' was called with no arguments
309
+ Usage: 'teletype new PROJECT_NAME'\n
310
+ OUT
311
+ command = "teletype new"
312
+ out, err, status = Open3.capture3(command)
313
+ expect([out, err, status.exitstatus]).to match_array([output, '', 1])
314
+ end
315
+
316
+ it "displays help" do
317
+ output = <<-OUT
318
+ Usage:
319
+ teletype new PROJECT_NAME [OPTIONS]
320
+
321
+ Options:
322
+ -a, [--author=name1 name2] # Author(s) of this library
323
+ [--ext], [--no-ext] # Generate a boilerpalate for C extension
324
+ [--coc], [--no-coc] # Generate a code of conduct file
325
+ # Default: true
326
+ -f, [--force] # Overwrite existing files
327
+ -h, [--help], [--no-help] # Display usage information
328
+ -l, [--license=mit] # Generate a license file
329
+ # Default: mit
330
+ # Possible values: agplv3, apache, bsd2, bsd3, gplv2, gplv3, lgplv3, mit, mplv2, custom
331
+ -t, [--test=rspec] # Generate a test setup
332
+ # Default: rspec
333
+ # Possible values: rspec, minitest
334
+ [--no-color] # Disable colorization in output
335
+ -r, [--dry-run], [--no-dry-run] # Run but do not make any changes
336
+ [--debug], [--no-debug] # Run in debug mode
337
+
338
+ Description:
339
+ The 'teletype new' command creates a new command line application with a
340
+ default directory structure and configuration at the specified path.
341
+
342
+ The PROJECT_NAME will be the name for the directory that includes all the
343
+ files and be the default binary name.
344
+
345
+ Example: teletype new cli_app
346
+ OUT
347
+
348
+ command = "teletype new --help"
349
+ out, err, status = Open3.capture3(command)
350
+ expect(out).to eq(output)
351
+ expect(err).to eq('')
352
+ expect(status.exitstatus).to eq(0)
353
+ end
354
+ end
@@ -0,0 +1,21 @@
1
+ RSpec.describe 'teletype new --test', type: :cli do
2
+ it "generates a rspec test setup" do
3
+ app_name = tmp_path('newcli')
4
+ command = "teletype new #{app_name} --test rspec"
5
+ `#{command}`
6
+
7
+ expect(File.exist?('newcli/spec/unit/.gitkeep'))
8
+ expect(File.exist?('newcli/spec/support/.gitkeep'))
9
+ expect(File.exist?('newcli/spec/integration/.gitkeep'))
10
+ end
11
+
12
+ it "generates a minitest test setup" do
13
+ app_name = tmp_path('newcli')
14
+ command = "teletype new #{app_name} --test=minitest"
15
+ `#{command}`
16
+
17
+ expect(File.exist?('newcli/test/unit/.gitkeep'))
18
+ expect(File.exist?('newcli/test/support/.gitkeep'))
19
+ expect(File.exist?('newcli/test/integration/.gitkeep'))
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ RSpec.describe 'teletype' do
2
+ xit "prints available commands and global options" do
3
+ command = "teletype"
4
+
5
+ out = `#{command}`
6
+
7
+ expect(out).to eq(<<-OUT)
8
+ #{TTY::CLI.top_banner}Commands:
9
+ teletype add COMMAND_NAME [OPTIONS] # Add a command to the command line app.
10
+ teletype help [COMMAND] # Describe available commands or one specific command
11
+ teletype new PROJECT_NAME [OPTIONS] # Create a new command line app skeleton.
12
+ teletype version # TTY version
13
+
14
+ Options:
15
+ [--no-color] # Disable colorization in output.
16
+ -r, [--dry-run], [--no-dry-run] # Run but do not make any changes.
17
+ [--debug], [--no-debug] # Run with debug logging.
18
+
19
+ OUT
20
+ end
21
+ end
@@ -2,11 +2,9 @@
2
2
 
3
3
  if ENV['TRAVIS'] || ENV['COVERAGE']
4
4
  require 'simplecov'
5
- require 'coveralls'
6
5
 
7
6
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
7
  SimpleCov::Formatter::HTMLFormatter,
9
- Coveralls::SimpleCov::Formatter
10
8
  ]
11
9
 
12
10
  SimpleCov.start do
@@ -14,29 +12,62 @@ if ENV['TRAVIS'] || ENV['COVERAGE']
14
12
  end
15
13
  end
16
14
 
17
- require 'rubygems'
18
15
  require 'tty'
16
+ require 'tty-file'
17
+ require 'fileutils'
18
+ require 'open3'
19
19
 
20
- module Helpers
21
- def fixtures_dir
22
- File.join(File.dirname(__FILE__), 'fixtures')
20
+ class String
21
+ def unindent
22
+ gsub(/^[ \t]*/, '').chomp
23
23
  end
24
+ end
25
+
26
+ module TestHelpers
27
+ module Paths
28
+ def gem_root
29
+ File.expand_path("#{File.dirname(__FILE__)}/..")
30
+ end
24
31
 
25
- def fixtures_path(filename = nil)
26
- File.join(File.dirname(__FILE__), 'fixtures', filename.to_s)
32
+ def dir_path(*args)
33
+ path = File.join(gem_root, *args)
34
+ FileUtils.mkdir_p(path)
35
+ File.realpath(path)
36
+ end
37
+
38
+ def tmp_path(*args)
39
+ File.join(dir_path('tmp'), *args)
40
+ end
41
+
42
+ def fixtures_path(*args)
43
+ File.join(dir_path('spec/fixtures'), *args)
44
+ end
45
+
46
+ def within_dir(target, &block)
47
+ ::Dir.chdir(target, &block)
48
+ end
49
+ end
50
+
51
+ module Silent
52
+ def silent_run(*args)
53
+ out = Tempfile.new('tty-cmd')
54
+ result = system(*args, out: out.path)
55
+ return if result
56
+ out.rewind
57
+ fail "#{args.join} failed:\n#{out.read}"
58
+ end
27
59
  end
28
60
  end
29
61
 
30
62
  RSpec.configure do |config|
31
- config.include(Helpers)
63
+ config.include(TestHelpers::Paths)
64
+ config.include(TestHelpers::Silent)
65
+ config.after(:example, type: :cli) do
66
+ FileUtils.rm_rf(tmp_path)
67
+ end
32
68
  config.run_all_when_everything_filtered = true
33
69
  config.filter_run :focus
34
- config.order = 'random'
70
+ config.order = :random
35
71
  config.raise_errors_for_deprecations!
36
- end
37
-
38
- class String
39
- def normalize
40
- gsub(/^[ \t]*/, '').chomp
41
- end
72
+ config.disable_monkey_patching!
42
73
  end