tty 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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