ngi 0.2.3 → 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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +7 -1
  3. data/bin/ngi +1 -31
  4. data/lib/config/{angular_init.config.json → backup/angular_init.config.json} +0 -0
  5. data/lib/config/backup/config.components.aliases.yml +3 -0
  6. data/lib/config/backup/config.components.yml +55 -0
  7. data/lib/config/backup/config.configurable.yml +1 -0
  8. data/lib/config/backup/config.languages.yml +5 -0
  9. data/lib/config/backup/config.yml +3 -0
  10. data/lib/config/backup/template-skeleton.js +93 -0
  11. data/lib/config/config.components.aliases.yml +3 -0
  12. data/lib/config/config.components.yml +55 -0
  13. data/lib/config/config.configurable.yml +2 -0
  14. data/lib/config/config.languages.yml +5 -0
  15. data/lib/config/config.yml +4 -0
  16. data/lib/ngi.rb +4 -7
  17. data/lib/ngi/configure.rb +236 -75
  18. data/lib/ngi/delegate.rb +3 -8
  19. data/lib/ngi/generator.rb +74 -46
  20. data/lib/ngi/parser.rb +97 -0
  21. data/lib/{templates → ngi/templates}/markup/html/default/index.html +0 -0
  22. data/lib/{templates → ngi/templates}/script/coffee/default/basic.js +0 -0
  23. data/lib/{templates → ngi/templates}/script/coffee/default/config.js +0 -0
  24. data/lib/{templates → ngi/templates}/script/coffee/default/constant.js +0 -0
  25. data/lib/{templates → ngi/templates}/script/coffee/default/module.js +0 -0
  26. data/lib/{templates → ngi/templates}/script/es5/default/basic.js +0 -0
  27. data/lib/{templates → ngi/templates}/script/es5/default/config.js +0 -0
  28. data/lib/{templates → ngi/templates}/script/es5/default/constant.js +0 -0
  29. data/lib/{templates → ngi/templates}/script/es5/default/module.js +0 -0
  30. data/lib/ngi/utils/command_parser.rb +90 -75
  31. data/lib/ngi/utils/current_dir.rb +20 -0
  32. data/lib/ngi/utils/jser.rb +45 -32
  33. data/lib/ngi/utils/user_input.rb +22 -0
  34. data/lib/ngi/utils/utils.rb +4 -21
  35. data/lib/ngi/version.rb +1 -1
  36. data/ngi.gemspec +2 -1
  37. data/test/config/config.components.aliases.yml +3 -0
  38. data/test/config/config.components.yml +55 -0
  39. data/test/config/config.configurable.yml +2 -0
  40. data/test/config/config.languages.yml +5 -0
  41. data/test/config/config.yml +4 -0
  42. data/test/finished_files/script/coffee/directive.finished.coffee +20 -0
  43. data/test/finished_files/script/es5/controller.finished.js +13 -0
  44. data/test/finished_files/script/es5/directive.finished.js +25 -0
  45. data/test/finished_files/script/es5/filter.finished.js +18 -0
  46. data/test/templates/markup/html/default/index.html +11 -0
  47. data/test/templates/script/coffee/default/basic.js +23 -0
  48. data/test/templates/script/coffee/default/config.js +12 -0
  49. data/test/templates/script/coffee/default/constant.js +7 -0
  50. data/test/templates/script/coffee/default/module.js +7 -0
  51. data/test/templates/script/es5/default/basic.js +29 -0
  52. data/test/templates/script/es5/default/config.js +13 -0
  53. data/test/templates/script/es5/default/constant.js +7 -0
  54. data/test/templates/script/es5/default/module.js +7 -0
  55. data/test/test_ngi.rb +274 -56
  56. data/test/testing_utils.rb +26 -0
  57. metadata +78 -36
  58. data/lib/dep/json.rb +0 -62
  59. data/lib/dep/json/add/bigdecimal.rb +0 -28
  60. data/lib/dep/json/add/complex.rb +0 -28
  61. data/lib/dep/json/add/core.rb +0 -11
  62. data/lib/dep/json/add/date.rb +0 -34
  63. data/lib/dep/json/add/date_time.rb +0 -50
  64. data/lib/dep/json/add/exception.rb +0 -31
  65. data/lib/dep/json/add/ostruct.rb +0 -31
  66. data/lib/dep/json/add/range.rb +0 -29
  67. data/lib/dep/json/add/rational.rb +0 -27
  68. data/lib/dep/json/add/regexp.rb +0 -30
  69. data/lib/dep/json/add/struct.rb +0 -30
  70. data/lib/dep/json/add/symbol.rb +0 -25
  71. data/lib/dep/json/add/time.rb +0 -38
  72. data/lib/dep/json/common.rb +0 -484
  73. data/lib/dep/json/ext.rb +0 -21
  74. data/lib/dep/json/ext/.keep +0 -0
  75. data/lib/dep/json/generic_object.rb +0 -70
  76. data/lib/dep/json/pure.rb +0 -21
  77. data/lib/dep/json/pure/generator.rb +0 -522
  78. data/lib/dep/json/pure/parser.rb +0 -359
  79. data/lib/dep/json/version.rb +0 -8
  80. data/test/sup/test.config.json +0 -100
