ngi 0.2.1

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