simple_commander 0.0.1 → 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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.byebug_history +15 -0
  3. data/.rubocop.yml +9 -0
  4. data/.rubocop_todo.yml +77 -0
  5. data/.travis.yml +6 -0
  6. data/Gemfile +1 -0
  7. data/History.rdoc +3 -0
  8. data/bin/simple_commander +1 -1
  9. data/coverage/.last_run.json +5 -0
  10. data/coverage/.resultset.json +1660 -0
  11. data/coverage/.resultset.json.lock +0 -0
  12. data/dir_glob.rb +7 -8
  13. data/ember_c +7 -38
  14. data/helper.rb +5 -0
  15. data/helpers/http_helper.rb +5 -0
  16. data/lib/simple_commander/command.rb +3 -3
  17. data/lib/simple_commander/configure.rb +2 -2
  18. data/lib/simple_commander/core_ext.rb +2 -2
  19. data/lib/simple_commander/delegates.rb +4 -3
  20. data/lib/simple_commander/help_formatters/base.rb +1 -1
  21. data/lib/simple_commander/help_formatters/terminal.rb +1 -1
  22. data/lib/simple_commander/help_formatters/terminal_compact.rb +1 -1
  23. data/lib/simple_commander/help_formatters.rb +4 -4
  24. data/lib/simple_commander/helpers/io.rb +128 -0
  25. data/lib/simple_commander/helpers.rb +1 -0
  26. data/lib/simple_commander/import.rb +1 -1
  27. data/lib/simple_commander/methods.rb +4 -4
  28. data/lib/simple_commander/platform.rb +1 -1
  29. data/lib/simple_commander/runner.rb +28 -6
  30. data/lib/simple_commander/user_interaction.rb +2 -2
  31. data/lib/simple_commander/version.rb +2 -2
  32. data/lib/simple_commander.rb +1 -0
  33. data/simple_commander.gemspec +2 -1
  34. data/spec/command_spec.rb +157 -0
  35. data/spec/configure_spec.rb +37 -0
  36. data/spec/core_ext/array_spec.rb +18 -0
  37. data/spec/core_ext/object_spec.rb +19 -0
  38. data/spec/help_formatters/terminal_compact_spec.rb +69 -0
  39. data/spec/help_formatters/terminal_spec.rb +67 -0
  40. data/spec/methods_spec.rb +20 -0
  41. data/spec/runner_spec.rb +659 -0
  42. data/spec/spec_helper.rb +82 -0
  43. data/spec/ui_spec.rb +30 -0
  44. data/test.rb +24 -0
  45. data/todo.yml +16 -4
  46. metadata +37 -2
File without changes
data/dir_glob.rb CHANGED
@@ -4,13 +4,12 @@ require 'fileutils'
4
4
  FileUtils.rm('Manifest')
5
5
 
6
6
  def glob(path)
7
- return if !File.directory?(path) && path != "**"
8
- path = "#{path}/*"
9
- Dir.glob(path) do |file|
10
- File.open("Manifest", 'a') {|f| f.write("#{file}\n") }
11
- glob(file)
12
- end
7
+ return if !File.directory?(path) && path != '**'
8
+ path = "#{path}/*"
9
+ Dir.glob(path) do |file|
10
+ File.open('Manifest', 'a') { |f| f.write("#{file}\n") }
11
+ glob(file)
12
+ end
13
13
  end
14
14
 
15
- glob("**")
16
-
15
+ glob('**')
data/ember_c CHANGED
@@ -1,54 +1,23 @@
1
1
  #!/usr/bin/env ruby
2
- require 'byebug'
3
- require 'simple_commander/import'
2
+ $LOAD_PATH.unshift File.expand_path './lib'
4
3
 
4
+ require 'simple_commander/import'
5
+ require './helpers/http_helper'
5
6
 
6
7
  program :name, 'ember-c'
7
8
  program :version, '0.0.1'
8
9
  program :description, 'implementing ember with modified commander'
10
+ helpers 'IO', 'HTTP'
9
11
 
10
12
  command :new do
11
13
  syntax = 'ember-c new <name>'
12
14
  summary = 'create a new ember project'