@@ -3,20 +3,15 @@
3
3
  # github.com/joshbeam/angular_init
4
4
  # MIT License
5
5
 
6
- # CURRENT_DIR is defined in angualr_init.rb
7
-
8
- # require CURRENT_DIR+'/generator'
9
- # require CURRENT_DIR+'/configure'
10
-
11
- require_relative 'generator'
12
- require_relative 'configure'
13
-
14
6
  # Generator and Configure are "wrapped" in this class
15
7
  # that "delegates" (hence the name "Delegate")
16
8
  # the flow of control to either the Generator class
17
9
  # or the Configure class, based on the argument passed
18
10
  # in (which is handled by bin/ngi)
19
11
  class Delegate
12
+ require_relative 'generator'
13
+ require_relative 'configure'
14
+
20
15
  Generator = ::Generator
21
16
  Configure = ::Configure
22
17
  end
@@ -7,7 +7,20 @@ require_relative 'utils/utils'
7
7
 
8
8
  # This class generates templates (hence the name "Generator")
9
9
  class Generator
10
- Utils = ::Utils
10
+ # STDIN is separated into a class so that
11
+ # it can be extracted and tested
12
+ class AcceptInput
13
+ def self.str(type)
14
+ case type
15
+ when :condensed
16
+ $stdin.gets.gsub(WHITESPACE, EMPTY)
17
+ when :comma_delimited_to_array
18
+ $stdin.gets.split(',').map(&:strip).reject(&:empty?)
19
+ when :downcased
20
+ $stdin.gets.strip.downcase
21
+ end
22
+ end
23
+ end
11
24
 
12
25
  # Here we just implement
13
26
  # the virtual class Utils::AskLoop
@@ -15,7 +28,7 @@ class Generator
15
28
  def self.ask(args)
16
29
  print "\n#{args[:prompt]}"
17
30
 
18
- answer = $stdin.gets.strip.downcase
31
+ answer = AcceptInput.str(:downcased)
19
32
 
20
33
  loop do
21
34
  break if args[:check] == answer
@@ -29,29 +42,41 @@ class Generator
29
42
 
30
43
  WHITESPACE = /\s*/
31
44
  EMPTY = ''
32
- CURRENT_DIR = File.dirname(__FILE__)
45
+ Utils::CurrentDir.dir = File.dirname(__FILE__)
33
46
 
34
47
  ################################
35
48
 
36
49
  # SET UP ALL THE CONFIG OPTIONS
37
50
  # Generator.new (the initialization function) is called in self.run
38
51
 
39
- def initialize(args)
40
- @type, @config = args[:type], args[:config]['global']
52
+ # An extraction of the template file/directory for
53
+ # the generator... This way it can be separated, redefined,
54
+ # and tested.
55
+ class TemplateDir
56
+ attr_reader :dir
41
57
 
42
- component = @config['components'].find { |t| t['name'] == @type }
58
+ def initialize(component)
59
+ @dir = "#{Utils::CurrentDir.dir}/templates/"
60
+ @dir << "#{component['type']}/#{component['language']}"
61
+ @dir << "/#{component['using']}/#{component['template']}"
62
+ end
43
63
 
