spader 0.0.1.pre.pre
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/bin/spader +329 -0
- data/lib/spader/command.rb +15 -0
- data/lib/spader/commands/build.rb +121 -0
- data/lib/spader/commands/generate.rb +63 -0
- data/lib/spader/document.rb +23 -0
- data/lib/spader/documents/manifest.rb +25 -0
- data/lib/spader/documents/messages.rb +18 -0
- data/lib/spader/documents/project.rb +32 -0
- data/lib/spader/util.rb +136 -0
- data/lib/spader.rb +116 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d2603fbd12b3088658c382bf48ed92c41f66b6da5169692e96aa6b026b77907a
|
4
|
+
data.tar.gz: ac8d0454a647b8fc19878769504f00922b1c3af66d50e2e3506740f4b178f8a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fbc7426da951f50bdfb54515ecf29a27f6104df0e63598d6e442022bb434194affb1e1d055d596ba8d5e1474b8d2c56e8c768ee1303a430edcefa34826eec2ed
|
7
|
+
data.tar.gz: d5417d40a5b74db83a7b90d3fb55b5b865d4205230d1002bff3ea8e22e4bd3d229fd4c47a9a4d5a2110d81c72f60f314768bc62a7ff9af047df0cc4bfa236869
|
data/bin/spader
ADDED
@@ -0,0 +1,329 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# SPADER
|
4
|
+
# WebExtension maker's toolkit.
|
5
|
+
# Copyright (C) 2020 Cosmic Shovel, Inc.
|
6
|
+
|
7
|
+
require "spader"
|
8
|
+
|
9
|
+
#require_relative "rb/dl_libs"
|
10
|
+
#require_relative "rb/rendering_helpers"
|
11
|
+
|
12
|
+
########################################################################################
|
13
|
+
|
14
|
+
if ARGV.length() == 0 || ARGV.include?("--help") || ARGV.include?("-h")
|
15
|
+
puts "spader <command> <args>\nvalid commands: generate, download, build, help\nvalid parameters:\n* generate: <project title>\n* download: none\n* build: <extension path> <browser> <environment> <version> [--zip]\n* help: <command>\n"
|
16
|
+
exit(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
spader_command = ARGV[0]
|
20
|
+
spader_command_args = ARGV.drop(1)
|
21
|
+
|
22
|
+
begin
|
23
|
+
|
24
|
+
case spader_command
|
25
|
+
when "build"
|
26
|
+
Spader.build(spader_command_args)
|
27
|
+
#dmsg("Building...")
|
28
|
+
#build(ARGV[1].dup(), ARGV[2].dup(), ARGV[3].dup(), ARGV[4].dup(), ARGV.include?("--zip"))
|
29
|
+
when "download"
|
30
|
+
Spader.download(spader_command_args)
|
31
|
+
#dmsg("Downloading...")
|
32
|
+
#dmsg("Not implemented!")
|
33
|
+
when "generate"
|
34
|
+
Spader.generate(spader_command_args)
|
35
|
+
#dmsg("Generating skeleton...")
|
36
|
+
|
37
|
+
#title = ARGV[1]
|
38
|
+
|
39
|
+
#if title.nil?()
|
40
|
+
# dmsg("ruby spader.rb --skeleton <extension name>")
|
41
|
+
# exit(0)
|
42
|
+
#end
|
43
|
+
|
44
|
+
#generate_skeleton(__dir__ + "/#{title.downcase().gsub(" ", "_")}/", title)
|
45
|
+
when "help"
|
46
|
+
case spader_command_args[0]
|
47
|
+
when "build"
|
48
|
+
puts "The build command compiles your code into a WebExtension."
|
49
|
+
when "download"
|
50
|
+
puts "The download command installs bit-perfect copies of third party libraries into your source directory ."
|
51
|
+
when "skeleton"
|
52
|
+
puts "The skeleton command generates an empty but build-able project directory."
|
53
|
+
else
|
54
|
+
puts "Invalid command: #{spader_command_args[0]}"
|
55
|
+
end
|
56
|
+
|
57
|
+
exit(0)
|
58
|
+
else
|
59
|
+
puts "Invalid command, exiting."
|
60
|
+
exit(0)
|
61
|
+
end
|
62
|
+
rescue Spader::Command::InvalidParametersError => e
|
63
|
+
puts "Aborting due to invalid parameters."
|
64
|
+
exit(1)
|
65
|
+
end
|
66
|
+
|
67
|
+
exit(0)
|
68
|
+
|
69
|
+
zip_it = ARGV.include?("--zip")
|
70
|
+
dl_libs = ARGV.include?("--download-libs")
|
71
|
+
generate_skeleton = ARGV.include?("--skeleton")
|
72
|
+
|
73
|
+
if ARGV.length() < 3 && !dl_libs && !generate_skeleton
|
74
|
+
dmsg("ruby spader.rb <browser> <environment> <version> [--zip]")
|
75
|
+
dmsg("OR")
|
76
|
+
dmsg("ruby spader.rb --download-libs")
|
77
|
+
dmsg("OR")
|
78
|
+
dmsg("ruby spader.rb --skeleton <extension name>")
|
79
|
+
exit(0)
|
80
|
+
end
|
81
|
+
|
82
|
+
if generate_skeleton
|
83
|
+
title = ARGV[1]
|
84
|
+
|
85
|
+
if title.nil?()
|
86
|
+
dmsg("ruby spader.rb --skeleton <extension name>")
|
87
|
+
exit(0)
|
88
|
+
end
|
89
|
+
|
90
|
+
dmsg("Initializing extension: #{title}")
|
91
|
+
generate_skeleton(__dir__ + "/#{title.downcase().gsub(" ", "_")}/", title)
|
92
|
+
exit(0)
|
93
|
+
end
|
94
|
+
|
95
|
+
browser = ARGV[0]
|
96
|
+
environment = ARGV[1]
|
97
|
+
version = ARGV[2].dup()
|
98
|
+
|
99
|
+
browser_requires_polyfill = is_browser_chromal?(browser)
|
100
|
+
build_info = DateTime.now().strftime("%Y-%m-%d @ %H:%M:%S")
|
101
|
+
out_dir = "dist/#{environment}/#{browser}/"
|
102
|
+
camel_domain = "dissident.be"
|
103
|
+
api_endpoint = "dissident.be"
|
104
|
+
charts_domain = "charts-dev.camelcamelcamel.com"
|
105
|
+
#analytics_endpoint = "127.0.0.1:8787/"
|
106
|
+
analytics_endpoint = "hello.camelcamelcamel.com/camelizer"
|
107
|
+
zoom_levels = [0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1.0, 1.1, 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 4.0, 5.0]
|
108
|
+
|
109
|
+
case browser
|
110
|
+
when "firefox"
|
111
|
+
zoom_levels = [0.3, 0.5, 0.67, 0.8, 0.9, 1.0, 1.1, 1.2, 1.33, 1.5, 1.7, 2.0, 2.4, 3.0]
|
112
|
+
when "safari"
|
113
|
+
zoom_levels = []
|
114
|
+
end
|
115
|
+
|
116
|
+
case environment
|
117
|
+
when "production"
|
118
|
+
out_dir << "#{version}/"
|
119
|
+
camel_domain = "camelcamelcamel.com"
|
120
|
+
api_endpoint = "izer.camelcamelcamel.com"
|
121
|
+
charts_domain = "charts.camelcamelcamel.com"
|
122
|
+
when "development"
|
123
|
+
version << "000"
|
124
|
+
end
|
125
|
+
|
126
|
+
if dl_libs
|
127
|
+
dl_libs(__dir__)
|
128
|
+
exit(0)
|
129
|
+
end
|
130
|
+
|
131
|
+
required_domains = [
|
132
|
+
"camelcamelcamel.com",
|
133
|
+
"amazon.com",
|
134
|
+
"amazon.co.uk",
|
135
|
+
"amazon.fr",
|
136
|
+
"amazon.de",
|
137
|
+
"amazon.es",
|
138
|
+
"amazon.ca",
|
139
|
+
"amazon.it",
|
140
|
+
"amazon.com.au",
|
141
|
+
"camelizer.net",
|
142
|
+
"camelizer.org",
|
143
|
+
]
|
144
|
+
|
145
|
+
html_templates = [
|
146
|
+
"html/main.html.erb",
|
147
|
+
"html/background.html.erb",
|
148
|
+
"html/camel.html.erb",
|
149
|
+
"html/options.html.erb",
|
150
|
+
]
|
151
|
+
|
152
|
+
js_templates = [
|
153
|
+
"js/3camelizer.js.erb",
|
154
|
+
"js/main.js.erb",
|
155
|
+
"js/background.js.erb",
|
156
|
+
"js/camel.js.erb",
|
157
|
+
"js/options.js.erb",
|
158
|
+
"js/content_script/announce.js.erb",
|
159
|
+
]
|
160
|
+
|
161
|
+
static_files = [
|
162
|
+
"js/jquery/jquery-3.5.1.min.js",
|
163
|
+
"js/foundation/foundation.js",
|
164
|
+
"js/tooltipster/tooltipster.bundle.js",
|
165
|
+
"js/util/what-input.js",
|
166
|
+
"js/content_script/get_all_anchors.js",
|
167
|
+
"js/content_script/set_firstrun_options.js",
|
168
|
+
"js/introjs/intro.js",
|
169
|
+
"txt/privacy.txt",
|
170
|
+
"icon/icon-16.png",
|
171
|
+
"icon/icon-32.png",
|
172
|
+
"icon/icon-48.png",
|
173
|
+
"icon/icon-64.png",
|
174
|
+
"icon/icon-96.png",
|
175
|
+
"icon/icon-128.png",
|
176
|
+
"icon/icon-256.png",
|
177
|
+
"icon/help-logo.png",
|
178
|
+
"icon/gradient.png",
|
179
|
+
"icon/chart_error.png",
|
180
|
+
"font/fa-solid-900.woff2",
|
181
|
+
"font/KFOmCnqEu92Fr1Mu7GxKOzY.woff2",
|
182
|
+
"font/KFOmCnqEu92Fr1Mu4mxK.woff2"
|
183
|
+
]
|
184
|
+
|
185
|
+
if browser_requires_polyfill
|
186
|
+
static_files << "js/browser/browser-polyfill.min.js"
|
187
|
+
end
|
188
|
+
|
189
|
+
translated_files = {
|
190
|
+
"manifest/#{browser}.json" => "manifest.json",
|
191
|
+
#"config/#{browser}.js" => "config.js",
|
192
|
+
#"environment/#{environment}.js" => "environment.js",
|
193
|
+
}
|
194
|
+
|
195
|
+
dirs = [
|
196
|
+
]
|
197
|
+
|
198
|
+
case browser
|
199
|
+
when"firefox"
|
200
|
+
translated_files["txt/links.txt"] = "amo-reviewer-links.txt"
|
201
|
+
end
|
202
|
+
|
203
|
+
SassC.load_paths << (__dir__ + "/scss/")
|
204
|
+
SassC.load_paths << (__dir__ + "/scss/foundation/")
|
205
|
+
|
206
|
+
dmsg("BUILDING #{browser}/#{environment} into #{out_dir}")
|
207
|
+
|
208
|
+
Dir.chdir(__dir__)
|
209
|
+
|
210
|
+
if Dir.exists?(out_dir)
|
211
|
+
dmsg(" Removing old dirs")
|
212
|
+
FileUtils.remove_dir(out_dir)
|
213
|
+
end
|
214
|
+
|
215
|
+
dmsg(" Ensuring dirs exist")
|
216
|
+
FileUtils.mkdir_p(out_dir)
|
217
|
+
|
218
|
+
dmsg(" Compiling SCSS")
|
219
|
+
Dir.chdir(__dir__ + "/scss/")
|
220
|
+
scss = SassC::Engine.new(read_file("3camelizer.scss"), style: :expanded).render()
|
221
|
+
|
222
|
+
Dir.chdir(__dir__)
|
223
|
+
|
224
|
+
dmsg(" Writing #{pretty_float(scss.length().to_f() / 1024.0)} KB to #{out_dir}/3camelizer.css")
|
225
|
+
write_file("#{out_dir}/3camelizer.css", scss)
|
226
|
+
|
227
|
+
if browser == "safari"
|
228
|
+
Dir.chdir(__dir__ + "/scss/")
|
229
|
+
scss = SassC::Engine.new(read_file("safari.scss"), style: :expanded).render()
|
230
|
+
|
231
|
+
Dir.chdir(__dir__)
|
232
|
+
|
233
|
+
dmsg(" Writing #{pretty_float(scss.length().to_f() / 1024.0)} KB to #{out_dir}/safari.css")
|
234
|
+
write_file("#{out_dir}/safari.css", scss)
|
235
|
+
end
|
236
|
+
|
237
|
+
dmsg(" Rendering JS")
|
238
|
+
js_templates.each do |infile|
|
239
|
+
outfile = out_dir + File.basename(infile, ".erb")
|
240
|
+
dmsg(" Rendering #{infile} to #{outfile}")
|
241
|
+
js = render(infile)
|
242
|
+
dmsg(" Writing #{pretty_float(js.length().to_f() / 1024.0)} KB")
|
243
|
+
write_file(outfile, js)
|
244
|
+
end
|
245
|
+
|
246
|
+
dmsg(" Rendering HTML...")
|
247
|
+
html_templates.each do |infile|
|
248
|
+
outfile = out_dir + File.basename(infile, ".erb")
|
249
|
+
dmsg(" Rendering #{infile} to #{outfile}")
|
250
|
+
html = render(infile)
|
251
|
+
dmsg(" Writing #{pretty_float(html.length().to_f() / 1024.0)} KB")
|
252
|
+
write_file(outfile, html)
|
253
|
+
end
|
254
|
+
|
255
|
+
dmsg(" Copying files...")
|
256
|
+
|
257
|
+
static_files.each do |infile|
|
258
|
+
outfile = out_dir + File.basename(infile)
|
259
|
+
dmsg(" Copying #{infile} to #{outfile}")
|
260
|
+
FileUtils.cp(infile, outfile)
|
261
|
+
end
|
262
|
+
|
263
|
+
translated_files.each do |infile,outfile|
|
264
|
+
outpath = out_dir + outfile
|
265
|
+
dmsg(" Copying #{infile} to #{outpath}")
|
266
|
+
FileUtils.cp(infile, outpath)
|
267
|
+
end
|
268
|
+
|
269
|
+
dirs.each do |indir|
|
270
|
+
Dir.entries(indir).each do |entry|
|
271
|
+
if entry[0, 1] == "."
|
272
|
+
next
|
273
|
+
end
|
274
|
+
|
275
|
+
dmsg(" Copying #{indir + "/" + entry} to #{out_dir + entry}")
|
276
|
+
|
277
|
+
FileUtils.cp(indir + "/" + entry, out_dir + entry)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
dmsg(" Copying _locales to #{out_dir + "_locales"}")
|
282
|
+
FileUtils.cp_r("_locales", out_dir + "_locales")
|
283
|
+
|
284
|
+
dmsg(" Updating manifest.json")
|
285
|
+
manifest = JSON.parse(read_file(out_dir + "manifest.json"))
|
286
|
+
manifest["version"] = version
|
287
|
+
|
288
|
+
perms = [
|
289
|
+
"activeTab",
|
290
|
+
"storage",
|
291
|
+
# "cookies",
|
292
|
+
#"tabs",
|
293
|
+
]
|
294
|
+
|
295
|
+
if !is_browser_chromal?(browser)
|
296
|
+
perms << "tabs"
|
297
|
+
end
|
298
|
+
|
299
|
+
required_domains.each do |dom|
|
300
|
+
perms << "http://#{dom}/*"
|
301
|
+
perms << "https://#{dom}/*"
|
302
|
+
perms << "http://*.#{dom}/*"
|
303
|
+
perms << "https://*.#{dom}/*"
|
304
|
+
end
|
305
|
+
|
306
|
+
manifest["permissions"] += perms
|
307
|
+
|
308
|
+
if environment == "development"
|
309
|
+
manifest["permissions"] << "http://*.dissident.be/*"
|
310
|
+
manifest["permissions"] << "http://dissident.be/*"
|
311
|
+
manifest["permissions"] << "https://*.dissident.be/*"
|
312
|
+
manifest["permissions"] << "https://dissident.be/*"
|
313
|
+
end
|
314
|
+
|
315
|
+
manifest["default_locale"] = "en"
|
316
|
+
|
317
|
+
manifest["options_ui"] = {
|
318
|
+
"page" => "options.html",
|
319
|
+
}
|
320
|
+
|
321
|
+
write_file(out_dir + "manifest.json", JSON.pretty_generate(manifest))
|
322
|
+
|
323
|
+
if zip_it
|
324
|
+
dmsg(" Creating zip archive...")
|
325
|
+
zip_file = ZipFileGenerator.new(out_dir, "dist/3camelizer-#{browser}-#{environment}-#{version}.zip")
|
326
|
+
zip_file.write()
|
327
|
+
end
|
328
|
+
|
329
|
+
dmsg("Build complete!")
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#require "spader/commands/build"
|
2
|
+
#require "spader/commands/download"
|
3
|
+
|
4
|
+
module Spader
|
5
|
+
class Command
|
6
|
+
class InvalidParametersError < StandardError; end;
|
7
|
+
|
8
|
+
def execute()
|
9
|
+
puts "RUNNING #{self.class}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require "spader/commands/generate"
|
14
|
+
require "spader/commands/build"
|
15
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Spader
|
2
|
+
class BuildCommand < Command
|
3
|
+
attr_accessor :zip, :path, :browsers, :browser, :environment, :version, :build_info
|
4
|
+
|
5
|
+
def initialize()
|
6
|
+
@path = nil
|
7
|
+
@zip = false
|
8
|
+
@environment = "development"
|
9
|
+
@version = "0.0.0"
|
10
|
+
@browsers = BROWSERS
|
11
|
+
@browser = nil
|
12
|
+
@build_info = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute()
|
16
|
+
super
|
17
|
+
puts "Building #{@path} @ v#{@version}/#{@environment} for #{@browsers.length} browser(s)."
|
18
|
+
|
19
|
+
if @path.nil?() || @path.empty?()
|
20
|
+
puts "Path is required."
|
21
|
+
raise InvalidParametersError
|
22
|
+
end
|
23
|
+
|
24
|
+
scss_dir = @path + "scss/"
|
25
|
+
font_dir = @path + "font/"
|
26
|
+
html_dir = @path + "html/"
|
27
|
+
icon_dir = @path + "icon/"
|
28
|
+
java_dir = @path + "js/"
|
29
|
+
mani_dir = @path + "manifest/"
|
30
|
+
msgs_dir = @path + "_locales/"
|
31
|
+
|
32
|
+
SassC.load_paths << scss_dir
|
33
|
+
|
34
|
+
dirs_in_dir(scss_dir).each do |dir|
|
35
|
+
SassC.load_paths << dir
|
36
|
+
end
|
37
|
+
|
38
|
+
@build_info = DateTime.now().strftime("%Y-%m-%d @ %H:%M:%S")
|
39
|
+
|
40
|
+
@browsers.each do |browser|
|
41
|
+
@browser = browser
|
42
|
+
dest_dir = @path + "dist/#{@environment}/#{browser}/"
|
43
|
+
|
44
|
+
if environment == "production"
|
45
|
+
dest_dir << "#{@version}/"
|
46
|
+
end
|
47
|
+
|
48
|
+
puts "Output dir: #{dest_dir}"
|
49
|
+
|
50
|
+
if Dir.exists?(dest_dir)
|
51
|
+
FileUtils.remove_dir(dest_dir)
|
52
|
+
end
|
53
|
+
|
54
|
+
FileUtils.mkdir_p(dest_dir)
|
55
|
+
|
56
|
+
# manifest
|
57
|
+
in_manifest = mani_dir + "#{browser}.json"
|
58
|
+
out_manifest = dest_dir + "manifest.json"
|
59
|
+
FileUtils.cp(in_manifest, out_manifest)
|
60
|
+
|
61
|
+
# messages
|
62
|
+
FileUtils.cp_r(msgs_dir, dest_dir + "_locales")
|
63
|
+
|
64
|
+
scss_files = primary_files_in_dir(scss_dir)
|
65
|
+
|
66
|
+
scss_files.each do |scss_file|
|
67
|
+
puts scss_file
|
68
|
+
in_filename = File.basename(scss_file)
|
69
|
+
out_file = dest_dir + in_filename.gsub(".erb", "").gsub(".css", "").gsub(".scss", "")
|
70
|
+
out_file << ".css"
|
71
|
+
scss_data = nil
|
72
|
+
|
73
|
+
if in_filename.include?(".erb")
|
74
|
+
scss_data = render(scss_file)
|
75
|
+
else
|
76
|
+
scss_data = read_file(scss_file)
|
77
|
+
end
|
78
|
+
|
79
|
+
scss_data = SassC::Engine.new(scss_data, :style => :expanded).render()
|
80
|
+
write_file(out_file, scss_data)
|
81
|
+
end
|
82
|
+
|
83
|
+
js_files = primary_files_in_dir(java_dir)
|
84
|
+
|
85
|
+
js_files.each do |js_file|
|
86
|
+
puts js_file
|
87
|
+
in_filename = File.basename(js_file)
|
88
|
+
out_file = dest_dir + in_filename.gsub(".erb", "").gsub(".js", "")
|
89
|
+
out_file << ".js"
|
90
|
+
js_data = nil
|
91
|
+
|
92
|
+
if in_filename.include?(".erb")
|
93
|
+
js_data = render(js_file)
|
94
|
+
else
|
95
|
+
js_data = read_file(js_file)
|
96
|
+
end
|
97
|
+
|
98
|
+
write_file(out_file, js_data)
|
99
|
+
end
|
100
|
+
|
101
|
+
html_files = primary_files_in_dir(html_dir)
|
102
|
+
|
103
|
+
html_files.each do |html_file|
|
104
|
+
puts html_file
|
105
|
+
in_filename = File.basename(html_file)
|
106
|
+
out_file = dest_dir + in_filename.gsub(".erb", "").gsub(".html", "")
|
107
|
+
out_file << ".html"
|
108
|
+
html_data = nil
|
109
|
+
|
110
|
+
if in_filename.include?(".erb")
|
111
|
+
html_data = render(html_file)
|
112
|
+
else
|
113
|
+
html_data = read_file(html_data)
|
114
|
+
end
|
115
|
+
|
116
|
+
write_file(out_file, html_data)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "spader/command"
|
2
|
+
|
3
|
+
module Spader
|
4
|
+
class GenerateCommand < Command
|
5
|
+
attr_accessor :path, :title
|
6
|
+
|
7
|
+
def execute()
|
8
|
+
super
|
9
|
+
puts "Generating \"#{@title}\" into #{@path}"
|
10
|
+
|
11
|
+
if @path.nil?() || @path.empty?() || @title.nil?() || @title.empty?()
|
12
|
+
puts "Path and Title are required."
|
13
|
+
raise InvalidParametersError
|
14
|
+
end
|
15
|
+
|
16
|
+
project = Project.generate(@path, :title => @title)
|
17
|
+
|
18
|
+
if Dir.exists?(project.path)
|
19
|
+
puts "Removing existing dir..."
|
20
|
+
FileUtils.remove_dir(project.path)
|
21
|
+
end
|
22
|
+
|
23
|
+
FileUtils.mkdir_p(project.path)
|
24
|
+
|
25
|
+
project.save_json(project.path + "spader.json")
|
26
|
+
|
27
|
+
new_dirs = [
|
28
|
+
"_locales/en",
|
29
|
+
"dist/development",
|
30
|
+
"dist/production",
|
31
|
+
"font",
|
32
|
+
"html",
|
33
|
+
"icon",
|
34
|
+
"js",
|
35
|
+
"manifest",
|
36
|
+
"promo",
|
37
|
+
"scss",
|
38
|
+
"txt",
|
39
|
+
]
|
40
|
+
|
41
|
+
new_dirs.each do |new_dir|
|
42
|
+
FileUtils.mkdir_p(project.path + new_dir)
|
43
|
+
end
|
44
|
+
|
45
|
+
FileUtils.touch(project.path + "txt/README.md")
|
46
|
+
|
47
|
+
messages = Messages.generate(project.title)
|
48
|
+
messages.save_json(project.path + "_locales/en/messages.json")
|
49
|
+
|
50
|
+
manifest = Manifest.generate()
|
51
|
+
|
52
|
+
BROWSERS.each do |browser|
|
53
|
+
if browser == "chrome"
|
54
|
+
manifest.document["update_url"] = "http://clients2.google.com/service/update2/crx"
|
55
|
+
else
|
56
|
+
manifest.document.delete("update_url")
|
57
|
+
end
|
58
|
+
|
59
|
+
manifest.save_json(project.path + "manifest/#{browser}.json")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Spader
|
2
|
+
require "spader/util"
|
3
|
+
|
4
|
+
class Document
|
5
|
+
attr_accessor :document
|
6
|
+
|
7
|
+
def initialize()
|
8
|
+
@document = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def load_json(path)
|
12
|
+
@document = JSON.parse(read_file(path))
|
13
|
+
end
|
14
|
+
|
15
|
+
def save_json(path)
|
16
|
+
write_file(path, JSON.pretty_generate(@document))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require "spader/documents/project"
|
21
|
+
require "spader/documents/manifest"
|
22
|
+
require "spader/documents/messages"
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Spader
|
2
|
+
class Manifest < Document
|
3
|
+
def self.generate()
|
4
|
+
manifest = Manifest.new()
|
5
|
+
|
6
|
+
manifest.document = {
|
7
|
+
"manifest_version" => 2,
|
8
|
+
"name" => "__MSG_appName__",
|
9
|
+
"short_name" => "__MSG_appName__",
|
10
|
+
"description" => "__MSG_appDesc__",
|
11
|
+
"default_locale" => "en",
|
12
|
+
"version" => "0.0.1",
|
13
|
+
"icons" => {
|
14
|
+
"32" => "icon.png",
|
15
|
+
},
|
16
|
+
"author" => "Sleve Mcdichael",
|
17
|
+
"homepage_url" => "https://cosmicshovel.com/",
|
18
|
+
"permissions" => [
|
19
|
+
],
|
20
|
+
}
|
21
|
+
|
22
|
+
return manifest
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Spader
|
2
|
+
class Messages < Document
|
3
|
+
def self.generate(project_title)
|
4
|
+
messages = Messages.new()
|
5
|
+
|
6
|
+
messages.document = {
|
7
|
+
"appName" => {
|
8
|
+
"message" => project_title,
|
9
|
+
},
|
10
|
+
"appDesc" => {
|
11
|
+
"message" => "This is a WebExtension project."
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
return messages
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Spader
|
2
|
+
class Project < Document
|
3
|
+
attr_accessor :title, :url, :author, :html, :js, :scss, :path
|
4
|
+
|
5
|
+
def self.generate(base_dir, opts = {})
|
6
|
+
project = Project.new()
|
7
|
+
project.path = File.absolute_path(base_dir, Dir.pwd) + File::SEPARATOR
|
8
|
+
project.title = opts.delete(:title) || "Example Title"
|
9
|
+
project.url = opts.delete(:url) || "https://cosmicshovel.com/"
|
10
|
+
project.author = opts.delete(:author) || "Cosmic Shovel, Inc."
|
11
|
+
project.html = []
|
12
|
+
project.js = []
|
13
|
+
project.scss = []
|
14
|
+
|
15
|
+
return project
|
16
|
+
end
|
17
|
+
|
18
|
+
def save_json(path)
|
19
|
+
@document = {
|
20
|
+
"path" => @path,
|
21
|
+
"title" => @title,
|
22
|
+
"url" => @url,
|
23
|
+
"author" => @author,
|
24
|
+
"html" => @html,
|
25
|
+
"js" => @js,
|
26
|
+
"scss" => @scss,
|
27
|
+
}
|
28
|
+
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/spader/util.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
def write_file(filename, data, append = false)
|
2
|
+
if data.is_a?(String)
|
3
|
+
data = data.force_encoding(Encoding::UTF_8)
|
4
|
+
end
|
5
|
+
|
6
|
+
begin
|
7
|
+
File.open(filename, append ? "a" : "w") { |f|
|
8
|
+
f.write(data)
|
9
|
+
}
|
10
|
+
rescue Exception => e
|
11
|
+
dmsg(e)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def read_file(filename)
|
16
|
+
begin
|
17
|
+
File.open(filename, "r") do |f|
|
18
|
+
return f.readlines().join("")
|
19
|
+
end
|
20
|
+
rescue Exception => e
|
21
|
+
dmsg(e)
|
22
|
+
end
|
23
|
+
|
24
|
+
return nil
|
25
|
+
end
|
26
|
+
|
27
|
+
# eventually this should use a special Spader binding
|
28
|
+
# and allow users to expose their own variables
|
29
|
+
def render(template)
|
30
|
+
browser = $spader_cmd.browser
|
31
|
+
build_info = $spader_cmd.build_info
|
32
|
+
camel_domain = "dissident.be"
|
33
|
+
api_endpoint = "dissident.be"
|
34
|
+
charts_domain = "charts-dev.camelcamelcamel.com"
|
35
|
+
analytics_endpoint = "hello.camelcamelcamel.com/camelizer"
|
36
|
+
browser_requires_polyfill = is_browser_chromal?()
|
37
|
+
zoom_levels = [0.25, 0.33, 0.5, 0.67, 0.75, 0.8, 0.9, 1.0, 1.1, 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 4.0, 5.0]
|
38
|
+
b = binding
|
39
|
+
template = File.absolute_path(template, $spader_cmd.path)
|
40
|
+
|
41
|
+
return ERB.new(read_file(template)).result(b)
|
42
|
+
end
|
43
|
+
|
44
|
+
def pad10(str_num)
|
45
|
+
return "%02d" % [str_num.to_i()]
|
46
|
+
end
|
47
|
+
|
48
|
+
def dmsg(msg, cache = false)
|
49
|
+
t = DateTime.now()
|
50
|
+
msg = msg.is_a?(String) ? msg : msg.inspect()
|
51
|
+
|
52
|
+
puts "[#{pad10(t.hour())}:#{pad10(t.min())}:#{pad10(t.sec())}] " + msg
|
53
|
+
end
|
54
|
+
|
55
|
+
def pretty_float(f)
|
56
|
+
return ("%0.2f" % f)
|
57
|
+
end
|
58
|
+
|
59
|
+
def is_camelizer_three_oh_oh?(ver)
|
60
|
+
return Gem::Version.new(ver) == Gem::Version.new("3.0.0")
|
61
|
+
end
|
62
|
+
|
63
|
+
def anchor_target()
|
64
|
+
if !is_browser_chromal?()
|
65
|
+
return ""
|
66
|
+
end
|
67
|
+
|
68
|
+
return "target=\"_blank\""
|
69
|
+
end
|
70
|
+
|
71
|
+
def is_browser_chromal?()
|
72
|
+
return %w[chrome edge opera brave].include?($spader_cmd.browser.downcase())
|
73
|
+
end
|
74
|
+
|
75
|
+
def browsers()
|
76
|
+
return Spader::BROWSERS
|
77
|
+
end
|
78
|
+
|
79
|
+
def entries(path)
|
80
|
+
list = Dir.entries(path).delete_if {|f| f == "." || f == ".."}
|
81
|
+
out = []
|
82
|
+
|
83
|
+
list.each do |entry|
|
84
|
+
full_path = path.dup()
|
85
|
+
|
86
|
+
if path[-1, 1] != "/"
|
87
|
+
full_path << "/"
|
88
|
+
end
|
89
|
+
|
90
|
+
full_path << entry
|
91
|
+
out << full_path
|
92
|
+
end
|
93
|
+
|
94
|
+
return out
|
95
|
+
end
|
96
|
+
|
97
|
+
def dirs_in_dir(path)
|
98
|
+
list = entries(path).delete_if {|f| !File.directory?(f)}
|
99
|
+
out = []
|
100
|
+
|
101
|
+
list.each do |entry|
|
102
|
+
if entry[-1, 1] != "/"
|
103
|
+
entry << "/"
|
104
|
+
end
|
105
|
+
|
106
|
+
out << entry
|
107
|
+
end
|
108
|
+
|
109
|
+
return out
|
110
|
+
end
|
111
|
+
|
112
|
+
def files_in_dir(path)
|
113
|
+
list = entries(path).delete_if {|f| File.directory?(f)}
|
114
|
+
|
115
|
+
return list
|
116
|
+
end
|
117
|
+
|
118
|
+
def primary_files_in_dir(path)
|
119
|
+
return files_in_dir(path).delete_if {|f| File.basename(f)[0, 1] == "_"}
|
120
|
+
end
|
121
|
+
|
122
|
+
def partial_files_in_dir(path)
|
123
|
+
return files_in_dir(path).delete_if {|f| File.basename(f)[0, 1] != "_"}
|
124
|
+
end
|
125
|
+
|
126
|
+
def primary_scss_files()
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
def primary_js_files()
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
def primary_html_files()
|
135
|
+
|
136
|
+
end
|
data/lib/spader.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
#require "spader/util"
|
2
|
+
#require "spader/zip"
|
3
|
+
#require "spader/skeleton"
|
4
|
+
#require "spader/build"
|
5
|
+
#require "spader/download"
|
6
|
+
|
7
|
+
require "spader/command"
|
8
|
+
require "spader/document"
|
9
|
+
|
10
|
+
$spader_cmd = nil
|
11
|
+
|
12
|
+
module Spader
|
13
|
+
BROWSERS = %w[chrome edge firefox opera safari].freeze()
|
14
|
+
ENVIRONMENTS = %w[development production].freeze()
|
15
|
+
|
16
|
+
require "date"
|
17
|
+
require "fileutils"
|
18
|
+
require "json"
|
19
|
+
|
20
|
+
require "sassc"
|
21
|
+
require "uglifier"
|
22
|
+
|
23
|
+
require "optparse"
|
24
|
+
|
25
|
+
def self.build(args)
|
26
|
+
cmd = BuildCommand.new()
|
27
|
+
|
28
|
+
OptionParser.new do |opts|
|
29
|
+
opts.banner = "Usage: spader build <path> [options]"
|
30
|
+
|
31
|
+
def opts.show_usage()
|
32
|
+
puts self
|
33
|
+
exit(1)
|
34
|
+
end
|
35
|
+
|
36
|
+
if args.empty?()
|
37
|
+
opts.show_usage()
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("-e", "--environment=ENVIRONMENT", "The target environment") do |env|
|
41
|
+
if !ENVIRONMENTS.include?(env)
|
42
|
+
opts.warn("Invalid environment specified")
|
43
|
+
opts.show_usage()
|
44
|
+
end
|
45
|
+
|
46
|
+
cmd.environment = env
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on("-b", "--browsers=BROWSERS", "The target browser(s) in a comma-separated list") do |browsers|
|
50
|
+
cmd.browsers = browsers.split(",")
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on("-v", "--version=VERSION", "The build version") do |version|
|
54
|
+
cmd.version = version
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on("--zip", "Create a zip file of the build") do
|
58
|
+
cmd.zip = true
|
59
|
+
end
|
60
|
+
|
61
|
+
begin
|
62
|
+
opts.order(args) do |path|
|
63
|
+
cmd.path = File.absolute_path(path, Dir.pwd)
|
64
|
+
|
65
|
+
if cmd.path[-1, 1] != File::SEPARATOR
|
66
|
+
cmd.path << File::SEPARATOR
|
67
|
+
end
|
68
|
+
end
|
69
|
+
rescue OptionParser::ParseError => e
|
70
|
+
opts.warn(e.message)
|
71
|
+
opts.show_usage()
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
$spader_cmd = cmd
|
76
|
+
cmd.execute()
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.generate(args)
|
80
|
+
cmd = GenerateCommand.new()
|
81
|
+
|
82
|
+
OptionParser.new do |opts|
|
83
|
+
opts.banner = "Usage: spader generate <path>"
|
84
|
+
|
85
|
+
def opts.show_usage()
|
86
|
+
puts self
|
87
|
+
exit(1)
|
88
|
+
end
|
89
|
+
|
90
|
+
if args.empty?()
|
91
|
+
opts.show_usage()
|
92
|
+
end
|
93
|
+
|
94
|
+
begin
|
95
|
+
opts.order(args) do |path|
|
96
|
+
cmd.path = File.absolute_path(path, Dir.pwd)
|
97
|
+
|
98
|
+
if cmd.path[-1, 1] != File::SEPARATOR
|
99
|
+
cmd.path << File::SEPARATOR
|
100
|
+
end
|
101
|
+
end
|
102
|
+
rescue OptionParser::ParseError => e
|
103
|
+
opts.warn(e.message)
|
104
|
+
opts.show_usage()
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
while cmd.title.nil?() || cmd.title.empty?() do
|
109
|
+
puts "What is the name of your extension?"
|
110
|
+
cmd.title = STDIN.gets().chomp()
|
111
|
+
end
|
112
|
+
|
113
|
+
$spader_cmd = cmd
|
114
|
+
cmd.execute()
|
115
|
+
end
|
116
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.pre.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cosmic Shovel, Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-25 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Spader provides a framework for building WebExtensions, making it easy
|
14
|
+
to target multiple browsers.
|
15
|
+
email: sup@cosmicshovel.com
|
16
|
+
executables:
|
17
|
+
- spader
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/spader
|
22
|
+
- lib/spader.rb
|
23
|
+
- lib/spader/command.rb
|
24
|
+
- lib/spader/commands/build.rb
|
25
|
+
- lib/spader/commands/generate.rb
|
26
|
+
- lib/spader/document.rb
|
27
|
+
- lib/spader/documents/manifest.rb
|
28
|
+
- lib/spader/documents/messages.rb
|
29
|
+
- lib/spader/documents/project.rb
|
30
|
+
- lib/spader/util.rb
|
31
|
+
homepage: https://github.com/cosmic-shovel/spader
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
metadata: {}
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.3.1
|
49
|
+
requirements: []
|
50
|
+
rubygems_version: 3.1.4
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: WebExtension maker's toolkit.
|
54
|
+
test_files: []
|