ngi 0.2.1

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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +164 -0
  6. data/Rakefile +2 -0
  7. data/bin/ngi +35 -0
  8. data/lib/config/angular_init.config.json +100 -0
  9. data/lib/config/backup.angular_init.config.json +72 -0
  10. data/lib/dep/json.rb +62 -0
  11. data/lib/dep/json/add/bigdecimal.rb +28 -0
  12. data/lib/dep/json/add/complex.rb +28 -0
  13. data/lib/dep/json/add/core.rb +11 -0
  14. data/lib/dep/json/add/date.rb +34 -0
  15. data/lib/dep/json/add/date_time.rb +50 -0
  16. data/lib/dep/json/add/exception.rb +31 -0
  17. data/lib/dep/json/add/ostruct.rb +31 -0
  18. data/lib/dep/json/add/range.rb +29 -0
  19. data/lib/dep/json/add/rational.rb +27 -0
  20. data/lib/dep/json/add/regexp.rb +30 -0
  21. data/lib/dep/json/add/struct.rb +30 -0
  22. data/lib/dep/json/add/symbol.rb +25 -0
  23. data/lib/dep/json/add/time.rb +38 -0
  24. data/lib/dep/json/common.rb +484 -0
  25. data/lib/dep/json/ext.rb +21 -0
  26. data/lib/dep/json/ext/.keep +0 -0
  27. data/lib/dep/json/generic_object.rb +70 -0
  28. data/lib/dep/json/pure.rb +21 -0
  29. data/lib/dep/json/pure/generator.rb +522 -0
  30. data/lib/dep/json/pure/parser.rb +359 -0
  31. data/lib/dep/json/version.rb +8 -0
  32. data/lib/ngi.rb +16 -0
  33. data/lib/ngi/configure.rb +165 -0
  34. data/lib/ngi/delegate.rb +24 -0
  35. data/lib/ngi/generator.rb +199 -0
  36. data/lib/ngi/utils/command_parser.rb +104 -0
  37. data/lib/ngi/utils/jser.rb +46 -0
  38. data/lib/ngi/utils/utils.rb +30 -0
  39. data/lib/ngi/version.rb +3 -0
  40. data/lib/templates/markup/html/default/index.html +11 -0
  41. data/lib/templates/script/coffee/default/basic.js +23 -0
  42. data/lib/templates/script/coffee/default/config.js +12 -0
  43. data/lib/templates/script/coffee/default/constant.js +7 -0
  44. data/lib/templates/script/coffee/default/module.js +7 -0
  45. data/lib/templates/script/es5/default/basic.js +29 -0
  46. data/lib/templates/script/es5/default/config.js +13 -0
  47. data/lib/templates/script/es5/default/constant.js +7 -0
  48. data/lib/templates/script/es5/default/module.js +7 -0
  49. data/ngi.gemspec +23 -0
  50. metadata +129 -0
@@ -0,0 +1,24 @@
1
+ # angular_init (short-name: ngi)
2
+ # Copyright 2015 Joshua Beam
3
+ # github.com/joshbeam/angular_init
4
+ # MIT License
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
+ # Generator and Configure are "wrapped" in this class
15
+ # that "delegates" (hence the name "Delegate")
16
+ # the flow of control to either the Generator class
17
+ # or the Configure class, based on the argument passed
18
+ # in (which is handled by bin/ngi)
19
+
20
+ class Delegate
21
+ # Review: is this the best way to do it?
22
+ Generator = ::Generator
23
+ Configure = ::Configure
24
+ end
@@ -0,0 +1,199 @@
1
+ # angular_init (short-name: ngi)
2
+ # Copyright 2015 Joshua Beam
3
+ # github.com/joshbeam/angular_init
4
+ # MIT License
5
+
6
+ require_relative "utils/utils"
7
+
8
+ # This class generates templates (hence the name "Generator")
9
+ class Generator
10
+ Utils = ::Utils
11
+
12
+ class AskLoop < Utils::AskLoop
13
+ def self.ask(args)
14
+ puts "\n"
15
+ print args[:prompt]
16
+
17
+ answer = $stdin.gets.strip.downcase
18
+
19
+ while true
20
+ if args[:check] == answer
21
+ break
22
+ else
23
+ puts "Exited!"
24
+ exit
25
+ end
26
+ end
27
+
28
+ answer
29
+ end
30
+ end
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
@@ -0,0 +1,104 @@
1
+ # angular_init (short-name: ngi)
2
+ # Copyright 2015 Joshua Beam
3
+ # github.com/joshbeam/angular_init
4
+ # MIT License
5
+
6
+
7
+ # Similar to Ruby's OptionParser
8
+ # However, this is customized for angular_init
9
+
10
+ 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
@@ -0,0 +1,46 @@
1
+ # angular_init (short-name: ngi)
2
+ # Copyright 2015 Joshua Beam
3
+ # github.com/joshbeam/angular_init
4
+ # MIT License
5
+
6
+ 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
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
32
+
33
+ include JSer
34
+ end
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
43
+
44
+ include JSer
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ # angular_init (short-name: ngi)
2
+ # Copyright 2015 Joshua Beam
3
+ # github.com/joshbeam/angular_init
4
+ # MIT License
5
+
6
+ require_relative "command_parser"
7
+ require_relative "jser"
8
+
9
+ module Utils
10
+ CommandParser = ::CommandParser
11
+ JSArray = JSer::JSArray
12
+ JSHash = JSer::JSHash
13
+
14
+ class AskLoop; end
15
+
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
25
+
26
+ def valid?(input)
27
+ @valid_inputs.include?(input)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Ngi
2
+ VERSION = "0.2.1"
3
+ end
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html ng-app="{{module}}">
3
+ <head>
4
+ <link href="" rel="stylesheet" type="text/css" />
5
+ <meta charset="utf-8">
6
+ <title></title>
7
+ </head>
8
+ <body>
9
+ <script src=""></script>
10
+ </body>
11
+ </html>
@@ -0,0 +1,23 @@
1
+ ((app) ->
2
+
3
+ 'use strict'
4
+
5
+ {{name}}.$inject = {{inject | array_string}}
6
+
7
+ app.{{type}} '{{name}}', {{name}}
8
+
9
+ {{name}} = ({{inject | comma_delimited_variables}}) ->
10
+ {% if directive %}
11
+ d =
12
+ restrict: 'A'
13
+ link: link
14
+
15
+ link = (scope, element, attrs) ->
16
+
17
+ d
18
+ {% endif directive %}
19
+ {% if filter %}
20
+ (input) ->
21
+ input
22
+ {% endif filter %}
23
+ ) angular.module('{{module}}')