13
15
  description = 'Create a new ember project'
14
16
  action do |args, options|
15
- puts args[0]
16
- global
17
- end
18
- end
19
-
20
-
21
- command :this do
22
- command :is do
23
- command :ok do
24
- command :dont do
25
- command :worry do
26
- action do
27
- puts "this is ok dont worry"
28
- end
29
- end
30
- end
31
-
32
- command :also do
33
- action do
34
- puts "this is ok also"
35
- end
36
- end
17
+ run_cmd(File.expand_path './') do
18
+ say `ls`
37
19
  end
38
- end
39
- end
40
-
41
- command :parent do
42
- command :child do
43
- action do |args, options|
44
- puts 'nested child'
45
- end
46
- end
47
- end
48
-
49
- command 'do this' do
50
- action do |args, options|
51
- puts "do this!"
20
+ http_get
52
21
  end
53
22
  end
54
23
 
data/helper.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Helper
2
+ def testing
3
+ say 'testing!!!'
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module HTTP_helper
2
+ def http_get
3
+ say "HTTP GET"
4
+ end
5
+ end
@@ -1,6 +1,6 @@
1
1
  require 'optparse'
2
2
 
3
- module Commander
3
+ module SimpleCommander
4
4
  class Command
5
5
  attr_accessor :name, :examples, :syntax, :description, :super_self
6
6
  attr_accessor :summary, :proxy_options, :options
@@ -28,7 +28,7 @@ module Commander
28
28
  end
29
29
 
30
30
  def inspect
31
- "<Commander::Command::Options #{ __hash__.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') }>"
31
+ "<SimpleCommander::Command::Options #{ __hash__.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') }>"
32
32
  end
33
33
  end
34
34
 
@@ -218,7 +218,7 @@ module Commander
218
218
  end
219
219
 
220
220
  def inspect
221
- "<Commander::Command:#{name}>"
221
+ "<SimpleCommander::Command:#{name}>"
222
222
  end
223
223
  end
224
224
  end
@@ -1,7 +1,7 @@
1
- module Commander
1
+ module SimpleCommander
2
2
  def configure(*configuration_opts, &configuration_block)
3
3
  configuration_module = Module.new
4
- configuration_module.extend Commander::Methods
4
+ configuration_module.extend SimpleCommander::Methods
5
5
 
6
6
  configuration_module.class_exec(*configuration_opts, &configuration_block)
7
7
 
@@ -1,2 +1,2 @@
1
- require 'commander/core_ext/array'
2
- require 'commander/core_ext/object'
1
+ require 'simple_commander/core_ext/array'
2
+ require 'simple_commander/core_ext/object'
@@ -1,9 +1,10 @@
1
- module Commander
1
+ module SimpleCommander
2
2
  module Delegates
3
3
  %w(
4
4
  add_command
5
5
  command
6
6
  program
7
+ helpers
7
8
  run!
8
9
  global_option
9
10
  alias_command
@@ -13,13 +14,13 @@ module Commander
13
14
  ).each do |meth|
14
15
  eval <<-END, binding, __FILE__, __LINE__
15
16
  def #{meth}(*args, &block)
16
- ::Commander::Runner.instance.#{meth}(*args, &block)
17
+ ::SimpleCommander::Runner.instance.#{meth}(*args, &block)
17
18
  end
18
19
  END
19
20
  end
20
21
 
21
22
  def defined_commands(*args, &block)
22
- ::Commander::Runner.instance.commands(*args, &block)
23
+ ::SimpleCommander::Runner.instance.commands(*args, &block)
23
24
  end
24
25
  end
25
26
  end
@@ -1,4 +1,4 @@
1
- module Commander
1
+ module SimpleCommander
2
2
  ##
3
3
  # = Help Formatter
4
4
  #
@@ -1,6 +1,6 @@
1
1
  require 'erb'
2
2
 
3
- module Commander
3
+ module SimpleCommander
4
4
  module HelpFormatter
5
5
  class Terminal < Base
6
6
  def render
@@ -1,6 +1,6 @@
1
1
  require 'erb'
2
2
 
3
- module Commander
3
+ module SimpleCommander
4
4
  module HelpFormatter
