rbtils 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/model_data.rb ADDED
@@ -0,0 +1,97 @@
1
+ module Granify
2
+ module Model
3
+ class Data
4
+ attr_accessor :identifier, :branch, :browser, :files_with_errors
5
+
6
+ def initialize()
7
+ @d = Hash.new([])
8
+
9
+ # setup defaults
10
+ defaults = {
11
+ :issues => {:errors => 0, :warnings => 0},
12
+ :status => {:success => 0, :error => 0, :total => 0, :errors_per_file => 0},
13
+ :success_rate => {:int => 0, :str => "0%"},
14
+ :log => '',
15
+ :below_acceptable_limit => false
16
+ }
17
+
18
+ @branch = Command::Exec.git_current_branch
19
+ @files_with_errors = []
20
+
21
+ @d.merge! defaults
22
+ end
23
+
24
+ def unset(key)
25
+ @d.delete(key.to_sym)
26
+ end
27
+
28
+ def instance_var(key, val = nil)
29
+ self.class.__send__(:attr_accessor, key)
30
+ instance_variable_set("@#{key}", val)
31
+ end
32
+
33
+ def serialize
34
+ @d.to_json
35
+ end
36
+
37
+ def status
38
+ get(:status)
39
+ end
40
+
41
+ def success_rate
42
+ get(:success_rate)
43
+ end
44
+
45
+ def increment_issues(key, val)
46
+ @d[:issues][key.to_sym] += val
47
+ end
48
+
49
+ def increment_status(key, val)
50
+ @d[:status][key.to_sym] += val
51
+ end
52
+
53
+ def issues
54
+ get(:issues)
55
+ end
56
+
57
+ def issues=(val)
58
+ set(:issues, val)
59
+ end
60
+
61
+ def log
62
+ get(:log, Granify::DEFAULT_LOG)
63
+ end
64
+
65
+ def add_to_error_list(file)
66
+ @files_with_errors << file
67
+ end
68
+
69
+ def identifier=(val)
70
+ @identifier = val
71
+
72
+ # create the log file now
73
+ @d[:log] = Log.new(@branch, Time.now, @identifier)
74
+ end
75
+
76
+ def below_acceptable_limit?
77
+ get(:below_acceptable_limit) == true
78
+ end
79
+
80
+ def below_acceptable_limit=(val)
81
+ set(:below_acceptable_limit, val)
82
+ end
83
+
84
+ def bind!(seed_data)
85
+ @d = seed_data
86
+ end
87
+
88
+ def get(key, default = @d.default)
89
+ @d[key] || default
90
+ end
91
+
92
+ def set(key, val = nil)
93
+ @d[key] = val
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,232 @@
1
+ module Granify
2
+ module Model
3
+ class Hound < Model::Base
4
+ def coffee_data(files = [])
5
+ @data.identifier = :coffeelint
6
+
7
+ if files.size > 0
8
+ Notify.sinfo("Using command arguments as file list source")
9
+ end
10
+
11
+ # check if there are any files within the pwd
12
+ if files.size == 0
13
+ files = Utils.get_files(:coffee)
14
+
15
+ if files.size > 0
16
+ Notify.sinfo("Using #{Dir.pwd} as file list source")
17
+ end
18
+ end
19
+
20
+ # check the current git queue for JS/Coffee files to lint
21
+ if files.size == 0
22
+ files = Utils.get_files_from_git(:coffee)
23
+
24
+ if files.size > 0
25
+ Notify.sinfo("Using current git-commit queue as file list source")
26
+ end
27
+ end
28
+
29
+ # there were no files in the pwd, expand scope to all JS/Coffee files
30
+ if files.size == 0
31
+ files = Utils.get_all_files(:coffee)
32
+
33
+ if files.size > 0
34
+ Notify.sinfo("Using all .coffee files in current path (#{Dir.pwd}) as file list source")
35
+ end
36
+ end
37
+
38
+ # update total file size
39
+ @data.increment_status(:total, files.size)
40
+
41
+ # no coffeescript files anywhere?? don't try to lint anything
42
+ if files.size > 0
43
+ files.each do |file|
44
+ @command.lint(file, @data.log)
45
+
46
+ if @command.response
47
+ @data.status[:success] +=1
48
+ else
49
+ @data.status[:error] +=1
50
+ @data.add_to_error_list(file)
51
+ end
52
+ end
53
+
54
+ @data.log.total_files_processed = files.size
55
+
56
+ validation_issues_in_coffee(@data.log)
57
+
58
+ @data.success_rate[:int] = ((@data.status[:success].to_f / files.size.to_f) * 100).round(0)
59
+ @data.success_rate[:str] = @data.success_rate[:int].to_s + "%"
60
+ @data.status[:errors_per_file] = (@data.issues[:errors] / files.size.to_f).round(0)
61
+ @data.below_acceptable_limit = @data.success_rate[:int] > 70 && @data.status[:errors_per_file] < 5
62
+ else
63
+ Notify.error("No coffeescript files to process, exiting")
64
+ # don't need the current log file
65
+ @data.log.delete
66
+ end
67
+
68
+ @data
69
+ end
70
+
71
+ def widgets_data(files = [])
72
+ @data.identifier = :coffeelint
73
+
74
+ if files.size > 0
75
+ Notify.sinfo("Using command arguments as file list source")
76
+ end
77
+
78
+ # check if there are any files within the pwd
79
+ if files.size == 0
80
+ files = Utils.get_files(:coffee)
81
+
82
+ if files.size > 0
83
+ Notify.sinfo("Using #{Dir.pwd} as file list source")
84
+ end
85
+ end
86
+
87
+ # check the current git queue for JS/Coffee files to lint
88
+ if files.size == 0
89
+ files = Utils.get_files_from_git(:coffee)
90
+
91
+ if files.size > 0
92
+ Notify.sinfo("Using current git-commit queue as file list source")
93
+ end
94
+ end
95
+
96
+ # there were no files in the pwd, expand scope to all widget files
97
+ if files.size == 0
98
+ files = Utils.get_all_files(:coffee, 'widgets|widget_component')
99
+
100
+ if files.size > 0
101
+ Notify.sinfo("Using #{files.size} #{@data.identifier} files in (#{Dir.pwd}/widgets|widget_component) as file list source")
102
+ end
103
+ end
104
+
105
+ # update total file size
106
+ @data.increment_status(:total, files.size)
107
+
108
+ # no coffeescript files anywhere?? don't try to lint anything
109
+ if files.size > 0
110
+ files.each do |file|
111
+ @command.lint(file, @data.log)
112
+
113
+ if @command.response
114
+ @data.status[:success] +=1
115
+ else
116
+ @data.status[:error] +=1
117
+ @data.add_to_error_list(file)
118
+ end
119
+ end
120
+
121
+ @data.log.total_files_processed = files.size
122
+
123
+ validation_issues_in_coffee(@data.log)
124
+
125
+ @data.success_rate[:int] = ((@data.status[:success].to_f / files.size.to_f) * 100).round(0)
126
+ @data.success_rate[:str] = @data.success_rate[:int].to_s + "%"
127
+ @data.status[:errors_per_file] = (@data.issues[:errors] / files.size.to_f).round(0)
128
+ @data.below_acceptable_limit = @data.success_rate[:int] > 70 && @data.status[:errors_per_file] < 5
129
+ else
130
+ Notify.error("No coffeescript files to process, exiting")
131
+ # don't need the current log file
132
+ @data.log.delete
133
+ end
134
+
135
+ @data
136
+ end
137
+
138
+ def ruby_data(files = [])
139
+ @data.identifier = :ruby
140
+
141
+ if files.size > 0
142
+ Notify.sinfo("Using command arguments as file list source")
143
+ end
144
+
145
+ # check if there are any files within the pwd
146
+ # COMMENTED OUT for now because this may not be required functionality
147
+ # if files.size == 0
148
+ # files = Utils.get_files(:rb)
149
+
150
+ # if files.size > 0
151
+ # Notify.sinfo("Using #{Dir.pwd} as file list source")
152
+ # end
153
+ # end
154
+
155
+ # check the current git queue for JS/Coffee files to lint
156
+ if files.size == 0
157
+ files = Utils.get_files_from_git(:rb)
158
+
159
+ if files.size > 0
160
+ Notify.sinfo("Using current git-commit queue as file list source")
161
+ end
162
+ end
163
+
164
+ # there were no files in the pwd, expand scope to all widget files
165
+ if files.size == 0
166
+ files = Utils.get_all_files(:rb)
167
+
168
+ if files.size > 0
169
+ Notify.sinfo("Using #{files.size} #{@data.identifier} files in (#{Dir.pwd}/widgets|widget_component) as file list source")
170
+ end
171
+ end
172
+
173
+ if files.size > 0
174
+ files.each do |file|
175
+ @command.arbitrary("rubocop #{file}", @data.log)
176
+
177
+ if @command.response
178
+ @data.status[:success] +=1
179
+ else
180
+ @data.status[:error] +=1
181
+ @data.add_to_error_list(file)
182
+ end
183
+ end
184
+
185
+ @data.log.total_files_processed = @data.status[:total]
186
+
187
+ validation_issues_in_ruby(@data.log)
188
+
189
+ @data.status[:errors_per_file] = (@data.issues[:errors] / @data.status[:total]).round(0)
190
+ @data.success_rate[:int] = @data.status[:errors_per_file]
191
+ @data.success_rate[:str] = @data.success_rate[:int].to_s + "%"
192
+ @data.below_acceptable_limit = @data.success_rate[:int] > 90 && @data.status[:errors_per_file] < 5
193
+ else
194
+ Notify.error("No coffeescript files to process, exiting")
195
+ # don't need the current log file
196
+ @data.log.delete
197
+ end
198
+
199
+ @data
200
+ end
201
+
202
+ private
203
+ # TODO: can these be replaced by Log.errors
204
+ def validation_issues_in_coffee(file)
205
+ File.foreach(file.path) do |line|
206
+ matches = line.match(/Lint\! » (\d+) errors and (\d+)/)
207
+
208
+ if matches
209
+ @data.increment_issues(:errors, matches[1].to_i)
210
+ @data.increment_issues(:warnings, matches[2].to_i)
211
+ end
212
+ end
213
+
214
+ @data.issues
215
+ end
216
+
217
+ # TODO: benchmark, this may be super slow
218
+ def validation_issues_in_ruby(file)
219
+ last_line = IO.readlines(file.path)[-1].chomp
220
+ #matches = last_line.match(/(\d+) files inspected\, (\d+)/)
221
+ matches = last_line.scan(/[0-9]+/)
222
+
223
+ if matches
224
+ @data.increment_issues(:errors, matches[1].to_i)
225
+ @data.increment_status(:total, matches[0].to_i)
226
+ end
227
+
228
+ @data.issues
229
+ end
230
+ end
231
+ end
232
+ end
data/lib/request.rb ADDED
@@ -0,0 +1,20 @@
1
+ module Granify
2
+ class Request
3
+ attr_reader :controller, :command, :custom, :flags, :raw_flags
4
+
5
+ def initialize
6
+ @controller = ARGV[0].to_sym rescue nil
7
+
8
+ if ARGV.size > 1
9
+ @command = ARGV[1].to_sym rescue nil
10
+
11
+ if ARGV.size > 2
12
+ @custom = ARGV[2..ARGV.size].select { |p| !p.start_with?('-') }.map &:to_sym || []
13
+ # TODO: parameterize flag key/values
14
+ @flags = ARGV[2..ARGV.size].select { |f| f.start_with?('-') }.map { |f| f.split("=").map &:to_sym } || []
15
+ @raw_flags = ARGV[2..ARGV.size].select { |f| f.start_with?('-') } || []
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/router.rb ADDED
@@ -0,0 +1,73 @@
1
+ module Granify
2
+ class Router
3
+ def route
4
+ # Populate request params
5
+ $request = Request.new
6
+
7
+ # include the controller
8
+ if File.exists? "#{Granify::CONTROLLER_DIR}#{$request.controller}.rb"
9
+ require "#{Granify::CONTROLLER_DIR}#{$request.controller}.rb"
10
+ end
11
+
12
+ # include helpers
13
+ if File.exists? "#{Granify::HELPER_DIR}#{$request.controller}.rb"
14
+ require "#{Granify::HELPER_DIR}#{$request.controller}.rb"
15
+ end
16
+
17
+ # include models
18
+ if File.exists? "#{Granify::MODEL_DIR}#{$request.controller}.rb"
19
+ require "#{Granify::MODEL_DIR}#{$request.controller}.rb"
20
+ end
21
+
22
+ # Create object context and pass it the required command line arguments
23
+ begin
24
+ controller = Granify::Controller.const_get $request.controller.capitalize rescue false
25
+
26
+ if !controller
27
+ raise "Controller not found: #{$request.controller.capitalize}"
28
+ end
29
+
30
+ context = controller.new
31
+
32
+ if context.can_exec? $request.controller, $request.command
33
+ context.pre_exec
34
+
35
+ # no command sent? Use default to populate model data
36
+ model_method = ($request.command ? $request.command : context.default_method).to_s + "_data"
37
+
38
+ # populate model data
39
+ method = context.model.public_method(model_method) rescue false
40
+
41
+ # model is not set, use Base model instead so the controller still has
42
+ # access to model methods
43
+ if context.model.nil?
44
+ context.model = Model::Base.new
45
+ end
46
+
47
+ # If the method exists, set model data accordingly
48
+ # If it doesn't exist then just fail silently, the model may not
49
+ # be required by some controllers
50
+ if method.respond_to? :call
51
+ context.model.data = method.call($request.custom || [])
52
+ end
53
+
54
+ if context.methods_require_internet.include? $request.command
55
+ if !Utils.has_internet_connection?
56
+ raise RuntimeError, "Command `granify #{$request.controller} #{$request.command}` requires a connection to the internet.\nPlease check your network configuration settings."
57
+ end
58
+ end
59
+
60
+ # Run the controller
61
+ context.exec
62
+
63
+ # Run cleanup commands
64
+ context.post_exec
65
+ end
66
+ rescue RuntimeError => e
67
+ Notify.error("#{e.to_s}")
68
+ rescue NameError => e
69
+ Notify.error("#{e.to_s}\n#{e.backtrace.join("\n")}")
70
+ end
71
+ end
72
+ end
73
+ end
data/lib/utils.rb ADDED
@@ -0,0 +1,123 @@
1
+ module Granify
2
+ class Utils
3
+ @cache = Hash.new
4
+
5
+ # Gets a list of files from the current directory with a specific extension
6
+ def self.get_files(ext)
7
+ @cache[:files] ||= Hash.new
8
+ @cache[:files][ext] ||= []
9
+
10
+ Dir["*.#{ext}"].each do |file|
11
+ @cache[:files][ext].push file
12
+ end
13
+
14
+ @cache[:files][ext]
15
+ end
16
+
17
+ # Gets a list of all files in the project with a specific extension
18
+ def self.get_all_files(ext, ignore_paths = '')
19
+ @cache[:files] ||= Hash.new
20
+ @cache[:files][ext] ||= []
21
+
22
+ if @cache[:files][ext].empty?
23
+ Dir["**/*.#{ext}"].each do |file|
24
+ if !ignore_paths.empty?
25
+ # file is a widget
26
+ if /\/#{ignore_paths}/.match(file)
27
+ @cache[:files][ext].push file
28
+ end
29
+ else
30
+ # file is not a widget
31
+ @cache[:files][ext].push file
32
+ end
33
+ end
34
+ end
35
+
36
+ @cache[:files][ext]
37
+ end
38
+
39
+ # Gets a list of files from the current git commit queue with a specific
40
+ # extension
41
+ def self.get_files_from_git(ext)
42
+ @cache[:files] ||= Hash.new
43
+ @cache[:files][ext] ||= []
44
+
45
+ modified_files = `git status --porcelain`.split("\n")
46
+ modified_files.each do |file|
47
+ if file.match(/#{ext}/)
48
+ @cache[:files][ext].push file.strip.match(/[A-Z ]+(.*)/)[1]
49
+ end
50
+ end
51
+
52
+ @cache[:files][ext]
53
+ end
54
+
55
+ # Generate a filename
56
+ def self.generate_path(branch, time, identifier)
57
+ # create the directory if needed
58
+ Logs.mkdir identifier
59
+
60
+ # create a new log file with a path based on the input parameters
61
+ #Log.new(identifier, branch, time)
62
+ end
63
+
64
+ # Convert hash keys to symbols
65
+ def self.symbolize_keys(hash)
66
+ Hash[hash.map{ |k, v| [k.to_sym, v] }]
67
+ end
68
+
69
+ # Create a directory wherever the script is called from, if required
70
+ def self.mklocaldir(name)
71
+ dir = "#{Dir.pwd}/#{name.downcase}/"
72
+
73
+ if !Dir.exist? dir
74
+ Dir.mkdir dir
75
+ else
76
+ dir
77
+ end
78
+ end
79
+
80
+ def self.os
81
+ begin
82
+ @os ||= (
83
+ host_os = RbConfig::CONFIG['host_os']
84
+ case host_os
85
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
86
+ :windows
87
+ when /darwin|mac os/
88
+ :macosx
89
+ when /linux/
90
+ :linux
91
+ when /solaris|bsd/
92
+ :unix
93
+ else
94
+ raise TypeError, "unknown os: #{host_os.inspect}"
95
+ end
96
+ )
97
+ rescue err
98
+ Notify.error(err.message)
99
+ end
100
+ end
101
+
102
+ def self.json?(string)
103
+ begin
104
+ !!JSON.parse(string)
105
+ rescue
106
+ false
107
+ end
108
+ end
109
+
110
+ def self.http_response_code(url = nil)
111
+ begin
112
+ request = Net::HTTP.get_response(URI.parse(url || "http://google.com"))
113
+ request.code.to_i
114
+ rescue
115
+ 500
116
+ end
117
+ end
118
+
119
+ def self.has_internet_connection?
120
+ Utils.http_response_code < 499
121
+ end
122
+ end
123
+ end