44
- # basically just rebuilding the object so we can use it here
45
- @component = {
46
- of_type: component['type'],
47
- language: @config['language'][component['type']],
48
- using: component['using'], template: component['template']
49
- }
64
+ def read
65
+ f = File.open(@dir)
66
+ content = f.read
67
+ f.close
50
68
 
51
- template_dir = "#{CURRENT_DIR}/../templates/"
52
- template_dir << "#{@component[:of_type]}/#{@component[:language]}/#{@component[:using]}/#{@component[:template]}"
69
+ content
70
+ end
71
+ end
72
+
73
+ def initialize(args)
74
+ @type, @config = args[:type], args[:config]
53
75
 
54
- @template_file = IO.read(template_dir)
76
+ @component = args[:component]
77
+ @component['language'] = @config['language'][@component['type']]
78
+
79
+ @template_file = TemplateDir.new(@component).read
55
80
 
56
81
  yield(self) if block_given?
57
82
  end
@@ -61,30 +86,30 @@ class Generator
61
86
  def new_file_name
62
87
  print '[?] New file name: '
63
88
 
64
- @new_file = $stdin.gets.gsub(WHITESPACE, EMPTY)
89
+ @new_file = AcceptInput.str(:condensed)
65
90
  end
66
91
 
67
92
  def module_name
68
93
  print '[?] Module name: '
69
94
 
70
- @module_name = $stdin.gets.gsub(WHITESPACE, EMPTY)
95
+ @module_name = AcceptInput.str(:condensed)
71
96
  end
72
97
 
73
98
  def name
74
99
  print "[?] #{@type.capitalize} name: "
75
100
 
76
- @name = $stdin.gets.gsub(WHITESPACE, EMPTY)
101
+ @name = AcceptInput.str(:condensed)
77
102
  end
78
103
 
79
104
  def inject
80
- # REVIEW: use symbols instead of strings?
81
105
  special = %w(routes controller).include?(@type)
82
106
  auto_injections = [
83
107
  { for_type: 'routes', service: '$routeProvider' },
84
108
  { for_type: 'controller', service: '$scope' }
85
109
  ]
86
110
 
87
- injection = special ? auto_injections.select { |inj| inj[:for_type] == @type }[0][:service] : nil
111
+ for_type = -> (inj) { inj[:for_type] == @type }
112
+ injection = special ? auto_injections.find(&for_type)[:service] : nil
88
113
 
89
114
  auto_injection_statement = special ? " (already injected #{injection})" : ''
90
115
 
@@ -93,42 +118,41 @@ class Generator
93
118
  # accepts a comma-delimited list
94
119
  # EXAMPLE: testService, testService2
95
120
  # => [testService,testService2]
96
- @dependencies = $stdin.gets.split(',').map(&:strip).reject(&:empty?)
97
-
98
- # automatically inject $scope into a controller
99
- # FIXME: don't use index accessors (numbers are confusing)
100
- @dependencies << auto_injections[1][:service] if @type == 'controller' && !@dependencies.include?(auto_injections[1][:service])
121
+ @dependencies = AcceptInput.str(:comma_delimited_to_array)
101
122
 
102
- # automatically insert $routeProvider into a routes config
103
- @dependencies << auto_injections[0][:service] if @type == 'routes' && !@dependencies.include?(auto_injections[0][:service])
123
+ @dependencies << injection unless injection.nil?
104
124
  end
105
125
 
106
126
  def replace
107
- # inject may or may not have run... if it wasn't run, then @dependencies was never set
108
- # for example, for html templates, we don't run the inject function
109
- # @dependencies = @dependencies || []
127
+ # inject may or may not have run...
128
+ # if it wasn't run, then @dependencies was never set
110
129
  @dependencies ||= []
111
130
  has_dependencies = @dependencies.size > 0
112
131
 
113
- # Use 'config' as the type, since 'routes' is really an alias for a specific type of 'config'.
114
132
  # TODO: map aliases from config file
115
133
  @type = 'config' if @type == 'routes'
116
134
 
117
135
  # Regex replacements to generate the template