5
5
  class TerminalCompact < Terminal
6
6
  def template(name)
@@ -1,8 +1,8 @@
1
- module Commander
1
+ module SimpleCommander
2
2
  module HelpFormatter
3
- autoload :Base, 'commander/help_formatters/base'
4
- autoload :Terminal, 'commander/help_formatters/terminal'
5
- autoload :TerminalCompact, 'commander/help_formatters/terminal_compact'
3
+ autoload :Base, 'simple_commander/help_formatters/base'
4
+ autoload :Terminal, 'simple_commander/help_formatters/terminal'
5
+ autoload :TerminalCompact, 'simple_commander/help_formatters/terminal_compact'
6
6
 
7
7
  class Context
8
8
  def initialize(target)
@@ -0,0 +1,128 @@
1
+ require 'erb'
2
+
3
+ module IO_helper
4
+ def run_cmd(path)
5
+ FileUtils.cd(path) do
6
+ yield
7
+ end
8
+ end
9
+
10
+ def mkdir(dest)
11
+ if(File.directory?(dest))
12
+ puts "#{dest} already exist!"
13
+ return 0
14
+ end
15
+ FileUtils.mkdir(dest)
16
+ end
17
+
18
+ def copy(src, dest)
19
+ FileUtils.cp(src, dest)
20
+ end
21
+
22
+ def copy_dir(src, dest)
23
+ FileUtils.copy_entry(src, dest)
24
+ end
25
+
26
+ def template(src, dest, replace=false)
27
+ if(File.file?(dest) and !replace)
28
+ puts "#{dest} already exist!"
29
+ return 0
30
+ end
31
+ template = File.open(src, 'r')
32
+ file_contents = template.read
33
+ template.close
34
+ renderer = ERB.new(file_contents)
35
+ result = renderer.result(binding)
36
+ output = File.open(dest, 'w+')
37
+ output.write(result)
38
+ output.close
39
+ end
40
+
41
+ def rm_file(path)
42
+ FileUtils.remove_file path
43
+ end
44
+
45
+ def rm_dir(path)
46
+ FileUtils.rmdir path
47
+ end
48
+
49
+ def in_file?(string, path)
50
+ regexp, content = Regexp.new string
51
+ File.open(path, 'r'){|f| content = f.read }
52
+ content =~ regexp
53
+ end
54
+
55
+ def write_start(string, path)
56
+ lines = []
57
+ File.open(path, 'r'){|f| lines = f.readlines }
58
+ lines.unshift("#{string}\n")
59
+ File.open(path, 'w+'){|f| f.write(lines.join)}
60
+ end
61
+
62
+ def write_end(string, path)
63
+ lines = []
64
+ File.open(path, 'r'){|f| lines = f.readlines }
65
+ lines << "#{string}\n"
66
+ File.open(path, 'w+'){|f| f.write(lines.join)}
67
+ end
68
+
69
+ def write_after(id, string, path)
70
+ lines = []
71
+ File.open(path, 'r'){|f| lines = f.readlines }
72
+ new_lines = lines.inject([]) do |result, value|
73
+ if value.include? id
74
+ result << value
75
+ result << "#{string}\n"
76
+ else
77
+ result << value
78
+ end
79
+ end
80
+ File.open(path, 'w+'){|f| f.write(new_lines.join)}
81
+ end
82
+
83
+ def rm_string(string, path)
84
+ regexp = Regexp.new string
85
+ lines = []
86
+ File.open(path, 'r'){|f| lines = f.readlines }
87
+ new_lines = lines.reject{|line| line =~ regexp }
88
+ File.open(path, 'w+'){|f| f.write(new_lines.join)}
89
+ end
90
+
91
+ def rm_block(start_id, end_id, path)
92
+ start_regexp = Regexp.new start_id
93
+ end_regexp = Regexp.new end_id
94
+ lines, new_lines, result = [], [], true
95
+ File.open(path, 'r'){|f| lines = f.readlines }
96
+ lines.chunk { |line|
97
+ if line =~ start_regexp
98
+ result = false
99
+ elsif line =~ end_regexp
100
+ result = true
101
+ end
102
+ result
103
+ }.each{ |result, arr|
104
+ if result
105
+ arr[0] =~ end_regexp ? arr.shift : arr
106
+ new_lines << arr
107
+ end
108
+ }
109
+ File.open(path, 'w+'){|f| f.write(new_lines.join)}
110
+ end
111
+
112
+ def cli_exist?(path, cli)
113
+ File.directory?("#{path}/#{cli}")
114
+ end
115
+
116
+ def command_exist?(path, command)
117
+ File.file?("#{path}/subcommands/#{command}.rb")
118
+ end
119
+
120
+ def subcommand_exist?(path, command, subcommand)
121
+ File.file?("#{path}/subcommands/#{command}/#{command}_#{subcommand}.rb")
122
+ end
123
+
124
+ def have_subcommands?(path, cli, command)
125
+ in_file? /register/,
126
+ "#{path}/#{cli}/subcommands/#{command}.rb"
127
+ end
128
+ end
@@ -0,0 +1 @@
1
+ require 'simple_commander/helpers/io'
@@ -1,5 +1,5 @@
1
1
  require 'simple_commander'
