ngi 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 119801cbccb57371891100b9178b947823859d00
4
- data.tar.gz: b129e85c5cc365c3e4fc2f2672fe1c0e40ca7506
3
+ metadata.gz: c3e2d5d2fceb01e3e06c14c3580561bd3a15329f
4
+ data.tar.gz: 3fa569d585f690a60ee5bb6c52567620d167310b
5
5
  SHA512:
6
- metadata.gz: 255746a7d8b4dcf7c23f38cae6829adba8631860c9c8da90c48583ffd446889c541f362456d5237d3a2c63c1b51f7084832b37439610f39d907f9492bce3ac19
7
- data.tar.gz: e6fd90484636fc1a66ec48dfe7082022c8f80795edf6538701af40fa68cbaebea07ae53a3b72723a0820ab01fa3409f54249056efeefbd554315bc90e7b4ad03
6
+ metadata.gz: 114412c6662f27aebef62423bdf4d91b9b4bafec03b4938fefa9789470e44f4c1ffda7f9468c1e2072b85113bf91421ced34add0dd39587ff0fdeb024b5f8bce
7
+ data.tar.gz: 5dc112cf93b96791658c9100656d3c0f37513bab2f49c68a67e87e7b9a7b375c10b7cbd1ea45598587caa3dc67da3a6e4cba6e22546dbdbe774c36b4fe0b6825
data/README.md CHANGED
@@ -1,8 +1,26 @@
1
- # angular_init 0.2.0
1
+ # angular_init 0.2.2
2
+
3
+ ## Quick Start
4
+
5
+ ngi creates AngularJS templates for you from the command line.
6
+
7
+ **Get up and running in seconds:**
8
+
9
+ [![Gem Version](https://badge.fury.io/rb/ngi.svg)](http://badge.fury.io/rb/ngi)
10
+
11
+ ```shell
12
+ $ gem install ngi
13
+ $ cd ~/MyAwesomeApp # => go to your app
14
+ $ ngi controller # => creates a new AngularJS controller
15
+ ```
16
+
17
+ ## Know everything
2
18
 
3
19
  <a href="http://joshbeam.github.io/angular_init">Website</a>
4
20
 
5
- **What's different?**
21
+ **Having issues?** Email me (Josh) at <a href="mailto:frontendcollisionblog@gmail.com">frontendcollisionblog@gmail.com</a>. I'll usually respond within an hour or so. You can also report a bug by opening a new issue through GitHub, or if you want to add a feature yourself, just fork and submit a pull request!
22
+
23
+ **What's new in 0.2.x?**
6
24
  - Install it as a gem (`gem install ngi`)
7
25
  - You can now make an `index` boilerplate HTML page (`ngi index`)
8
26
  - Use `ngi -h` to see all commands
@@ -46,7 +64,7 @@ After you [do the 1-step installation][install] of `ngi` (the short-name for the
46
64
  # all done!
47
65
  ```
48
66
 
49
- ## Output (your new boilerplate code)
67
+ ## Output (new boilerplate code)
50
68
 
51
69
  ```javascript
52
70
  // ~/MyAwesomeApp/myAwesome.controller.js
@@ -78,6 +96,7 @@ By the way, the output of this little tool is meant to follow [John Papa's Angul
78
96
  ## Coming soon
79
97
 
80
98
  - Add custom templates and languages
99
+ - Possible Node.js version
81
100
 
82
101
  Feel free to fork the project or get <a href="http://frontendcollisionblog.com/about">in touch with Josh (me)</a> with any feature requests!
83
102
 
@@ -142,7 +161,7 @@ The command line tool itself is written in <a href="https://www.ruby-lang.org/en
142
161
 
143
162
  # Technical Information
144
163
 
145
- **Version** 0.2.0
164
+ **Version** 0.2.2 (uses <a href="http://semver.org/">Semantic Versioning</a>)
146
165
 
147
166
  **Language** Ruby
148
167
 
@@ -150,7 +169,32 @@ The command line tool itself is written in <a href="https://www.ruby-lang.org/en
150
169
 
151
170
  <hr>
152
171
 
153
- &copy; 2015 Joshua Beam (MIT License) &mdash; <a href="http://frontendcollisionblog.com">Front End Collision</a>
172
+ **Disclaimer**
173
+
174
+ `angular_init` and `ngi` and the author (Joshua Beam) are not directly associated with <a href="http://angularjs.org">AngularJS</a>.
175
+
176
+ **Copyright (c) 2015 Joshua Beam** &mdash; <a href="http://frontendcollisionblog.com">Front End Collision</a>
177
+
178
+ MIT License
179
+
180
+ Permission is hereby granted, free of charge, to any person obtaining
181
+ a copy of this software and associated documentation files (the
182
+ "Software"), to deal in the Software without restriction, including
183
+ without limitation the rights to use, copy, modify, merge, publish,
184
+ distribute, sublicense, and/or sell copies of the Software, and to
185
+ permit persons to whom the Software is furnished to do so, subject to
186
+ the following conditions:
187
+
188
+ The above copyright notice and this permission notice shall be
189
+ included in all copies or substantial portions of the Software.
190
+
191
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
192
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
193
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
194
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
195
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
196
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
197
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
154
198
 
155
199
  [install]: #installation-in-1-step
156
200
  [sample-usage]: #sample-usage
data/bin/ngi CHANGED
@@ -9,27 +9,30 @@
9
9
  require_relative '../lib/ngi'
10
10
  require_relative '../lib/ngi/utils/utils'
11
11
 
12
+ # This class is just a wrapper for the main process
13
+ # of ngi
12
14
  class Parser
13
- @@config = Ngi::Delegate::Configure.new.from_json
14
- @@types = Ngi::UserInput.new(valid_inputs: @@config['global']['components'].collect{ |t| t['name'] })
15
-
16
- def self.parse(args)
17
- parser = Utils::CommandParser.new do |parser|
18
- parser.name = "ngi"
19
- parser.version = Ngi::VERSION
20
- parser.banner << "\n(<command> can be one of the following)"
21
-
22
- parser.on(@@types.valid_inputs, "Create a new component") do |command|
23
- Ngi::Delegate::Generator.run(type: command, config: @@config)
24
- end
25
-
26
- parser.on(["-o","--options"], "Configure ngi") do
27
- Ngi::Delegate::Configure.run()
28
- end
29
- end
30
-
31
- parser.parse(args)
32
- end
15
+ def self.parse(args)
16
+ p = Utils::CommandParser.new do |parser|
17
+ config = Ngi::Delegate::Configure.new.from_json
18
+ components = config['global']['components'].collect { |t| t['name'] }
19
+ types = Ngi::UserInput.new(valid_inputs: components)
20
+
21
+ parser.name = 'ngi'
22
+ parser.version = Ngi::VERSION
23
+ parser.banner << "\n(<command> can be one of the following)"
24
+
25
+ parser.on(types.valid_inputs, 'Create a new component') do |command|
26
+ Ngi::Delegate::Generator.run(type: command, config: config)
27
+ end
28
+
29
+ parser.on(['-o', '--options'], 'Configure ngi') do
30
+ Ngi::Delegate::Configure.run
31
+ end
32
+ end
33
+
34
+ p.parse(args)
35
+ end
33
36
  end
34
37
 
35
- Parser.parse(ARGV)
38
+ Parser.parse(ARGV)
data/lib/ngi.rb CHANGED
@@ -5,12 +5,15 @@
5
5
 
6
6
  CURRENT_DIR = File.dirname(__FILE__)
7
7
 
8
- require_relative "ngi/delegate"
9
- require_relative "ngi/utils/utils"
10
- require_relative "ngi/version"
8
+ require_relative 'ngi/delegate'
9
+ require_relative 'ngi/utils/utils'
10
+ require_relative 'ngi/version'
11
11
 
12
+ # This module wraps the basic classes
13
+ # of the tool ngi (in other words, this
14
+ # module simply provides namespace)
12
15
  module Ngi
13
- # REVIEW: Is this the best way to do it?
14
- Delegate = ::Delegate
15
- UserInput = ::Utils::UserInput
16
- end
16
+ # REVIEW: Is this the best way to do it?
17
+ Delegate = ::Delegate
18
+ UserInput = ::Utils::UserInput
19
+ end
@@ -5,161 +5,156 @@
5
5
 
6
6
  # CURRENT_DIR is defined in angualr_init.rb
7
7
 
8
- # require CURRENT_DIR+'/../../../lib/json'
9
- # require CURRENT_DIR+'/../utils/utils'
10
-
11
- require_relative '../dep/json'
8
+ # require_relative '../dep/json'
9
+ require 'json'
12
10
  require_relative 'utils/utils'
13
11
 
12
+ # Run the user through an interactive
13
+ # session of configuring ngi
14
14
  class Configure
15
- attr_accessor :file, :location
16
-
17
- Utils = ::Utils
18
- JSArray = Utils::JSArray
19
- JSHash = Utils::JSHash
20
-
21
- # Make Questioner accesible as in: Configure::Questioner.run()
22
- # "Questioner" simply starts an interactive prompt to guide
23
- # the user in configuring src/config/agular_init.config.json,
24
- # which is a JSON file that holds all the global configurable
25
- # options (like language to use, templates, etc.)
26
- class Questioner
27
- attr_accessor :file
28
-
29
- def initialize(file)
30
- @file = file
15
+ attr_accessor :file, :location
31
16
 
32
- @GLOBAL = @file['global']
33
- # TODO: extend array with this inject function?
17
+ Utils = ::Utils
18
+ JSArray = Utils::JSArray
19
+ JSHash = Utils::JSHash
34
20
 
35
- # The options for languages to use
36
- @LANGUAGES = @GLOBAL['languages']
21
+ # Make Questioner accesible as in: Configure::Questioner.run()
22
+ # "Questioner" simply starts an interactive prompt to guide
23
+ # the user in configuring src/config/agular_init.config.json,
24
+ # which is a JSON file that holds all the global configurable
25
+ # options (like language to use, templates, etc.)
26
+ class Questioner
27
+ attr_accessor :file
37
28
 
38
- # The properties in key => value format of the properties the user can configure
39
- @CONFIGURABLE = @GLOBAL['configurable']
29
+ def initialize(file)
30
+ @file = file
40
31
 
41
- # An array of the properties that the user is allowed to configure,
42
- # according to src/config/angular_init.config.json
43
- @CONFIGURABLE_PROPERTIES = @CONFIGURABLE.collect{ |k,v| v }
32
+ @GLOBAL = @file['global']
33
+ # TODO: extend array with this inject function?
44
34
 
45
- if block_given?
46
- yield(self)
47
- end
48
- end
35
+ # The options for languages to use
36
+ @LANGUAGES = @GLOBAL['languages']
49
37
 
50
- def choose_configurable_property
51
- line_break = "\n------------------"
38
+ # The properties in key => value format of the properties the user can configure
39
+ @CONFIGURABLE = @GLOBAL['configurable']
52
40
 
53
- puts "\nCurrent settings #{line_break}"
54
- @CONFIGURABLE.each_with_index do | (k,v),i |
55
- puts "#{i+1}) "+v.capitalize+": "+JSHash.new(@GLOBAL[v]).to_str
56
- end
41
+ # An array of the properties that the user is allowed to configure,
42
+ # according to src/config/angular_init.config.json
43
+ @CONFIGURABLE_PROPERTIES = @CONFIGURABLE.collect { |_k, v| v }
57
44
 
58
- # return
59
- AskLoop.ask(:check => @CONFIGURABLE_PROPERTIES, :valid => JSArray.new(@CONFIGURABLE_PROPERTIES).to_str)
60
- end
45
+ yield(self) if block_given?
46
+ end
61
47
 
62
- def configure_property(property)
63
- case property
64
- when @CONFIGURABLE['language']
65
- language_types = @LANGUAGES.collect{|type,languages| type if languages.size > 1 }.reject{|t| t.nil?}
48
+ def choose_configurable_property
49
+ line_break = "\n------------------"
66
50
 
67
- type = AskLoop.ask(:check => language_types, :valid => JSArray.new(language_types).to_str)
51
+ puts "\nCurrent settings #{line_break}"
52
+ @CONFIGURABLE.each_with_index do |(_k, v), i|
53
+ puts "#{i + 1}) " + v.capitalize + ': ' + JSHash.new(@GLOBAL[v]).to_str
54
+ end
68
55
 
69
- language_opts = @LANGUAGES.reject{|t,languages| languages if t != type}[type].reject{|l| l == @GLOBAL['language'][type]}
56
+ # return
57
+ AskLoop.ask(check: @CONFIGURABLE_PROPERTIES, valid: JSArray.new(@CONFIGURABLE_PROPERTIES).to_str)
58
+ end
70
59
 
71
- language = AskLoop.ask(:check => language_opts, :valid => JSArray.new(language_opts).to_str)
60
+ def configure_property(property)
61
+ case property
62
+ when @CONFIGURABLE['language']
63
+ language_types = @LANGUAGES.collect { |type, languages| type if languages.size > 1 }.reject(&:nil?)
72
64
 
73
- answer = @GLOBAL['language']
65
+ type = AskLoop.ask(check: language_types, valid: JSArray.new(language_types).to_str)
74
66
 
75
- answer[type] = language
76
- end
67
+ language_opts = @LANGUAGES.reject { |t, languages| languages if t != type }[type].reject { |l| l == @GLOBAL['language'][type] }
77
68
 
78
- # TODO: add ability to add templates
69
+ language = AskLoop.ask(check: language_opts, valid: JSArray.new(language_opts).to_str)
79
70
 
80
- answer
81
- end
71
+ answer = @GLOBAL['language']
82
72
 
73
+ answer[type] = language
74
+ end
83
75
 
84
- def self.run(file)
85
- q = Questioner.new(file) do |q|
86
- configurable_property = q.choose_configurable_property
76
+ # TODO: add ability to add templates
87
77
 
88
- result = q.configure_property(configurable_property)
78
+ answer
79
+ end
89
80
 
90
- q.file['global'][configurable_property] = result
81
+ def self.run(file)
82
+ questioner = Questioner.new(file) do |q|
83
+ configurable_property = q.choose_configurable_property
91
84
 
92
- puts configurable_property.capitalize+' set to: '+JSHash.new(result).to_str
93
- end
85
+ result = q.configure_property(configurable_property)
94
86
 
95
- q.file
96
- end
97
- end
87
+ q.file['global'][configurable_property] = result
98
88
 
99
- # Here, we implement the virtual class "Utils::AskLoop"
100
- # (see src/ruby/utils/utils.rb)
101
- # This implementation just creates a loop that asks
102
- # for user input
103
- class AskLoop < Utils::AskLoop
104
- def self.ask(args)
105
- puts "\n"
106
- puts 'Choose from: '+args[:valid]
89
+ puts configurable_property.capitalize + ' set to: ' + JSHash.new(result).to_str
90
+ end
107
91
 
108
- answer = $stdin.gets.strip
92
+ questioner.file
93
+ end
94
+ end
109
95
 
110
- while true
111
- if args[:check].include?(answer)
112
- break
113
- else
114
- puts 'Choose from: '+args[:valid]
115
- puts '(or press ctrl+c to exit)'
116
- answer = $stdin.gets.strip
117
- end
118
- end
96
+ # Here, we implement the virtual class "Utils::AskLoop"
97
+ # (see src/ruby/utils/utils.rb)
98
+ # This implementation just creates a loop that asks
99
+ # for user input
100
+ class AskLoop < Utils::AskLoop
101
+ def self.ask(args)
102
+ puts "\n"
103
+ puts 'Choose from: ' + args[:valid]
119
104
 
120
- answer
121
- end
122
- end
105
+ answer = $stdin.gets.strip
123
106
 
124
- # The only thing we do here is load the JSON config file basically
125
- # as just a string in JSON format.
126
- # It will be converted to a Ruby hash in from_json below
127
- def initialize
128
- @location = CURRENT_DIR+'/config/angular_init.config.json'
129
- @file = IO.read(@location)
107
+ loop do
108
+ if args[:check].include?(answer)
109
+ break
110
+ else
111
+ puts 'Choose from: ' + args[:valid]
112
+ puts '(or press ctrl+c to exit)'
113
+ answer = $stdin.gets.strip
114
+ end
115
+ end
130
116
 
131
- if block_given?
132
- yield(self)
133
- end
134
- end
117
+ answer
118
+ end
119
+ end
135
120
 
136
- # Convert the file to a Ruby hash
137
- def from_json
138
- JSON.parse(@file)
139
- end
121
+ # The only thing we do here is load the JSON config file basically
122
+ # as just a string in JSON format.
123
+ # It will be converted to a Ruby hash in from_json below
124
+ def initialize
125
+ @location = CURRENT_DIR + '/config/angular_init.config.json'
126
+ @file = IO.read(@location)
140
127
 
141
- # Generate a "prettified" JSON version of our
142
- # newly updated Ruby hash with the user's options
143
- def to_json
144
- JSON.pretty_generate(@file)
145
- end
146
-
147
- # Here we actually write the new JSON config file
148
- # to src/config/angular_init.config.json
149
- def write
150
- new_file = to_json
128
+ yield(self) if block_given?
129
+ end
151
130
 
152
- File.open(@location,'w') do |f|
153
- f.write(new_file)
154
- f.close
155
- end
156
- end
131
+ # Convert the file to a Ruby hash
132
+ def from_json
133
+ JSON.parse(@file)
134
+ end
157
135
 
158
- def self.run
159
- Configure.new do |c|
160
- c.file = Configure::Questioner.run(c.from_json)
136
+ # Generate a "prettified" JSON version of our
137
+ # newly updated Ruby hash with the user's options
138
+ def to_json
139
+ JSON.pretty_generate(@file)
140
+ end
141
+
142
+ # Here we actually write the new JSON config file
143
+ # to src/config/angular_init.config.json
144
+ def write
145
+ new_file = to_json
161
146
 
162
- c.write
163
- end
164
- end
165
- end
147
+ File.open(@location, 'w') do |f|
148
+ f.write(new_file)
149
+ f.close
150
+ end
151
+ end
152
+
153
+ def self.run
154
+ Configure.new do |c|
155
+ c.file = Configure::Questioner.run(c.from_json)
156
+
157
+ c.write
158
+ end
159
+ end
160
+ end
@@ -16,9 +16,7 @@ require_relative 'configure'
16
16
  # the flow of control to either the Generator class
17
17
  # or the Configure class, based on the argument passed
18
18
  # in (which is handled by bin/ngi)
19
-
20
19
  class Delegate
21
- # Review: is this the best way to do it?
22
- Generator = ::Generator
23
- Configure = ::Configure
24
- end
20
+ Generator = ::Generator
21
+ Configure = ::Configure
22
+ end
@@ -3,197 +3,191 @@
3
3
  # github.com/joshbeam/angular_init
4
4
  # MIT License
5
5
 
6
- require_relative "utils/utils"
6
+ require_relative 'utils/utils'
7
7
 
8
8
  # This class generates templates (hence the name "Generator")
9
9
  class Generator
10
- Utils = ::Utils
10
+ Utils = ::Utils
11
11
 
12
- class AskLoop < Utils::AskLoop
13
- def self.ask(args)
14
- puts "\n"
15
- print args[:prompt]
12
+ class AskLoop < Utils::AskLoop
13
+ def self.ask(args)
14
+ puts "\n"
15
+ print args[:prompt]
16
16
 
17
- answer = $stdin.gets.strip.downcase
17
+ answer = $stdin.gets.strip.downcase
18
18
 
19
- while true
20
- if args[:check] == answer
21
- break
22
- else
23
- puts "Exited!"
24
- exit
25
- end
26
- end
19
+ loop do
20
+ if args[:check] == answer
21
+ break
22
+ else
23
+ puts 'Exited!'
24
+ exit
25
+ end
26
+ end
27
27
 
28
- answer
29
- end
30
- end
28
+ answer
29
+ end
30
+ end
31
31
 
32
- WHITESPACE = /\s*/
33
- EMPTY = ""
34
- CURRENT_DIR = File.dirname(__FILE__)
35
-
36
- ################################
37
-
38
- # SET UP ALL THE CONFIG OPTIONS
39
- # Generator.new (the initialization function) is called in self.run
40
-
41
- def initialize(args)
42
- @type = args[:type]
43
- @config = args[:config]['global']
44
-
45
- all_components = @config['components']
46
- component = all_components.find{ |t| t['name'] == @type }
47
-
48
- # basically just rebuilding the object so we can use it here
49
- @component = {
50
- :of_type => component['type'],
51
- :language => @config['language'][component['type']],
52
- :using => component['using'],
53
- :template => component['template']
54
- }
55
-
56
- template_dir = "#{CURRENT_DIR}/../templates/"
57
- template_dir << "#{@component[:of_type]}/#{@component[:language]}/#{@component[:using]}/#{@component[:template]}"
58
-
59
- @template_file = IO.read(template_dir)
60
-
61
- if block_given?
62
- yield(self)
63
- end
64
- end
65
-
66
- ###############################
67
-
68
- def new_file_name
69
- print "[?] New file name: "
70
-
71
- @new_file = $stdin.gets.gsub(WHITESPACE,EMPTY)
72
- end
73
-
74
- def module_name
75
- print "[?] Module name: "
76
-
77
- @module_name = $stdin.gets.gsub(WHITESPACE,EMPTY)
78
- end
79
-
80
- def name
81
- print "[?] #{@type.capitalize} name: "
82
-
83
- @name = $stdin.gets.gsub(WHITESPACE,EMPTY)
84
- end
85
-
86
- def inject
87
- # REVIEW: use symbols instead of strings?
88
- special = ['routes','controller'].include?(@type)
89
- auto_injections = [
90
- {
91
- :for_type => 'routes',
92
- :service => '$routeProvider'
93
- },
94
- {
95
- :for_type => 'controller',
96
- :service => '$scope'
97
- }
98
- ]
99
-
100
- injection = special ? auto_injections.select { |inj| inj[:for_type] == @type }[0][:service] : nil
101
-
102
- auto_injection_statement = special ? " (already injected #{injection})" : ''
103
-
104
- print "[?] Inject#{auto_injection_statement}: "
105
-
106
- # accepts a comma-delimited list
107
- # EXAMPLE: testService, testService2
108
- # => [testService,testService2]
109
- @dependencies = $stdin.gets.split(',').map { |dep| dep.strip }.reject(&:empty?)
110
-
111
- # automatically inject $scope into a controller
112
- # FIXME: don't use index accessors (numbers are confusing)
113
- @dependencies << auto_injections[1][:service] if @type == 'controller' && !@dependencies.include?(auto_injections[1][:service])
114
-
115
- # automatically insert $routeProvider into a routes config
116
- @dependencies << auto_injections[0][:service] if @type == 'routes' && !@dependencies.include?(auto_injections[0][:service])
117
- end
118
-
119
- def replace
120
- # inject may or may not have run... if it wasn't run, then @dependencies was never set
121
- # for example, for html templates, we don't run the inject function
122
- # @dependencies = @dependencies || []
123
- @dependencies ||= []
124
- has_dependencies = @dependencies.size > 0
125
-
126
- # Use 'config' as the type, since 'routes' is really an alias for a specific type of 'config'.
127
- # TODO: map aliases from config file
128
- @type = 'config' if @type == 'routes'
129
-
130
- # Regex replacements to generate the template
131
- @template_file = @template_file
132
- .gsub(/\{\{type\}\}/,@type)
133
- .gsub(/\{\{name\}\}/,@name || "")
134
- .gsub(/\{\{module\}\}/, "#@module_name")
135
- .gsub(
136
- /\{\{inject\s\|\sarray_string\}\}/,
137
- has_dependencies ?
138
- @dependencies.to_s.gsub(/"/,'\'')
139
- : '[]'
140
- )
141
- .gsub(
142
- /\{\{inject\s\|\scomma_delimited_variables\}\}/,
143
- has_dependencies ?
144
- @dependencies.each_with_index.inject("") { |str,(dep,i)| str+=dep.to_s+(i == @dependencies.size-1 ? "" : ", ") }
145
- : ""
146
- )
147
- end
148
-
149
- def tag
150
- # If Liquid-style tags are used in a template that can be used
151
- # for multiple components, remove those parts that don't
152
- # belong to the type of component user wants to generate
153
- @template_file = @template_file
154
- .gsub(/\{\%\sif\s#{@type}\s\%\}(.*)\{\%\sendif\s#{@type}\s\%\}/m, '\1')
155
- .gsub(/\s\{\%\sif\s.*\s\%\}.*\{\%\sendif\s.*\s\%\}/m, '')
156
- end
157
-
158
- def write
159
- # create the new file
160
- def overwrite?
161
- AskLoop.ask(:check => "y", :prompt => "File exists already, overwrite it? (y/n) ")
162
- end
163
-
164
- if(File.exist?(@new_file))
165
- overwrite?
166
- end
167
-
168
- File.open(@new_file,'w') do |file|
169
- file.write(@template_file)
170
- file.close
171
- end
172
- end
173
-
174
- # Use this function to be able to say AngularInit::Delegate::Generator.run() inside the executable file
175
- # This function simply goes through all of the methods in order to interactively
176
- # prompt the user to generate a new template
177
- def self.run(args)
178
- Generator.new(args) do |g|
179
- g.new_file_name
180
-
181
- # we don't need to define the module if we're creating a module
182
- g.module_name unless args[:type] == 'module'
183
-
184
- # 'run', 'config', and 'routes' don't have custom names in AngularJS
185
- # REVIEW: use symbols instead of strings?
186
- g.name unless ['run','config','routes','index'].include? args[:type]
187
-
188
- g.inject unless ['index'].include? args[:type]
189
-
190
- g.replace
191
-
192
- g.tag
193
-
194
- g.write
195
- end
196
-
197
- puts 'All done!'
198
- end
199
- end
32
+ WHITESPACE = /\s*/
33
+ EMPTY = ''
34
+ CURRENT_DIR = File.dirname(__FILE__)
35
+
36
+ ################################
37
+
38
+ # SET UP ALL THE CONFIG OPTIONS
39
+ # Generator.new (the initialization function) is called in self.run
40
+
41
+ def initialize(args)
42
+ @type = args[:type]
43
+ @config = args[:config]['global']
44
+
45
+ all_components = @config['components']
46
+ component = all_components.find { |t| t['name'] == @type }
47
+
48
+ # basically just rebuilding the object so we can use it here
49
+ @component = {
50
+ of_type: component['type'],
51
+ language: @config['language'][component['type']],
52
+ using: component['using'],
53
+ template: component['template']
54
+ }
55
+
56
+ template_dir = "#{CURRENT_DIR}/../templates/"
57
+ template_dir << "#{@component[:of_type]}/#{@component[:language]}/#{@component[:using]}/#{@component[:template]}"
58
+
59
+ @template_file = IO.read(template_dir)
60
+
61
+ yield(self) if block_given?
62
+ end
63
+
64
+ ###############################
65
+
66
+ def new_file_name
67
+ print '[?] New file name: '
68
+
69
+ @new_file = $stdin.gets.gsub(WHITESPACE, EMPTY)
70
+ end
71
+
72
+ def module_name
73
+ print '[?] Module name: '
74
+
75
+ @module_name = $stdin.gets.gsub(WHITESPACE, EMPTY)
76
+ end
77
+
78
+ def name
79
+ print "[?] #{@type.capitalize} name: "
80
+
81
+ @name = $stdin.gets.gsub(WHITESPACE, EMPTY)
82
+ end
83
+
84
+ def inject
85
+ # REVIEW: use symbols instead of strings?
86
+ special = %w(routes controller).include?(@type)
87
+ auto_injections = [
88
+ {
89
+ for_type: 'routes',
90
+ service: '$routeProvider'
91
+ },
92
+ {
93
+ for_type: 'controller',
94
+ service: '$scope'
95
+ }
96
+ ]
97
+
98
+ injection = special ? auto_injections.select { |inj| inj[:for_type] == @type }[0][:service] : nil
99
+
100
+ auto_injection_statement = special ? " (already injected #{injection})" : ''
101
+
102
+ print "[?] Inject#{auto_injection_statement}: "
103
+
104
+ # accepts a comma-delimited list
105
+ # EXAMPLE: testService, testService2
106
+ # => [testService,testService2]
107
+ @dependencies = $stdin.gets.split(',').map(&:strip).reject(&:empty?)
108
+
109
+ # automatically inject $scope into a controller
110
+ # FIXME: don't use index accessors (numbers are confusing)
111
+ @dependencies << auto_injections[1][:service] if @type == 'controller' && !@dependencies.include?(auto_injections[1][:service])
112
+
113
+ # automatically insert $routeProvider into a routes config
114
+ @dependencies << auto_injections[0][:service] if @type == 'routes' && !@dependencies.include?(auto_injections[0][:service])
115
+ end
116
+
117
+ def replace
118
+ # inject may or may not have run... if it wasn't run, then @dependencies was never set
119
+ # for example, for html templates, we don't run the inject function
120
+ # @dependencies = @dependencies || []
121
+ @dependencies ||= []
122
+ has_dependencies = @dependencies.size > 0
123
+
124
+ # Use 'config' as the type, since 'routes' is really an alias for a specific type of 'config'.
125
+ # TODO: map aliases from config file
126
+ @type = 'config' if @type == 'routes'
127
+
128
+ # Regex replacements to generate the template
129
+ @template_file = @template_file
130
+ .gsub(/\{\{type\}\}/, @type)
131
+ .gsub(/\{\{name\}\}/, @name || '')
132
+ .gsub(/\{\{module\}\}/, "#{@module_name}")
133
+ .gsub(
134
+ /\{\{inject\s\|\sarray_string\}\}/,
135
+ has_dependencies ?
136
+ @dependencies.to_s.gsub(/"/, '\'') : '[]'
137
+ )
138
+ .gsub(
139
+ /\{\{inject\s\|\scomma_delimited_variables\}\}/,
140
+ has_dependencies ?
141
+ @dependencies.each_with_index.inject('') { |str, (dep, i)| str += dep.to_s + (i == @dependencies.size - 1 ? '' : ', ') } : ''
142
+ )
143
+ end
144
+
145
+ def tag
146
+ # If Liquid-style tags are used in a template that can be used
147
+ # for multiple components, remove those parts that don't
148
+ # belong to the type of component user wants to generate
149
+ @template_file = @template_file
150
+ .gsub(/\{\%\sif\s#{@type}\s\%\}(.*)\{\%\sendif\s#{@type}\s\%\}/m, '\1')
151
+ .gsub(/\s\{\%\sif\s.*\s\%\}.*\{\%\sendif\s.*\s\%\}/m, '')
152
+ end
153
+
154
+ def write
155
+ # create the new file
156
+ def overwrite?
157
+ AskLoop.ask(check: 'y', prompt: 'File exists already, overwrite it? (y/n) ')
158
+ end
159
+
160
+ overwrite? if File.exist?(@new_file)
161
+
162
+ File.open(@new_file, 'w') do |file|
163
+ file.write(@template_file)
164
+ file.close
165
+ end
166
+ end
167
+
168
+ # Use this function to be able to say AngularInit::Delegate::Generator.run() inside the executable file
169
+ # This function simply goes through all of the methods in order to interactively
170
+ # prompt the user to generate a new template
171
+ def self.run(args)
172
+ Generator.new(args) do |g|
173
+ g.new_file_name
174
+
175
+ # we don't need to define the module if we're creating a module
176
+ g.module_name unless args[:type] == 'module'
177
+
178
+ # 'run', 'config', and 'routes' don't have custom names in AngularJS
179
+ # REVIEW: use symbols instead of strings?
180
+ g.name unless %w(run config routes index).include? args[:type]
181
+
182
+ g.inject unless ['index'].include? args[:type]
183
+
184
+ g.replace
185
+
186
+ g.tag
187
+
188
+ g.write
189
+ end
190
+
191
+ puts 'All done!'
192
+ end
193
+ end
@@ -3,102 +3,99 @@
3
3
  # github.com/joshbeam/angular_init
4
4
  # MIT License
5
5
 
6
-
7
6
  # Similar to Ruby's OptionParser
8
7
  # However, this is customized for angular_init
9
-
10
8
  class CommandParser
11
- attr_reader :args
12
- attr_accessor :banner, :version, :separator, :name
13
-
14
- def initialize
15
- # TODO: to "Usage #{file_name}", etc.
16
- @name = "<CLI>"
17
- @banner = "Usage: #{@name} <command>"
18
- @version = "0.0.0"
19
- @separator = "===================="
20
- @listeners = []
21
-
22
- # automatically register some listeners
23
- register_help
24
- register_version
25
-
26
- # be able to pass in a block for setup
27
- if block_given?
28
- yield(self)
29
- end
30
- end
31
-
32
- def name=(name)
33
- # need to also replace the name in the banner
34
- @banner = @banner.gsub(@name,name)
35
-
36
- @name = name
37
- end
38
-
39
- # register the listeners
40
- def on(options,description="",&block)
41
- listener = {}
42
-
43
- # be able to pass in a single argument, or an array of arguments
44
- options = *options unless options.is_a? Array
45
-
46
- listener[:options] = options.map do |opt|
47
- opt.strip.split(" ")
48
- end
49
-
50
- listener[:block] = block
51
- listener[:description] = description
52
-
53
- @listeners << listener
54
- end
55
-
56
- def parse(args)
57
- # puts @listeners
58
- matched_listener = {
59
- :options => nil,
60
- :block => nil
61
- }
62
-
63
- @listeners.each do |listener|
64
- listener[:options].each do |opt_arr|
65
- if opt_arr == args
66
- matched_listener[:options] = opt_arr
67
- matched_listener[:block] = listener[:block]
68
- break
69
- end
70
- end
71
- end
72
-
73
- unless matched_listener[:options].nil?
74
- # matched_listener[:options] should always be an array
75
- # when we call, we can each member of that array to be
76
- # passed separately
77
- matched_listener[:block].call(*matched_listener[:options])
78
- else
79
- # if there was no match, show the help menu
80
- parse(["-h"])
81
- end
82
- end
83
-
84
- def register_help
85
- # automaticaly register this listener
86
- on(["-h","--help"],"Show the help menu") do
87
- puts @separator
88
- puts @banner
89
-
90
- @listeners.each_with_index do |listener,i|
91
- puts "\n"
92
- puts "(#{i+1}) #{listener[:description]}: #{listener[:options].join(', ')}"
93
- end
94
- puts @separator
95
- end
96
- end
97
-
98
- def register_version
99
- # automaticaly register this listener
100
- on(["-v","--version"],"Show the version") do
101
- puts "#{@name} #{@version}"
102
- end
103
- end
104
- end
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
27
+
28
+ def name=(name)
29
+ # need to also replace the name in the banner
30
+ @banner = @banner.gsub(@name, name)
31
+
32
+ @name = name
33
+ end
34
+
35
+ # register the listeners
36
+ def on(options, description = '', &block)
37
+ listener = {}
38
+
39
+ # be able to pass in a single argument, or an array of arguments
40
+ options = *options unless options.is_a? Array
41
+
42
+ listener[:options] = options.map do |opt|
43
+ opt.strip.split(' ')
44
+ end
45
+
46
+ listener[:block] = block
47
+ listener[:description] = description
48
+
49
+ @listeners << listener
50
+ end
51
+
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
66
+ end
67
+ end
68
+
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'])
77
+ end
78
+ end
79
+
80
+ def register_help
81
+ # automaticaly register this listener
82
+ on(['-h', '--help'], 'Show the help menu') do
83
+ puts @separator
84
+ puts @banner
85
+
86
+ @listeners.each_with_index do |listener, i|
87
+ desc = "\n" << "(#{i + 1}) #{listener[:description]}: "
88
+ desc << "#{listener[:options].join(', ')}"
89
+ puts desc
90
+ end
91
+ puts @separator
92
+ end
93
+ end
94
+
95
+ def register_version
96
+ # automaticaly register this listener
97
+ on(['-v', '--version'], 'Show the version') do
98
+ puts "#{@name} #{@version}"
99
+ end
100
+ end
101
+ end
@@ -3,44 +3,44 @@
3
3
  # github.com/joshbeam/angular_init
4
4
  # MIT License
5
5
 
6
+ # Since ngi is an AngularJS tool and the users
7
+ # are familiar with JavaScript, this module of classes
8
+ # prints a string version of a Ruby hash or array
9
+ # as it would appear in normal JavaScript syntax
10
+ # For example:
11
+ # { "hello" => "world" }
12
+ # becomes:
13
+ # { 'hello': 'world' }
14
+ # and ["some","array"]
15
+ # becomes:
16
+ # ['some','array']
6
17
  module JSer
7
- # Since ngi is an AngularJS tool and the users
8
- # are familiar with JavaScript, this class
9
- # prints a string version of a Ruby hash or array
10
- # as it would appear in normal JavaScript syntax
11
- # For example:
12
- # { "hello" => "world" }
13
- # becomes:
14
- # { 'hello': 'world' }
15
- # and ["some","array"]
16
- # becomes:
17
- # ['some','array']
18
- def to_str
19
- self.to_s.gsub(/\"/,"'").gsub(/\=\>/,": ")
20
- end
18
+ def to_str
19
+ to_s.gsub(/\"/, "'").gsub(/\=\>/, ': ')
20
+ end
21
21
 
22
- # A JSer class
23
- # Usage:
24
- # JSHash.new({"hello" => "world"}).to_str
25
- class JSHash < Hash
26
- def initialize(hash)
27
- super
28
- hash.each do |key,val|
29
- self[key] = val
30
- end
31
- end
22
+ # A JSer class
23
+ # Usage:
24
+ # JSHash.new({"hello" => "world"}).to_str
25
+ class JSHash < Hash
26
+ def initialize(hash)
27
+ super
28
+ hash.each do |key, val|
29
+ self[key] = val
30
+ end
31
+ end
32
32
 
33
- include JSer
34
- end
33
+ include JSer
34
+ end
35
35
 
36
- # Another JSer class
37
- # Usage:
38
- # JSArray.new(["some","array"]).to_str
39
- class JSArray < Array
40
- def initialize(array)
41
- super
42
- end
36
+ # Another JSer class
37
+ # Usage:
38
+ # JSArray.new(["some","array"]).to_str
39
+ class JSArray < Array
40
+ def initialize(array)
41
+ super
42
+ end
43
43
 
44
- include JSer
45
- end
46
- end
44
+ include JSer
45
+ end
46
+ end
@@ -3,28 +3,30 @@
3
3
  # github.com/joshbeam/angular_init
4
4
  # MIT License
5
5
 
6
- require_relative "command_parser"
7
- require_relative "jser"
6
+ require_relative 'command_parser'
7
+ require_relative 'jser'
8
8
 
9
+ # This module holds classes of basic utility
10
+ # functions used throughout Ngi
9
11
  module Utils
10
- CommandParser = ::CommandParser
11
- JSArray = JSer::JSArray
12
- JSHash = JSer::JSHash
12
+ CommandParser = ::CommandParser
13
+ JSArray = JSer::JSArray
14
+ JSHash = JSer::JSHash
13
15
 
14
- class AskLoop; end
16
+ class AskLoop; end
15
17
 
16
- # This class is just a way to meaningfully
17
- # collect an array of valid user inputs
18
- # for use with OptionParser in bin/ngi
19
- class UserInput
20
- attr_reader :valid_inputs
21
-
22
- def initialize(args)
23
- @valid_inputs = args[:valid_inputs]
24
- end
18
+ # This class is just a way to meaningfully
19
+ # collect an array of valid user inputs
20
+ # for use with OptionParser in bin/ngi
21
+ class UserInput
22
+ attr_reader :valid_inputs
25
23
 
26
- def valid?(input)
27
- @valid_inputs.include?(input)
28
- end
29
- end
30
- end
24
+ def initialize(args)
25
+ @valid_inputs = args[:valid_inputs]
26
+ end
27
+
28
+ def valid?(input)
29
+ @valid_inputs.include?(input)
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,11 @@
1
+ # angular_init (short-name: ngi)
2
+ # Copyright 2015 Joshua Beam
3
+ # github.com/joshbeam/angular_init
4
+ # MIT License
5
+
6
+ # The current version of Ngi.
7
+ # This uses semantic versioning.
8
+ # See http://semver.org/
1
9
  module Ngi
2
- VERSION = "0.2.1"
3
- end
10
+ VERSION = '0.2.2'
11
+ end
@@ -12,6 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = %q{This tool can make (for example) an AngularJS controller template file for you (.js), so that whenever you want to make a new controller for your app, you don't have to type the same starting code over and over again (by the way, this tool doesn't only create controllers. It does directives, filters... almost anything). ngi has one task, and one task only, which makes it lightweight and specialized. Most AngularJS developers are probably using the command line already (Gulp, Bower, npm, Git, etc.), so why not use the command line to streamline your code-writing too? Type less, write more AngularJS!}
13
13
  spec.homepage = "https://github.com/joshbeam/angular_init"
14
14
  spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.1"
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
17
18
  spec.executables = ["ngi"]
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ngi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Beam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-06 00:00:00.000000000 Z
11
+ date: 2015-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -101,6 +101,7 @@ files:
101
101
  - lib/templates/script/es5/default/constant.js
102
102
  - lib/templates/script/es5/default/module.js
103
103
  - ngi.gemspec
104
+ - ngi_example.gif
104
105
  homepage: https://github.com/joshbeam/angular_init
105
106
  licenses:
106
107
  - MIT
@@ -113,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
114
  requirements:
114
115
  - - ">="
115
116
  - !ruby/object:Gem::Version
116
- version: '0'
117
+ version: '2.1'
117
118
  required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  requirements:
119
120
  - - ">="