136
+ cdv = lambda do |s, (dep, i)|
137
+ s + dep.to_s + (i == @dependencies.size - 1 ? '' : ', ')
138
+ end
139
+
140
+ array_string = has_dependencies ? @dependencies.to_s.gsub(/"/, '\'') : '[]'
141
+
142
+ if has_dependencies == true
143
+ cdv_string = @dependencies.each_with_index.inject('', &cdv)
144
+ else
145
+ cdv_string = ''
146
+ end
147
+
148
+ cdv_regex = /\{\{inject\s\|\scomma_delimited_variables\}\}/
149
+
118
150
  @template_file = @template_file
119
151
  .gsub(/\{\{type\}\}/, @type)
120
152
  .gsub(/\{\{name\}\}/, @name || '')
121
- .gsub(/\{\{module\}\}/, "#{@module_name}")
122
- .gsub(
123
- /\{\{inject\s\|\sarray_string\}\}/,
124
- has_dependencies ?
125
- @dependencies.to_s.gsub(/"/, '\'') : '[]'
126
- )
127
- .gsub(
128
- /\{\{inject\s\|\scomma_delimited_variables\}\}/,
129
- has_dependencies ?
130
- @dependencies.each_with_index.inject('') { |str, (dep, i)| str += dep.to_s + (i == @dependencies.size - 1 ? '' : ', ') } : ''
131
- )
153
+ .gsub(/\{\{module\}\}/, @module_name)
154
+ .gsub(/\{\{inject\s\|\sarray_string\}\}/, array_string)
155
+ .gsub(cdv_regex, cdv_string)
132
156
  end
133
157
 
134
158
  def tag
@@ -143,7 +167,9 @@ class Generator
143
167
  def write
144
168
  # create the new file
145
169
  def overwrite?
146
- AskLoop.ask(check: 'y', prompt: 'File exists already, overwrite it? (y/n) ')
170
+ AskLoop.ask(
171
+ check: 'y', prompt: 'File exists already, overwrite it? (y/n) '
172
+ )
147
173
  end
148
174
 
149
175
  overwrite? if File.exist?(@new_file)
@@ -154,8 +180,11 @@ class Generator
154
180
  end
155
181
  end
156
182
 
157
- # Use this function to be able to say AngularInit::Delegate::Generator.run() inside the executable file
158
- # This function simply goes through all of the methods in order to interactively
183
+ # Use this function to be able to say
184
+ # Ngi::Delegate::Generator.run() inside
185
+ # the executable file.
186
+ # This function simply goes through all of the
187
+ # methods in order to interactively
159
188
  # prompt the user to generate a new template
160
189
  def self.run(args)
161
190
  Generator.new(args) do |g|
@@ -165,7 +194,6 @@ class Generator
165
194
  g.module_name unless args[:type] == 'module'
166
195
 
167
196
  # 'run', 'config', and 'routes' don't have custom names in AngularJS
168
- # REVIEW: use symbols instead of strings?
169
197
  g.name unless %w(run config routes index).include? args[:type]
170
198
 
171
199
  g.inject unless ['index'].include? args[:type]
@@ -0,0 +1,97 @@
1
+
2
+ require_relative 'utils/utils'
3
+ require_relative 'delegate'
4
+ require_relative 'version'
5
+
6
+ # This class is just a wrapper for the main process
7
+ # of ngi
8
+ class Parser
9
+ CURRENT_DIR = File.dirname(__FILE__)
10
+
11
+ COMPONENTS_FILE = "#{CURRENT_DIR}/../config/config.components.yml"
12
+ COMPONENTS_HASH = Delegate::Configure
13
+ .new(COMPONENTS_FILE)
14
+ .to_ruby(from: 'yaml')
15
+ COMPONENTS = COMPONENTS_HASH.collect { |c| c['name'] }
16
+
17
+ CONFIG_FILE = "#{CURRENT_DIR}/../config/config.yml"
18
+ CONFIG_HASH = Delegate::Configure.new(CONFIG_FILE).to_ruby(from: 'yaml')
19
+
20
+ CONFIGURABLE_FILE = "#{CURRENT_DIR}/../config/config.configurable.yml"
21
+ CONFIGURABLE = Delegate::Configure
22
+ .new(CONFIGURABLE_FILE).to_ruby(from: 'yaml')
23
+
24
+ LANGUAGES_FILE = "#{CURRENT_DIR}/../config/config.languages.yml"
25
+ LANGUAGES_HASH = Delegate::Configure.new(LANGUAGES_FILE).to_ruby(from: 'yaml')
26
+
27
+ # Abstraction to choose the component (custom or default)
28
+ class ComponentChooser
29
+ attr_reader :component
30
+
31
+ def initialize(args)
32
+ chosen_type = -> (c) { c['name'] == args[:type] }
33
+ @component = args[:components_hash].find(&chosen_type)
34
+
35
+ return unless args[:config_hash].key? 'templates'
36
+
37
+ custom = args[:config_hash]['templates'].find(&chosen_type)
38
+ language = args[:config_hash]['language'].collect { |_, v| v }
39
+
40
+ return if custom.nil?
41
+
42
+ template = custom['templates']
43
+ .find { |t| language.include? t['language'] }
44
+
45
+ return if template.nil?
46
+
47
+ template = template['template']
48
+ # Rebuild the object to be used by Delegate::Generator
49
+ custom = {
50
+ 'type' => custom['type'], 'using' => 'user',
51
+ 'template' => template, 'name' => custom['name']
52
+ }
53
+
54
+ @component = custom
55
+ end
56
+ end
57
+
58
+ def self.parse(args)
59
+ p = Utils::CommandParser.new do |parser|
60
+ components = Utils::UserInput.new(valid_inputs: COMPONENTS)
61
+
62
+ parser.name, parser.version = 'ngi', Ngi::VERSION
63
+ parser.banner << "\n(<command> can be one of the following)"
64
+
65
+ parser.on(components.valid_inputs, 'Create a new component') do |type|
66
+ component = ComponentChooser
67
+ .new(
68
+ type: type,
69
+ components_hash: COMPONENTS_HASH,
70
+ config_hash: CONFIG_HASH
71
+ )
72
+ .component
73
+
74
+ Delegate::Generator.run(
75
+ type: type,
76
+ config: CONFIG_HASH,
77
+ component: component
78
+ )
79
+ end
80
+
81
+ parser.on(['-o', '--options'], 'Configure ngi') do
82
+ Delegate::Configure.run(
83
+ write: true,
84
+ to: 'yaml',
85
+ destination: CONFIG_FILE,
86
+ languages: LANGUAGES_HASH,
87
+ config: CONFIG_HASH,
88
+ components: COMPONENTS,
89
+ components_hash: COMPONENTS_HASH,
90
+ configurable: CONFIGURABLE
91
+ )
92
+ end
93
+ end
94
+
95
+ p.parse(args)
96
+ end
97
+ end
@@ -3,99 +3,114 @@
3
3
  # github.com/joshbeam/angular_init
4
4
  # MIT License
5
5
 
6
- # Similar to Ruby's OptionParser
7
- # However, this is customized for angular_init
8
- class CommandParser
9
- attr_reader :args
10
- attr_accessor :banner, :version, :separator, :name
11
-
12
- def initialize
13
- # TODO: to "Usage #{file_name}", etc.
14
- @name = '<CLI>'
15
- @banner = "Usage: #{@name} <command>"
16
- @version = '0.0.0'
17
- @separator = '===================='
18
- @listeners = []
19
-
20
- # automatically register some listeners
21
- register_help
22
- register_version
23
-
24
- # be able to pass in a block for setup
25
- yield(self) if block_given?
26
- end
6
+ # Utilities
7
+ module Utils
8
+ # Similar to Ruby's OptionParser
9
+ # However, this is customized for angular_init
10
+ class CommandParser
11
+ attr_reader :args
12
+ attr_accessor :banner, :version, :separator, :name
13
+
14
+ # Create an abstraction of puts
15
+ # so that we can test it
16
+ class Output
17
+ def initialize(str)
18
+ @str = str
19
+ end
27
20
 
28
- def name=(name)
29
- # need to also replace the name in the banner
30
- @banner = @banner.gsub(@name, name)
21
+ def to_s
22
+ puts @str
23
+ end
24
+ end
31
25
 
32
- @name = name
33
- end
26
+ def initialize
27
+ # TODO: to "Usage #{file_name}", etc.
28
+ @name = '<CLI>'
29
+ @banner = "Usage: #{@name} <command>"
30
+ @version = '0.0.0'
31
+ @separator = '===================='
32
+ @listeners = []
34
33
 
35
- # register the listeners
36
- def on(options, description = '', &block)
37
- listener = {}
34
+ # automatically register some listeners
35
+ register_help
36
+ register_version
38
37
 
39
- # be able to pass in a single argument, or an array of arguments
40
- options = *options unless options.is_a? Array
38
+ # be able to pass in a block for setup
39
+ yield(self) if block_given?
40
+ end
41
+
42
+ def name=(name)
43
+ # need to also replace the name in the banner
44
+ @banner = @banner.gsub(@name, name)
41
45
 
42
- listener[:options] = options.map do |opt|
43
- opt.strip.split(' ')
46
+ @name = name
44
47
  end
45
48
 
46
- listener[:block] = block
47
- listener[:description] = description
49
+ # register the listeners
50
+ def on(options, description = '', &block)
51
+ listener = {}
48
52
 
49
- @listeners << listener
50
- end
53
+ # be able to pass in a single argument, or an array of arguments
54
+ options = *options unless options.is_a? Array
51
55
 
52
- def parse(args)
53
- # puts @listeners
54
- matched_listener = {
55
- options: nil,
56
- block: nil
57
- }
58
-
59
- @listeners.each do |listener|
60
- listener[:options].each do |opt_arr|
61
- if opt_arr == args
62
- matched_listener[:options] = opt_arr
63
- matched_listener[:block] = listener[:block]
64
- break
65
- end
56
+ listener[:options] = options.map do |opt|
57
+ opt.strip.split(' ')
66
58
  end
59
+
60
+ listener[:block] = block
61
+ listener[:description] = description
62
+
63
+ @listeners << listener
67
64
  end
68
65
 
69
- if !matched_listener[:options].nil?
70
- # matched_listener[:options] should always be an array
71
- # when we call, we can each member of that array to be
72
- # passed separately
73
- matched_listener[:block].call(*matched_listener[:options])
74
- else
75
- # if there was no match, show the help menu
76
- parse(['-h'])
66
+ def parse(args)
67
+ # puts @listeners
68
+ matched_listener = {
69
+ options: nil,
70
+ block: nil
71
+ }
72
+
73
+ @listeners.each do |listener|
74
+ listener[:options].each do |opt_arr|
75
+ if opt_arr == args
76
+ matched_listener[:options] = opt_arr
77
+ matched_listener[:block] = listener[:block]
78
+ break
79
+ end
80
+ end
81
+ end
82
+
83
+ if !matched_listener[:options].nil?
84
+ # matched_listener[:options] should always be an array
85
+ # when we call, we can each member of that array to be
86
+ # passed separately
87
+ matched_listener[:block].call(*matched_listener[:options])
88
+ else
89
+ # if there was no match, show the help menu
90
+ parse(['-h'])
91
+ end
77
92
  end
78
- end
79
93
 
80
- def register_help
81
- # automaticaly register this listener
82
- on(['-h', '--help'], 'Show the help menu') do
83
- puts @separator
84
- puts @banner
94
+ def register_help
95
+ # automaticaly register this listener
96
+ on(['-h', '--help'], 'Show the help menu') do
97
+ Output.new(@separator).to_s
98
+ Output.new(@banner).to_s
85
99
 
86
- @listeners.each_with_index do |listener, i|
87
- desc = "\n" << "(#{i + 1}) #{listener[:description]}: "
88
- desc << "#{listener[:options].join(', ')}"
89
- puts desc
100
+ @listeners.each_with_index do |listener, i|
101
+ desc = "\n" << "(#{i + 1}) #{listener[:description]}: "
102
+ desc << "#{listener[:options].join(', ')}"
103
+ Output.new(desc).to_s
104
+ end
105
+ Output.new(@separator).to_s
90
106
  end
91
- puts @separator
92
107
  end
93
- end
94
108
 
95
- def register_version
96
- # automaticaly register this listener
97
- on(['-v', '--version'], 'Show the version') do
98
- puts "#{@name} #{@version}"
109
+ def register_version
110
+ # automaticaly register this listener
111
+ on(['-v', '--version'], 'Show the version') do
112
+ Output.new("#{@name} #{@version}").to_s
113
+ end
99
114
  end
100
115
  end
101
116
  end