2
2
 
3
- include Commander::Methods
3
+ include SimpleCommander::Methods
4
4
 
5
5
  at_exit { run! }
@@ -1,8 +1,8 @@
1
- module Commander
1
+ module SimpleCommander
2
2
  module Methods
3
- include Commander::UI
4
- include Commander::UI::AskForClass
5
- include Commander::Delegates
3
+ include SimpleCommander::UI
4
+ include SimpleCommander::UI::AskForClass
5
+ include SimpleCommander::Delegates
6
6
 
7
7
  if $stdin.tty? && (cols = $terminal.output_cols) >= 40
8
8
  $terminal.wrap_at = cols - 5
@@ -1,4 +1,4 @@
1
- module Commander
1
+ module SimpleCommander
2
2
  module Platform
3
3
  def self.jruby?
4
4
  defined?(RUBY_ENGINE) && (RUBY_ENGINE == 'jruby')
@@ -1,6 +1,6 @@
1
1
  require 'optparse'
2
2
 
3
- module Commander
3
+ module SimpleCommander
4
4
  class Runner
5
5
  #--
6
6
  # Exceptions
@@ -8,6 +8,7 @@ module Commander
8
8
 
9
9
  class CommandError < StandardError; end
10
10
  class InvalidCommandError < CommandError; end
11
+ class UndefinedHelperError < StandardError; end
11
12
 
12
13
  ##
13
14
  # Array of commands.
@@ -36,6 +37,28 @@ module Commander
36
37
  @never_trace = false
37
38
  create_default_commands
38
39
  end
40
+
41
+ ##
42
+ # search in the helpers folders for the helpers module
43
+ # and include in the runner
44
+
45
+ def helpers(*args)
46
+ args.each do |h|
47
+ helper_name = "#{h}_helper"
48
+ fail UndefinedHelperError, "Invalid helper #{helper_name}",
49
+ caller if !helper_exist? helper_name
50
+ SimpleCommander::Runner.send(:include,
51
+ Object.const_get(helper_name))
52
+ end
53
+ end
54
+
55
+ ##
56
+ # check if the helper exist
57
+
58
+ def helper_exist?(helper)
59
+ Object.const_defined?(helper) &&
60
+ Object.const_get(helper).instance_of?(::Module)
61
+ end
39
62
 
40
63
  ##
41
64
  # Return singleton Runner instance.
@@ -64,11 +87,11 @@ module Commander
64
87
  global_option('-t', '--trace', 'Display backtrace when an error occurs') { trace = true } unless @never_trace || @always_trace
65
88
  parse_global_options
66
89
  remove_global_options options, @args
67
- have_action?
68
90
  if trace
69
91
  run_active_command
70
92
  else
71
93
  begin
94
+ have_action?
72
95
  run_active_command
73
96
  rescue InvalidCommandError => e
74
97
  abort "#{e}. Use --help for more information"
@@ -91,6 +114,7 @@ module Commander
91
114
  # tests if the current active command have an action block
