rbtils 0.0.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.
- checksums.yaml +7 -0
- data/lib/command.rb +179 -0
- data/lib/config.rb +52 -0
- data/lib/configs/coffeelint.json +116 -0
- data/lib/constants.rb +15 -0
- data/lib/controller.rb +127 -0
- data/lib/controllers/branch.rb +14 -0
- data/lib/controllers/clean.rb +10 -0
- data/lib/controllers/hound.rb +72 -0
- data/lib/controllers/minify.rb +40 -0
- data/lib/controllers/open.rb +58 -0
- data/lib/controllers/update.rb +41 -0
- data/lib/helper.rb +19 -0
- data/lib/helpers/time.rb +28 -0
- data/lib/log.rb +111 -0
- data/lib/logs.rb +34 -0
- data/lib/model.rb +26 -0
- data/lib/model_data.rb +97 -0
- data/lib/models/hound.rb +232 -0
- data/lib/request.rb +20 -0
- data/lib/router.rb +73 -0
- data/lib/utils.rb +123 -0
- metadata +64 -0
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
|
data/lib/models/hound.rb
ADDED
@@ -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
|