92
115
 
93
116
  def have_action?
117
+ require_valid_command
94
118
  goto_child_command if active_command.has_no_action?
95
119
  end
96
120
 
@@ -187,14 +211,12 @@ module Commander
187
211
  #
188
212
 
189
213
  def command(name, &block)
190
- Commander::Command.new(name).tap do |cmd|
214
+ SimpleCommander::Command.new(name).tap do |cmd|
191
215
  add_command(cmd) if block
192
216
  cmd.super_self = self
193
217
  cmd.instance_eval &block if block
194
218
  end
195
- #add_command(Commander::Command.new(name)) if block
196
- #yield add_command(Commander::Command.new(name)) if block
197
- @commands[name.to_s]
219
+ @commands[name.to_s]
198
220
  end
199
221
 
200
222
  ##
@@ -1,7 +1,7 @@
1
1
  require 'tempfile'
2
2
  require 'shellwords'
3
3
 
4
- module Commander
4
+ module SimpleCommander
5
5
  ##
6
6
  # = User Interaction
7
7
  #
@@ -257,7 +257,7 @@ module Commander
257
257
 
258
258
  def ask_editor(input = nil, preferred_editor = nil)
259
259
  editor = available_editor preferred_editor
260
- program = Commander::Runner.instance.program(:name).downcase rescue 'commander'
260
+ program = SimpleCommander::Runner.instance.program(:name).downcase rescue 'commander'
261
261
  tmpfile = Tempfile.new program
262
262
  begin
263
263
  tmpfile.write input if input
@@ -1,3 +1,3 @@
1
- module Commander
2
- VERSION = '0.0.1'
1
+ module SimpleCommander
2
+ VERSION = '0.1.0'
3
3
  end
@@ -32,4 +32,5 @@ require 'simple_commander/help_formatters'
32
32
  require 'simple_commander/platform'
33
33
  require 'simple_commander/delegates'
34
34
  require 'simple_commander/methods'
35
+ require 'simple_commander/helpers'
35
36
  require 'simple_commander/configure'
@@ -4,7 +4,7 @@ require 'simple_commander/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'simple_commander'
7
- s.version = Commander::VERSION
7
+ s.version = SimpleCommander::VERSION
8
8
  s.authors = ['Marcell Monteiro Cruz']
9
9
  s.email = ['0000marcell@gmail.com']
10
10
  s.license = 'MIT'
@@ -15,6 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
16
16
  s.require_paths = ['lib']
17
17
  s.license = 'MIT'
18
+ s.add_runtime_dependency('highline', '~> 1.7.2')
18
19
  s.add_development_dependency('rspec', '~> 3.2')
19
20
  s.add_development_dependency('rake')
20
21
  s.add_development_dependency('simplecov')
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleCommander::Command do
4
+ include SimpleCommander::Methods
5
+
6
+ before :each do
7
+ mock_terminal
8
+ create_test_command
9
+ end
10
+
11
+ describe 'Options' do
12
+ before :each do
13
+ @options = SimpleCommander::Command::Options.new
14
+ end
15
+
16
+ it 'should act like an open struct' do
17
+ @options.send = 'mail'
18
+ @options.call = true
19
+ expect(@options.send).to eq('mail')
20
+ expect(@options.call).to eq(true)
21
+ end
22
+
23
+ it 'should allow __send__ to function as always' do
24
+ @options.send = 'foo'
25
+ expect(@options.__send__(:send)).to eq('foo')
26
+ end
27
+ end
28
+
29
+ describe '#option' do
30
+ it 'should add options' do
31
+ expect { @command.option '--recursive' }.to change(@command.options, :length).from(1).to(2)
32
+ end
33
+
34
+ it 'should allow procs as option handlers' do
35
+ @command.option('--recursive') { |recursive| expect(recursive).to be true }
36
+ @command.run '--recursive'
37
+ end
38
+
39
+ it 'should allow usage of common method names' do
40
+ @command.option '--open file'
41
+ @command.when_called { |_, options| expect(options.open).to eq('foo') }
42
+ @command.run '--open', 'foo'
43
+ end
44
+ end
45
+
46
+ describe '#run' do
47
+ describe 'should invoke #when_called' do
48
+ it 'with arguments seperated from options' do
49
+ @command.when_called { |args, _options| expect(args.join(' ')).to eq('just some args') }
50
+ @command.run '--verbose', 'just', 'some', 'args'
51
+ end
52
+
53
+ it 'calling the #call method by default when an object is called' do
54
+ object = double 'Object'
55
+ expect(object).to receive(:call).once
56
+ @command.when_called object
57
+ @command.run 'foo'
58
+ end
59
+
60
+ it 'should allow #action as an alias to #when_called' do
61
+ object = double 'Object'
62
+ expect(object).to receive(:call).once
63
+ @command.action object
64
+ @command.run 'foo'
65
+ end
66
+
67
+ it 'calling an arbitrary method when an object is called' do
68
+ object = double 'Object'
69
+ expect(object).to receive(:foo).once
70
+ @command.when_called object, :foo
71
+ @command.run 'foo'
72
+ end
73
+
74
+ it 'should raise an error when no handler is present' do
75
+ expect { @command.when_called }.to raise_error(ArgumentError)
76
+ end
77
+ end
78
+
79
+ describe 'should populate options with' do
80
+ it 'boolean values' do
81
+ @command.option '--[no-]toggle'
82
+ @command.when_called { |_, options| expect(options.toggle).to be true }
83
+ @command.run '--toggle'
84
+ @command.when_called { |_, options| expect(options.toggle).to be false }
85
+ @command.run '--no-toggle'
86
+ end
87
+
88
+ it 'mandatory arguments' do
89
+ @command.option '--file FILE'
90
+ @command.when_called { |_, options| expect(options.file).to eq('foo') }
91
+ @command.run '--file', 'foo'
92
+ expect { @command.run '--file' }.to raise_error(OptionParser::MissingArgument)
93
+ end
94
+
95
+ describe 'optional arguments' do
96
+ before do
97
+ @command.option '--use-config [file] '
98
+ end
99
+
100
+ it 'should return the argument when provided' do
101
+ @command.when_called { |_, options| expect(options.use_config).to eq('foo') }
102
+ @command.run '--use-config', 'foo'
103
+ end
104
+
105
+ it 'should return true when present without an argument' do
106
+ @command.when_called { |_, options| expect(options.use_config).to be true }
107
+ @command.run '--use-config'
108
+ end
109
+
110
+ it 'should return nil when not present' do
111
+ @command.when_called { |_, options| expect(options.use_config).to be_nil }
112
+ @command.run
113
+ end
114
+ end
115
+
116
+ describe 'typed arguments' do
117
+ before do
118
+ @command.option '--interval N', Integer
119
+ end
120
+
121
+ it 'should parse valid values' do
122
+ @command.when_called { |_, options| expect(options.interval).to eq(5) }
123
+ @command.run '--interval', '5'
124
+ end
125
+
126
+ it 'should reject invalid values' do
127
+ expect { @command.run '--interval', 'invalid' }.to raise_error(OptionParser::InvalidArgument)
128
+ end
129
+ end
130
+
131
+ it 'lists' do
132
+ @command.option '--fav COLORS', Array
133
+ @command.when_called { |_, options| expect(options.fav).to eq(%w(red green blue)) }
134
+ @command.run '--fav', 'red,green,blue'
135
+ end
136
+
137
+ it 'lists with multi-word items' do
138
+ @command.option '--fav MOVIES', Array
139
+ @command.when_called { |_, options| expect(options.fav).to eq(['super\ bad', 'nightmare']) }
140
+ @command.run '--fav', 'super\ bad,nightmare'
141
+ end
142
+
143
+ it 'defaults' do
144
+ @command.option '--files LIST', Array
145
+ @command.option '--interval N', Integer
146
+ @command.when_called do |_, options|
147
+ options.default \
148
+ files: %w(foo bar),
149
+ interval: 5
150
+ expect(options.files).to eq(%w(foo bar))
151
+ expect(options.interval).to eq(15)
152
+ end
153
+ @command.run '--interval', '15'
154
+ end
155
+ end
156
+ end
157
+ end